26
26
import pathlib
27
27
import re
28
28
import subprocess
29
- import sys
30
- import functools
29
+
31
30
32
31
from concurrent .futures import ThreadPoolExecutor
33
32
57
56
58
57
ALIASES_BRAND_NAMES = {
59
58
"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" ,
61
61
"edgebadge" : "Adafruit EdgeBadge" ,
62
62
"pyportal_pynt" : "Adafruit PyPortal Pynt" ,
63
63
"gemma_m0_pycon2018" : "Adafruit Gemma M0 PyCon 2018" ,
87
87
"usb" : "CIRCUITPY_PYUSB" ,
88
88
}
89
89
90
- MODULES_NOT_IN_BINDINGS = [ "binascii" , "errno" , "json" , "re" , "ulab" ]
90
+ MODULES_NOT_IN_BINDINGS = ["binascii" , "errno" , "json" , "re" , "ulab" ]
91
91
92
92
FROZEN_EXCLUDES = ["examples" , "docs" , "tests" , "utils" , "conf.py" , "setup.py" ]
93
93
"""Files and dirs at the root of a frozen directory that should be ignored.
@@ -105,7 +105,8 @@ def get_circuitpython_root_dir():
105
105
106
106
107
107
def 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."""
109
110
shared_bindings_modules = [
110
111
module .name
111
112
for module in (get_circuitpython_root_dir () / "shared-bindings" ).iterdir ()
@@ -114,7 +115,8 @@ def get_bindings():
114
115
bindings_modules = []
115
116
for d in get_circuitpython_root_dir ().glob ("ports/*/bindings" ):
116
117
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 ())
118
120
119
121
120
122
def get_board_mapping ():
@@ -127,7 +129,6 @@ def get_board_mapping():
127
129
board_path = root_dir / "ports" / port / "boards"
128
130
for board_path in os .scandir (board_path ):
129
131
if board_path .is_dir ():
130
- board_files = os .listdir (board_path .path )
131
132
board_id = board_path .name
132
133
aliases = ALIASES_BY_BOARD .get (board_path .name , [])
133
134
boards [board_id ] = {
@@ -181,7 +182,10 @@ def get_settings_from_makefile(port_dir, board_name):
181
182
}
182
183
183
184
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" ],
185
189
encoding = "utf-8" ,
186
190
errors = "replace" ,
187
191
stdout = subprocess .PIPE ,
@@ -288,7 +292,6 @@ def lookup_setting(settings, key, default=""):
288
292
return value
289
293
290
294
291
- @functools .cache
292
295
def all_ports_all_boards (ports = SUPPORTED_PORTS ):
293
296
for port in ports :
294
297
port_dir = get_circuitpython_root_dir () / "ports" / port
@@ -298,7 +301,9 @@ def all_ports_all_boards(ports=SUPPORTED_PORTS):
298
301
yield (port , entry )
299
302
300
303
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 ):
302
307
"""Compiles a list of the available core modules available for each
303
308
board.
304
309
"""
@@ -309,17 +314,64 @@ def support_matrix(arg):
309
314
port_dir = get_circuitpython_root_dir () / "ports" / port
310
315
settings = get_settings_from_makefile (str (port_dir ), entry .name )
311
316
312
- if use_branded_name :
317
+ if use_branded_name or add_branded_name :
313
318
with open (entry / "mpconfigboard.h" ) as get_name :
314
319
board_contents = get_name .read ()
315
320
board_name_re = re .search (
316
321
r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)" , board_contents
317
322
)
318
323
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
320
331
else :
321
332
board_name = entry .name
322
333
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
+
323
375
board_modules = []
324
376
for module in base :
325
377
key = base [module ]["key" ]
@@ -344,14 +396,25 @@ def support_matrix(arg):
344
396
frozen_modules .sort ()
345
397
346
398
# 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
347
414
board_matrix = [
348
415
(
349
416
board_name ,
350
- {
351
- "modules" : board_modules ,
352
- "frozen_libraries" : frozen_modules ,
353
- "extensions" : board_extensions ,
354
- },
417
+ board_info
355
418
)
356
419
]
357
420
if entry .name in ALIASES_BY_BOARD :
@@ -361,14 +424,24 @@ def support_matrix(arg):
361
424
alias = ALIASES_BRAND_NAMES [alias ]
362
425
else :
363
426
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
364
441
board_matrix .append (
365
442
(
366
443
alias ,
367
- {
368
- "modules" : board_modules ,
369
- "frozen_libraries" : frozen_modules ,
370
- "extensions" : board_extensions ,
371
- },
444
+ board_info
372
445
)
373
446
)
374
447
0 commit comments