diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-02-07 02:10:12 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-02-07 02:23:02 +0100 |
| commit | de19fe5c05d6d6a361f68ac0a116aae4dc1db140 (patch) | |
| tree | e32dc4fb19b4a75940d55c918c865a4589cd7811 | |
| parent | a1d60774464dfb8d401706fc8a5ea682c246d97b (diff) | |
Update stm32-data, update build scripts for new schema.
| m--------- | stm32-data | 0 | ||||
| -rw-r--r-- | stm32-metapac-gen/src/data.rs | 31 | ||||
| -rw-r--r-- | stm32-metapac-gen/src/lib.rs | 123 | ||||
| -rw-r--r-- | stm32-metapac-gen/src/main.rs | 4 |
4 files changed, 88 insertions, 70 deletions
diff --git a/stm32-data b/stm32-data | |||
| Subproject ffa64b996c53d9551bf5d333016ce17fbe38153 | Subproject 69ac5bce28972de33b57497454421c6ac862b0e | ||
diff --git a/stm32-metapac-gen/src/data.rs b/stm32-metapac-gen/src/data.rs index baeb8c83f..2fa4c4b04 100644 --- a/stm32-metapac-gen/src/data.rs +++ b/stm32-metapac-gen/src/data.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use serde::Deserialize; | 1 | use serde::Deserialize; |
| 2 | use std::collections::{BTreeMap, HashMap}; | 2 | use std::collections::HashMap; |
| 3 | 3 | ||
| 4 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | 4 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] |
| 5 | pub struct Chip { | 5 | pub struct Chip { |
| @@ -27,9 +27,15 @@ pub struct MemoryRegion { | |||
| 27 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | 27 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] |
| 28 | pub struct Core { | 28 | pub struct Core { |
| 29 | pub name: String, | 29 | pub name: String, |
| 30 | pub peripherals: BTreeMap<String, Peripheral>, | 30 | pub peripherals: Vec<Peripheral>, |
| 31 | pub interrupts: BTreeMap<String, u32>, | 31 | pub interrupts: Vec<Interrupt>, |
| 32 | pub dma_channels: BTreeMap<String, DmaChannel>, | 32 | pub dma_channels: Vec<DmaChannel>, |
| 33 | } | ||
| 34 | |||
| 35 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | ||
| 36 | pub struct Interrupt { | ||
| 37 | pub name: String, | ||
| 38 | pub number: u32, | ||
| 33 | } | 39 | } |
| 34 | 40 | ||
| 35 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | 41 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] |
| @@ -40,17 +46,24 @@ pub struct Package { | |||
| 40 | 46 | ||
| 41 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | 47 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] |
| 42 | pub struct Peripheral { | 48 | pub struct Peripheral { |
| 49 | pub name: String, | ||
| 43 | pub address: u64, | 50 | pub address: u64, |
| 44 | #[serde(default)] | 51 | #[serde(default)] |
| 45 | pub block: Option<String>, | 52 | pub block: Option<String>, |
| 46 | #[serde(default)] | 53 | #[serde(default)] |
| 47 | pub rcc: Option<PeripheralRcc>, | 54 | pub rcc: Option<PeripheralRcc>, |
| 48 | #[serde(default)] | 55 | #[serde(default)] |
| 49 | pub pins: Vec<Pin>, | 56 | pub pins: Vec<PeripheralPin>, |
| 50 | #[serde(default)] | 57 | #[serde(default)] |
| 51 | pub dma_channels: BTreeMap<String, Vec<PeripheralDmaChannel>>, | 58 | pub dma_channels: Vec<PeripheralDmaChannel>, |
| 52 | #[serde(default)] | 59 | #[serde(default)] |
| 53 | pub interrupts: BTreeMap<String, String>, | 60 | pub interrupts: Vec<PeripheralInterrupt>, |
| 61 | } | ||
| 62 | |||
| 63 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | ||
| 64 | pub struct PeripheralInterrupt { | ||
| 65 | pub signal: String, | ||
| 66 | pub interrupt: String, | ||
| 54 | } | 67 | } |
| 55 | 68 | ||
| 56 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | 69 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] |
| @@ -74,7 +87,7 @@ pub struct PeripheralRccRegister { | |||
| 74 | } | 87 | } |
| 75 | 88 | ||
| 76 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | 89 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] |
| 77 | pub struct Pin { | 90 | pub struct PeripheralPin { |
| 78 | pub pin: String, | 91 | pub pin: String, |
| 79 | pub signal: String, | 92 | pub signal: String, |
| 80 | pub af: Option<String>, | 93 | pub af: Option<String>, |
| @@ -82,6 +95,7 @@ pub struct Pin { | |||
| 82 | 95 | ||
| 83 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] | 96 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] |
| 84 | pub struct DmaChannel { | 97 | pub struct DmaChannel { |
| 98 | pub name: String, | ||
| 85 | pub dma: String, | 99 | pub dma: String, |
| 86 | pub channel: u32, | 100 | pub channel: u32, |
| 87 | pub dmamux: Option<String>, | 101 | pub dmamux: Option<String>, |
| @@ -90,6 +104,7 @@ pub struct DmaChannel { | |||
| 90 | 104 | ||
| 91 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Hash)] | 105 | #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Hash)] |
| 92 | pub struct PeripheralDmaChannel { | 106 | pub struct PeripheralDmaChannel { |
| 107 | pub signal: String, | ||
| 93 | pub channel: Option<String>, | 108 | pub channel: Option<String>, |
| 94 | pub dmamux: Option<String>, | 109 | pub dmamux: Option<String>, |
| 95 | pub request: Option<u32>, | 110 | pub request: Option<u32>, |
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs index 3a8f81119..a4d4de5f5 100644 --- a/stm32-metapac-gen/src/lib.rs +++ b/stm32-metapac-gen/src/lib.rs | |||
| @@ -96,8 +96,8 @@ pub fn gen_chip( | |||
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | // Load DBGMCU register for chip | 98 | // Load DBGMCU register for chip |
| 99 | let mut dbgmcu: Option<ir::IR> = core.peripherals.iter().find_map(|(name, p)| { | 99 | let mut dbgmcu: Option<ir::IR> = core.peripherals.iter().find_map(|p| { |
| 100 | if name == "DBGMCU" { | 100 | if p.name == "DBGMCU" { |
| 101 | p.block.as_ref().map(|block| { | 101 | p.block.as_ref().map(|block| { |
| 102 | let bi = BlockInfo::parse(block); | 102 | let bi = BlockInfo::parse(block); |
| 103 | let dbgmcu_reg_path = options | 103 | let dbgmcu_reg_path = options |
| @@ -123,7 +123,12 @@ pub fn gen_chip( | |||
| 123 | let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new(); | 123 | let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new(); |
| 124 | let mut dbgmcu_table: Vec<Vec<String>> = Vec::new(); | 124 | let mut dbgmcu_table: Vec<Vec<String>> = Vec::new(); |
| 125 | 125 | ||
| 126 | let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address as u32; | 126 | let gpio_base = core |
| 127 | .peripherals | ||
| 128 | .iter() | ||
| 129 | .find(|p| p.name == "GPIOA") | ||
| 130 | .unwrap() | ||
| 131 | .address as u32; | ||
| 127 | let gpio_stride = 0x400; | 132 | let gpio_stride = 0x400; |
| 128 | 133 | ||
| 129 | let number_suffix_re = Regex::new("^(.*?)[0-9]*$").unwrap(); | 134 | let number_suffix_re = Regex::new("^(.*?)[0-9]*$").unwrap(); |
| @@ -139,15 +144,15 @@ pub fn gen_chip( | |||
| 139 | } | 144 | } |
| 140 | } | 145 | } |
| 141 | 146 | ||
| 142 | for (name, p) in &core.peripherals { | 147 | for p in &core.peripherals { |
| 143 | let captures = number_suffix_re.captures(&name).unwrap(); | 148 | let captures = number_suffix_re.captures(&p.name).unwrap(); |
| 144 | let root_peri_name = captures.get(1).unwrap().as_str().to_string(); | 149 | let root_peri_name = captures.get(1).unwrap().as_str().to_string(); |
| 145 | peripheral_counts.insert( | 150 | peripheral_counts.insert( |
| 146 | root_peri_name.clone(), | 151 | root_peri_name.clone(), |
| 147 | peripheral_counts.get(&root_peri_name).map_or(1, |v| v + 1), | 152 | peripheral_counts.get(&root_peri_name).map_or(1, |v| v + 1), |
| 148 | ); | 153 | ); |
| 149 | let mut ir_peri = ir::Peripheral { | 154 | let mut ir_peri = ir::Peripheral { |
| 150 | name: name.clone(), | 155 | name: p.name.clone(), |
| 151 | array: None, | 156 | array: None, |
| 152 | base_address: p.address, | 157 | base_address: p.address, |
| 153 | block: None, | 158 | block: None, |
| @@ -165,7 +170,7 @@ pub fn gen_chip( | |||
| 165 | 170 | ||
| 166 | for pin in &p.pins { | 171 | for pin in &p.pins { |
| 167 | let mut row = Vec::new(); | 172 | let mut row = Vec::new(); |
| 168 | row.push(name.clone()); | 173 | row.push(p.name.clone()); |
| 169 | row.push(bi.module.clone()); | 174 | row.push(bi.module.clone()); |
| 170 | row.push(bi.block.clone()); | 175 | row.push(bi.block.clone()); |
| 171 | row.push(pin.pin.clone()); | 176 | row.push(pin.pin.clone()); |
| @@ -176,50 +181,48 @@ pub fn gen_chip( | |||
| 176 | peripheral_pins_table.push(row); | 181 | peripheral_pins_table.push(row); |
| 177 | } | 182 | } |
| 178 | 183 | ||
| 179 | for (signal, irq_name) in &p.interrupts { | 184 | for irq in &p.interrupts { |
| 180 | let mut row = Vec::new(); | 185 | let mut row = Vec::new(); |
| 181 | row.push(name.clone()); | 186 | row.push(p.name.clone()); |
| 182 | row.push(bi.module.clone()); | 187 | row.push(bi.module.clone()); |
| 183 | row.push(bi.block.clone()); | 188 | row.push(bi.block.clone()); |
| 184 | row.push(signal.clone()); | 189 | row.push(irq.signal.clone()); |
| 185 | row.push(irq_name.to_ascii_uppercase()); | 190 | row.push(irq.interrupt.to_ascii_uppercase()); |
| 186 | interrupt_table.push(row) | 191 | interrupt_table.push(row) |
| 187 | } | 192 | } |
| 188 | 193 | ||
| 189 | for (request, dma_channels) in &p.dma_channels { | 194 | for ch in &p.dma_channels { |
| 190 | for channel in dma_channels.iter() { | 195 | let mut row = Vec::new(); |
| 191 | let mut row = Vec::new(); | 196 | row.push(p.name.clone()); |
| 192 | row.push(name.clone()); | 197 | row.push(bi.module.clone()); |
| 193 | row.push(bi.module.clone()); | 198 | row.push(bi.block.clone()); |
| 194 | row.push(bi.block.clone()); | 199 | row.push(ch.signal.clone()); |
| 195 | row.push(request.clone()); | 200 | row.push(if let Some(channel) = &ch.channel { |
| 196 | row.push(if let Some(channel) = &channel.channel { | 201 | format!("{{channel: {}}}", channel) |
| 197 | format!("{{channel: {}}}", channel) | 202 | } else if let Some(dmamux) = &ch.dmamux { |
| 198 | } else if let Some(dmamux) = &channel.dmamux { | 203 | format!("{{dmamux: {}}}", dmamux) |
| 199 | format!("{{dmamux: {}}}", dmamux) | 204 | } else { |
| 200 | } else { | 205 | unreachable!(); |
| 201 | unreachable!(); | 206 | }); |
| 202 | }); | 207 | |
| 203 | 208 | row.push(if let Some(request) = ch.request { | |
| 204 | row.push(if let Some(request) = channel.request { | 209 | request.to_string() |
| 205 | request.to_string() | 210 | } else { |
| 206 | } else { | 211 | "()".to_string() |
| 207 | "()".to_string() | 212 | }); |
| 208 | }); | 213 | |
| 209 | 214 | if peripheral_dma_channels_table | |
| 210 | if peripheral_dma_channels_table | 215 | .iter() |
| 211 | .iter() | 216 | .find(|a| a[..a.len() - 1] == row[..row.len() - 1]) |
| 212 | .find(|a| a[..a.len() - 1] == row[..row.len() - 1]) | 217 | .is_none() |
| 213 | .is_none() | 218 | { |
| 214 | { | 219 | peripheral_dma_channels_table.push(row); |
| 215 | peripheral_dma_channels_table.push(row); | ||
| 216 | } | ||
| 217 | } | 220 | } |
| 218 | } | 221 | } |
| 219 | 222 | ||
| 220 | let mut peripheral_row = Vec::new(); | 223 | let mut peripheral_row = Vec::new(); |
| 221 | peripheral_row.push(bi.module.clone()); | 224 | peripheral_row.push(bi.module.clone()); |
| 222 | peripheral_row.push(name.clone()); | 225 | peripheral_row.push(p.name.clone()); |
| 223 | peripherals_table.push(peripheral_row); | 226 | peripherals_table.push(peripheral_row); |
| 224 | 227 | ||
| 225 | if let Some(old_version) = | 228 | if let Some(old_version) = |
| @@ -236,15 +239,15 @@ pub fn gen_chip( | |||
| 236 | 239 | ||
| 237 | match bi.module.as_str() { | 240 | match bi.module.as_str() { |
| 238 | "gpio" => { | 241 | "gpio" => { |
| 239 | let port_letter = name.chars().skip(4).next().unwrap(); | 242 | let port_letter = p.name.chars().skip(4).next().unwrap(); |
| 240 | assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride); | 243 | assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride); |
| 241 | let port_num = (p.address as u32 - gpio_base) / gpio_stride; | 244 | let port_num = (p.address as u32 - gpio_base) / gpio_stride; |
| 242 | 245 | ||
| 243 | for pin_num in 0..16 { | 246 | for pin_num in 0u32..16 { |
| 244 | let pin_name = format!("P{}{}", port_letter, pin_num); | 247 | let pin_name = format!("P{}{}", port_letter, pin_num); |
| 245 | pin_table.push(vec![ | 248 | pin_table.push(vec![ |
| 246 | pin_name.clone(), | 249 | pin_name.clone(), |
| 247 | name.clone(), | 250 | p.name.clone(), |
| 248 | port_num.to_string(), | 251 | port_num.to_string(), |
| 249 | pin_num.to_string(), | 252 | pin_num.to_string(), |
| 250 | format!("EXTI{}", pin_num), | 253 | format!("EXTI{}", pin_num), |
| @@ -256,12 +259,12 @@ pub fn gen_chip( | |||
| 256 | 259 | ||
| 257 | if let Some(rcc) = &p.rcc { | 260 | if let Some(rcc) = &p.rcc { |
| 258 | let mut clock = rcc.clock.to_ascii_lowercase(); | 261 | let mut clock = rcc.clock.to_ascii_lowercase(); |
| 259 | if name.starts_with("TIM") { | 262 | if p.name.starts_with("TIM") { |
| 260 | clock = format!("{}_tim", clock) | 263 | clock = format!("{}_tim", clock) |
| 261 | } | 264 | } |
| 262 | 265 | ||
| 263 | let mut row = Vec::new(); | 266 | let mut row = Vec::new(); |
| 264 | row.push(name.clone()); | 267 | row.push(p.name.clone()); |
| 265 | row.push(bi.module.clone()); | 268 | row.push(bi.module.clone()); |
| 266 | row.push(bi.block.clone()); | 269 | row.push(bi.block.clone()); |
| 267 | row.push(clock); | 270 | row.push(clock); |
| @@ -286,17 +289,17 @@ pub fn gen_chip( | |||
| 286 | dev.peripherals.push(ir_peri); | 289 | dev.peripherals.push(ir_peri); |
| 287 | } | 290 | } |
| 288 | 291 | ||
| 289 | for (id, channel_info) in &core.dma_channels { | 292 | for ch in &core.dma_channels { |
| 290 | let mut row = Vec::new(); | 293 | let mut row = Vec::new(); |
| 291 | let dma_peri = core.peripherals.get(&channel_info.dma).unwrap(); | 294 | let dma_peri = core.peripherals.iter().find(|p| p.name == ch.dma).unwrap(); |
| 292 | let bi = BlockInfo::parse(dma_peri.block.as_ref().unwrap()); | 295 | let bi = BlockInfo::parse(dma_peri.block.as_ref().unwrap()); |
| 293 | 296 | ||
| 294 | row.push(id.clone()); | 297 | row.push(ch.name.clone()); |
| 295 | row.push(channel_info.dma.clone()); | 298 | row.push(ch.dma.clone()); |
| 296 | row.push(bi.module.clone()); | 299 | row.push(bi.module.clone()); |
| 297 | row.push(channel_info.channel.to_string()); | 300 | row.push(ch.channel.to_string()); |
| 298 | if let Some(dmamux) = &channel_info.dmamux { | 301 | if let Some(dmamux) = &ch.dmamux { |
| 299 | let dmamux_channel = channel_info.dmamux_channel.unwrap(); | 302 | let dmamux_channel = ch.dmamux_channel.unwrap(); |
| 300 | row.push(format!( | 303 | row.push(format!( |
| 301 | "{{dmamux: {}, dmamux_channel: {}}}", | 304 | "{{dmamux: {}, dmamux_channel: {}}}", |
| 302 | dmamux, dmamux_channel | 305 | dmamux, dmamux_channel |
| @@ -307,21 +310,21 @@ pub fn gen_chip( | |||
| 307 | 310 | ||
| 308 | dma_channels_table.push(row); | 311 | dma_channels_table.push(row); |
| 309 | 312 | ||
| 310 | let dma_peri_name = channel_info.dma.clone(); | 313 | let dma_peri_name = ch.dma.clone(); |
| 311 | dma_channel_counts.insert( | 314 | dma_channel_counts.insert( |
| 312 | dma_peri_name.clone(), | 315 | dma_peri_name.clone(), |
| 313 | dma_channel_counts.get(&dma_peri_name).map_or(1, |v| v + 1), | 316 | dma_channel_counts.get(&dma_peri_name).map_or(1, |v| v + 1), |
| 314 | ); | 317 | ); |
| 315 | } | 318 | } |
| 316 | 319 | ||
| 317 | for (name, &num) in &core.interrupts { | 320 | for irq in &core.interrupts { |
| 318 | dev.interrupts.push(ir::Interrupt { | 321 | dev.interrupts.push(ir::Interrupt { |
| 319 | name: name.clone(), | 322 | name: irq.name.clone(), |
| 320 | description: None, | 323 | description: None, |
| 321 | value: num, | 324 | value: irq.number, |
| 322 | }); | 325 | }); |
| 323 | 326 | ||
| 324 | let name = name.to_ascii_uppercase(); | 327 | let name = irq.name.to_ascii_uppercase(); |
| 325 | 328 | ||
| 326 | interrupt_table.push(vec![name.clone()]); | 329 | interrupt_table.push(vec![name.clone()]); |
| 327 | 330 | ||
| @@ -383,11 +386,11 @@ pub fn gen_chip( | |||
| 383 | 386 | ||
| 384 | let mut device_x = String::new(); | 387 | let mut device_x = String::new(); |
| 385 | 388 | ||
| 386 | for (name, _) in &core.interrupts { | 389 | for irq in &core.interrupts { |
| 387 | write!( | 390 | write!( |
| 388 | &mut device_x, | 391 | &mut device_x, |
| 389 | "PROVIDE({} = DefaultHandler);\n", | 392 | "PROVIDE({} = DefaultHandler);\n", |
| 390 | name.to_ascii_uppercase() | 393 | irq.name.to_ascii_uppercase() |
| 391 | ) | 394 | ) |
| 392 | .unwrap(); | 395 | .unwrap(); |
| 393 | } | 396 | } |
| @@ -441,7 +444,7 @@ fn load_chip(options: &Options, name: &str) -> Chip { | |||
| 441 | let chip_path = options | 444 | let chip_path = options |
| 442 | .data_dir | 445 | .data_dir |
| 443 | .join("chips") | 446 | .join("chips") |
| 444 | .join(&format!("{}.yaml", name)); | 447 | .join(&format!("{}.json", name)); |
| 445 | let chip = fs::read(chip_path).expect(&format!("Could not load chip {}", name)); | 448 | let chip = fs::read(chip_path).expect(&format!("Could not load chip {}", name)); |
| 446 | serde_yaml::from_slice(&chip).unwrap() | 449 | serde_yaml::from_slice(&chip).unwrap() |
| 447 | } | 450 | } |
diff --git a/stm32-metapac-gen/src/main.rs b/stm32-metapac-gen/src/main.rs index 5ed751f1e..fd1e2a060 100644 --- a/stm32-metapac-gen/src/main.rs +++ b/stm32-metapac-gen/src/main.rs | |||
| @@ -16,9 +16,9 @@ fn main() { | |||
| 16 | std::fs::read_dir(data_dir.join("chips")) | 16 | std::fs::read_dir(data_dir.join("chips")) |
| 17 | .unwrap() | 17 | .unwrap() |
| 18 | .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string())) | 18 | .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string())) |
| 19 | .filter(|s| s.ends_with(".yaml")) | 19 | .filter(|s| s.ends_with(".json")) |
| 20 | .filter(|s| !s.starts_with("STM32GBK")) // cursed weird STM32G4 | 20 | .filter(|s| !s.starts_with("STM32GBK")) // cursed weird STM32G4 |
| 21 | .map(|s| s.strip_suffix(".yaml").unwrap().to_string()) | 21 | .map(|s| s.strip_suffix(".json").unwrap().to_string()) |
| 22 | .collect() | 22 | .collect() |
| 23 | } | 23 | } |
| 24 | _ => panic!("usage: stm32-metapac-gen [chip?]"), | 24 | _ => panic!("usage: stm32-metapac-gen [chip?]"), |
