diff options
| -rw-r--r-- | stm32-metapac/build.rs | 78 |
1 files changed, 59 insertions, 19 deletions
diff --git a/stm32-metapac/build.rs b/stm32-metapac/build.rs index 008c9eb37..4c7c0e0d4 100644 --- a/stm32-metapac/build.rs +++ b/stm32-metapac/build.rs | |||
| @@ -105,6 +105,30 @@ macro_rules! {} {{ | |||
| 105 | .unwrap(); | 105 | .unwrap(); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | fn find_reg_for_field<'c>( | ||
| 109 | rcc: &'c ir::IR, | ||
| 110 | reg_prefix: &str, | ||
| 111 | field_name: &str, | ||
| 112 | ) -> Option<(&'c str, &'c str)> { | ||
| 113 | rcc.fieldsets.iter().find_map(|(name, fieldset)| { | ||
| 114 | if name.starts_with(reg_prefix) { | ||
| 115 | fieldset | ||
| 116 | .fields | ||
| 117 | .iter() | ||
| 118 | .find_map(|field| { | ||
| 119 | if field_name == field.name { | ||
| 120 | return Some(field.name.as_str()); | ||
| 121 | } else { | ||
| 122 | None | ||
| 123 | } | ||
| 124 | }) | ||
| 125 | .map(|n| (name.as_str(), n)) | ||
| 126 | } else { | ||
| 127 | None | ||
| 128 | } | ||
| 129 | }) | ||
| 130 | } | ||
| 131 | |||
| 108 | fn main() { | 132 | fn main() { |
| 109 | let dir = "../stm32-data/data"; | 133 | let dir = "../stm32-data/data"; |
| 110 | 134 | ||
| @@ -131,6 +155,16 @@ fn main() { | |||
| 131 | peripherals: Vec::new(), | 155 | peripherals: Vec::new(), |
| 132 | }; | 156 | }; |
| 133 | 157 | ||
| 158 | // Load RCC register for chip | ||
| 159 | let chip_family = chip.family.to_ascii_lowercase().clone(); | ||
| 160 | let rcc_family = chip_family.strip_prefix("stm32").unwrap(); | ||
| 161 | //.strip_prefix("stm32") | ||
| 162 | //.unwrap(); | ||
| 163 | let rcc_reg_path = Path::new(&dir) | ||
| 164 | .join("registers") | ||
| 165 | .join(&format!("rcc_{}.yaml", rcc_family)); | ||
| 166 | let mut rcc: ir::IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap(); | ||
| 167 | |||
| 134 | let mut peripheral_versions: HashMap<String, String> = HashMap::new(); | 168 | let mut peripheral_versions: HashMap<String, String> = HashMap::new(); |
| 135 | let mut pin_table: Vec<Vec<String>> = Vec::new(); | 169 | let mut pin_table: Vec<Vec<String>> = Vec::new(); |
| 136 | let mut interrupt_table: Vec<Vec<String>> = Vec::new(); | 170 | let mut interrupt_table: Vec<Vec<String>> = Vec::new(); |
| @@ -217,30 +251,36 @@ fn main() { | |||
| 217 | }; | 251 | }; |
| 218 | assert_eq!(p.address, dma_base + dma_stride * dma_num); | 252 | assert_eq!(p.address, dma_base + dma_stride * dma_num); |
| 219 | } | 253 | } |
| 220 | "spi" => { | 254 | |
| 221 | if let Some(clock) = &p.clock { | 255 | _ => {} |
| 222 | // Workaround for APB1 register being split on some chip families. Assume | 256 | } |
| 223 | // first register until we can find a way to hint which register is used | 257 | |
| 224 | let reg = clock.to_ascii_lowercase(); | 258 | if let Some(clock) = &p.clock { |
| 225 | let (enable_reg, reset_reg) = if chip.family == "STM32H7" && clock == "APB1" | 259 | // Workaround for clock registers being split on some chip families. Assume fields are |
| 226 | { | 260 | // named after peripheral and look for first field matching and use that register. |
| 227 | (format!("{}lenr", reg), format!("{}lrstr", reg)) | 261 | let en = find_reg_for_field(&rcc, clock, &format!("{}EN", name)); |
| 228 | } else if chip.family.starts_with("STM32L4") && clock == "APB1" { | 262 | let rst = find_reg_for_field(&rcc, clock, &format!("{}RST", name)); |
| 229 | (format!("{}enr1", reg), format!("{}rstr1", reg)) | 263 | |
| 230 | } else { | 264 | match (en, rst) { |
| 231 | (format!("{}enr", reg), format!("{}rstr", reg)) | 265 | (Some((enable_reg, enable_field)), Some((reset_reg, reset_field))) => { |
| 232 | }; | ||
| 233 | let field = name.to_ascii_lowercase(); | ||
| 234 | peripheral_rcc_table.push(vec![ | 266 | peripheral_rcc_table.push(vec![ |
| 235 | name.clone(), | 267 | name.clone(), |
| 236 | enable_reg, | 268 | enable_reg.to_ascii_lowercase(), |
| 237 | reset_reg, | 269 | reset_reg.to_ascii_lowercase(), |
| 238 | format!("set_{}en", field), | 270 | format!("set_{}", enable_field.to_ascii_lowercase()), |
| 239 | format!("set_{}rst", field), | 271 | format!("set_{}", reset_field.to_ascii_lowercase()), |
| 240 | ]); | 272 | ]); |
| 241 | } | 273 | } |
| 274 | (None, Some(_)) => { | ||
| 275 | println!("Unable to find enable register for {}", name) | ||
| 276 | } | ||
| 277 | (Some(_), None) => { | ||
| 278 | println!("Unable to find reset register for {}", name) | ||
| 279 | } | ||
| 280 | (None, None) => { | ||
| 281 | println!("Unable to find enable and reset register for {}", name) | ||
| 282 | } | ||
| 242 | } | 283 | } |
| 243 | _ => {} | ||
| 244 | } | 284 | } |
| 245 | } | 285 | } |
| 246 | 286 | ||
