diff --git a/stm32-data-gen/src/chips.rs b/stm32-data-gen/src/chips.rs index 368e709..dd131bd 100644 --- a/stm32-data-gen/src/chips.rs +++ b/stm32-data-gen/src/chips.rs @@ -807,8 +807,6 @@ static NOPELIST: &[&str] = &[ // Not supported, not planned unless someone wants to do it. "STM32MP", // not supported yet, planned. Pull requests welcome! - "STM32H52", - "STM32H53", "STM32H7R", "STM32H7S", "STM32U5F", diff --git a/stm32-data-gen/src/interrupts.rs b/stm32-data-gen/src/interrupts.rs index 28487b6..f14ce13 100644 --- a/stm32-data-gen/src/interrupts.rs +++ b/stm32-data-gen/src/interrupts.rs @@ -5,6 +5,7 @@ use log::*; use crate::chips::ChipGroup; use crate::normalize_peris::normalize_peri_name; use crate::regex; +use crate::util::RegexMap; mod xml { use serde::Deserialize; @@ -104,12 +105,17 @@ impl ChipInterrupts { core.interrupts.sort_unstable_by_key(|x| x.number); // =================== Populate peripheral interrupts - let want_nvic_name = pick_nvic(chip_name, &core.name); + let core_name = &core.name; + let want_nvic_name = pick_nvic(chip_name, core_name); let chip_nvic = group .ips .values() .find(|x| x.name == want_nvic_name) - .ok_or_else(|| format!("couldn't find nvic. chip_name={chip_name} want_nvic_name={want_nvic_name}")) + .ok_or_else(|| { + format!( + "couldn't find nvic. chip_name={chip_name} core_name={core_name} want_nvic_name={want_nvic_name}" + ) + }) .unwrap(); let nvic_strings = self .irqs @@ -503,33 +509,18 @@ fn valid_signals(peri: &str) -> Vec { vec!["GLOBAL".to_string()] } -fn pick_nvic(chip_name: &str, core_name: &str) -> String { - // Most chips have a single NVIC, named "NVIC" - let mut res = "NVIC"; - +static PICK_NVIC: RegexMap<&str> = RegexMap::new(&[ // Exception 1: Multicore: NVIC1 is the first core, NVIC2 is the second. We have to pick the right one. - if ["H745", "H747", "H755", "H757", "WL54", "WL55"].contains(&&chip_name[5..9]) { - if core_name == "cm7" { - res = "NVIC1"; - } else { - res = "NVIC2" - } - } - if &chip_name[5..8] == "WL5" { - if core_name == "cm4" { - res = "NVIC1"; - } else { - res = "NVIC2" - } - } - + ("STM32H7(45|47|55|57).*:cm7", "NVIC1"), + ("STM32H7(45|47|55|57).*:cm4", "NVIC2"), + ("STM32WL5.*:cm4", "NVIC1"), + ("STM32WL5.*:cm0p", "NVIC2"), // Exception 2: TrustZone: NVIC1 is Secure mode, NVIC2 is NonSecure mode. For now, we pick the NonSecure one. - if ["L5", "U5"].contains(&&chip_name[5..7]) { - res = "NVIC2" - } - if ["H56", "H57", "WBA"].contains(&&chip_name[5..8]) { - res = "NVIC2" - } + ("STM32(L5|U5|H5[2367]|WBA).*", "NVIC2"), + // catch-all: Most chips have a single NVIC, named "NVIC" + (".*", "NVIC"), +]); - res.to_string() +fn pick_nvic(chip_name: &str, core_name: &str) -> String { + PICK_NVIC.must_get(&format!("{chip_name}:{core_name}")).to_string() } diff --git a/stm32-data-gen/src/main.rs b/stm32-data-gen/src/main.rs index e01f330..74dc6aa 100644 --- a/stm32-data-gen/src/main.rs +++ b/stm32-data-gen/src/main.rs @@ -8,6 +8,7 @@ mod memory; mod normalize_peris; mod rcc; mod registers; +mod util; #[macro_export] macro_rules! regex { diff --git a/stm32-data-gen/src/memory.rs b/stm32-data-gen/src/memory.rs index ffd2ab1..3532e19 100644 --- a/stm32-data-gen/src/memory.rs +++ b/stm32-data-gen/src/memory.rs @@ -1,7 +1,8 @@ -use regex::Regex; use stm32_data_serde::chip::memory::{self, Settings}; use stm32_data_serde::chip::Memory; +use crate::util::RegexMap; + struct Mem { name: &'static str, address: u32, @@ -139,10 +140,12 @@ static MEMS: RegexMap<&[Mem]> = RegexMap::new(&[ ("STM32G47..B", mem!(BANK_1 0x08000000 128, SRAM 0x20000000 96, SRAM2 0x20014000 0)), ("STM32G47..C", mem!(BANK_1 0x08000000 256, SRAM 0x20000000 96, SRAM2 0x20014000 0)), ("STM32G49..C", mem!(BANK_1 0x08000000 256, SRAM 0x20000000 32, SRAM2 0x20014000 0)), - // H5. TODO: check - ("STM32H5...B", mem!(BANK_1 0x08000000 64, BANK_2 0x08010000 64, SRAM 0x20000000 32, SRAM2 0x20004000 0)), - ("STM32H5...G", mem!(BANK_1 0x08000000 1024, SRAM 0x20000000 256, SRAM2 0x20040000 0)), - ("STM32H5...I", mem!(BANK_1 0x08000000 1024, BANK_2 0x08100000 1024, SRAM 0x20000000 256, SRAM2 0x20040000 0)), + // H5. + ("STM32H5...B", mem!(BANK_1 0x08000000 64, BANK_2 0x08010000 64, SRAM1 0x20000000 16, SRAM2 0x20004000 16)), + ("STM32H5...C", mem!(BANK_1 0x08000000 128, BANK_2 0x08020000 128, SRAM1 0x20000000 128, SRAM2 0x20020000 80, SRAM3 0x20034000 64)), + ("STM32H5...E", mem!(BANK_1 0x08000000 256, BANK_2 0x08040000 256, SRAM1 0x20000000 128, SRAM2 0x20020000 80, SRAM3 0x20034000 64)), + ("STM32H5...G", mem!(BANK_1 0x08000000 512, BANK_2 0x08080000 512, SRAM1 0x20000000 256, SRAM2 0x20040000 64, SRAM3 0x20050000 320)), + ("STM32H5...I", mem!(BANK_1 0x08000000 1024, BANK_2 0x08100000 1024, SRAM1 0x20000000 256, SRAM2 0x20040000 64, SRAM3 0x20050000 320)), // H7. TODO: check ("STM32H7...E", mem!(BANK_1 0x08000000 512, SRAM 0x24000000 128)), ("STM32H7[23]..G", mem!(BANK_1 0x08000000 1024, SRAM 0x24000000 128)), @@ -277,28 +280,9 @@ static FLASH_INFO: RegexMap = RegexMap::new(&[ ("STM32.*", FlashInfo{ erase_value: 0xFF, write_size: 8, erase_size: &[( 2*1024, 0)] }), ]); -struct RegexMap { - map: &'static [(&'static str, T)], -} - -impl RegexMap { - const fn new(map: &'static [(&'static str, T)]) -> Self { - Self { map } - } - - fn get(&self, key: &str) -> Option<&T> { - for (k, v) in self.map { - if Regex::new(&format!("^{k}$")).unwrap().is_match(key) { - return Some(v); - } - } - None - } -} - pub fn get(chip: &str) -> Vec { - let mems = *MEMS.get(chip).unwrap(); - let flash = FLASH_INFO.get(chip).unwrap(); + let mems = *MEMS.must_get(chip); + let flash = FLASH_INFO.must_get(chip); let mut res = Vec::new(); diff --git a/stm32-data-gen/src/util.rs b/stm32-data-gen/src/util.rs new file mode 100644 index 0000000..37eefb8 --- /dev/null +++ b/stm32-data-gen/src/util.rs @@ -0,0 +1,28 @@ +use regex::Regex; + +pub struct RegexMap { + map: &'static [(&'static str, T)], +} + +impl RegexMap { + pub const fn new(map: &'static [(&'static str, T)]) -> Self { + Self { map } + } + + pub fn get(&self, key: &str) -> Option<&T> { + for (k, v) in self.map { + if Regex::new(&format!("^{k}$")).unwrap().is_match(key) { + return Some(v); + } + } + None + } + + #[track_caller] + pub fn must_get(&self, key: &str) -> &T { + let Some(res) = self.get(key) else { + panic!("no regexmap for key '{key}'") + }; + res + } +}