diff options
| -rw-r--r-- | embassy-macros/src/chip/stm32.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/clock.rs | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 7 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/h7/mod.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l0/mod.rs | 19 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 1 |
6 files changed, 48 insertions, 28 deletions
diff --git a/embassy-macros/src/chip/stm32.rs b/embassy-macros/src/chip/stm32.rs index 71eb98905..274560a03 100644 --- a/embassy-macros/src/chip/stm32.rs +++ b/embassy-macros/src/chip/stm32.rs | |||
| @@ -9,10 +9,14 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream | |||
| 9 | quote!( | 9 | quote!( |
| 10 | use #embassy_stm32_path::{interrupt, peripherals, clock::Clock, time::Hertz}; | 10 | use #embassy_stm32_path::{interrupt, peripherals, clock::Clock, time::Hertz}; |
| 11 | 11 | ||
| 12 | let (p, mut c) = #embassy_stm32_path::init(#config); | 12 | let p = #embassy_stm32_path::init(#config); |
| 13 | 13 | ||
| 14 | let mut c = Clock::new( | ||
| 15 | unsafe { <peripherals::TIM2 as embassy::util::Steal>::steal() }, | ||
| 16 | interrupt::take!(TIM2), | ||
| 17 | ); | ||
| 14 | let clock = unsafe { make_static(&mut c) }; | 18 | let clock = unsafe { make_static(&mut c) }; |
| 15 | clock.start(); | 19 | clock.start_tim2(); |
| 16 | 20 | ||
| 17 | let mut alarm = clock.alarm1(); | 21 | let mut alarm = clock.alarm1(); |
| 18 | unsafe { #embassy_path::time::set_clock(clock) }; | 22 | unsafe { #embassy_path::time::set_clock(clock) }; |
diff --git a/embassy-stm32/src/clock.rs b/embassy-stm32/src/clock.rs index 2ae0a3ba0..70679c141 100644 --- a/embassy-stm32/src/clock.rs +++ b/embassy-stm32/src/clock.rs | |||
| @@ -33,6 +33,20 @@ fn calc_now(period: u32, counter: u16) -> u64 { | |||
| 33 | ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) | 33 | ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static mut CLOCK_FREQS: Option<ClockFreqs> = None; | ||
| 37 | |||
| 38 | #[derive(Copy, Clone)] | ||
| 39 | pub struct ClockFreqs { | ||
| 40 | pub tim2: Hertz, | ||
| 41 | } | ||
| 42 | |||
| 43 | /// Sets the clock frequencies | ||
| 44 | /// | ||
| 45 | /// Safety: Sets a mutable global. | ||
| 46 | pub unsafe fn set_freqs(freqs: ClockFreqs) { | ||
| 47 | CLOCK_FREQS.replace(freqs); | ||
| 48 | } | ||
| 49 | |||
| 36 | struct AlarmState { | 50 | struct AlarmState { |
| 37 | timestamp: Cell<u64>, | 51 | timestamp: Cell<u64>, |
| 38 | #[allow(clippy::type_complexity)] | 52 | #[allow(clippy::type_complexity)] |
| @@ -59,8 +73,6 @@ const ALARM_COUNT: usize = 3; | |||
| 59 | pub struct Clock<T: Instance> { | 73 | pub struct Clock<T: Instance> { |
| 60 | _inner: T, | 74 | _inner: T, |
| 61 | irq: T::Interrupt, | 75 | irq: T::Interrupt, |
| 62 | /// Clock frequency | ||
| 63 | frequency: Hertz, | ||
| 64 | /// Number of 2^23 periods elapsed since boot. | 76 | /// Number of 2^23 periods elapsed since boot. |
| 65 | period: AtomicU32, | 77 | period: AtomicU32, |
| 66 | /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. | 78 | /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. |
| @@ -68,23 +80,37 @@ pub struct Clock<T: Instance> { | |||
| 68 | } | 80 | } |
| 69 | 81 | ||
| 70 | impl<T: Instance> Clock<T> { | 82 | impl<T: Instance> Clock<T> { |
| 71 | pub fn new(peripheral: T, irq: T::Interrupt, frequency: Hertz) -> Self { | 83 | pub fn new(peripheral: T, irq: T::Interrupt) -> Self { |
| 72 | Self { | 84 | Self { |
| 73 | _inner: peripheral, | 85 | _inner: peripheral, |
| 74 | irq, | 86 | irq, |
| 75 | frequency, | ||
| 76 | period: AtomicU32::new(0), | 87 | period: AtomicU32::new(0), |
| 77 | alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]), | 88 | alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]), |
| 78 | } | 89 | } |
| 79 | } | 90 | } |
| 80 | 91 | ||
| 81 | pub fn start(&'static self) { | 92 | // TODO: Temporary until clock code generation is in place |
| 93 | pub fn start_tim2(&'static self) { | ||
| 94 | #[cfg(feature = "_stm32l0")] | ||
| 95 | unsafe { | ||
| 96 | let rcc = crate::pac::RCC; | ||
| 97 | rcc.apb1enr() | ||
| 98 | .modify(|w| w.set_tim2en(crate::pac::rcc::vals::Lptimen::ENABLED)); | ||
| 99 | rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); | ||
| 100 | rcc.apb1rstr().modify(|w| w.set_tim2rst(false)); | ||
| 101 | } | ||
| 102 | |||
| 103 | let timer_freq = unsafe { CLOCK_FREQS.unwrap().tim2 }; | ||
| 104 | self.start(timer_freq); | ||
| 105 | } | ||
| 106 | |||
| 107 | pub fn start(&'static self, timer_freq: Hertz) { | ||
| 82 | let inner = T::inner(); | 108 | let inner = T::inner(); |
| 83 | 109 | ||
| 84 | // NOTE(unsafe) Critical section to use the unsafe methods | 110 | // NOTE(unsafe) Critical section to use the unsafe methods |
| 85 | critical_section::with(|_| { | 111 | critical_section::with(|_| { |
| 86 | unsafe { | 112 | unsafe { |
| 87 | inner.prepare(self.frequency); | 113 | inner.prepare(timer_freq); |
| 88 | } | 114 | } |
| 89 | 115 | ||
| 90 | self.irq.set_handler_context(self as *const _ as *mut _); | 116 | self.irq.set_handler_context(self as *const _ as *mut _); |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index a1fa22111..49ead8506 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -36,7 +36,6 @@ pub mod time; | |||
| 36 | 36 | ||
| 37 | pub use embassy_macros::interrupt; | 37 | pub use embassy_macros::interrupt; |
| 38 | pub use pac::{interrupt, peripherals, Peripherals}; | 38 | pub use pac::{interrupt, peripherals, Peripherals}; |
| 39 | pub use rcc::SystemClock; | ||
| 40 | 39 | ||
| 41 | // workaround for svd2rust-generated code using `use crate::generic::*;` | 40 | // workaround for svd2rust-generated code using `use crate::generic::*;` |
| 42 | pub(crate) use pac::regs::generic; | 41 | pub(crate) use pac::regs::generic; |
| @@ -61,12 +60,14 @@ impl Default for Config { | |||
| 61 | } | 60 | } |
| 62 | 61 | ||
| 63 | /// Initialize embassy. | 62 | /// Initialize embassy. |
| 64 | pub fn init(config: Config) -> (Peripherals, SystemClock) { | 63 | pub fn init(config: Config) -> Peripherals { |
| 65 | let p = Peripherals::take(); | 64 | let p = Peripherals::take(); |
| 66 | 65 | ||
| 67 | unsafe { | 66 | unsafe { |
| 68 | dma::init(); | 67 | dma::init(); |
| 69 | pac::init_exti(); | 68 | pac::init_exti(); |
| 70 | (p, rcc::init(config.rcc)) | 69 | rcc::init(config.rcc); |
| 71 | } | 70 | } |
| 71 | |||
| 72 | p | ||
| 72 | } | 73 | } |
diff --git a/embassy-stm32/src/rcc/h7/mod.rs b/embassy-stm32/src/rcc/h7/mod.rs index 9a9c7ef0f..26d9f0bb9 100644 --- a/embassy-stm32/src/rcc/h7/mod.rs +++ b/embassy-stm32/src/rcc/h7/mod.rs | |||
| @@ -529,5 +529,4 @@ impl<'d> Rcc<'d> { | |||
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | // TODO | 531 | // TODO |
| 532 | pub type SystemClock = (); | 532 | pub unsafe fn init(_config: Config) {} |
| 533 | pub unsafe fn init(_config: Config) -> SystemClock {} | ||
diff --git a/embassy-stm32/src/rcc/l0/mod.rs b/embassy-stm32/src/rcc/l0/mod.rs index daa8431a6..44e88d365 100644 --- a/embassy-stm32/src/rcc/l0/mod.rs +++ b/embassy-stm32/src/rcc/l0/mod.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | use crate::clock::Clock; | 1 | use crate::clock::Clock; |
| 2 | use crate::clock::{set_freqs, ClockFreqs}; | ||
| 2 | use crate::interrupt; | 3 | use crate::interrupt; |
| 3 | use crate::pac; | 4 | use crate::pac; |
| 4 | use crate::pac::peripherals::{self, RCC, TIM2}; | 5 | use crate::pac::peripherals::{self, RCC, TIM2}; |
| @@ -585,10 +586,7 @@ pub struct MCOEnabled(()); | |||
| 585 | #[derive(Clone, Copy)] | 586 | #[derive(Clone, Copy)] |
| 586 | pub struct LSE(()); | 587 | pub struct LSE(()); |
| 587 | 588 | ||
| 588 | // We use TIM2 as SystemClock | 589 | pub unsafe fn init(config: Config) { |
| 589 | pub type SystemClock = Clock<TIM2>; | ||
| 590 | |||
| 591 | pub unsafe fn init(config: Config) -> SystemClock { | ||
| 592 | let rcc = pac::RCC; | 590 | let rcc = pac::RCC; |
| 593 | let enabled = vals::Iophen::ENABLED; | 591 | let enabled = vals::Iophen::ENABLED; |
| 594 | rcc.iopenr().write(|w| { | 592 | rcc.iopenr().write(|w| { |
| @@ -602,14 +600,7 @@ pub unsafe fn init(config: Config) -> SystemClock { | |||
| 602 | 600 | ||
| 603 | let mut r = <peripherals::RCC as embassy::util::Steal>::steal(); | 601 | let mut r = <peripherals::RCC as embassy::util::Steal>::steal(); |
| 604 | let clocks = r.freeze(config); | 602 | let clocks = r.freeze(config); |
| 605 | 603 | set_freqs(ClockFreqs { | |
| 606 | rcc.apb1enr().modify(|w| w.set_tim2en(Lptimen::ENABLED)); | 604 | tim2: clocks.apb1_clk(), |
| 607 | rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); | 605 | }); |
| 608 | rcc.apb1rstr().modify(|w| w.set_tim2rst(false)); | ||
| 609 | |||
| 610 | Clock::new( | ||
| 611 | <peripherals::TIM2 as embassy::util::Steal>::steal(), | ||
| 612 | interrupt::take!(TIM2), | ||
| 613 | clocks.apb1_clk(), | ||
| 614 | ) | ||
| 615 | } | 606 | } |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 9b8c66331..2ede725a1 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -6,7 +6,6 @@ cfg_if::cfg_if! { | |||
| 6 | mod l0; | 6 | mod l0; |
| 7 | pub use l0::*; | 7 | pub use l0::*; |
| 8 | } else { | 8 | } else { |
| 9 | pub type SystemClock = (); | ||
| 10 | #[derive(Default)] | 9 | #[derive(Default)] |
| 11 | pub struct Config {} | 10 | pub struct Config {} |
| 12 | pub unsafe fn init(_config: Config) -> SystemClock { | 11 | pub unsafe fn init(_config: Config) -> SystemClock { |
