import xml.etree.ElementTree as ElementTree
import re
from pathlib import Path
from natsort import natsorted
dir_path = Path(r'C:\Program Files (x86)\STMicroelectronics\STM32Cube\STM32CubeMX\db\mcu\IP')
FEATURE = 'F0'
p = '{http://mcd.rou.st.com/modules.php?name=mcu}GPIO_Pin'
s = '{http://mcd.rou.st.com/modules.php?name=mcu}PinSignal'
sp = '{http://mcd.rou.st.com/modules.php?name=mcu}SpecificParameter'
pv = '{http://mcd.rou.st.com/modules.php?name=mcu}PossibleValue'
re_chip_name = re.compile(r'^GPIO-STM32(\w*)_gpio\w*.xml$')
re_af_name = re.compile(r'^GPIO_(AF\d*)_\w*$')
re_pin_name = re.compile(r'^P[A-K]\d{1,2}')
def print_red(*args):
print('\033[31m', end='')
print(*args, end='')
print('\033[0m')
def transpose(din):
dout = {}
for key1, inner in din.items():
for key2, value in inner.items():
dout.setdefault(key2, {})[key1] = value
return dout
def get_pins():
pins = {}
for path in dir_path.iterdir():
if not path.name.startswith('GPIO-STM32' + FEATURE):
continue
chip_type = re_chip_name.match(path.name).group(1)
tree = ElementTree.parse(str(path))
root = tree.getroot()
for pin in root.findall(p):
for signal in pin.findall(s):
for parameter in signal.findall(sp):
for possible_value in parameter.findall(pv):
pin_name = re_pin_name.findall(pin.attrib['Name'])[0]
signal_name = signal.attrib['Name']
try:
af = re_af_name.match(possible_value.text).group(1)
pins \
.setdefault(pin_name, {}) \
.setdefault(signal_name, {}) \
.setdefault(af, []).append(chip_type)
except AttributeError:
print_red(path, possible_value.text)
return pins
def get_afs(pattern: re.Pattern):
all_pins = get_pins()
all_signals = transpose(all_pins)
outstring = ''
for signal, pins in natsorted(all_signals.items()):
if not pattern.match(signal):
continue
outstring += f'static {signal}: Map<&str, u8> = phf_map! {{\n'
for pin, afs in natsorted(pins.items()):
assert len(afs) == 1
af = list(afs.keys())[0]
outstring += f' "{pin.lower()}" => {af[-1]},\n'
outstring += '};\n\n'
mapped_signals.append(signal)
return outstring
if __name__ == '__main__':
mapped_signals = []
re_spis = re.compile(r'^SPI\d_(SCK|MISO|MOSI)')
re_i2cs = re.compile(r'^I2C\d_(SCL|SDA)')
re_uarts = re.compile(r'^USART\d_(TX|RX)')
outstring = ''
outstring += get_afs(re_i2cs)
outstring += get_afs(re_spis)
outstring += get_afs(re_uarts)
af_map_string = 'pub static AF_MAP: Map<&str, &Map<&str, u8>> = phf_map! {\n'
for signal in mapped_signals:
af_map_string += f' "{signal}" => &{signal},\n'
af_map_string += '};\n\n'
imports = 'use phf::{phf_map, Map};\n\n'
print(imports + af_map_string + outstring)