summaryrefslogtreecommitdiff
path: root/ports/stm32/make-stmconst.py
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/make-stmconst.py')
-rw-r--r--ports/stm32/make-stmconst.py267
1 files changed, 169 insertions, 98 deletions
diff --git a/ports/stm32/make-stmconst.py b/ports/stm32/make-stmconst.py
index 41ec9b56f..1b3cc08d9 100644
--- a/ports/stm32/make-stmconst.py
+++ b/ports/stm32/make-stmconst.py
@@ -11,16 +11,23 @@ import re
# Python 2/3 compatibility
import platform
-if platform.python_version_tuple()[0] == '2':
+
+if platform.python_version_tuple()[0] == "2":
+
def convert_bytes_to_str(b):
return b
-elif platform.python_version_tuple()[0] == '3':
+
+
+elif platform.python_version_tuple()[0] == "3":
+
def convert_bytes_to_str(b):
try:
- return str(b, 'utf8')
+ return str(b, "utf8")
except ValueError:
# some files have invalid utf8 bytes, so filter them out
- return ''.join(chr(l) for l in b if l <= 126)
+ return "".join(chr(l) for l in b if l <= 126)
+
+
# end compatibility code
# given a list of (name,regex) pairs, find the first one that matches the given line
@@ -31,29 +38,64 @@ def re_match_first(regexs, line):
return name, match
return None, None
+
class LexerError(Exception):
def __init__(self, line):
self.line = line
+
class Lexer:
- re_io_reg = r'__IO uint(?P<bits>8|16|32)_t +(?P<reg>[A-Z0-9]+)'
- re_comment = r'(?P<comment>[A-Za-z0-9 \-/_()&]+)'
- re_addr_offset = r'Address offset: (?P<offset>0x[0-9A-Z]{2,3})'
+ re_io_reg = r"__IO uint(?P<bits>8|16|32)_t +(?P<reg>[A-Z0-9]+)"
+ re_comment = r"(?P<comment>[A-Za-z0-9 \-/_()&]+)"
+ re_addr_offset = r"Address offset: (?P<offset>0x[0-9A-Z]{2,3})"
regexs = (
- ('#define hex', re.compile(r'#define +(?P<id>[A-Z0-9_]+) +\(?(\(uint32_t\))?(?P<hex>0x[0-9A-F]+)U?L?\)?($| */\*)')),
- ('#define X', re.compile(r'#define +(?P<id>[A-Z0-9_]+) +(?P<id2>[A-Z0-9_]+)($| +/\*)')),
- ('#define X+hex', re.compile(r'#define +(?P<id>[A-Za-z0-9_]+) +\(?(?P<id2>[A-Z0-9_]+) \+ (?P<hex>0x[0-9A-F]+)U?L?\)?($| +/\*)')),
- ('#define typedef', re.compile(r'#define +(?P<id>[A-Z0-9_]+(ext)?) +\(\([A-Za-z0-9_]+_TypeDef \*\) (?P<id2>[A-Za-z0-9_]+)\)($| +/\*)')),
- ('typedef struct', re.compile(r'typedef struct$')),
- ('{', re.compile(r'{$')),
- ('}', re.compile(r'}$')),
- ('} TypeDef', re.compile(r'} *(?P<id>[A-Z][A-Za-z0-9_]+)_(?P<global>([A-Za-z0-9_]+)?)TypeDef;$')),
- ('IO reg', re.compile(re_io_reg + r'; */\*!< *' + re_comment + r', +' + re_addr_offset + r' *\*/')),
- ('IO reg array', re.compile(re_io_reg + r'\[(?P<array>[2-8])\]; */\*!< *' + re_comment + r', +' + re_addr_offset + r'-(0x[0-9A-Z]{2,3}) *\*/')),
+ (
+ "#define hex",
+ re.compile(
+ r"#define +(?P<id>[A-Z0-9_]+) +\(?(\(uint32_t\))?(?P<hex>0x[0-9A-F]+)U?L?\)?($| */\*)"
+ ),
+ ),
+ ("#define X", re.compile(r"#define +(?P<id>[A-Z0-9_]+) +(?P<id2>[A-Z0-9_]+)($| +/\*)")),
+ (
+ "#define X+hex",
+ re.compile(
+ r"#define +(?P<id>[A-Za-z0-9_]+) +\(?(?P<id2>[A-Z0-9_]+) \+ (?P<hex>0x[0-9A-F]+)U?L?\)?($| +/\*)"
+ ),
+ ),
+ (
+ "#define typedef",
+ re.compile(
+ r"#define +(?P<id>[A-Z0-9_]+(ext)?) +\(\([A-Za-z0-9_]+_TypeDef \*\) (?P<id2>[A-Za-z0-9_]+)\)($| +/\*)"
+ ),
+ ),
+ ("typedef struct", re.compile(r"typedef struct$")),
+ ("{", re.compile(r"{$")),
+ ("}", re.compile(r"}$")),
+ (
+ "} TypeDef",
+ re.compile(r"} *(?P<id>[A-Z][A-Za-z0-9_]+)_(?P<global>([A-Za-z0-9_]+)?)TypeDef;$"),
+ ),
+ (
+ "IO reg",
+ re.compile(
+ re_io_reg + r"; */\*!< *" + re_comment + r", +" + re_addr_offset + r" *\*/"
+ ),
+ ),
+ (
+ "IO reg array",
+ re.compile(
+ re_io_reg
+ + r"\[(?P<array>[2-8])\]; */\*!< *"
+ + re_comment
+ + r", +"
+ + re_addr_offset
+ + r"-(0x[0-9A-Z]{2,3}) *\*/"
+ ),
+ ),
)
def __init__(self, filename):
- self.file = open(filename, 'rb')
+ self.file = open(filename, "rb")
self.line_number = 0
def next_match(self, strictly_next=False):
@@ -62,7 +104,7 @@ class Lexer:
line = convert_bytes_to_str(line)
self.line_number += 1
if len(line) == 0:
- return ('EOF', None)
+ return ("EOF", None)
match = re_match_first(Lexer.regexs, line.strip())
if strictly_next or match[0] is not None:
return match
@@ -73,6 +115,7 @@ class Lexer:
raise LexerError(self.line_number)
return match
+
def parse_file(filename):
lexer = Lexer(filename)
@@ -81,71 +124,75 @@ def parse_file(filename):
periphs = []
while True:
m = lexer.next_match()
- if m[0] == 'EOF':
+ if m[0] == "EOF":
break
- elif m[0] == '#define hex':
+ elif m[0] == "#define hex":
d = m[1].groupdict()
- consts[d['id']] = int(d['hex'], base=16)
- elif m[0] == '#define X':
+ consts[d["id"]] = int(d["hex"], base=16)
+ elif m[0] == "#define X":
d = m[1].groupdict()
- if d['id2'] in consts:
- consts[d['id']] = consts[d['id2']]
- elif m[0] == '#define X+hex':
+ if d["id2"] in consts:
+ consts[d["id"]] = consts[d["id2"]]
+ elif m[0] == "#define X+hex":
d = m[1].groupdict()
- if d['id2'] in consts:
- consts[d['id']] = consts[d['id2']] + int(d['hex'], base=16)
- elif m[0] == '#define typedef':
+ if d["id2"] in consts:
+ consts[d["id"]] = consts[d["id2"]] + int(d["hex"], base=16)
+ elif m[0] == "#define typedef":
d = m[1].groupdict()
- if d['id2'] in consts:
- periphs.append((d['id'], consts[d['id2']]))
- elif m[0] == 'typedef struct':
- lexer.must_match('{')
+ if d["id2"] in consts:
+ periphs.append((d["id"], consts[d["id2"]]))
+ elif m[0] == "typedef struct":
+ lexer.must_match("{")
m = lexer.next_match()
regs = []
- while m[0] in ('IO reg', 'IO reg array'):
+ while m[0] in ("IO reg", "IO reg array"):
d = m[1].groupdict()
- reg = d['reg']
- offset = int(d['offset'], base=16)
- bits = int(d['bits'])
- comment = d['comment']
- if m[0] == 'IO reg':
+ reg = d["reg"]
+ offset = int(d["offset"], base=16)
+ bits = int(d["bits"])
+ comment = d["comment"]
+ if m[0] == "IO reg":
regs.append((reg, offset, bits, comment))
else:
- for i in range(int(d['array'])):
+ for i in range(int(d["array"])):
regs.append((reg + str(i), offset + i * bits // 8, bits, comment))
m = lexer.next_match()
- if m[0] == '}':
+ if m[0] == "}":
pass
- elif m[0] == '} TypeDef':
- reg_defs[m[1].groupdict()['id']] = regs
+ elif m[0] == "} TypeDef":
+ reg_defs[m[1].groupdict()["id"]] = regs
else:
raise LexerError(lexer.line_number)
return periphs, reg_defs
+
def print_int_obj(val, needed_mpzs):
if -0x40000000 <= val < 0x40000000:
- print('MP_ROM_INT(%#x)' % val, end='')
+ print("MP_ROM_INT(%#x)" % val, end="")
else:
- print('MP_ROM_PTR(&mpz_%08x)' % val, end='')
+ print("MP_ROM_PTR(&mpz_%08x)" % val, end="")
needed_mpzs.add(val)
+
def print_periph(periph_name, periph_val, needed_qstrs, needed_mpzs):
qstr = periph_name.upper()
- print('{ MP_ROM_QSTR(MP_QSTR_%s), ' % qstr, end='')
+ print("{ MP_ROM_QSTR(MP_QSTR_%s), " % qstr, end="")
print_int_obj(periph_val, needed_mpzs)
- print(' },')
+ print(" },")
needed_qstrs.add(qstr)
+
def print_regs(reg_name, reg_defs, needed_qstrs, needed_mpzs):
reg_name = reg_name.upper()
for r in reg_defs:
- qstr = reg_name + '_' + r[0]
- print('{ MP_ROM_QSTR(MP_QSTR_%s), ' % qstr, end='')
+ qstr = reg_name + "_" + r[0]
+ print("{ MP_ROM_QSTR(MP_QSTR_%s), " % qstr, end="")
print_int_obj(r[1], needed_mpzs)
- print(' }, // %s-bits, %s' % (r[2], r[3]))
+ print(" }, // %s-bits, %s" % (r[2], r[3]))
needed_qstrs.add(qstr)
+
# This version of print regs groups registers together into submodules (eg GPIO submodule).
# This makes the qstrs shorter, and makes the list of constants more manageable (since
# they are not all in one big module) but it is then harder to compile the constants, and
@@ -154,21 +201,28 @@ def print_regs(reg_name, reg_defs, needed_qstrs, needed_mpzs):
# And for the number of constants we have, this function seems to use about the same amount
# of ROM as print_regs.
def print_regs_as_submodules(reg_name, reg_defs, modules, needed_qstrs):
- mod_name_lower = reg_name.lower() + '_'
+ mod_name_lower = reg_name.lower() + "_"
mod_name_upper = mod_name_lower.upper()
modules.append((mod_name_lower, mod_name_upper))
- print("""
+ print(
+ """
STATIC const mp_rom_map_elem_t stm_%s_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_%s) },
-""" % (mod_name_lower, mod_name_upper))
+"""
+ % (mod_name_lower, mod_name_upper)
+ )
needed_qstrs.add(mod_name_upper)
for r in reg_defs:
- print(' { MP_ROM_QSTR(MP_QSTR_%s), MP_ROM_INT(%#x) }, // %s-bits, %s' % (r[0], r[1], r[2], r[3]))
+ print(
+ " { MP_ROM_QSTR(MP_QSTR_%s), MP_ROM_INT(%#x) }, // %s-bits, %s"
+ % (r[0], r[1], r[2], r[3])
+ )
needed_qstrs.add(r[0])
- print("""};
+ print(
+ """};
STATIC MP_DEFINE_CONST_DICT(stm_%s_globals, stm_%s_globals_table);
@@ -177,23 +231,35 @@ const mp_obj_module_t stm_%s_obj = {
.name = MP_QSTR_%s,
.globals = (mp_obj_dict_t*)&stm_%s_globals,
};
-""" % (mod_name_lower, mod_name_lower, mod_name_lower, mod_name_upper, mod_name_lower))
+"""
+ % (mod_name_lower, mod_name_lower, mod_name_lower, mod_name_upper, mod_name_lower)
+ )
+
def main():
- cmd_parser = argparse.ArgumentParser(description='Extract ST constants from a C header file.')
- cmd_parser.add_argument('file', nargs=1, help='input file')
- cmd_parser.add_argument('-q', '--qstr', dest='qstr_filename', default='build/stmconst_qstr.h',
- help='Specified the name of the generated qstr header file')
- cmd_parser.add_argument('--mpz', dest='mpz_filename', default='build/stmconst_mpz.h',
- help='the destination file of the generated mpz header')
+ cmd_parser = argparse.ArgumentParser(description="Extract ST constants from a C header file.")
+ cmd_parser.add_argument("file", nargs=1, help="input file")
+ cmd_parser.add_argument(
+ "-q",
+ "--qstr",
+ dest="qstr_filename",
+ default="build/stmconst_qstr.h",
+ help="Specified the name of the generated qstr header file",
+ )
+ cmd_parser.add_argument(
+ "--mpz",
+ dest="mpz_filename",
+ default="build/stmconst_mpz.h",
+ help="the destination file of the generated mpz header",
+ )
args = cmd_parser.parse_args()
periphs, reg_defs = parse_file(args.file[0])
# add legacy GPIO constants that were removed when upgrading CMSIS
- if 'GPIO' in reg_defs and 'stm32f4' in args.file[0]:
- reg_defs['GPIO'].append(['BSRRL', 0x18, 16, 'legacy register'])
- reg_defs['GPIO'].append(['BSRRH', 0x1a, 16, 'legacy register'])
+ if "GPIO" in reg_defs and "stm32f4" in args.file[0]:
+ reg_defs["GPIO"].append(["BSRRL", 0x18, 16, "legacy register"])
+ reg_defs["GPIO"].append(["BSRRH", 0x1A, 16, "legacy register"])
modules = []
needed_qstrs = set()
@@ -206,55 +272,60 @@ def main():
print_periph(periph_name, periph_val, needed_qstrs, needed_mpzs)
for reg in (
- 'ADC',
+ "ADC",
#'ADC_Common',
#'CAN_TxMailBox',
#'CAN_FIFOMailBox',
#'CAN_FilterRegister',
#'CAN',
- 'CRC',
- 'DAC',
- 'DBGMCU',
- 'DMA_Stream',
- 'DMA',
- 'EXTI',
- 'FLASH',
- 'GPIO',
- 'SYSCFG',
- 'I2C',
- 'IWDG',
- 'PWR',
- 'RCC',
- 'RTC',
+ "CRC",
+ "DAC",
+ "DBGMCU",
+ "DMA_Stream",
+ "DMA",
+ "EXTI",
+ "FLASH",
+ "GPIO",
+ "SYSCFG",
+ "I2C",
+ "IWDG",
+ "PWR",
+ "RCC",
+ "RTC",
#'SDIO',
- 'SPI',
- 'TIM',
- 'USART',
- 'WWDG',
- 'RNG',
- ):
+ "SPI",
+ "TIM",
+ "USART",
+ "WWDG",
+ "RNG",
+ ):
if reg in reg_defs:
print_regs(reg, reg_defs[reg], needed_qstrs, needed_mpzs)
- #print_regs_as_submodules(reg, reg_defs[reg], modules, needed_qstrs)
+ # print_regs_as_submodules(reg, reg_defs[reg], modules, needed_qstrs)
- #print("#define MOD_STM_CONST_MODULES \\")
- #for mod_lower, mod_upper in modules:
+ # print("#define MOD_STM_CONST_MODULES \\")
+ # for mod_lower, mod_upper in modules:
# print(" { MP_ROM_QSTR(MP_QSTR_%s), MP_ROM_PTR(&stm_%s_obj) }, \\" % (mod_upper, mod_lower))
print("")
- with open(args.qstr_filename, 'wt') as qstr_file:
- print('#if MICROPY_PY_STM', file=qstr_file)
+ with open(args.qstr_filename, "wt") as qstr_file:
+ print("#if MICROPY_PY_STM", file=qstr_file)
for qstr in sorted(needed_qstrs):
- print('Q({})'.format(qstr), file=qstr_file)
- print('#endif // MICROPY_PY_STM', file=qstr_file)
+ print("Q({})".format(qstr), file=qstr_file)
+ print("#endif // MICROPY_PY_STM", file=qstr_file)
- with open(args.mpz_filename, 'wt') as mpz_file:
+ with open(args.mpz_filename, "wt") as mpz_file:
for mpz in sorted(needed_mpzs):
- assert 0 <= mpz <= 0xffffffff
- print('STATIC const mp_obj_int_t mpz_%08x = {{&mp_type_int}, '
- '{.neg=0, .fixed_dig=1, .alloc=2, .len=2, ' '.dig=(uint16_t*)(const uint16_t[]){%#x, %#x}}};'
- % (mpz, mpz & 0xffff, (mpz >> 16) & 0xffff), file=mpz_file)
+ assert 0 <= mpz <= 0xFFFFFFFF
+ print(
+ "STATIC const mp_obj_int_t mpz_%08x = {{&mp_type_int}, "
+ "{.neg=0, .fixed_dig=1, .alloc=2, .len=2, "
+ ".dig=(uint16_t*)(const uint16_t[]){%#x, %#x}}};"
+ % (mpz, mpz & 0xFFFF, (mpz >> 16) & 0xFFFF),
+ file=mpz_file,
+ )
+
if __name__ == "__main__":
main()