From bfa999a2e0e9ef7ef8984ac213d73bda004320cd Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Wed, 26 May 2021 21:42:07 +0200 Subject: [PATCH] Assume tim2 in macro and remove clock setup in chip specific rcc init Add temporary start_tim2() fn to Clock to assist macro in starting embassy clock --- embassy-macros/src/chip/stm32.rs | 8 +++++-- embassy-stm32/src/clock.rs | 38 +++++++++++++++++++++++++++----- embassy-stm32/src/lib.rs | 7 +++--- embassy-stm32/src/rcc/h7/mod.rs | 3 +-- embassy-stm32/src/rcc/l0/mod.rs | 19 +++++----------- 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 71eb9890..274560a0 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 quote!( use #embassy_stm32_path::{interrupt, peripherals, clock::Clock, time::Hertz}; - let (p, mut c) = #embassy_stm32_path::init(#config); + let p = #embassy_stm32_path::init(#config); + let mut c = Clock::new( + unsafe { ::steal() }, + interrupt::take!(TIM2), + ); let clock = unsafe { make_static(&mut c) }; - clock.start(); + clock.start_tim2(); let mut alarm = clock.alarm1(); unsafe { #embassy_path::time::set_clock(clock) }; diff --git a/embassy-stm32/src/clock.rs b/embassy-stm32/src/clock.rs index 2ae0a3ba..70679c14 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 { ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) } +static mut CLOCK_FREQS: Option = None; + +#[derive(Copy, Clone)] +pub struct ClockFreqs { + pub tim2: Hertz, +} + +/// Sets the clock frequencies +/// +/// Safety: Sets a mutable global. +pub unsafe fn set_freqs(freqs: ClockFreqs) { + CLOCK_FREQS.replace(freqs); +} + struct AlarmState { timestamp: Cell, #[allow(clippy::type_complexity)] @@ -59,8 +73,6 @@ const ALARM_COUNT: usize = 3; pub struct Clock { _inner: T, irq: T::Interrupt, - /// Clock frequency - frequency: Hertz, /// Number of 2^23 periods elapsed since boot. period: AtomicU32, /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. @@ -68,23 +80,37 @@ pub struct Clock { } impl Clock { - pub fn new(peripheral: T, irq: T::Interrupt, frequency: Hertz) -> Self { + pub fn new(peripheral: T, irq: T::Interrupt) -> Self { Self { _inner: peripheral, irq, - frequency, period: AtomicU32::new(0), alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]), } } - pub fn start(&'static self) { + // TODO: Temporary until clock code generation is in place + pub fn start_tim2(&'static self) { + #[cfg(feature = "_stm32l0")] + unsafe { + let rcc = crate::pac::RCC; + rcc.apb1enr() + .modify(|w| w.set_tim2en(crate::pac::rcc::vals::Lptimen::ENABLED)); + rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); + rcc.apb1rstr().modify(|w| w.set_tim2rst(false)); + } + + let timer_freq = unsafe { CLOCK_FREQS.unwrap().tim2 }; + self.start(timer_freq); + } + + pub fn start(&'static self, timer_freq: Hertz) { let inner = T::inner(); // NOTE(unsafe) Critical section to use the unsafe methods critical_section::with(|_| { unsafe { - inner.prepare(self.frequency); + inner.prepare(timer_freq); } 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 a1fa2211..49ead850 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -36,7 +36,6 @@ pub mod time; pub use embassy_macros::interrupt; pub use pac::{interrupt, peripherals, Peripherals}; -pub use rcc::SystemClock; // workaround for svd2rust-generated code using `use crate::generic::*;` pub(crate) use pac::regs::generic; @@ -61,12 +60,14 @@ impl Default for Config { } /// Initialize embassy. -pub fn init(config: Config) -> (Peripherals, SystemClock) { +pub fn init(config: Config) -> Peripherals { let p = Peripherals::take(); unsafe { dma::init(); pac::init_exti(); - (p, rcc::init(config.rcc)) + rcc::init(config.rcc); } + + p } diff --git a/embassy-stm32/src/rcc/h7/mod.rs b/embassy-stm32/src/rcc/h7/mod.rs index 9a9c7ef0..26d9f0bb 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> { } // TODO -pub type SystemClock = (); -pub unsafe fn init(_config: Config) -> SystemClock {} +pub unsafe fn init(_config: Config) {} diff --git a/embassy-stm32/src/rcc/l0/mod.rs b/embassy-stm32/src/rcc/l0/mod.rs index daa8431a..44e88d36 100644 --- a/embassy-stm32/src/rcc/l0/mod.rs +++ b/embassy-stm32/src/rcc/l0/mod.rs @@ -1,4 +1,5 @@ use crate::clock::Clock; +use crate::clock::{set_freqs, ClockFreqs}; use crate::interrupt; use crate::pac; use crate::pac::peripherals::{self, RCC, TIM2}; @@ -585,10 +586,7 @@ pub struct MCOEnabled(()); #[derive(Clone, Copy)] pub struct LSE(()); -// We use TIM2 as SystemClock -pub type SystemClock = Clock; - -pub unsafe fn init(config: Config) -> SystemClock { +pub unsafe fn init(config: Config) { let rcc = pac::RCC; let enabled = vals::Iophen::ENABLED; rcc.iopenr().write(|w| { @@ -602,14 +600,7 @@ pub unsafe fn init(config: Config) -> SystemClock { let mut r = ::steal(); let clocks = r.freeze(config); - - rcc.apb1enr().modify(|w| w.set_tim2en(Lptimen::ENABLED)); - rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); - rcc.apb1rstr().modify(|w| w.set_tim2rst(false)); - - Clock::new( - ::steal(), - interrupt::take!(TIM2), - clocks.apb1_clk(), - ) + set_freqs(ClockFreqs { + tim2: clocks.apb1_clk(), + }); } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 9b8c6633..2ede725a 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -6,7 +6,6 @@ cfg_if::cfg_if! { mod l0; pub use l0::*; } else { - pub type SystemClock = (); #[derive(Default)] pub struct Config {} pub unsafe fn init(_config: Config) -> SystemClock {