diff options
| -rw-r--r-- | embassy-macros/src/chip/stm32.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/clock.rs | 24 | ||||
| -rw-r--r-- | stm32-metapac/gen/src/lib.rs | 62 |
3 files changed, 45 insertions, 46 deletions
diff --git a/embassy-macros/src/chip/stm32.rs b/embassy-macros/src/chip/stm32.rs index 274560a03..0a3a5abb9 100644 --- a/embassy-macros/src/chip/stm32.rs +++ b/embassy-macros/src/chip/stm32.rs | |||
| @@ -16,7 +16,10 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream | |||
| 16 | interrupt::take!(TIM2), | 16 | interrupt::take!(TIM2), |
| 17 | ); | 17 | ); |
| 18 | let clock = unsafe { make_static(&mut c) }; | 18 | let clock = unsafe { make_static(&mut c) }; |
| 19 | clock.start_tim2(); | 19 | |
| 20 | // TODO: Is TIM2 always APB1? | ||
| 21 | let timer_freq = unsafe { #embassy_stm32_path::rcc::get_freqs().apb1_clk }; | ||
| 22 | clock.start(timer_freq); | ||
| 20 | 23 | ||
| 21 | let mut alarm = clock.alarm1(); | 24 | let mut alarm = clock.alarm1(); |
| 22 | unsafe { #embassy_path::time::set_clock(clock) }; | 25 | unsafe { #embassy_path::time::set_clock(clock) }; |
diff --git a/embassy-stm32/src/clock.rs b/embassy-stm32/src/clock.rs index 7f478e790..39a96402a 100644 --- a/embassy-stm32/src/clock.rs +++ b/embassy-stm32/src/clock.rs | |||
| @@ -11,6 +11,7 @@ use embassy::time::{Clock as EmbassyClock, TICKS_PER_SECOND}; | |||
| 11 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; | 11 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; |
| 12 | use crate::pac::timer::TimGp16; | 12 | use crate::pac::timer::TimGp16; |
| 13 | use crate::peripherals; | 13 | use crate::peripherals; |
| 14 | use crate::rcc::RccPeripheral; | ||
| 14 | use crate::time::Hertz; | 15 | use crate::time::Hertz; |
| 15 | 16 | ||
| 16 | // Clock timekeeping works with something we call "periods", which are time intervals | 17 | // Clock timekeeping works with something we call "periods", which are time intervals |
| @@ -76,27 +77,12 @@ impl<T: Instance> Clock<T> { | |||
| 76 | } | 77 | } |
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | // TODO: Temporary until clock code generation is in place | ||
| 80 | pub fn start_tim2(&'static self) { | ||
| 81 | cfg_if::cfg_if! { | ||
| 82 | if #[cfg(rcc_l0)] { | ||
| 83 | unsafe { | ||
| 84 | let rcc = crate::pac::RCC; | ||
| 85 | rcc.apb1enr() | ||
| 86 | .modify(|w| w.set_tim2en(true)); | ||
| 87 | rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); | ||
| 88 | rcc.apb1rstr().modify(|w| w.set_tim2rst(false)); | ||
| 89 | } | ||
| 90 | |||
| 91 | let timer_freq = unsafe { crate::rcc::get_freqs().apb1_clk }; | ||
| 92 | self.start(timer_freq); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | pub fn start(&'static self, timer_freq: Hertz) { | 80 | pub fn start(&'static self, timer_freq: Hertz) { |
| 98 | let inner = T::inner(); | 81 | let inner = T::inner(); |
| 99 | 82 | ||
| 83 | T::enable(); | ||
| 84 | T::reset(); | ||
| 85 | |||
| 100 | // NOTE(unsafe) Critical section to use the unsafe methods | 86 | // NOTE(unsafe) Critical section to use the unsafe methods |
| 101 | critical_section::with(|_| { | 87 | critical_section::with(|_| { |
| 102 | unsafe { | 88 | unsafe { |
| @@ -359,7 +345,7 @@ pub(crate) mod sealed { | |||
| 359 | } | 345 | } |
| 360 | } | 346 | } |
| 361 | 347 | ||
| 362 | pub trait Instance: sealed::Instance + Sized + 'static {} | 348 | pub trait Instance: sealed::Instance + Sized + RccPeripheral + 'static {} |
| 363 | 349 | ||
| 364 | macro_rules! impl_timer { | 350 | macro_rules! impl_timer { |
| 365 | ($inst:ident) => { | 351 | ($inst:ident) => { |
diff --git a/stm32-metapac/gen/src/lib.rs b/stm32-metapac/gen/src/lib.rs index c4090ccaf..6db950be3 100644 --- a/stm32-metapac/gen/src/lib.rs +++ b/stm32-metapac/gen/src/lib.rs | |||
| @@ -267,32 +267,42 @@ pub fn gen(options: Options) { | |||
| 267 | _ => {} | 267 | _ => {} |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | if let Some(clock) = &p.clock { | 270 | if let Some(rcc) = &rcc { |
| 271 | if let Some(rcc) = &rcc { | 271 | // Workaround for clock registers being split on some chip families. Assume fields are |
| 272 | // Workaround for clock registers being split on some chip families. Assume fields are | 272 | // named after peripheral and look for first field matching and use that register. |
| 273 | // named after peripheral and look for first field matching and use that register. | 273 | // |
| 274 | let en = find_reg_for_field(&rcc, clock, &format!("{}EN", name)); | 274 | // Not all peripherals have the clock hint due to insufficient information from |
| 275 | let rst = find_reg_for_field(&rcc, clock, &format!("{}RST", name)); | 275 | // chip definition. If clock is not specified, the first matching register with the |
| 276 | 276 | // expected field will be used. | |
| 277 | match (en, rst) { | 277 | let en = find_reg_for_field( |
| 278 | (Some((enable_reg, enable_field)), Some((reset_reg, reset_field))) => { | 278 | &rcc, |
| 279 | peripheral_rcc_table.push(vec![ | 279 | p.clock.as_ref().unwrap_or(&String::new()), |
| 280 | name.clone(), | 280 | &format!("{}EN", name), |
| 281 | enable_reg.to_ascii_lowercase(), | 281 | ); |
| 282 | reset_reg.to_ascii_lowercase(), | 282 | let rst = find_reg_for_field( |
| 283 | format!("set_{}", enable_field.to_ascii_lowercase()), | 283 | &rcc, |
| 284 | format!("set_{}", reset_field.to_ascii_lowercase()), | 284 | p.clock.as_ref().unwrap_or(&String::new()), |
| 285 | ]); | 285 | &format!("{}RST", name), |
| 286 | } | 286 | ); |
| 287 | (None, Some(_)) => { | 287 | |
| 288 | println!("Unable to find enable register for {}", name) | 288 | match (en, rst) { |
| 289 | } | 289 | (Some((enable_reg, enable_field)), Some((reset_reg, reset_field))) => { |
| 290 | (Some(_), None) => { | 290 | peripheral_rcc_table.push(vec![ |
| 291 | println!("Unable to find reset register for {}", name) | 291 | name.clone(), |
| 292 | } | 292 | enable_reg.to_ascii_lowercase(), |
| 293 | (None, None) => { | 293 | reset_reg.to_ascii_lowercase(), |
| 294 | println!("Unable to find enable and reset register for {}", name) | 294 | format!("set_{}", enable_field.to_ascii_lowercase()), |
| 295 | } | 295 | format!("set_{}", reset_field.to_ascii_lowercase()), |
| 296 | ]); | ||
| 297 | } | ||
| 298 | (None, Some(_)) => { | ||
| 299 | println!("Unable to find enable register for {}", name) | ||
| 300 | } | ||
| 301 | (Some(_), None) => { | ||
| 302 | println!("Unable to find reset register for {}", name) | ||
| 303 | } | ||
| 304 | (None, None) => { | ||
| 305 | println!("Unable to find enable and reset register for {}", name) | ||
| 296 | } | 306 | } |
| 297 | } | 307 | } |
| 298 | } | 308 | } |
