29
29
SUPPORTED_PORTS = ["atmel-samd" , "nrf" ]
30
30
31
31
32
+ def parse_port_config (contents , chip_keyword = None ):
33
+ """ Compile a dictionary of port-wide module configs, which may
34
+ be categorized by chipset.
35
+ """
36
+ chip_fam = "all"
37
+ ifeq_found = False
38
+ port_config_results = {"all" : []}
39
+
40
+ chip_pattern = ""
41
+ if chip_keyword :
42
+ chip_pattern = (
43
+ re .compile ("(?<=ifeq\s\(\$\({}\)\,)(\w+)" .format (chip_keyword ))
44
+ )
45
+
46
+ for line in contents :
47
+ if chip_keyword :
48
+ if not ifeq_found :
49
+ check_ifeq = chip_pattern .search (line )
50
+ if check_ifeq :
51
+ ifeq_found = True
52
+ chip_fam = check_ifeq .group (1 )
53
+ print ("found chip:" , chip_fam )
54
+ else :
55
+ ifeq_found = False
56
+ chip_fam = "all"
57
+ else :
58
+ if "endif" in line :
59
+ ifeq_found = False
60
+ chip_fam = "all"
61
+
62
+ if "CIRCUITPY_" in line :
63
+ if chip_fam in port_config_results :
64
+ port_config_results [chip_fam ].append (line .rstrip ("\n " ))
65
+ else :
66
+ port_config_results [chip_fam ] = [line .rstrip ("\n " )]
67
+
68
+ #print(port_config_results)
69
+ return port_config_results
70
+
32
71
def get_shared_bindings ():
33
72
""" Get a list of modules in shared-bindings based on folder names
34
73
"""
@@ -45,13 +84,15 @@ def read_mpconfig():
45
84
return configs
46
85
47
86
48
- def build_module_map (modules , configs ):
87
+ def build_module_map ():
49
88
""" Establish the base of the JSON file, based on the contents from
50
89
`configs`. Base will contain module names, if they're part of
51
90
the `FULL_BUILD`, or their default value (0 | 1).
52
91
53
92
"""
54
93
base = dict ()
94
+ modules = get_shared_bindings ()
95
+ configs = read_mpconfig ()
55
96
full_build = False
56
97
for module in modules :
57
98
full_name = module
@@ -71,55 +112,122 @@ def build_module_map(modules, configs):
71
112
"name" : full_name ,
72
113
"full_build" : str (full_build ),
73
114
"default_value" : default_val ,
74
- "excluded" : []
115
+ "excluded" : {}
75
116
}
76
117
77
- return get_excluded_boards ( base )
118
+ return base
78
119
79
120
80
121
def get_excluded_boards (base ):
81
122
""" Cycles through each board's `mpconfigboard.mk` file to determine
82
123
if each module is included or not. Boards are selected by existence
83
124
in a port listed in `SUPPORTED_PORTS` (e.g. `/port/nrf/feather_52840`)
125
+
126
+ Boards are further categorized by their respective chipset (SAMD21,
127
+ SAMD51, nRF52840, etc.)
84
128
"""
85
129
modules = list (base .keys ())
130
+
131
+ re_board_chip = None
132
+ chip_keyword = None
86
133
for port in SUPPORTED_PORTS :
87
- port_dir = "ports/{}/boards" .format (port )
88
- for entry in os .scandir (port_dir ):
134
+ # each port appears to use its own define for the chipset
135
+ if port in ["atmel-samd" ]:
136
+ re_board_chip = re .compile ("CHIP_FAMILY\s=\s(\w+)" )
137
+ chip_keyword = "CHIP_FAMILY"
138
+ elif port in ["nrf" ]:
139
+ re_board_chip = re .compile ("MCU_VARIANT\s=\s(\w+)" )
140
+
141
+ port_dir = "ports/{}" .format (port )
142
+
143
+ port_config_contents = ""
144
+ with open (os .path .join (port_dir , "mpconfigport.mk" )) as port_config :
145
+ port_config_contents = port_config .readlines ()
146
+ port_config = parse_port_config (port_config_contents , chip_keyword )
147
+
148
+ for entry in os .scandir (os .path .join (port_dir , "boards" )):
89
149
if not entry .is_dir ():
90
150
continue
151
+
91
152
contents = ""
92
153
board_dir = os .path .join (entry .path , "mpconfigboard.mk" )
93
- #print(board_dir)
94
154
with open (board_dir ) as board :
95
155
contents = board .read ()
156
+
157
+ board_chip = re_board_chip .search (contents )
158
+ #print(entry.name, board_chip.group(1))
159
+ if not board_chip :
160
+ board_chip = "Unknown Chip"
161
+ else :
162
+ board_chip = board_chip .group (1 )
163
+
164
+ # add port_config results to contents
165
+ contents += "\n " + "\n " .join (port_config ["all" ])
166
+ if board_chip in port_config :
167
+ contents += "\n " + "\n " .join (port_config [board_chip ])
168
+
96
169
for module in modules :
170
+ board_is_excluded = False
97
171
# check if board uses `SMALL_BUILD`. if yes, and current
98
172
# module is marked as `FULL_BUILD`, board is excluded
99
173
small_build = re .search ("CIRCUITPY_SMALL_BUILD = 1" , contents )
100
174
if small_build and base [module ]["full_build" ] == "1" :
101
- base [module ]["excluded" ].append (entry .name )
102
- continue
103
-
175
+ board_is_excluded = True
104
176
# check if module is specifically disabled for this board
105
177
re_pattern = "CIRCUITPY_{}\s=\s(\w)" .format (module .upper ())
106
178
find_module = re .search (re_pattern , contents )
107
179
if not find_module :
108
180
# check if default inclusion is off ('0'). if the board doesn't
109
181
# have it explicitly enabled, its excluded.
110
182
if base [module ]["default_value" ] == "0" :
111
- base [module ]["excluded" ].append (entry .name )
112
- continue
113
- if (find_module .group (1 ) == "0" and
114
- find_module .group (1 ) != base [module ]["default_value" ]):
115
- base [module ]["excluded" ].append (entry .name )
116
-
183
+ board_is_excluded = True
184
+ else :
185
+ if (find_module .group (1 ) == "0" and
186
+ find_module .group (1 ) != base [module ]["default_value" ]):
187
+ board_is_excluded = True
188
+
189
+ if board_is_excluded :
190
+ if board_chip in base [module ]["excluded" ]:
191
+ base [module ]["excluded" ][board_chip ].append (entry .name )
192
+ else :
193
+ base [module ]["excluded" ][board_chip ] = [entry .name ]
194
+ #print(json.dumps(base, indent=2))
117
195
return base
118
196
119
197
120
- def support_matrix ():
121
- modules = get_shared_bindings ()
122
- configs = read_mpconfig ()
123
- base = build_module_map (sorted (modules ), configs )
198
+ def support_matrix_excluded_boards ():
199
+ """ Compiles a list of available modules, and which board definitions
200
+ do not include them.
201
+ """
202
+ base = build_module_map ()
124
203
125
- return base
204
+ return get_excluded_boards (base )
205
+
206
+ def support_matrix_by_board ():
207
+ """ Compiles a list of the available core modules available for each
208
+ board.
209
+ """
210
+ base = build_module_map ()
211
+ base_with_exclusions = get_excluded_boards (base )
212
+
213
+ boards = dict ()
214
+ for port in SUPPORTED_PORTS :
215
+ port_dir = "ports/{}/boards" .format (port )
216
+ for entry in os .scandir (port_dir ):
217
+ if not entry .is_dir ():
218
+ continue
219
+ board_modules = []
220
+ for module in base_with_exclusions .keys ():
221
+ #print(module)
222
+ board_has_module = True
223
+ if base_with_exclusions [module ]["excluded" ]:
224
+ for port in base_with_exclusions [module ]["excluded" ].values ():
225
+ #print(port)
226
+ if entry .name in port :
227
+ board_has_module = False
228
+
229
+ if board_has_module :
230
+ board_modules .append (base_with_exclusions [module ]["name" ])
231
+ boards [entry .name ] = sorted (board_modules )
232
+
233
+ return boards
0 commit comments