aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-macros/src/chip/stm32.rs5
-rw-r--r--embassy-stm32/src/clock.rs24
-rw-r--r--stm32-metapac/gen/src/lib.rs62
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};
11use crate::interrupt::{CriticalSection, Interrupt, Mutex}; 11use crate::interrupt::{CriticalSection, Interrupt, Mutex};
12use crate::pac::timer::TimGp16; 12use crate::pac::timer::TimGp16;
13use crate::peripherals; 13use crate::peripherals;
14use crate::rcc::RccPeripheral;
14use crate::time::Hertz; 15use 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
362pub trait Instance: sealed::Instance + Sized + 'static {} 348pub trait Instance: sealed::Instance + Sized + RccPeripheral + 'static {}
363 349
364macro_rules! impl_timer { 350macro_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 }