This repository was archived by the owner on Nov 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 138
Expand file tree
/
Copy pathu_data.py
More file actions
444 lines (378 loc) · 15.2 KB
/
Copy pathu_data.py
File metadata and controls
444 lines (378 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#!/usr/bin/env python
'''Get the ubxlib instance data from a table in a .md file.'''
from scripts import u_settings
# The file that contains the instance data must be
# a .md file with a table in it containing the data.
# The instance data must be the only table in the file
# and must be in Markdown format as follows:
#
# | instance | description | MCU | board | platform | toolchain | module(s) | APIs supported | UBXLIB_FEATURES | #defines |
#
# ... where:
#
# instance is a set of integers x or x.y or x.y.z,
# description is a textual description,
# MCU is the name of the MCU, e.g. ESP32 or NRF52 or STM32F4,
# board the name of the board, only used by the Zephyr platform,
# platform is the name of the platform, e.g. ESP-IDF or STM32Cube,
# toolchain is the name of a toolchain for that platform, e.g. SES or GCC for nRF5,
# module(s) are the modules connected to the MCU on that platform,
# e.g. SARA-R412M-03B, NINA-B3, M8; where there is more
# than one spaces should be used as separators,
# APIs supported are the APIs that should run on that platform separated by
# spaces, e.g. port net mqtt
# UBXLIB_FEATURES are the ubxlib features to include (gnss cell, short_range, etc.); if empty then use defaults (which is all)
# #defines are the #defines to be applied for this instance, separated by
# spaces, e.g. MY_FLAG U_CFG_APP_PIN_CELLULAR_ENABLE_POWER=-1
#
# The outer column separators may be omitted, case is ignored.
# Prefix to put at the start of all prints
PROMPT = "u_data: "
# The prefix(es) that identify a cellular module
CELLULAR_MODULE_STARTS_WITH = ["SARA", "LARA", "LENA", "LEXI"]
# The prefix(es) that identify a short-range module
SHORT_RANGE_MODULE_STARTS_WITH = ["NINA", "NORA", "ANNA", "ODIN"]
# The file that contains the instance data as a table
# in Markdown format
DATA_FILE = u_settings.DATA_FILE #DATABASE.md
# The prefix to add to a cellular module
CELLULAR_MODULE_TYPE_PREFIX = u_settings.CELLULAR_MODULE_TYPE_PREFIX
# The prefix to add to a short range module
SHORT_RANGE_MODULE_TYPE_PREFIX = u_settings.SHORT_RANGE_MODULE_TYPE_PREFIX
# The prefix to add to a GNSS module
GNSS_MODULE_TYPE_PREFIX = u_settings.GNSS_MODULE_TYPE_PREFIX
def get(filename):
'''Read the instance database from a table in a .md file'''
database = []
row = {}
instance = []
file_handle = open(filename, "r", encoding="utf8")
# Read lines from the file until we hit a row of our table,
# which is defined as a line with at least six '|'
# characters in it
contents = file_handle.read()
lines = contents.splitlines()
for line in lines:
items = line.split("|")
if len(items) >= 7:
index = 0
row.clear()
for item in items:
# Find the instance item,
# should begin with a numeral
stripped = item.strip()
if stripped[:1].isdigit() and index == 0:
# Parse out the numbers and
# add them to the row database
# as a dictionary item
numbers = stripped.split(".")
del instance[:]
for number in numbers:
instance.append(int(number))
row["instance"] = instance[:]
index += 1
else:
# Deal with the other items
if index == 1:
# Description
row["description"] = stripped
index += 1
elif index == 2:
# MCU
row["mcu"] = stripped
index += 1
elif index == 3:
# Board
row["board"] = stripped
index += 1
elif index == 4:
# Platform
row["platform"] = stripped
index += 1
elif index == 5:
# Toolchain
row["toolchain"] = stripped
index += 1
elif index == 6:
# Modules
row["modules"] = stripped.split()
index += 1
elif index == 7:
# APIs
row["apis"] = stripped.split()
index += 1
elif index == 8:
# Featuress
row["UBXLIB_FEATURES"] = stripped.split()
index += 1
elif index == 9:
# #defines
row["defines"] = stripped.split()
index += 1
database.append(row.copy())
file_handle.close()
return database
def display(database):
'''Print out the instances from database'''
print(f"{PROMPT} {len(database)} instance(s) found:")
for row in database:
# Instance first
item = ""
for idx, number in enumerate(row["instance"]):
if idx == 0:
item += str(number)
else:
item += "." + str(number)
item = item.rjust(8)
# Then description
item += f": \"{row['description']}\""
# Then MCU
if row["mcu"] != "":
item += f" {row['mcu']} MCU with"
else:
item += " with"
# Then board
if row["board"] != "":
item += f" {row['board']} board with"
else:
item += " with"
# Then platform
if row["platform"] != "":
item += f" {row['platform']} platform with"
else:
item += " with"
# Then toolchain
if row["toolchain"] != "":
item += f" toolchain \"{row['toolchain']}\""
else:
item += " default toolchain,"
# Then modules
if row["modules"]:
item += " and"
for idx, module in enumerate(row["modules"]):
if idx == 0:
item += " " + module
else:
item += ", " + module
else:
item += " no"
item += " module(s) supporting"
# Then APIs
if row["apis"]:
item += " the API(s)"
for idx, api in enumerate(row["apis"]):
if idx == 0:
item += " \"" + api + "\""
else:
item += ", \"" + api + "\""
else:
item += " no APIs"
# Then UBXLIB_FEATURES
if row["UBXLIB_FEATURES"]:
item += " the UBXLIB_FEATURES"
for idx, ubxlib_feature in enumerate(row["UBXLIB_FEATURES"]):
if idx == 0:
item += " \"" + ubxlib_feature + "\""
else:
item += ", \"" + ubxlib_feature + "\""
else:
item += " default UBXLIB_FEATURES"
# Then the #defines
if row["defines"]:
item += " with required #define(s)"
for idx, define in enumerate(row["defines"]):
if idx == 0:
item += " " + define
else:
item += ", " + define
else:
item += " with no required #defines"
print(f"{item}.")
def get_instances_for_mcu(database, mcu):
'''Return a list of instances that support the given MCU'''
instances = []
for row in database:
if row["mcu"].lower() == mcu.lower():
instances.append(row["instance"][:])
return instances
def get_instances_for_platform_mcu_toolchain(database, platform, mcu, toolchain):
'''Return a list of instances that support a platform/MCU/toolchain combination'''
instances = []
for row in database:
if (row["platform"].lower() == platform.lower()) and \
(mcu is None or (row["mcu"].lower() == mcu.lower())) and \
(toolchain is None or (row["toolchain"].lower() == toolchain.lower())):
instances.append(row["instance"][:])
return instances
def get_toolchains_for_platform_mcu(database, platform, mcu):
'''Return the toolchains for the given platform and MCU combination'''
toolchains = []
for row in database:
if (row["platform"].lower() == platform.lower()) and \
(mcu is None or (row["mcu"].lower() == mcu.lower())) and \
row["toolchain"] is not None:
toolchains.append(row["toolchain"])
return toolchains
def get_instances_for_api(database, api):
'''Return a list of instances that support the given API'''
instances = []
for row in database:
found = False
for _api in row["apis"]:
if not found and (_api.lower() == api.lower()):
instances.append(row["instance"][:])
found = True
return instances
def get_instances_all(database):
'''Return all instances'''
instances = []
for row in database:
instances.append(row["instance"][:])
return instances
def get_platform_for_instance(database, instance):
'''Return the platform that is used by the given instance'''
platform = None
for row in database:
if instance == row["instance"]:
platform = row["platform"]
break
return platform
def get_cellular_module_for_instance(database, instance):
'''Return the cellular module that is used in the given instance'''
module_name = None
for row in database:
if instance == row["instance"]:
if row["modules"]:
for module in row["modules"]:
for starts_with in CELLULAR_MODULE_STARTS_WITH:
if module.startswith(starts_with):
module_name = CELLULAR_MODULE_TYPE_PREFIX + module
break
if module_name:
break
return module_name
def get_short_range_module_for_instance(database, instance):
'''Return the short-range module that is used in the given instance'''
module_name = None
for row in database:
if instance == row["instance"]:
if row["modules"]:
for module in row["modules"]:
for starts_with in SHORT_RANGE_MODULE_STARTS_WITH:
if module.startswith(starts_with):
module_name = SHORT_RANGE_MODULE_TYPE_PREFIX + module
break
if module_name:
break
return module_name
def get_gnss_module_for_instance(database, instance):
'''Return the GNSS module that is used in the given instance'''
module_name = None
for row in database:
if instance == row["instance"]:
if row["modules"]:
for module in row["modules"]:
could_be_gnss = True
for starts_with in CELLULAR_MODULE_STARTS_WITH:
if module.startswith(starts_with):
could_be_gnss = False
break
if could_be_gnss:
for starts_with in SHORT_RANGE_MODULE_STARTS_WITH:
if module.startswith(starts_with):
could_be_gnss = False
break
if could_be_gnss:
module_name = GNSS_MODULE_TYPE_PREFIX + module
break
return module_name
def get_ubxlib_features_for_instance(database, instance):
'''Return the ubxlib features that should be built for the given instance'''
ubxlib_features = None
for row in database:
if instance == row["instance"]:
ubxlib_features = row["UBXLIB_FEATURES"]
return ubxlib_features
def get_defines_for_instance(database, instance):
'''Return the defines that are required by the given instance'''
defines = None
bandmask_already_defined = False
for row in database:
if instance == row["instance"]:
defines = row["defines"]
if not defines:
defines = []
# If there is a cellular module on this instance, add its
# name to the defines list
cellular_module_name = get_cellular_module_for_instance(database, instance)
if cellular_module_name:
defines.append("U_CFG_TEST_CELL_MODULE_TYPE=" + cellular_module_name)
# If there is a short-range module on this instance, add its
# name to the defines list
short_range_module_name = get_short_range_module_for_instance(database, instance)
if short_range_module_name:
defines.append("U_CFG_TEST_SHORT_RANGE_MODULE_TYPE=" + short_range_module_name)
# If there is a GNSS module on this instance, add its
# name to the defines list
gnss_module_name = get_gnss_module_for_instance(database, instance)
if gnss_module_name:
defines.append("U_CFG_TEST_GNSS_MODULE_TYPE=" + gnss_module_name)
# Also, when running testing it is best to run the
# the "port" tests first as, if there's a problem with the
# port, you want to notice it first.
# This also acts as a flag to indicate that we're running
# under u_runner automation
defines.append("U_RUNNER_TOP_STR=port")
for define in defines:
if define.startswith("U_CELL_TEST_CFG_BANDMASK1"):
bandmask_already_defined = True
break
if not bandmask_already_defined:
# When running tests on cellular LTE modules, so
# SARA-R4 or SARA-R5, we need to set the RF band we
# are running in to NOT include the public network,
# since otherwise the modules can sometimes wander off
# onto it.
defines.append("U_CELL_TEST_CFG_BANDMASK1=0x000010ULL")
return defines
def get_toolchain_for_instance(database, instance):
'''Return the toolchain for the given instance'''
toolchain = None
for row in database:
if instance == row["instance"]:
toolchain = row["toolchain"]
break
return toolchain
def get_mcu_for_instance(database, instance):
'''Return the MCU for the given instance'''
mcu = None
for row in database:
if instance == row["instance"]:
mcu = row["mcu"]
break
return mcu
def get_board_for_instance(database, instance):
'''Return the board for the given instance'''
board = None
for row in database:
if instance == row["instance"]:
board = row["board"]
break
return board
def get_description_for_instance(database, instance):
'''Return the description for the given instance'''
description = None
for row in database:
if instance == row["instance"]:
description = row["description"]
return description
def api_in_database(database, api):
'''Return true if the given api is in the database'''
is_in_database = False
for row in database:
if not is_in_database:
for _api in row["apis"]:
if _api == api:
is_in_database = True
break
return is_in_database