aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-11-29 02:10:06 +0100
committerDario Nieuwenhuis <[email protected]>2021-11-29 02:28:02 +0100
commitb0fabfab5d3700f1e283d1f693c01c6682aacbda (patch)
treee52697150ecbbf317617cd79ff9e8e64e828c151
parent3332c4070555f8c87564aa90f61091c9fa4aef8a (diff)
Update stm32-data: rcc regs info comes from yamls now.
-rw-r--r--embassy-stm32/src/can/bxcan.rs8
-rw-r--r--embassy-stm32/src/dma/dmamux.rs15
-rw-r--r--embassy-stm32/src/gpio.rs12
-rw-r--r--embassy-stm32/src/rcc/mod.rs27
m---------stm32-data0
-rw-r--r--stm32-metapac-gen/src/data.rs24
-rw-r--r--stm32-metapac-gen/src/lib.rs133
-rw-r--r--stm32-metapac-gen/src/main.rs4
8 files changed, 75 insertions, 148 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index cc057b092..3c8c27308 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -103,7 +103,7 @@ crate::pac::peripherals!(
103 103
104crate::pac::peripherals!( 104crate::pac::peripherals!(
105 (can, CAN) => { 105 (can, CAN) => {
106 unsafe impl bxcan::FilterOwner for peripherals::$inst { 106 unsafe impl bxcan::FilterOwner for peripherals::CAN {
107 const NUM_FILTER_BANKS: u8 = 14; 107 const NUM_FILTER_BANKS: u8 = 14;
108 } 108 }
109 }; 109 };
@@ -144,4 +144,10 @@ crate::pac::peripheral_pins!(
144 ($inst:ident, can, CAN, $pin:ident, RX, $af:expr) => { 144 ($inst:ident, can, CAN, $pin:ident, RX, $af:expr) => {
145 impl_pin!($inst, $pin, RxPin, $af); 145 impl_pin!($inst, $pin, RxPin, $af);
146 }; 146 };
147 ($inst:ident, can, CAN, $pin:ident, TX) => {
148 impl_pin!($inst, $pin, TxPin, 0);
149 };
150 ($inst:ident, can, CAN, $pin:ident, RX) => {
151 impl_pin!($inst, $pin, RxPin, 0);
152 };
147); 153);
diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs
index 14218d56a..83dcff4e8 100644
--- a/embassy-stm32/src/dma/dmamux.rs
+++ b/embassy-stm32/src/dma/dmamux.rs
@@ -49,16 +49,11 @@ pac::dma_channels! {
49 49
50/// safety: must be called only once 50/// safety: must be called only once
51pub(crate) unsafe fn init() { 51pub(crate) unsafe fn init() {
52 pac::peripherals! { 52 crate::pac::peripheral_rcc! {
53 (dmamux, $peri:ident) => { 53 ($name:ident, dmamux, DMAMUX, $clock:ident, ($reg:ident, $field:ident, $set_field:ident), $rst:tt) => {
54 { 54 crate::pac::RCC.$reg().modify(|reg| {
55 pac::peripheral_rcc! { 55 reg.$set_field(true);
56 ($peri, $clock:ident, $en_reg:ident, $rst_reg:ident, $en_fn:ident, $rst_fn:ident) => { 56 });
57 use crate::rcc::sealed::RccPeripheral;
58 crate::peripherals::$peri::enable()
59 };
60 }
61 }
62 }; 57 };
63 } 58 }
64} 59}
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 246cdb041..49a109847 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -601,14 +601,10 @@ crate::pac::pins!(
601); 601);
602 602
603pub(crate) unsafe fn init() { 603pub(crate) unsafe fn init() {
604 crate::pac::gpio_rcc! { 604 crate::pac::peripheral_rcc! {
605 ($en_reg:ident) => { 605 ($name:ident, gpio, GPIO, $clock:ident, ($reg:ident, $field:ident, $set_field:ident), $rst:tt) => {
606 crate::pac::RCC.$en_reg().modify(|reg| { 606 crate::pac::RCC.$reg().modify(|reg| {
607 crate::pac::gpio_rcc! { 607 reg.$set_field(true);
608 ($name:ident, $clock:ident, $en_reg, $rst_reg:ident, $en_fn:ident, $rst_fn:ident) => {
609 reg.$en_fn(true);
610 };
611 }
612 }); 608 });
613 }; 609 };
614 } 610 }
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index b926eb8ce..9883543df 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -120,35 +120,33 @@ pub(crate) mod sealed {
120pub trait RccPeripheral: sealed::RccPeripheral + 'static {} 120pub trait RccPeripheral: sealed::RccPeripheral + 'static {}
121 121
122crate::pac::peripheral_rcc!( 122crate::pac::peripheral_rcc!(
123 ($inst:ident, $clk:ident, $enable:ident, $reset:ident, $perien:ident, $perirst:ident) => { 123 ($inst:ident, gpio, GPIO, $clk:ident, $en:tt, $rst:tt) => {};
124 ($inst:ident, $module:ident, $block:ident, $clk:ident, ($en_reg:ident, $en_field:ident, $en_set_field:ident), ($rst_reg:ident, $rst_field:ident, $rst_set_field:ident)) => {
124 impl sealed::RccPeripheral for peripherals::$inst { 125 impl sealed::RccPeripheral for peripherals::$inst {
125 fn frequency() -> crate::time::Hertz { 126 fn frequency() -> crate::time::Hertz {
126 critical_section::with(|_| { 127 critical_section::with(|_| {
127 unsafe { 128 unsafe { get_freqs().$clk }
128 let freqs = get_freqs();
129 freqs.$clk
130 }
131 }) 129 })
132 } 130 }
133 fn enable() { 131 fn enable() {
134 critical_section::with(|_| { 132 critical_section::with(|_| {
135 unsafe { 133 unsafe {
136 crate::pac::RCC.$enable().modify(|w| w.$perien(true)); 134 crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(true));
137 } 135 }
138 }) 136 })
139 } 137 }
140 fn disable() { 138 fn disable() {
141 critical_section::with(|_| { 139 critical_section::with(|_| {
142 unsafe { 140 unsafe {
143 crate::pac::RCC.$enable().modify(|w| w.$perien(false)); 141 crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(false));
144 } 142 }
145 }) 143 })
146 } 144 }
147 fn reset() { 145 fn reset() {
148 critical_section::with(|_| { 146 critical_section::with(|_| {
149 unsafe { 147 unsafe {
150 crate::pac::RCC.$reset().modify(|w| w.$perirst(true)); 148 crate::pac::RCC.$rst_reg().modify(|w| w.$rst_set_field(true));
151 crate::pac::RCC.$reset().modify(|w| w.$perirst(false)); 149 crate::pac::RCC.$rst_reg().modify(|w| w.$rst_set_field(false));
152 } 150 }
153 }) 151 })
154 } 152 }
@@ -156,27 +154,24 @@ crate::pac::peripheral_rcc!(
156 154
157 impl RccPeripheral for peripherals::$inst {} 155 impl RccPeripheral for peripherals::$inst {}
158 }; 156 };
159 ($inst:ident, $clk:ident, $enable:ident, $perien:ident) => { 157 ($inst:ident, $module:ident, $block:ident, $clk:ident, ($en_reg:ident, $en_field:ident, $en_set_field:ident), _) => {
160 impl sealed::RccPeripheral for peripherals::$inst { 158 impl sealed::RccPeripheral for peripherals::$inst {
161 fn frequency() -> crate::time::Hertz { 159 fn frequency() -> crate::time::Hertz {
162 critical_section::with(|_| { 160 critical_section::with(|_| {
163 unsafe { 161 unsafe { get_freqs().$clk }
164 let freqs = get_freqs();
165 freqs.$clk
166 }
167 }) 162 })
168 } 163 }
169 fn enable() { 164 fn enable() {
170 critical_section::with(|_| { 165 critical_section::with(|_| {
171 unsafe { 166 unsafe {
172 crate::pac::RCC.$enable().modify(|w| w.$perien(true)); 167 crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(true));
173 } 168 }
174 }) 169 })
175 } 170 }
176 fn disable() { 171 fn disable() {
177 critical_section::with(|_| { 172 critical_section::with(|_| {
178 unsafe { 173 unsafe {
179 crate::pac::RCC.$enable().modify(|w| w.$perien(false)); 174 crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(false));
180 } 175 }
181 }) 176 })
182 } 177 }
diff --git a/stm32-data b/stm32-data
Subproject e60ce40e6f9d29e9a8b45ea7b9118e0d55b3092 Subproject ec3fb03dc0325e62ed55ac2dd949b412f3f864e
diff --git a/stm32-metapac-gen/src/data.rs b/stm32-metapac-gen/src/data.rs
index deaf09d3e..baeb8c83f 100644
--- a/stm32-metapac-gen/src/data.rs
+++ b/stm32-metapac-gen/src/data.rs
@@ -42,11 +42,9 @@ pub struct Package {
42pub struct Peripheral { 42pub struct Peripheral {
43 pub address: u64, 43 pub address: u64,
44 #[serde(default)] 44 #[serde(default)]
45 pub kind: Option<String>,
46 #[serde(default)]
47 pub block: Option<String>, 45 pub block: Option<String>,
48 #[serde(default)] 46 #[serde(default)]
49 pub clock: Option<String>, 47 pub rcc: Option<PeripheralRcc>,
50 #[serde(default)] 48 #[serde(default)]
51 pub pins: Vec<Pin>, 49 pub pins: Vec<Pin>,
52 #[serde(default)] 50 #[serde(default)]
@@ -56,6 +54,26 @@ pub struct Peripheral {
56} 54}
57 55
58#[derive(Debug, Eq, PartialEq, Clone, Deserialize)] 56#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
57pub struct PeripheralRcc {
58 pub clock: String,
59 pub registers: PeripheralRccRegisters,
60}
61
62#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
63pub struct PeripheralRccRegisters {
64 #[serde(default)]
65 pub enable: Option<PeripheralRccRegister>,
66 #[serde(default)]
67 pub reset: Option<PeripheralRccRegister>,
68}
69
70#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
71pub struct PeripheralRccRegister {
72 pub register: String,
73 pub field: String,
74}
75
76#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
59pub struct Pin { 77pub struct Pin {
60 pub pin: String, 78 pub pin: String,
61 pub signal: String, 79 pub signal: String,
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index 9fe3be55c..3a8f81119 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -1,5 +1,4 @@
1use chiptool::generate::CommonModule; 1use chiptool::generate::CommonModule;
2use chiptool::ir::IR;
3use proc_macro2::TokenStream; 2use proc_macro2::TokenStream;
4use regex::Regex; 3use regex::Regex;
5use std::collections::{BTreeMap, HashMap, HashSet}; 4use std::collections::{BTreeMap, HashMap, HashSet};
@@ -17,24 +16,6 @@ use chiptool::{generate, ir, transform};
17mod data; 16mod data;
18use data::*; 17use data::*;
19 18
20fn find_reg<'c>(rcc: &'c ir::IR, reg_regex: &str, field_name: &str) -> Option<(&'c str, &'c str)> {
21 let reg_regex = Regex::new(reg_regex).unwrap();
22
23 for (name, fieldset) in &rcc.fieldsets {
24 // Workaround for some families that prefix register aliases with C1_, which does
25 // not help matching for clock name.
26 if !name.starts_with("C1") && !name.starts_with("C2") && reg_regex.is_match(name) {
27 for field in &fieldset.fields {
28 if field_name == field.name {
29 return Some((name.as_str(), field.name.as_str()));
30 }
31 }
32 }
33 }
34
35 None
36}
37
38fn make_peripheral_counts(out: &mut String, data: &BTreeMap<String, u8>) { 19fn make_peripheral_counts(out: &mut String, data: &BTreeMap<String, u8>) {
39 write!( 20 write!(
40 out, 21 out,
@@ -130,21 +111,6 @@ pub fn gen_chip(
130 } 111 }
131 }); 112 });
132 113
133 // Load RCC register for chip
134 let (_, rcc) = core
135 .peripherals
136 .iter()
137 .find(|(name, _)| name == &"RCC")
138 .expect("RCC peripheral missing");
139
140 let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
141 let bi = BlockInfo::parse(&rcc_block);
142 let rcc_reg_path = options
143 .data_dir
144 .join("registers")
145 .join(&format!("{}_{}.yaml", bi.module, bi.version));
146 let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap();
147
148 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new(); 114 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
149 let mut pin_table: Vec<Vec<String>> = Vec::new(); 115 let mut pin_table: Vec<Vec<String>> = Vec::new();
150 let mut interrupt_table: Vec<Vec<String>> = Vec::new(); 116 let mut interrupt_table: Vec<Vec<String>> = Vec::new();
@@ -156,8 +122,6 @@ pub fn gen_chip(
156 let mut peripheral_counts: BTreeMap<String, u8> = BTreeMap::new(); 122 let mut peripheral_counts: BTreeMap<String, u8> = BTreeMap::new();
157 let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new(); 123 let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new();
158 let mut dbgmcu_table: Vec<Vec<String>> = Vec::new(); 124 let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
159 let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
160 let mut gpio_regs: HashSet<String> = HashSet::new();
161 125
162 let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address as u32; 126 let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address as u32;
163 let gpio_stride = 0x400; 127 let gpio_stride = 0x400;
@@ -290,88 +254,38 @@ pub fn gen_chip(
290 _ => {} 254 _ => {}
291 } 255 }
292 256
293 // Workaround for clock registers being split on some chip families. Assume fields are 257 if let Some(rcc) = &p.rcc {
294 // named after peripheral and look for first field matching and use that register. 258 let mut clock = rcc.clock.to_ascii_lowercase();
295 let mut en = find_reg(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); 259 if name.starts_with("TIM") {
296 let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); 260 clock = format!("{}_tim", clock)
297 261 }
298 if en.is_none() && name.ends_with("1") {
299 en = find_reg(
300 &rcc,
301 "^.+ENR\\d*$",
302 &format!("{}EN", &name[..name.len() - 1]),
303 );
304 rst = find_reg(
305 &rcc,
306 "^.+RSTR\\d*$",
307 &format!("{}RST", &name[..name.len() - 1]),
308 );
309 }
310
311 match (en, rst) {
312 (Some((enable_reg, enable_field)), reset_reg_field) => {
313 let clock = match &p.clock {
314 Some(clock) => clock.as_str(),
315 None => {
316 // No clock was specified, derive the clock name from the enable register name.
317 // N.B. STM32G0 has only one APB bus but split ENR registers
318 // (e.g. APBENR1).
319 Regex::new("([A-Z]+\\d*)ENR\\d*")
320 .unwrap()
321 .captures(enable_reg)
322 .unwrap()
323 .get(1)
324 .unwrap()
325 .as_str()
326 }
327 };
328
329 let clock = if name.starts_with("TIM") {
330 format!("{}_tim", clock.to_ascii_lowercase())
331 } else {
332 clock.to_ascii_lowercase()
333 };
334
335 let mut row = Vec::with_capacity(6);
336 row.push(name.clone());
337 row.push(clock);
338 row.push(enable_reg.to_ascii_lowercase());
339
340 if let Some((reset_reg, reset_field)) = reset_reg_field {
341 row.push(reset_reg.to_ascii_lowercase());
342 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
343 row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
344 } else {
345 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
346 }
347 262
348 if !name.starts_with("GPIO") { 263 let mut row = Vec::new();
349 peripheral_rcc_table.push(row); 264 row.push(name.clone());
265 row.push(bi.module.clone());
266 row.push(bi.block.clone());
267 row.push(clock);
268
269 for reg in [&rcc.registers.enable, &rcc.registers.reset] {
270 if let Some(reg) = reg {
271 row.push(format!(
272 "({}, {}, set_{})",
273 reg.register.to_ascii_lowercase(),
274 reg.field.to_ascii_lowercase(),
275 reg.field.to_ascii_lowercase()
276 ));
350 } else { 277 } else {
351 gpio_rcc_table.push(row); 278 row.push("_".to_string())
352 gpio_regs.insert(enable_reg.to_ascii_lowercase());
353 } 279 }
354 } 280 }
355 (None, Some(_)) => { 281
356 println!("Unable to find enable register for {}", name) 282 peripheral_rcc_table.push(row);
357 }
358 (None, None) => {
359 println!("Unable to find enable and reset register for {}", name)
360 }
361 } 283 }
362 } 284 }
363 285
364 dev.peripherals.push(ir_peri); 286 dev.peripherals.push(ir_peri);
365 } 287 }
366 288
367 for reg in gpio_regs {
368 gpio_rcc_table.push(vec![reg]);
369 }
370
371 // We should always find GPIO RCC regs. If not, it means something
372 // is broken and GPIO won't work because it's not enabled.
373 assert!(!gpio_rcc_table.is_empty());
374
375 for (id, channel_info) in &core.dma_channels { 289 for (id, channel_info) in &core.dma_channels {
376 let mut row = Vec::new(); 290 let mut row = Vec::new();
377 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap(); 291 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
@@ -502,7 +416,6 @@ pub fn gen_chip(
502 &peripheral_dma_channels_table, 416 &peripheral_dma_channels_table,
503 ); 417 );
504 make_table(&mut data, "peripheral_rcc", &peripheral_rcc_table); 418 make_table(&mut data, "peripheral_rcc", &peripheral_rcc_table);
505 make_table(&mut data, "gpio_rcc", &gpio_rcc_table);
506 make_table(&mut data, "dma_channels", &dma_channels_table); 419 make_table(&mut data, "dma_channels", &dma_channels_table);
507 make_table(&mut data, "dbgmcu", &dbgmcu_table); 420 make_table(&mut data, "dbgmcu", &dbgmcu_table);
508 make_peripheral_counts(&mut data, &peripheral_counts); 421 make_peripheral_counts(&mut data, &peripheral_counts);
@@ -547,6 +460,8 @@ pub fn gen(options: Options) {
547 let mut chip_core_names: Vec<String> = Vec::new(); 460 let mut chip_core_names: Vec<String> = Vec::new();
548 461
549 for chip_name in &options.chips { 462 for chip_name in &options.chips {
463 println!("Generating {}...", chip_name);
464
550 let chip = load_chip(&options, chip_name); 465 let chip = load_chip(&options, chip_name);
551 for (core_index, core) in chip.cores.iter().enumerate() { 466 for (core_index, core) in chip.cores.iter().enumerate() {
552 let chip_core_name = match chip.cores.len() { 467 let chip_core_name = match chip.cores.len() {
diff --git a/stm32-metapac-gen/src/main.rs b/stm32-metapac-gen/src/main.rs
index c4ea77145..5ed751f1e 100644
--- a/stm32-metapac-gen/src/main.rs
+++ b/stm32-metapac-gen/src/main.rs
@@ -8,7 +8,7 @@ fn main() {
8 8
9 let args: Vec<String> = args().collect(); 9 let args: Vec<String> = args().collect();
10 10
11 let chips = match &args[..] { 11 let mut chips = match &args[..] {
12 [_, chip] => { 12 [_, chip] => {
13 vec![chip.clone()] 13 vec![chip.clone()]
14 } 14 }
@@ -24,6 +24,8 @@ fn main() {
24 _ => panic!("usage: stm32-metapac-gen [chip?]"), 24 _ => panic!("usage: stm32-metapac-gen [chip?]"),
25 }; 25 };
26 26
27 chips.sort();
28
27 gen(Options { 29 gen(Options {
28 out_dir, 30 out_dir,
29 data_dir, 31 data_dir,