Merge pull request #114 from DCNick3/use-signals-from-mcu-xml
Use signals from mcu xml
This commit is contained in:
commit
1ed34d0869
@ -471,6 +471,7 @@ def parse_pin_name(pin_name):
|
||||
|
||||
return port, pin
|
||||
|
||||
|
||||
def get_peri_addr(defines, pname):
|
||||
possible_defines = alt_peri_defines.get(pname) or [f'{pname}_BASE', pname]
|
||||
for d in possible_defines:
|
||||
@ -478,6 +479,7 @@ def get_peri_addr(defines, pname):
|
||||
return addr
|
||||
return None
|
||||
|
||||
|
||||
def parse_chips():
|
||||
os.makedirs('data/chips', exist_ok=True)
|
||||
|
||||
@ -503,7 +505,7 @@ def parse_chips():
|
||||
|
||||
print(f)
|
||||
|
||||
r = xmltodict.parse(open(f, 'rb'))['Mcu']
|
||||
r = xmltodict.parse(open(f, 'rb'), force_list=['Signal'])['Mcu']
|
||||
|
||||
package_names = expand_name(r['@RefName'])
|
||||
package_rams = r['Ram']
|
||||
@ -590,25 +592,6 @@ def parse_chips():
|
||||
chip_af = removesuffix(chip_af, '_gpio_v1_0')
|
||||
chip_af = af[chip_af]
|
||||
|
||||
# Analog pins are in the MCU XML, not in the GPIO XML.
|
||||
analog_pins = {}
|
||||
for pin_name, pin in chip['pins'].items():
|
||||
for signal in children(pin, 'Signal'):
|
||||
if p := parse_signal_name(signal['@Name']):
|
||||
peri_name, signal_name = p
|
||||
if peri_name.startswith('ADC') or peri_name.startswith('DAC') or peri_name.startswith('COMP') or peri_name.startswith('OPAMP'):
|
||||
if peri_name not in analog_pins:
|
||||
analog_pins[peri_name] = []
|
||||
analog_pins[peri_name].append(OrderedDict({
|
||||
'pin': pin_name,
|
||||
'signal': signal_name,
|
||||
}))
|
||||
|
||||
for pname, p in analog_pins.items():
|
||||
p = remove_duplicates(p)
|
||||
sort_pins(p)
|
||||
analog_pins[pname] = p
|
||||
|
||||
cores = []
|
||||
for core_xml in children(chip['xml'], 'Core'):
|
||||
core_name = corename(core_xml)
|
||||
@ -656,6 +639,25 @@ def parse_chips():
|
||||
if pname not in peri_kinds and (addr := get_peri_addr(defines, pname)):
|
||||
peri_kinds[pname] = 'unknown'
|
||||
|
||||
# get possible used GPIOs for each peripheral from the chip xml
|
||||
# it's not the full info we would want (stuff like AFIO info which comes from GPIO xml),
|
||||
# but we actually need to use it because of F1 line
|
||||
# which doesn't include non-remappable peripherals in GPIO xml
|
||||
# and some weird edge cases like STM32F030C6 (see merge_periph_pins_info)
|
||||
periph_pins = OrderedDict()
|
||||
for pin_name, pin in chip['pins'].items():
|
||||
for signal in pin['Signal']:
|
||||
signal = signal['@Name']
|
||||
# TODO: What are those signals (well, GPIO is clear) Which peripheral do they belong to?
|
||||
if signal not in {'GPIO', 'CEC', 'AUDIOCLK', 'VDDTCXO'} and 'EXTI' not in signal:
|
||||
periph, signal = signal.split('_', maxsplit=1)
|
||||
pins = periph_pins.setdefault(periph, [])
|
||||
pins.append(OrderedDict(pin=pin_name, signal=signal))
|
||||
for periph, pins in periph_pins.items():
|
||||
pins = remove_duplicates(pins)
|
||||
sort_pins(pins)
|
||||
periph_pins[periph] = pins
|
||||
|
||||
peris = {}
|
||||
for pname, pkind in peri_kinds.items():
|
||||
addr = get_peri_addr(defines, pname)
|
||||
@ -672,9 +674,12 @@ def parse_chips():
|
||||
if block := match_peri(chip_name + ':' + pname + ':' + pkind):
|
||||
p['block'] = block
|
||||
|
||||
if pins := chip_af.get(pname):
|
||||
p['pins'] = pins
|
||||
elif pins := analog_pins.get(pname):
|
||||
if pins := periph_pins.get(pname):
|
||||
# merge the core xml info with GPIO xml info to hopefully get the full picture
|
||||
# if the peripheral does not exist in the GPIO xml (one of the notable one is ADC)
|
||||
# it probably doesn't need any AFIO writes to work
|
||||
if af_pins := chip_af.get(pname):
|
||||
pins = merge_periph_pins_info('STM32F1' in chip_name, pname, pins, af_pins)
|
||||
p['pins'] = pins
|
||||
|
||||
if chip_nvic in chip_interrupts:
|
||||
@ -806,6 +811,44 @@ def parse_chips():
|
||||
f.write(yaml.dump(chip, width=500))
|
||||
|
||||
|
||||
SIGNAL_REMAP = {
|
||||
# for some godforsaken reason UART4's and UART5's CTS are called CTS_NSS in the GPIO xml
|
||||
# so try to match with these
|
||||
'CTS': 'CTS_NSS'
|
||||
}
|
||||
|
||||
|
||||
def merge_periph_pins_info(is_f1, periph_name, core_pins, af_pins):
|
||||
if is_f1:
|
||||
# TODO: actually handle the F1 AFIO information when it will be extracted
|
||||
return core_pins
|
||||
|
||||
# covert to dict
|
||||
af_pins = {(v['pin'], v['signal']): v for v in af_pins}
|
||||
for pin in core_pins:
|
||||
af = af_pins.get((pin['pin'], pin['signal']), {'af': None})['af']
|
||||
|
||||
# try to look for a signal with another name
|
||||
if af is None and (remap := SIGNAL_REMAP.get(pin['signal'])):
|
||||
af = af_pins.get((pin['pin'], remap), {'af': None})['af']
|
||||
|
||||
# it appears that for __some__ STM32 MCUs there is no AFIO specified in GPIO file
|
||||
# (notably - STM32F030C6 with it's I2C1 on PF6 and PF7)
|
||||
# but the peripheral can actually be mapped to different pins
|
||||
# this breaks embassy's model, so we pretend that it's AF 0
|
||||
# Reference Manual states that there's no GPIOF_AFR register
|
||||
# but according to Cube-generated core it's OK to write to AFIO reg, it seems to be ignored
|
||||
# TODO: are there any more signals that have this "feature"
|
||||
if af is None and periph_name == 'I2C1':
|
||||
af = 0
|
||||
|
||||
if af is not None:
|
||||
# Kinda not nice to modify this dict, but doesn't seem to be a problem
|
||||
pin['af'] = af
|
||||
return core_pins
|
||||
pass
|
||||
|
||||
|
||||
af = {}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user