2626import pathlib
2727import re
2828import subprocess
29- import sys
30- import functools
29+
3130
3231from concurrent .futures import ThreadPoolExecutor
3332
5756
5857ALIASES_BRAND_NAMES = {
5958 "circuitplayground_express_4h" : "Adafruit Circuit Playground Express 4-H" ,
60- "circuitplayground_express_digikey_pycon2019" : "Circuit Playground Express Digi-Key PyCon 2019" ,
59+ "circuitplayground_express_digikey_pycon2019" :
60+ "Circuit Playground Express Digi-Key PyCon 2019" ,
6161 "edgebadge" : "Adafruit EdgeBadge" ,
6262 "pyportal_pynt" : "Adafruit PyPortal Pynt" ,
6363 "gemma_m0_pycon2018" : "Adafruit Gemma M0 PyCon 2018" ,
8787 "usb" : "CIRCUITPY_PYUSB" ,
8888}
8989
90- MODULES_NOT_IN_BINDINGS = [ "binascii" , "errno" , "json" , "re" , "ulab" ]
90+ MODULES_NOT_IN_BINDINGS = ["binascii" , "errno" , "json" , "re" , "ulab" ]
9191
9292FROZEN_EXCLUDES = ["examples" , "docs" , "tests" , "utils" , "conf.py" , "setup.py" ]
9393"""Files and dirs at the root of a frozen directory that should be ignored.
@@ -105,7 +105,8 @@ def get_circuitpython_root_dir():
105105
106106
107107def get_bindings ():
108- """Get a list of modules in shared-bindings and ports/*/bindings based on folder names."""
108+ """Get a list of modules in shared-bindings and ports/*/bindings
109+ based on folder names."""
109110 shared_bindings_modules = [
110111 module .name
111112 for module in (get_circuitpython_root_dir () / "shared-bindings" ).iterdir ()
@@ -114,7 +115,8 @@ def get_bindings():
114115 bindings_modules = []
115116 for d in get_circuitpython_root_dir ().glob ("ports/*/bindings" ):
116117 bindings_modules .extend (module .name for module in d .iterdir () if d .is_dir ())
117- return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS + list (ADDITIONAL_MODULES .keys ())
118+ return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS + \
119+ list (ADDITIONAL_MODULES .keys ())
118120
119121
120122def get_board_mapping ():
@@ -127,7 +129,6 @@ def get_board_mapping():
127129 board_path = root_dir / "ports" / port / "boards"
128130 for board_path in os .scandir (board_path ):
129131 if board_path .is_dir ():
130- board_files = os .listdir (board_path .path )
131132 board_id = board_path .name
132133 aliases = ALIASES_BY_BOARD .get (board_path .name , [])
133134 boards [board_id ] = {
@@ -181,7 +182,10 @@ def get_settings_from_makefile(port_dir, board_name):
181182 }
182183
183184 contents = subprocess .run (
184- ["make" , "-C" , port_dir , "-f" , "Makefile" , f"BOARD={ board_name } " , "print-CFLAGS" , "print-CIRCUITPY_BUILD_EXTENSIONS" , "print-FROZEN_MPY_DIRS" , "print-SRC_PATTERNS" , "print-SRC_SUPERVISOR" ],
185+ ["make" , "-C" , port_dir , "-f" , "Makefile" , f"BOARD={ board_name } " ,
186+ "print-CFLAGS" , "print-CIRCUITPY_BUILD_EXTENSIONS" ,
187+ "print-FROZEN_MPY_DIRS" , "print-SRC_PATTERNS" ,
188+ "print-SRC_SUPERVISOR" ],
185189 encoding = "utf-8" ,
186190 errors = "replace" ,
187191 stdout = subprocess .PIPE ,
@@ -288,7 +292,6 @@ def lookup_setting(settings, key, default=""):
288292 return value
289293
290294
291- @functools .cache
292295def all_ports_all_boards (ports = SUPPORTED_PORTS ):
293296 for port in ports :
294297 port_dir = get_circuitpython_root_dir () / "ports" / port
@@ -298,7 +301,9 @@ def all_ports_all_boards(ports=SUPPORTED_PORTS):
298301 yield (port , entry )
299302
300303
301- def support_matrix_by_board (use_branded_name = True , withurl = True ):
304+ def support_matrix_by_board (use_branded_name = True , withurl = True ,
305+ add_port = False , add_chips = False ,
306+ add_pins = False , add_branded_name = False ):
302307 """Compiles a list of the available core modules available for each
303308 board.
304309 """
@@ -309,17 +314,64 @@ def support_matrix(arg):
309314 port_dir = get_circuitpython_root_dir () / "ports" / port
310315 settings = get_settings_from_makefile (str (port_dir ), entry .name )
311316
312- if use_branded_name :
317+ if use_branded_name or add_branded_name :
313318 with open (entry / "mpconfigboard.h" ) as get_name :
314319 board_contents = get_name .read ()
315320 board_name_re = re .search (
316321 r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)" , board_contents
317322 )
318323 if board_name_re :
319- board_name = board_name_re .group (1 ).strip ('"' )
324+ branded_name = board_name_re .group (1 ).strip ('"' )
325+ if '"' in branded_name : # sometimes the closing " is not at line end
326+ branded_name = branded_name [:branded_name .index ('"' )]
327+ board_name = branded_name
328+
329+ if use_branded_name :
330+ board_name = branded_name
320331 else :
321332 board_name = entry .name
322333
334+ if add_chips :
335+ with open (entry / "mpconfigboard.h" ) as get_name :
336+ board_contents = get_name .read ()
337+ mcu_re = re .search (
338+ r'(?<=MICROPY_HW_MCU_NAME)\s+(.+)' , board_contents
339+ )
340+ if mcu_re :
341+ mcu = mcu_re .group (1 ).strip ('"' )
342+ if '"' in mcu : # in case the closing " is not at line end
343+ mcu = mcu [:mcu .index ('"' )]
344+ else :
345+ mcu = ""
346+ with open (entry / "mpconfigboard.mk" ) as get_name :
347+ board_contents = get_name .read ()
348+ flash_re = re .search (
349+ r'(?<=EXTERNAL_FLASH_DEVICES)\s+=\s+(.+)' , board_contents
350+ )
351+ if flash_re :
352+ # deal with the variability in the way multiple flash chips
353+ # are denoted. We want them to end up as a quoted,
354+ # comma separated string
355+ flash = flash_re .group (1 ).replace ('"' ,'' )
356+ flash = f'"{ flash } "'
357+ else :
358+ flash = ""
359+
360+ if add_pins :
361+ pins = []
362+ try :
363+ with open (entry / "pins.c" ) as get_name :
364+ pin_lines = get_name .readlines ()
365+ except FileNotFoundError : # silabs boards have no pins.c
366+ pass
367+ else :
368+ for p in pin_lines :
369+ pin_re = re .search (r"QSTR_([^\)]+).+pin_([^\)]+)" , p )
370+ if pin_re :
371+ board_pin = pin_re .group (1 )
372+ chip_pin = pin_re .group (2 )
373+ pins .append ((board_pin , chip_pin ))
374+
323375 board_modules = []
324376 for module in base :
325377 key = base [module ]["key" ]
@@ -344,14 +396,25 @@ def support_matrix(arg):
344396 frozen_modules .sort ()
345397
346398 # generate alias boards too
399+
400+ board_info = {
401+ "modules" : board_modules ,
402+ "frozen_libraries" : frozen_modules ,
403+ "extensions" : board_extensions ,
404+ }
405+ if add_branded_name :
406+ board_info ["branded_name" ] = branded_name
407+ if add_port :
408+ board_info ["port" ] = port
409+ if add_chips :
410+ board_info ["mcu" ] = mcu
411+ board_info ["flash" ] = flash
412+ if add_pins :
413+ board_info ["pins" ] = pins
347414 board_matrix = [
348415 (
349416 board_name ,
350- {
351- "modules" : board_modules ,
352- "frozen_libraries" : frozen_modules ,
353- "extensions" : board_extensions ,
354- },
417+ board_info
355418 )
356419 ]
357420 if entry .name in ALIASES_BY_BOARD :
@@ -361,14 +424,24 @@ def support_matrix(arg):
361424 alias = ALIASES_BRAND_NAMES [alias ]
362425 else :
363426 alias = alias .replace ("_" , " " ).title ()
427+ board_info = {
428+ "modules" : board_modules ,
429+ "frozen_libraries" : frozen_modules ,
430+ "extensions" : board_extensions ,
431+ }
432+ if add_branded_name :
433+ board_info ["branded_name" ] = branded_name
434+ if add_port :
435+ board_info ["port" ] = port
436+ if add_chips :
437+ board_info ["mcu" ] = mcu
438+ board_info ["flash" ] = flash
439+ if add_pins :
440+ board_info ["pins" ] = pins
364441 board_matrix .append (
365442 (
366443 alias ,
367- {
368- "modules" : board_modules ,
369- "frozen_libraries" : frozen_modules ,
370- "extensions" : board_extensions ,
371- },
444+ board_info
372445 )
373446 )
374447
0 commit comments