diff --git a/d b/d index e2ac187..9884a6c 100755 --- a/d +++ b/d @@ -18,6 +18,7 @@ case "$CMD" in ./d download-svd ./d download-headers ./d download-cubedb + ./d download-cubeprogdb ;; download-mcufinder) mkdir -p sources/mcufinder @@ -53,6 +54,10 @@ case "$CMD" in rm -rf sources/cubedb git clone --depth 1 https://github.com/embassy-rs/stm32cube-database.git sources/cubedb ;; + download-cubeprogdb) + rm -rf sources/cubeprogdb + git clone --depth 1 https://github.com/embassy-rs/stm32cubeprog-database.git sources/cubeprogdb + ;; install-chiptool) cargo install --git https://github.com/embassy-rs/chiptool ;; diff --git a/data/memories.yaml b/data/memories.yaml new file mode 100644 index 0000000..5d51f8b --- /dev/null +++ b/data/memories.yaml @@ -0,0 +1,702 @@ +- device-id: 0x410 + names: + - STM32F101 + - STM32F102 + - STM32F103 + ram: + address: 0x20000000 + bytes: 0x5000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x411 + names: + - STM32F2xx + ram: + address: 0x20000000 + bytes: 0x20000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x412 + names: + - STM32F101 + - STM32F102 + - STM32F103 + ram: + address: 0x20000000 + bytes: 0x2800 + flash: + address: 0x8000000 + bytes: 0x8000 +- device-id: 0x413 + names: + - STM32F405xx + - STM32F407xx + - STM32F415xx + - STM32F417xx + ram: + address: 0x20000000 + bytes: 0x20000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x414 + names: + - STM32F101 + - STM32F103 + ram: + address: 0x20000000 + bytes: 0x10000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x415 + names: + - STM32L4x1 + - STM32L475xx + - STM32L476xx + - STM32L486xx + ram: + address: 0x20000000 + bytes: 0x18000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x416 + names: + - STM32L100x8 + - STM32L100xB + - STM32L15xx6 + - STM32L15xx8 + - STM32L15xxB + ram: + address: 0x20000000 + bytes: 0x2800 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x417 + names: + - STM32L05x + - STM32L06x + - STM32L010 + ram: + address: 0x20000000 + bytes: 0x2000 + flash: + address: 0x8000000 + bytes: 0x10000 +- device-id: 0x418 + names: + - STM32F105 + - STM32F107 + ram: + address: 0x20000000 + bytes: 0x10000 + flash: + address: 0x8000000 + bytes: 0x40000 +- device-id: 0x419 + names: + - STM32F42xxx + - STM32F43xxx + ram: + address: 0x20000000 + bytes: 0x30000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x420 + names: + - STM32F100 + - STMMedium + ram: + address: 0x20000000 + bytes: 0x2000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x421 + names: + - STM32F446xx + ram: + address: 0x20000000 + bytes: 0x20000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x422 + names: + - STM32F302xB + - STM32F302xC + - STM32F303xB + - STM32F303xC + - STM32F358xx + ram: + address: 0x20000000 + bytes: 0xa000 + flash: + address: 0x8000000 + bytes: 0x40000 +- device-id: 0x423 + names: + - STM32F401xB + - STM32F401xC + ram: + address: 0x20000000 + bytes: 0x10000 + flash: + address: 0x8000000 + bytes: 0x40000 +- device-id: 0x425 + names: + - STM32L03x + - STM32L04x + - STM32L010 + ram: + address: 0x20000000 + bytes: 0x2000 + flash: + address: 0x8000000 + bytes: 0x8000 +- device-id: 0x427 + names: + - STM32L100xC + - STM32L15xxC + - STM32L162xC + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x40000 +- device-id: 0x428 + names: + - STM32F100 + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x429 + names: + - STM32L100x6xxA + - STM32L100x8xxA + - STM32L100xBxxA + - STM32L15xx6xxA + - STM32L15xx8xxA + - STM32L15xxBxxA + ram: + address: 0x20000000 + bytes: 0x4000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x430 + names: + - STM32F101 + - STM32F103 + ram: + address: 0x20000000 + bytes: 0x18000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x431 + names: + - STM32F411xC + - STM32F411xE + ram: + address: 0x20000000 + bytes: 0x10000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x432 + names: + - STM32F37xx + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x40000 +- device-id: 0x433 + names: + - STM32F401xD + - STM32F401xE + ram: + address: 0x20000000 + bytes: 0x10000 + flash: + address: 0x8000000 + bytes: 0x800000 +- device-id: 0x434 + names: + - STM32F469xx + - STM32F467xx + ram: + address: 0x20000000 + bytes: 0x50000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x435 + names: + - STM32L43xxx + - STM32L44xxx + ram: + address: 0x20000000 + bytes: 0xc000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x436 + names: + - STM32L15xxD + - STM32L162xD + ram: + address: 0x20000000 + bytes: 0xc000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x437 + names: + - STM32L15xxE + - STM32L162xE + ram: + address: 0x20000000 + bytes: 0x14000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x438 + names: + - STM32F303x4 + - STM32F303x6 + - STM32F303x8 + - STM32F328xx + - STM32F334xx + ram: + address: 0x20000000 + bytes: 0x3000 + flash: + address: 0x8000000 + bytes: 0x10000 +- device-id: 0x439 + names: + - STM32F301x4 + - STM32F301x6 + - STM32F301x8 + - STM32F302x4 + - STM32F302x6 + - STM32F302x8 + - STM32F318xx + ram: + address: 0x20000000 + bytes: 0x4000 + flash: + address: 0x8000000 + bytes: 0x10000 +- device-id: 0x440 + names: + - STM32F05x + - STM32F030x8 + ram: + address: 0x20000000 + bytes: 0x1ff8 + flash: + address: 0x8000000 + bytes: 0x10000 +- device-id: 0x441 + names: + - STM32F412 + ram: + address: 0x20000000 + bytes: 0x40000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x442 + names: + - STM32F09x + - STM32F030xC + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x40000 +- device-id: 0x443 + names: + - STM32C01x + ram: + address: 0x20000000 + bytes: 0x1800 + flash: + address: 0x8000000 + bytes: 0x8000 +- device-id: 0x444 + names: + - STM32F03x + ram: + address: 0x20000000 + bytes: 0x1000 + flash: + address: 0x8000000 + bytes: 0x8000 +- device-id: 0x445 + names: + - STM32F04x + - STM32F070x6 + ram: + address: 0x20000000 + bytes: 0x1800 + flash: + address: 0x8000000 + bytes: 0x8000 +- device-id: 0x446 + names: + - STM32F302xE + - STM32F303xE + - STM32F398xx + ram: + address: 0x20000000 + bytes: 0x10000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x447 + names: + - STM32L07x + - STM32L08x + - STM32L010 + ram: + address: 0x20000000 + bytes: 0x5000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x448 + names: + - STM32F07x + ram: + address: 0x20000000 + bytes: 0x4000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x449 + names: + - STM32F74x + - STM32F75x + ram: + address: 0x20000000 + bytes: 0x50000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x450 + names: + - STM32H7xx + ram: + address: 0x24000000 + bytes: 0x80000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x451 + names: + - STM32F76x + - STM32F77x + ram: + address: 0x20000000 + bytes: 0x80000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x452 + names: + - STM32F72x + - STM32F73x + ram: + address: 0x20000000 + bytes: 0x40000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x453 + names: + - STM32C0 + ram: + address: 0x20000000 + bytes: 0x1800 + flash: + address: 0x8000000 + bytes: 0x8000 +- device-id: 0x456 + names: + - STM32G051 + - STM32G061 + ram: + address: 0x20000000 + bytes: 0x4000 + flash: + address: 0x8000000 + bytes: 0x10000 +- device-id: 0x457 + names: + - STM32L01x + - STM32L02x + ram: + address: 0x20000000 + bytes: 0x800 + flash: + address: 0x8000000 + bytes: 0x4000 +- device-id: 0x458 + names: + - STM32F410 + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x460 + names: + - STM32G07x + - STM32G08x + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x461 + names: + - STM32L496xx + - STM32L4A6xx + ram: + address: 0x20000000 + bytes: 0x40000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x462 + names: + - STM32L45x + - STM32L46x + ram: + address: 0x20000000 + bytes: 0x20000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x463 + names: + - STM32F413 + - STM32F423 + ram: + address: 0x20000000 + bytes: 0x50000 + flash: + address: 0x8000000 + bytes: 0x180000 +- device-id: 0x464 + names: + - STM32L41x + ram: + address: 0x20000000 + bytes: 0xa000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x466 + names: + - STM32G03x + - STM32G04x + ram: + address: 0x20000000 + bytes: 0x2000 + flash: + address: 0x8000000 + bytes: 0x10000 +- device-id: 0x467 + names: + - STM32G0B1xx + - STM32G0C1xx + ram: + address: 0x20000000 + bytes: 0x20000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x468 + names: + - STM32G43x + - STM32G44x + ram: + address: 0x20000000 + bytes: 0x5000 + flash: + address: 0x8000000 + bytes: 0x20000 +- device-id: 0x469 + names: + - STM32G47x + - STM32G48x + ram: + address: 0x20000000 + bytes: 0x18000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x470 + names: + - STM32L4Rxxx + - STM32L4Sxxx + ram: + address: 0x20000000 + bytes: 0x30000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x471 + names: + - STM32L4Pxxx + - STM32L4Qxxx + ram: + address: 0x20000000 + bytes: 0x30000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x472 + names: + - STM32L5xx + ram: + address: 0x20000000 + bytes: 0x40000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x479 + names: + - STM32G491xC + - STM32G491xE + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x480 + names: + - STM32H7A + - STM32H7B + ram: + address: 0x24000000 + bytes: 0x100000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x481 + names: + - STM32U5xx + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x400000 +- device-id: 0x482 + names: + - STM32U575 + - STM32U585 + ram: + address: 0x20000000 + bytes: 0xc0000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x483 + names: + - STM32H72x + - STM32H73x + ram: + address: 0x24000000 + bytes: 0x20000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x484 + names: + - STM32H5xx + ram: + address: 0x20000000 + bytes: 0x40000 + flash: + address: 0x8000000 + bytes: 0x200000 +- device-id: 0x492 + names: + - STM32WBA55 + - STM32WBA54 + ram: + address: 0x20000000 + bytes: 0x10000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x494 + names: + - STM32WB1xxx + ram: + address: 0x20000000 + bytes: 0x3000 + flash: + address: 0x8000000 + bytes: 0x50000 +- device-id: 0x495 + names: + - STM32WB5x + ram: + address: 0x20000000 + bytes: 0x30000 + flash: + address: 0x8000000 + bytes: 0x100000 +- device-id: 0x496 + names: + - STM32WB35xx + ram: + address: 0x20000000 + bytes: 0x8000 + flash: + address: 0x8000000 + bytes: 0x80000 +- device-id: 0x497 + names: + - STM32WLxx + ram: + address: 0x20000000 + bytes: 0x3000 + flash: + address: 0x8000000 + bytes: 0x40000 +- device-id: 0x500 + names: + - STM32MP1 + ram: + address: 0x10000000 + bytes: 0x20000 +- device-id: 0x501 + names: + - STM32MP13xx + ram: + address: 0x10000000 + bytes: 0x20000 diff --git a/parse.py b/parse.py index 0b21927..91ef4a1 100755 --- a/parse.py +++ b/parse.py @@ -3,6 +3,7 @@ import sys import xmltodict import yaml + try: from yaml import CSafeLoader as SafeLoader except ImportError: @@ -15,6 +16,30 @@ from collections import OrderedDict from glob import glob +class DecimalInt: + def __init__(self, val): + self.val = val + + +def represent_decimal_int(dumper, data): + return dumper.represent_int(data.val) + + +yaml.add_representer(DecimalInt, represent_decimal_int) + + +class HexInt: + def __init__(self, val): + self.val = val + + +def represent_hex_int(dumper, data): + return dumper.represent_int(hex(data.val)) + + +yaml.add_representer(HexInt, represent_hex_int) + + def removeprefix(value: str, prefix: str, /) -> str: if value.startswith(prefix): return value[len(prefix):] @@ -112,6 +137,7 @@ def paren_ok(val): return False return n == 0 + # warning: horrible abomination ahead @@ -167,21 +193,21 @@ def parse_header(f): cur_core = "cm" + str(m.group(1)) if m.group(2) != None: cur_core += "p" - #print("Cur core is ", cur_core, "matched", l) + # print("Cur core is ", cur_core, "matched", l) found = False for core in cores: if core == cur_core: found = True if not found: cores.append(cur_core) - #print("Switching to core", cur_core, "for", f) + # print("Switching to core", cur_core, "for", f) elif m := re.match('.*else.*', l): cur_core = "all" if m := re.match('.*else.*CORE_CM(\\d+)(PLUS)?.*', l): cur_core = "cm" + str(m.group(1)) if m.group(2) != None: cur_core += "p" - #print("Cur core is ", cur_core, "matched", l) + # print("Cur core is ", cur_core, "matched", l) elif len(cores) > 1: # Pick the second core assuming we've already parsed one cur_core = cores[1] @@ -192,19 +218,19 @@ def parse_header(f): found = True if not found: cores.append(cur_core) - #print("Switching to core", cur_core, "for", f) + # print("Switching to core", cur_core, "for", f) elif m := re.match('.*endif.*', l): - #print("Switching to common core for", f) + # print("Switching to common core for", f) cur_core = "all" if cur_core not in irqs: - #print("Registering new core", cur_core) + # print("Registering new core", cur_core) irqs[cur_core] = {} if cur_core not in defines: defines[cur_core] = {} if m := re.match('([a-zA-Z0-9_]+)_IRQn += (\\d+),? +/\\*!< (.*) \\*/', l): - #print("Found irq for", cur_core) + # print("Found irq for", cur_core) irqs[cur_core][m.group(1)] = int(m.group(2)) if m := re.match('#define +([0-9A-Za-z_]+)\\(', l): @@ -217,11 +243,11 @@ def parse_header(f): continue val = val.split('/*')[0].strip() val = parse_value(val, defines[cur_core]) - #print("Found define for", cur_core) + # print("Found define for", cur_core) defines[cur_core][name] = val - #print("Found", len(cores), "cores for", f) - #print("Found", len(irqs['all']), "shared interrupts for", f) + # print("Found", len(cores), "cores for", f) + # print("Found", len(irqs['all']), "shared interrupts for", f) if len(cores) == 0: cores.append("all") @@ -369,7 +395,7 @@ perimap = [ def match_peri(peri): for r, block in perimap: - if re.match('^'+r+'$', peri): + if re.match('^' + r + '$', peri): if block == '': return None return block @@ -462,12 +488,30 @@ def chip_name_from_package_name(x): ] for a, b in name_map: - r, n = re.subn('^'+a+'$', b, x) + r, n = re.subn('^' + a + '$', b, x) if n != 0: return r raise Exception("bad name: {}".format(x)) +memories_map = { + 'flash': [ + 'FLASH', 'FLASH_BANK1', 'FLASH_BANK2', + 'D1_AXIFLASH', 'D1_AXIICP', + ], + 'ram': [ + 'SRAM', 'SRAM1', 'SRAM2', + 'D1_AXISRAM', + 'D1_ITCMRAM', + 'D1_DTCMRAM', + 'D1_AHBSRAM', + 'D2_AXISRAM', + 'D3_BKPSRAM', + 'D3_SRAM' + ], +} + + def parse_chips(): os.makedirs('data/chips', exist_ok=True) @@ -488,13 +532,19 @@ def parse_chips(): package_flashs = r['Flash'] die = r['Die'] if type(package_rams) != list: - package_rams = [package_rams]*len(package_names) + package_rams = [package_rams] * len(package_names) if type(package_flashs) != list: - package_flashs = [package_flashs]*len(package_names) + package_flashs = [package_flashs] * len(package_names) for package_i, package_name in enumerate(package_names): chip_name = chip_name_from_package_name(package_name) - flash = int(package_flashs[package_i]) - ram = int(package_rams[package_i]) + flash = OrderedDict({ + 'bytes': DecimalInt(int(package_flashs[package_i]) * 1024), + 'regions': {}, + }) + ram = OrderedDict({ + 'bytes': DecimalInt(int(package_rams[package_i]) * 1024), + 'regions': {}, + }) gpio_af = next(filter(lambda x: x['@Name'] == 'GPIO', r['IP']))['@Version'] gpio_af = removesuffix(gpio_af, '_gpio_v1_0') @@ -541,6 +591,7 @@ def parse_chips(): 'family': family, 'line': r['@Line'], 'die': die, + 'device-id': None, 'packages': [], 'datasheet': None, 'reference-manual': None, @@ -568,6 +619,11 @@ def parse_chips(): chips[chip_name]['reference-manual'] = rm[0] chips[chip_name]['application-notes'] = documents_for(chip_name, 'Application note') + if 'datasheet' in chips[chip_name] and chips[chip_name]['datasheet'] is None: + del chips[chip_name]['datasheet'] + if 'reference-manual' in chips[chip_name] and chips[chip_name]['reference-manual'] is None: + del chips[chip_name]['reference-manual'] + # Some packages have some peripehrals removed because the package had to # remove GPIOs useful for that peripheral. So we merge all peripherals from all packages. peris = chips[chip_name]['peripherals'] @@ -575,7 +631,7 @@ def parse_chips(): for ip in r['IP']: pname = ip['@InstanceName'] - pkind = ip['@Name']+':'+ip['@Version'] + pkind = ip['@Name'] + ':' + ip['@Version'] pkind = removesuffix(pkind, '_Cube') if pname == 'SYS': @@ -584,7 +640,7 @@ def parse_chips(): continue if pname.startswith('ADC'): if not 'ADC_COMMON' in peris: - peris['ADC_COMMON'] = 'ADC_COMMON:'+removesuffix(ip['@Version'], '_Cube') + peris['ADC_COMMON'] = 'ADC_COMMON:' + removesuffix(ip['@Version'], '_Cube') peris[pname] = pkind pins[pname] = [] @@ -637,11 +693,71 @@ def parse_chips(): chip_nvic = chip['nvic'] del chip['nvic'] + device_id = determine_device_id(chip_name) + if device_id is not None: + chip['device-id'] = HexInt(device_id) + else: + del chip['device-id'] + h = find_header(chip_name) if h is None: raise Exception("missing header for {}".format(chip_name)) h = headers_parsed[h] + found = [] + + for each in memories_map['flash']: + if each + '_BASE' in h['defines']['all']: + if each == 'FLASH': + key = 'BANK_1' + elif each == 'FLASH_BANK1': + key = 'BANK_1' + elif each == 'FLASH_BANK2': + key = 'BANK_2' + else: + key = each + + if key in found: + continue + + found.append(key) + + chip['flash']['regions'][key] = OrderedDict( { + 'base': HexInt(h['defines']['all'][each + '_BASE']) + } ) + + if key == 'BANK_1' or key == 'BANK_2': + flash_size = determine_flash_size(chip_name) + if flash_size is not None: + if flash_size > chip['flash']['bytes'].val: + flash_size = chip['flash']['bytes'].val + chip['flash']['regions'][key]['bytes'] = DecimalInt(flash_size) + + found = [] + + for each in memories_map['ram']: + if each + '_BASE' in h['defines']['all']: + if each == 'D1_AXISRAM': + key = 'SRAM' + elif each == 'SRAM1': + key = 'SRAM' + else: + key = each + + if key in found: + continue + + found.append(key) + + chip['ram']['regions'][key] = OrderedDict( { + 'base': HexInt(h['defines']['all'][each + '_BASE']) + } ) + + if key == 'SRAM': + ram_size = determine_ram_size(chip_name) + if ram_size is not None: + chip['ram']['regions'][key]['bytes'] = DecimalInt(ram_size) + # print("Got", len(chip['cores']), "cores") for core in chip['cores']: core_name = core['name'] @@ -652,7 +768,7 @@ def parse_chips(): if not core_name in h['interrupts'] or not core_name in h['defines']: core_name = 'all' - #print("Defining for core", core_name) + # print("Defining for core", core_name) # Gather all interrupts and defines for this core @@ -682,7 +798,7 @@ def parse_chips(): if pname in clocks[rcc]: p['clock'] = clocks[rcc][pname] - if block := match_peri(chip_name+':'+pname+':'+pkind): + if block := match_peri(chip_name + ':' + pname + ':' + pkind): p['block'] = block if pname in chip['pins']: @@ -705,7 +821,7 @@ def parse_chips(): # Handle GPIO specially. for p in range(20): - port = 'GPIO' + chr(ord('A')+p) + port = 'GPIO' + chr(ord('A') + p) if addr := defines.get(port + '_BASE'): block = 'gpio_v2/GPIO' if chip['family'] == 'STM32F1': @@ -723,7 +839,7 @@ def parse_chips(): p = OrderedDict({ 'address': addr, }) - if block := match_peri(chip_name+':'+dma+':DMA'): + if block := match_peri(chip_name + ':' + dma + ':DMA'): p['block'] = block if chip_nvic in chip_interrupts: @@ -735,13 +851,13 @@ def parse_chips(): # DMAMUX is not in the cubedb XMLs for dma in ('DMAMUX', 'DMAMUX1', "DMAMUX2"): - if addr := defines.get(dma+'_BASE'): + if addr := defines.get(dma + '_BASE'): kind = 'DMAMUX:v1' dbg_peri = OrderedDict({ 'address': addr, 'kind': kind, }) - if block := match_peri(chip_name+':'+dma+':'+kind): + if block := match_peri(chip_name + ':' + dma + ':' + kind): dbg_peri['block'] = block peris[dma] = dbg_peri @@ -832,7 +948,6 @@ def parse_chips(): # Process peripheral - DMA channel associations for pname, p in peris.items(): if (peri_chs := dma_channels[chip_dma]['peripherals'].get(pname)) is not None: - p['dma_channels'] = { req: [ ch @@ -846,7 +961,7 @@ def parse_chips(): del chip['pins'] del chip['peripherals'] - with open('data/chips/'+chip_name+'.yaml', 'w') as f: + with open('data/chips/' + chip_name + '.yaml', 'w') as f: f.write(yaml.dump(chip, width=500)) @@ -854,7 +969,7 @@ af = {} def parse_gpio_af(): - #os.makedirs('data/gpio_af', exist_ok=True) + # os.makedirs('data/gpio_af', exist_ok=True) for f in glob('sources/cubedb/mcu/IP/GPIO-*_gpio_v1_0_Modes.xml'): if 'STM32F1' in f: continue @@ -892,7 +1007,7 @@ def parse_gpio_af(): pins[pin_name] = afs # with open('data/gpio_af/'+ff+'.yaml', 'w') as f: - # f.write(yaml.dump(pins)) + # f.write(yaml.dump(pins)) af[ff] = pins @@ -912,7 +1027,7 @@ def parse_dma(): ff = removeprefix(ff, 'BDMA-') ff = removesuffix(ff, '_Modes.xml') - r = xmltodict.parse(open(f, 'rb'), force_list={'Mode', 'RefMode'}) + r = xmltodict.parse(open(f, 'rb'), force_list={'Mode', 'RefMode'}) chip_dma = { 'channels': {}, @@ -936,7 +1051,7 @@ def parse_dma(): with open(mf, 'r') as yaml_file: y = yaml.load(yaml_file, Loader=SafeLoader) mf = removesuffix(mf, '.yaml') - dmamux = mf[mf.index('_')+1:] # DMAMUX1 or DMAMUX2 + dmamux = mf[mf.index('_') + 1:] # DMAMUX1 or DMAMUX2 for (request_name, request_num) in y.items(): parts = request_name.split('_') @@ -970,8 +1085,8 @@ def parse_dma(): if low == 1: low -= 1 high -= 1 - for i in range(low, high+1): - chip_dma['channels'][n+'_CH'+str(i)] = OrderedDict({ + for i in range(low, high + 1): + chip_dma['channels'][n + '_CH' + str(i)] = OrderedDict({ 'dma': n, 'channel': i, 'dmamux': dmamux, @@ -1094,7 +1209,7 @@ def match_peri_clock(rcc_block, peri_name): family_clocks = peripheral_to_clock[rcc_block] if peri_name in family_clocks: return family_clocks[peri_name] - #print("found no clock for ", peri_name) + # print("found no clock for ", peri_name) if peri_name.endswith("1"): return match_peri_clock(rcc_block, removesuffix(peri_name, "1")) return None @@ -1210,7 +1325,45 @@ def filter_interrupts(peri_irqs, all_irqs): return filtered +memories = [] +def parse_memories(): + with open('data/memories.yaml', 'r') as yaml_file: + m = yaml.load(yaml_file, Loader=SafeLoader) + for each in m: + memories.append(each) + + +def determine_ram_size(chip_name): + for each in memories: + for name in each['names']: + if is_chip_name_match(name, chip_name): + return each['ram']['bytes'] + + return None + +def determine_flash_size(chip_name): + for each in memories: + for name in each['names']: + if is_chip_name_match(name, chip_name): + return each['flash']['bytes'] + + return None + +def determine_device_id(chip_name): + for each in memories: + for name in each['names']: + if is_chip_name_match(name, chip_name): + return each['device-id'] + return None + +def is_chip_name_match(pattern, chip_name): + pattern = pattern.replace('x', '.') + return re.match(pattern + ".*", chip_name) + + + +parse_memories() parse_interrupts() parse_rcc_regs() parse_documentations() diff --git a/util/parse_memory.py b/util/parse_memory.py new file mode 100644 index 0000000..3146414 --- /dev/null +++ b/util/parse_memory.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 + +import sys +import xmltodict +import yaml +from collections import OrderedDict +from glob import glob + +try: + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeLoader + + +def represent_ordereddict(dumper, data): + value = [] + + for item_key, item_value in data.items(): + node_key = dumper.represent_data(item_key) + node_value = dumper.represent_data(item_value) + + value.append((node_key, node_value)) + + return yaml.nodes.MappingNode(u'tag:yaml.org,2002:map', value) + +yaml.add_representer(OrderedDict, represent_ordereddict) + +def represent_int(dumper, data): + return dumper.represent_int(hex(data)) + +yaml.add_representer(int, represent_int) + +def splat_names(base, parts): + names = [] + for part in parts: + if part.startswith("STM32"): + names.append( base ) + elif part.startswith( base[5]): + names.append('STM32' + part) + else: + names.append( base[0: len(base) - len(part)] + part) + + return names + + +def split_names(str): + cleaned = [] + names = str.split("/") + current_base = None + for name in names: + name = name.split(' ')[0].strip() + if '-' in name: + parts = name.split('-') + current_base = parts[0] + splatted = splat_names(current_base, parts ) + current_base = splatted[0] + cleaned = cleaned + splatted + elif name.startswith("STM32"): + current_base = name + cleaned.append(name) + elif name.startswith( current_base[5]): + names.append('STM32' + name) + else: + cleaned.append( current_base[0: len(current_base) - len(name)] + name) + return cleaned + +memories = [] + +def parse_files(dir): + for f in sorted(glob(dir + '/*.xml')): + #print("parsing ", f); + device = xmltodict.parse(open(f, 'rb'))['Root']['Device'] + device_id = device['DeviceID'] + name = device['Name'] + names = split_names(name) + flash_size = None + flash_addr = None + ram_size = None + ram_addr = None + + for peripheral in device['Peripherals']['Peripheral']: + if peripheral['Name'] == 'Embedded SRAM' and ram_size is None: + configs = peripheral['Configuration'] + if type(configs) != list: + configs = [ configs ] + ram_addr = int(configs[0]['Parameters']['@address'], 16) + ram_size = int(configs[0]['Parameters']['@size'], 16) + #print( f'ram {addr} {size}') + if peripheral['Name'] == 'Embedded Flash' and flash_size is None: + configs = peripheral['Configuration'] + if type(configs) != list: + configs = [ configs ] + flash_addr = int(configs[0]['Parameters']['@address'], 16) + flash_size = int(configs[0]['Parameters']['@size'], 16) + #print( f'flash {addr} {size}') + + chunk = OrderedDict( { + 'device-id': int(device_id, 16), + 'names': names, + }) + + if ram_size is not None: + chunk['ram'] = OrderedDict( { + 'address': ram_addr, + 'bytes': ram_size, + }) + + if flash_size is not None: + chunk['flash'] = OrderedDict( { + 'address': flash_addr, + 'bytes': flash_size, + }) + + memories.append( chunk ) + +dir = "sources/cubeprogdb/db" + +parse_files(dir) + +with open('data/memories.yaml', 'w') as f: + f.write(yaml.dump(memories, width=500)) + +#print(yaml.dump(memories, width=500))