stm32-data/stm32data/memory.py
2022-06-27 02:09:18 +02:00

207 lines
6.5 KiB
Python

import sys
import re
import xmltodict
from glob import glob
from stm32data.util import *
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():
for f in sorted(glob('sources/cubeprogdb/db/*.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
write_size = None
erase_size = None
erase_value = 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)
erase_value = int(peripheral['ErasedValue'], 16)
write_size = int(configs[0]['Allignement'], 16)
bank = configs[0]['Bank']
if type(bank) != list:
bank = [bank]
fields = bank[0]['Field']
if type(fields) != list:
fields = [fields]
erase_size = int(fields[0]['Parameters']['@size'], 16)
for field in fields:
# print("Field", field)
erase_size = max(erase_size, int(field['Parameters']['@size'], 16))
#print( f'flash {addr} {size}')
chunk = {
'device-id': int(device_id, 16),
'names': names,
}
if ram_size is not None:
chunk['ram'] = {
'address': ram_addr,
'bytes': ram_size,
}
if flash_size is not None:
chunk['flash'] = {
'address': flash_addr,
'bytes': flash_size,
'erase_value': erase_value,
'write_size': write_size,
'erase_size': erase_size,
}
memories.append(chunk)
# The chips below are missing from cubeprogdb
memories.append({
'device-id': 0,
'names': ['STM32F302xD'],
'ram': {
'address': 0x20000000,
'bytes': 64*1024,
},
'flash': {
'address': 0x08000000,
'bytes': 384*1024,
'erase_value': 0xFF,
'write_size': 8,
'erase_size': 2048,
}
})
memories.append({
'device-id': 0,
'names': ['STM32F303xD'],
'ram': {
'address': 0x20000000,
'bytes': 80*1024,
},
'flash': {
'address': 0x08000000,
'bytes': 384*1024,
'erase_value': 0xFF,
'write_size': 8,
'erase_size': 2048,
}
})
memories.append({
'device-id': 0,
'names': ['STM32L100x6'],
'ram': {
'address': 0x20000000,
'bytes': 32*1024,
},
'flash': {
'address': 0x08000000,
'bytes': 4*1024,
'erase_value': 0xFF,
'write_size': 4,
'erase_size': 256,
}
})
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']
raise Exception(f'could not find ram size for {chip_name}')
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']
raise Exception(f'could not find flash size for {chip_name}')
def determine_flash_settings(chip_name):
for each in memories:
for name in each['names']:
if is_chip_name_match(name, chip_name):
return {
'erase_size': each['flash']['erase_size'],
'write_size': each['flash']['write_size'],
'erase_value': each['flash']['erase_value'],
}
raise Exception(f'could not find flash settings for {chip_name}')
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):
chip_name = chip_name.replace("STM32F479", "STM32F469") # F479 is missing, it's the same as F469.
chip_name = chip_name.replace("STM32G050", "STM32G051") # same...
chip_name = chip_name.replace("STM32G060", "STM32G061") # same...
chip_name = chip_name.replace("STM32G070", "STM32G071") # same...
chip_name = chip_name.replace("STM32G0B0", "STM32G0B1") # same...
chip_name = chip_name.replace("STM32G4A", "STM32G49") # same...
chip_name = chip_name.replace("STM32L422", "STM32L412") # same...
chip_name = chip_name.replace("STM32WB30", "STM32WB35") # same...
pattern = pattern.replace('x', '.')
return re.match(pattern + ".*", chip_name)