Merge pull request #47 from lulf/dual-core

Add support for parsing dual core chips
This commit is contained in:
Dario Nieuwenhuis 2021-06-16 16:24:40 +02:00 committed by GitHub
commit a39cc5e6d2
4 changed files with 2229 additions and 111 deletions

View File

@ -0,0 +1,181 @@
---
block/DBGMCU:
description: Microcontroller Debug Unit
items:
- name: IDCODER
description: DBGMCU Identity Code Register
byte_offset: 0
access: Read
fieldset: IDCODER
- name: CR
description: DBGMCU Configuration Register
byte_offset: 4
fieldset: CR
- name: APB1FZR1
description: DBGMCU CPU1 APB1 Peripheral Freeze Register 1
byte_offset: 60
fieldset: APB1FZR1
- name: C2APB1FZR1
description: "DBGMCU CPU2 APB1 Peripheral Freeze Register 1 [dual core device"
byte_offset: 64
fieldset: C2APB1FZR1
- name: APB1FZR2
description: DBGMCU CPU1 APB1 Peripheral Freeze Register 2
byte_offset: 68
fieldset: APB1FZR2
- name: C2APB1FZR2
description: "DBGMCU CPU2 APB1 Peripheral Freeze Register 2 [dual core device"
byte_offset: 72
fieldset: C2APB1FZR2
- name: APB2FZR
description: DBGMCU CPU1 APB2 Peripheral Freeze Register
byte_offset: 76
fieldset: APB2FZR
- name: C2APB2FZR
description: "DBGMCU CPU2 APB2 Peripheral Freeze Register [dual core device"
byte_offset: 80
fieldset: C2APB2FZR
fieldset/APB1FZR1:
description: DBGMCU CPU1 APB1 Peripheral Freeze Register 1
fields:
- name: DBG_TIM2_STOP
description: TIM2 stop in CPU1 debug
bit_offset: 0
bit_size: 1
- name: DBG_RTC_STOP
description: RTC stop in CPU1 debug
bit_offset: 10
bit_size: 1
- name: DBG_WWDG_STOP
description: WWDG stop in CPU1 debug
bit_offset: 11
bit_size: 1
- name: DBG_IWDG_STOP
description: IWDG stop in CPU1 debug
bit_offset: 12
bit_size: 1
- name: DBG_I2C1_STOP
description: I2C1 SMBUS timeout stop in CPU1 debug
bit_offset: 21
bit_size: 1
- name: DBG_I2C2_STOP
description: I2C2 SMBUS timeout stop in CPU1 debug
bit_offset: 22
bit_size: 1
- name: DBG_I2C3_STOP
description: I2C3 SMBUS timeout stop in CPU1 debug
bit_offset: 23
bit_size: 1
- name: DBG_LPTIM1_STOP
description: LPTIM1 stop in CPU1 debug
bit_offset: 31
bit_size: 1
fieldset/APB1FZR2:
description: DBGMCU CPU1 APB1 Peripheral Freeze Register 2
fields:
- name: DBG_LPTIM2_STOP
description: DBG_LPTIM2_STOP
bit_offset: 5
bit_size: 1
- name: DBG_LPTIM3_STOP
description: DBG_LPTIM3_STOP
bit_offset: 6
bit_size: 1
fieldset/APB2FZR:
description: DBGMCU CPU1 APB2 Peripheral Freeze Register
fields:
- name: DBG_TIM1_STOP
description: DBG_TIM1_STOP
bit_offset: 11
bit_size: 1
- name: DBG_TIM16_STOP
description: DBG_TIM16_STOP
bit_offset: 17
bit_size: 1
- name: DBG_TIM17_STOP
description: DBG_TIM17_STOP
bit_offset: 18
bit_size: 1
fieldset/C2APB1FZR1:
description: "DBGMCU CPU2 APB1 Peripheral Freeze Register 1 [dual core device"
fields:
- name: DBG_TIM2_STOP
description: DBG_TIM2_STOP
bit_offset: 0
bit_size: 1
- name: DBG_RTC_STOP
description: DBG_RTC_STOP
bit_offset: 10
bit_size: 1
- name: DBG_IWDG_STOP
description: DBG_IWDG_STOP
bit_offset: 12
bit_size: 1
- name: DBG_I2C1_STOP
description: DBG_I2C1_STOP
bit_offset: 21
bit_size: 1
- name: DBG_I2C2_STOP
description: DBG_I2C2_STOP
bit_offset: 22
bit_size: 1
- name: DBG_I2C3_STOP
description: DBG_I2C3_STOP
bit_offset: 23
bit_size: 1
- name: DBG_LPTIM1_STOP
description: DBG_LPTIM1_STOP
bit_offset: 31
bit_size: 1
fieldset/C2APB1FZR2:
description: "DBGMCU CPU2 APB1 Peripheral Freeze Register 2 [dual core device"
fields:
- name: DBG_LPTIM2_STOP
description: DBG_LPTIM2_STOP
bit_offset: 5
bit_size: 1
- name: DBG_LPTIM3_STOP
description: DBG_LPTIM3_STOP
bit_offset: 6
bit_size: 1
fieldset/C2APB2FZR:
description: "DBGMCU CPU2 APB2 Peripheral Freeze Register [dual core device"
fields:
- name: DBG_TIM1_STOP
description: DBG_TIM1_STOP
bit_offset: 11
bit_size: 1
- name: DBG_TIM16_STOP
description: DBG_TIM16_STOP
bit_offset: 17
bit_size: 1
- name: DBG_TIM17_STOP
description: DBG_TIM17_STOP
bit_offset: 18
bit_size: 1
fieldset/CR:
description: DBGMCU Configuration Register
fields:
- name: DBG_SLEEP
description: Allow debug in SLEEP mode
bit_offset: 0
bit_size: 1
- name: DBG_STOP
description: Allow debug in STOP mode
bit_offset: 1
bit_size: 1
- name: DBG_STANDBY
description: Allow debug in STANDBY mode
bit_offset: 2
bit_size: 1
fieldset/IDCODER:
description: DBGMCU Identity Code Register
fields:
- name: DEV_ID
description: Device ID
bit_offset: 0
bit_size: 12
- name: REV_ID
description: Revision
bit_offset: 16
bit_size: 16

1424
data/registers/rcc_wl5x.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,418 @@
---
block/SYSCFG:
description: System configuration controller
items:
- name: MEMRMP
description: memory remap register
byte_offset: 0
fieldset: MEMRMP
- name: CFGR1
description: configuration register 1
byte_offset: 4
fieldset: CFGR1
- name: EXTICR
description: external interrupt configuration register 1
array:
len: 4
stride: 4
byte_offset: 8
fieldset: EXTICR
- name: SCSR
description: SCSR
byte_offset: 24
fieldset: SCSR
- name: CFGR2
description: CFGR2
byte_offset: 28
fieldset: CFGR2
- name: SWPR
description: SWPR
byte_offset: 32
fieldset: SWPR
- name: SKR
description: SKR
byte_offset: 36
access: Write
fieldset: SKR
- name: IMR1
description: SYSCFG CPU1 interrupt mask register 1
byte_offset: 256
fieldset: IMR1
- name: IMR2
description: SYSCFG CPU1 interrupt mask register 2
byte_offset: 260
fieldset: IMR2
- name: C2IMR1
description: SYSCFG CPU2 interrupt mask register 1
byte_offset: 264
fieldset: C2IMR1
- name: C2IMR2
description: SYSCFG CPU2 interrupt mask register 2
byte_offset: 268
fieldset: C2IMR2
- name: RFDCR
description: radio debug control register
byte_offset: 520
fieldset: RFDCR
fieldset/C2IMR1:
description: SYSCFG CPU2 interrupt mask register 1
fields:
- name: RTCSTAMPTAMPLSECSSIM
description: RTCSTAMPTAMPLSECSSIM
bit_offset: 0
bit_size: 1
- name: RTCALARMIM
description: RTCALARMIM
bit_offset: 1
bit_size: 1
- name: RTCSSRUIM
description: RTCSSRUIM
bit_offset: 2
bit_size: 1
- name: RTCWKUPIM
description: RTCWKUPIM
bit_offset: 3
bit_size: 1
- name: RCCIM
description: RCCIM
bit_offset: 5
bit_size: 1
- name: FLASHIM
description: FLASHIM
bit_offset: 6
bit_size: 1
- name: PKAIM
description: PKAIM
bit_offset: 8
bit_size: 1
- name: AESIM
description: AESIM
bit_offset: 10
bit_size: 1
- name: COMPIM
description: COMPIM
bit_offset: 11
bit_size: 1
- name: ADCIM
description: ADCIM
bit_offset: 12
bit_size: 1
- name: DACIM
description: DACIM
bit_offset: 13
bit_size: 1
- name: EXTI0IM
description: EXTI0IM
bit_offset: 16
bit_size: 1
- name: EXTI1IM
description: EXTI1IM
bit_offset: 17
bit_size: 1
- name: EXTI2IM
description: EXTI2IM
bit_offset: 18
bit_size: 1
- name: EXTI3IM
description: EXTI3IM
bit_offset: 19
bit_size: 1
- name: EXTI4IM
description: EXTI4IM
bit_offset: 20
bit_size: 1
- name: EXTI5IM
description: EXTI5IM
bit_offset: 21
bit_size: 1
- name: EXTI6IM
description: EXTI6IM
bit_offset: 22
bit_size: 1
- name: EXTI7IM
description: EXTI7IM
bit_offset: 23
bit_size: 1
- name: EXTI8IM
description: EXTI8IM
bit_offset: 24
bit_size: 1
- name: EXTI9IM
description: EXTI9IM
bit_offset: 25
bit_size: 1
- name: EXTI10IM
description: EXTI10IM
bit_offset: 26
bit_size: 1
- name: EXTI11IM
description: EXTI11IM
bit_offset: 27
bit_size: 1
- name: EXTI12IM
description: EXTI12IM
bit_offset: 28
bit_size: 1
- name: EXTI13IM
description: EXTI13IM
bit_offset: 29
bit_size: 1
- name: EXTI14IM
description: EXTI14IM
bit_offset: 30
bit_size: 1
- name: EXTI15IM
description: EXTI15IM
bit_offset: 31
bit_size: 1
fieldset/C2IMR2:
description: SYSCFG CPU2 interrupt mask register 2
fields:
- name: DMA1CH1IM
description: DMA1CH1IM
bit_offset: 0
bit_size: 1
- name: DMA1CH2IM
description: DMA1CH2IM
bit_offset: 1
bit_size: 1
- name: DMA1CH3IM
description: DMA1CH3IM
bit_offset: 2
bit_size: 1
- name: DMA1CH4IM
description: DMA1CH4IM
bit_offset: 3
bit_size: 1
- name: DMA1CH5IM
description: DMA1CH5IM
bit_offset: 4
bit_size: 1
- name: DMA1CH6IM
description: DMA1CH6IM
bit_offset: 5
bit_size: 1
- name: DMA1CH7IM
description: DMA1CH7IM
bit_offset: 6
bit_size: 1
- name: DMA2CH1IM
description: DMA2CH1IM
bit_offset: 8
bit_size: 1
- name: DMA2CH2IM
description: DMA2CH2IM
bit_offset: 9
bit_size: 1
- name: DMA2CH3IM
description: DMA2CH3IM
bit_offset: 10
bit_size: 1
- name: DMA2CH4IM
description: DMA2CH4IM
bit_offset: 11
bit_size: 1
- name: DMA2CH5IM
description: DMA2CH5IM
bit_offset: 12
bit_size: 1
- name: DMA2CH6IM
description: DMA2CH6IM
bit_offset: 13
bit_size: 1
- name: DMA2CH7IM
description: DMA2CH7IM
bit_offset: 14
bit_size: 1
- name: DMAMUX1IM
description: DMAMUX1IM
bit_offset: 15
bit_size: 1
- name: PVM3IM
description: PVM3IM
bit_offset: 18
bit_size: 1
- name: PVDIM
description: PVDIM
bit_offset: 20
bit_size: 1
fieldset/CFGR1:
description: configuration register 1
fields:
- name: BOOSTEN
description: I/O analog switch voltage booster enable
bit_offset: 8
bit_size: 1
- name: I2C_PB6_FMP
description: Fast-mode Plus (Fm+) driving capability activation on PB6
bit_offset: 16
bit_size: 1
- name: I2C_PB7_FMP
description: Fast-mode Plus (Fm+) driving capability activation on PB7
bit_offset: 17
bit_size: 1
- name: I2C_PB8_FMP
description: Fast-mode Plus (Fm+) driving capability activation on PB8
bit_offset: 18
bit_size: 1
- name: I2C_PB9_FMP
description: Fast-mode Plus (Fm+) driving capability activation on PB9
bit_offset: 19
bit_size: 1
- name: I2C1_FMP
description: I2C1 Fast-mode Plus driving capability activation
bit_offset: 20
bit_size: 1
- name: I2C2_FMP
description: I2C2 Fast-mode Plus driving capability activation
bit_offset: 21
bit_size: 1
- name: I2C3_FMP
description: I2C3 Fast-mode Plus driving capability activation
bit_offset: 22
bit_size: 1
fieldset/CFGR2:
description: CFGR2
fields:
- name: CLL
description: CPU1 LOCKUP (Hardfault) output enable bit
bit_offset: 0
bit_size: 1
- name: SPL
description: SRAM2 parity lock bit
bit_offset: 1
bit_size: 1
- name: PVDL
description: PVD lock enable bit
bit_offset: 2
bit_size: 1
- name: ECCL
description: ECC Lock
bit_offset: 3
bit_size: 1
- name: SPF
description: SRAM2 parity error flag
bit_offset: 8
bit_size: 1
fieldset/EXTICR:
description: external interrupt configuration register 4
fields:
- name: EXTI
description: EXTI12 configuration bits
bit_offset: 0
bit_size: 3
array:
len: 4
stride: 4
fieldset/IMR1:
description: SYSCFG CPU1 interrupt mask register 1
fields:
- name: RTCSTAMPTAMPLSECSSIM
description: RTCSTAMPTAMPLSECSSIM
bit_offset: 0
bit_size: 1
- name: RTCSSRUIM
description: RTCSSRUIM
bit_offset: 2
bit_size: 1
- name: EXTI5IM
description: EXTI5IM
bit_offset: 21
bit_size: 1
- name: EXTI6IM
description: EXTI6IM
bit_offset: 22
bit_size: 1
- name: EXTI7IM
description: EXTI7IM
bit_offset: 23
bit_size: 1
- name: EXTI8IM
description: EXTI8IM
bit_offset: 24
bit_size: 1
- name: EXTI9IM
description: EXTI9IM
bit_offset: 25
bit_size: 1
- name: EXTI10IM
description: EXTI10IM
bit_offset: 26
bit_size: 1
- name: EXTI11IM
description: EXTI11IM
bit_offset: 27
bit_size: 1
- name: EXTI12IM
description: EXTI12IM
bit_offset: 28
bit_size: 1
- name: EXTI13IM
description: EXTI13IM
bit_offset: 29
bit_size: 1
- name: EXTI14IM
description: EXTI14IM
bit_offset: 30
bit_size: 1
- name: EXTI15IM
description: EXTI15IM
bit_offset: 31
bit_size: 1
fieldset/IMR2:
description: SYSCFG CPU1 interrupt mask register 2
fields:
- name: PVM3IM
description: PVM3IM
bit_offset: 18
bit_size: 1
- name: PVDIM
description: PVDIM
bit_offset: 20
bit_size: 1
fieldset/MEMRMP:
description: memory remap register
fields:
- name: MEM_MODE
description: Memory mapping selection
bit_offset: 0
bit_size: 3
fieldset/RFDCR:
description: radio debug control register
fields:
- name: RFTBSEL
description: radio debug test bus selection
bit_offset: 0
bit_size: 1
fieldset/SCSR:
description: SCSR
fields:
- name: SRAM2ER
description: SRAM2 erase
bit_offset: 0
bit_size: 1
- name: SRAMBSY
description: "SRAM1, SRAM2 and PKA SRAM busy by erase operation"
bit_offset: 1
bit_size: 1
- name: PKASRAMBSY
description: PKA SRAM busy by erase operation
bit_offset: 8
bit_size: 1
fieldset/SKR:
description: SKR
fields:
- name: KEY
description: SRAM2 write protection key for software erase
bit_offset: 0
bit_size: 8
fieldset/SWPR:
description: SWPR
fields:
- name: PWP
description: SRAM2 1Kbyte page 0 write protection
bit_offset: 0
bit_size: 1
array:
len: 32
stride: 1

317
parse.py
View File

@ -13,6 +13,12 @@ def removeprefix(value: str, prefix: str, /) -> str:
else: else:
return value[:] return value[:]
def corename(d):
if m := re.match('.*Cortex-M(\d+)(\+?)', d):
name = "cm" + str(m.group(1))
if m.group(2) == "+":
name += "p"
return name
def removesuffix(value: str, suffix: str, /) -> str: def removesuffix(value: str, suffix: str, /) -> str:
if value.endswith(suffix): if value.endswith(suffix):
@ -134,6 +140,8 @@ def parse_value(val, defines):
def parse_header(f): def parse_header(f):
irqs = {} irqs = {}
defines = {} defines = {}
cores = []
cur_core = 'all'
accum = '' accum = ''
for l in open(f, 'r', encoding='utf-8', errors='ignore'): for l in open(f, 'r', encoding='utf-8', errors='ignore'):
@ -144,11 +152,54 @@ def parse_header(f):
continue continue
accum = '' accum = ''
# Scoped by a single core
if m:= re.match('.*if defined.*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)
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)
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)
elif len(cores) > 1:
# Pick the second core assuming we've already parsed one
cur_core = cores[1]
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)
elif m:= re.match('.*endif.*', l):
#print("Switching to common core for", f)
cur_core = "all"
if cur_core not in irqs:
#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): if m := re.match('([a-zA-Z0-9_]+)_IRQn += (\\d+),? +/\\*!< (.*) \\*/', l):
irqs[m.group(1)] = int(m.group(2)) #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): if m := re.match('#define +([0-9A-Za-z_]+)\\(', l):
defines[m.group(1)] = -1 defines[cur_core][m.group(1)] = -1
if m := re.match('#define +([0-9A-Za-z_]+) +(.*)', l): if m := re.match('#define +([0-9A-Za-z_]+) +(.*)', l):
name = m.group(1) name = m.group(1)
val = m.group(2) val = m.group(2)
@ -156,10 +207,23 @@ def parse_header(f):
if name == 'FLASH_SIZE': if name == 'FLASH_SIZE':
continue continue
val = val.split('/*')[0].strip() val = val.split('/*')[0].strip()
val = parse_value(val, defines) val = parse_value(val, defines[cur_core])
defines[name] = val #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)
if len(cores) == 0:
cores.append("all")
for core in cores:
if core != "all":
irqs[core].update(irqs['all'])
defines[core].update(defines['all'])
return { return {
'cores': cores,
'interrupts': irqs, 'interrupts': irqs,
'defines': defines, 'defines': defines,
} }
@ -240,19 +304,23 @@ perimap = [
('.*:DAC:dacif_v3_0', 'dac_v2/DAC'), ('.*:DAC:dacif_v3_0', 'dac_v2/DAC'),
('.*:ADC:aditf5_v2_0', 'adc_v3/ADC'), ('.*:ADC:aditf5_v2_0', 'adc_v3/ADC'),
('.*:ADC_COMMON:aditf5_v2_0', 'adccommon_v3/ADC_COMMON'), ('.*:ADC_COMMON:aditf5_v2_0', 'adccommon_v3/ADC_COMMON'),
('.*:ADC_COMMON:aditf4_v3_0_WL', 'adccommon_v3/ADC_COMMON'),
('STM32F4.*:SYS:.*', 'syscfg_f4/SYSCFG'), ('STM32F4.*:SYS:.*', 'syscfg_f4/SYSCFG'),
('STM32L4.*:SYS:.*', 'syscfg_l4/SYSCFG'), ('STM32L4.*:SYS:.*', 'syscfg_l4/SYSCFG'),
('STM32L0.*:SYS:.*', 'syscfg_l0/SYSCFG'), ('STM32L0.*:SYS:.*', 'syscfg_l0/SYSCFG'),
('STM32H7.*:SYS:.*', 'syscfg_h7/SYSCFG'), ('STM32H7.*:SYS:.*', 'syscfg_h7/SYSCFG'),
('STM32WB55.*:SYS:.*', 'syscfg_wb55/SYSCFG'), ('STM32WB55.*:SYS:.*', 'syscfg_wb55/SYSCFG'),
('STM32WL.*:SYS:.*', 'syscfg_wl5x/SYSCFG'),
('STM32L0.*:RCC:.*', 'rcc_l0/RCC'), ('STM32L0.*:RCC:.*', 'rcc_l0/RCC'),
('STM32L4.*:RCC:.*', 'rcc_l4/RCC'), ('STM32L4.*:RCC:.*', 'rcc_l4/RCC'),
('STM32F4.*:RCC:.*', 'rcc_f4/RCC'), ('STM32F4.*:RCC:.*', 'rcc_f4/RCC'),
('STM32WL.*:RCC:.*', 'rcc_wl5x/RCC'),
('.*:STM32H7AB_rcc_v1_0', ''), # rcc_h7ab/RCC ('.*:STM32H7AB_rcc_v1_0', ''), # rcc_h7ab/RCC
('.*:STM32H7_rcc_v1_0', 'rcc_h7/RCC'), ('.*:STM32H7_rcc_v1_0', 'rcc_h7/RCC'),
('.*:STM32W_rcc_v1_0', 'rcc_wb55/RCC'), ('.*:STM32W_rcc_v1_0', 'rcc_wb55/RCC'),
('.*:STM32L0_dbgmcu_v1_0', 'dbg_l0/DBG'), ('.*:STM32L0_dbgmcu_v1_0', 'dbg_l0/DBG'),
('.*:STM32L0_crs_v1_0', 'crs_l0/CRS'), ('.*:STM32L0_crs_v1_0', 'crs_l0/CRS'),
('.*:STM32WL_dbgmcu_v1_0', 'dbgmcu_wl5x/DBGMCU'),
('.*SDMMC:sdmmc2_v1_0', 'sdmmc_v2/SDMMC'), ('.*SDMMC:sdmmc2_v1_0', 'sdmmc_v2/SDMMC'),
('.*:STM32H7_pwr_v1_0', 'pwr_h7/PWR'), ('.*:STM32H7_pwr_v1_0', 'pwr_h7/PWR'),
('.*:STM32H7_flash_v1_0', 'flash_h7/FLASH'), ('.*:STM32H7_flash_v1_0', 'flash_h7/FLASH'),
@ -266,10 +334,10 @@ rng_clock_map = [
('STM32L4.*:RNG:.*', 'AHB2'), ('STM32L4.*:RNG:.*', 'AHB2'),
('STM32F4.*:RNG:.*', 'AHB2'), ('STM32F4.*:RNG:.*', 'AHB2'),
('STM32H7.*:RNG:.*', 'AHB2'), ('STM32H7.*:RNG:.*', 'AHB2'),
('STM32WB55.*:RNG:.*', 'AHB3') ('STM32WB55.*:RNG:.*', 'AHB3'),
('STM32WL5.*:RNG:.*', 'AHB3')
] ]
def match_peri(peri): def match_peri(peri):
for r, block in perimap: for r, block in perimap:
if re.match(r, peri): if re.match(r, peri):
@ -368,16 +436,28 @@ def parse_chips():
core = r['Core'] core = r['Core']
family = r['@Family'] family = r['@Family']
# multicores have a list here. Just keep the first, to not break the schema. cores = []
if isinstance(core, list): if isinstance(core, list):
core = core[0] for core in core:
cores.append(OrderedDict(
{
'name': corename(core),
'peripherals': {},
}))
else:
cores.append(OrderedDict(
{
'name': corename(core),
'peripherals': {},
}))
if chip_name not in chips: if chip_name not in chips:
chips[chip_name] = OrderedDict({ chips[chip_name] = OrderedDict({
'name': chip_name, 'name': chip_name,
'family': family, 'family': family,
'line': r['@Line'], 'line': r['@Line'],
'core': core, 'cores': cores,
'flash': flash, 'flash': flash,
'ram': ram, 'ram': ram,
'gpio_af': gpio_af, 'gpio_af': gpio_af,
@ -411,7 +491,6 @@ def parse_chips():
continue continue
if pname.startswith('ADC'): if pname.startswith('ADC'):
if not 'ADC_COMMON' in peris: if not 'ADC_COMMON' in peris:
print(f'adding ADC_COMMON')
peris['ADC_COMMON'] = 'ADC_COMMON:'+removesuffix(ip['@Version'], '_Cube') peris['ADC_COMMON'] = 'ADC_COMMON:'+removesuffix(ip['@Version'], '_Cube')
peris[pname] = pkind peris[pname] = pkind
pins[pname] = [] pins[pname] = []
@ -458,122 +537,138 @@ def parse_chips():
raise Exception("missing header for {}".format(chip_name)) raise Exception("missing header for {}".format(chip_name))
h = headers_parsed[h] h = headers_parsed[h]
chip['interrupts'] = h['interrupts'] # print("Got", len(chip['cores']), "cores")
for core in chip['cores']:
core_name = core['name']
if not core_name in h['interrupts'] or not core_name in h['defines']:
core_name = 'all'
#print("Defining for core", core_name)
peris = {} # Gather all interrupts and defines for this core
for pname, pkind in chip['peripherals'].items(): interrupts = h['interrupts'][core_name]
addr = h['defines'].get(pname) defines = h['defines'][core_name]
if addr is None:
if pname == 'ADC_COMMON': core['interrupts'] = interrupts
addr = h['defines'].get('ADC1_COMMON') # print("INterrupts for", core, ":", interrupts)
if addr is None: #print("Defines for", core, ":", defines)
addr = h['defines'].get('ADC12_COMMON')
peris = {}
for pname, pkind in chip['peripherals'].items():
addr = defines.get(pname)
if addr is None:
if pname == 'ADC_COMMON':
addr = defines.get('ADC_COMMON')
if addr is None: if addr is None:
addr = h['defines'].get('ADC123_COMMON') addr = defines.get('ADC1_COMMON')
if addr is None: if addr is None:
continue addr = defines.get('ADC12_COMMON')
if addr is None:
p = OrderedDict({ addr = defines.get('ADC123_COMMON')
'address': addr, if addr is None:
'kind': pkind, continue
})
if pname in clocks[rcc]:
p['clock'] = clocks[rcc][pname]
elif chip['family'] == 'STM32H7' and pname == "SPI6":
p['clock'] = "APB4"
if block := match_peri(chip_name+':'+pname+':'+pkind):
p['block'] = block
if pname in chip['pins']:
if len(chip['pins'][pname]) > 0:
p['pins'] = chip['pins'][pname]
# RNG Clock definitions are not easily determined, so lookup in mapping
if block is not None and block.startswith("rng_"):
if (clock := match_rng_clock(chip_name+':'+pname+':'+pkind)) != None:
p['clock'] = clock
peris[pname] = p
family_extra = "data/extra/family/" + chip['family'] + ".yaml";
if os.path.exists(family_extra) :
with open(family_extra) as extra_f:
extra = yaml.load(extra_f, Loader=yaml.SafeLoader)
for (extra_name, extra_p) in extra['peripherals'].items():
peris[extra_name] = extra_p
# Handle GPIO specially.
for p in range(20):
port = 'GPIO' + chr(ord('A')+p)
if addr := h['defines'].get(port + '_BASE'):
block = 'gpio_v2/GPIO'
if chip['family'] == 'STM32F1':
block = 'gpio_v1/GPIO'
p = OrderedDict({ p = OrderedDict({
'address': addr, 'address': addr,
'block': block, 'kind': pkind,
}) })
peris[port] = p
# Handle DMA specially.
for dma in ('DMA1', "DMA2"):
if addr := h['defines'].get(dma + '_BASE'):
block = 'dma_v1/DMA'
if chip['family'] in ('STM32F4', 'STM32F7', 'STM32H7'):
block = 'dma_v2/DMA'
p = OrderedDict({ if pname in clocks[rcc]:
p['clock'] = clocks[rcc][pname]
elif chip['family'] == 'STM32H7' and pname == "SPI6":
p['clock'] = "APB4"
if block := match_peri(chip_name+':'+pname+':'+pkind):
p['block'] = block
if pname in chip['pins']:
if len(chip['pins'][pname]) > 0:
p['pins'] = chip['pins'][pname]
# RNG Clock definitions are not easily determined, so lookup in mapping
if block is not None and block.startswith("rng_"):
if (clock := match_rng_clock(chip_name+':'+pname+':'+pkind)) != None:
p['clock'] = clock
peris[pname] = p
family_extra = "data/extra/family/" + chip['family'] + ".yaml";
if os.path.exists(family_extra) :
with open(family_extra) as extra_f:
extra = yaml.load(extra_f, Loader=yaml.SafeLoader)
for (extra_name, extra_p) in extra['peripherals'].items():
peris[extra_name] = extra_p
# Handle GPIO specially.
for p in range(20):
port = 'GPIO' + chr(ord('A')+p)
if addr := defines.get(port + '_BASE'):
block = 'gpio_v2/GPIO'
if chip['family'] == 'STM32F1':
block = 'gpio_v1/GPIO'
p = OrderedDict({
'address': addr,
'block': block,
})
peris[port] = p
# Handle DMA specially.
for dma in ('DMA1', "DMA2"):
if addr := defines.get(dma + '_BASE'):
block = 'dma_v1/DMA'
if chip['family'] in ('STM32F4', 'STM32F7', 'STM32H7'):
block = 'dma_v2/DMA'
p = OrderedDict({
'address': addr,
'block': block,
})
peris[dma] = p
# EXTI is not in the cubedb XMLs
if addr := defines.get('EXTI_BASE'):
peris['EXTI'] = OrderedDict({
'address': addr, 'address': addr,
'block': block, 'kind': 'EXTI',
'block': 'exti_v1/EXTI',
}) })
peris[dma] = p
# EXTI is not in the cubedb XMLs # FLASH is not in the cubedb XMLs
if addr := h['defines'].get('EXTI_BASE'): if addr := defines.get('FLASH_R_BASE'):
peris['EXTI'] = OrderedDict({ kind = 'FLASH:' + chip_name[:7] + '_flash_v1_0'
'address': addr, flash_peri = OrderedDict({
'kind': 'EXTI', 'address': addr,
'block': 'exti_v1/EXTI', 'kind': kind,
}) })
if block := match_peri(kind):
flash_peri['block'] = block
peris['FLASH'] = flash_peri
# FLASH is not in the cubedb XMLs # DBGMCU is not in the cubedb XMLs
if addr := h['defines'].get('FLASH_R_BASE'): if addr := defines.get('DBGMCU_BASE'):
kind = 'FLASH:' + chip_name[:7] + '_flash_v1_0' kind = 'DBGMCU:' + chip_name[:7] + '_dbgmcu_v1_0'
flash_peri = OrderedDict({ dbg_peri = OrderedDict({
'address': addr, 'address': addr,
'kind': kind, 'kind': kind,
}) })
if block := match_peri(kind): if block := match_peri(kind):
flash_peri['block'] = block dbg_peri['block'] = block
peris['FLASH'] = flash_peri peris['DBGMCU'] = dbg_peri
# DBGMCU is not in the cubedb XMLs # CRS is not in the cubedb XMLs
if addr := h['defines'].get('DBGMCU_BASE'): if addr := defines.get('CRS_BASE'):
kind = 'DBGMCU:' + chip_name[:7] + '_dbgmcu_v1_0' kind = 'CRS:' + chip_name[:7] + '_crs_v1_0'
dbg_peri = OrderedDict({ crs_peri = OrderedDict({
'address': addr, 'address': addr,
'kind': kind, 'kind': kind,
}) })
if block := match_peri(kind): if block := match_peri(kind):
dbg_peri['block'] = block crs_peri['block'] = block
peris['DBGMCU'] = dbg_peri peris['CRS'] = crs_peri
core['peripherals'] = peris
# CRS is not in the cubedb XMLs
if addr := h['defines'].get('CRS_BASE'):
kind = 'CRS:' + chip_name[:7] + '_crs_v1_0'
crs_peri = OrderedDict({
'address': addr,
'kind': kind,
})
if block := match_peri(kind):
crs_peri['block'] = block
peris['CRS'] = crs_peri
chip['peripherals'] = peris
# remove all pins from the root of the chip before emitting. # remove all pins from the root of the chip before emitting.
del chip['pins'] 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)) f.write(yaml.dump(chip))