diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 925cf39b..bd4bab1f 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -39,6 +39,9 @@ fn exticr_regs() -> pac::afio::Afio { } pub unsafe fn on_irq() { + #[cfg(feature = "low-power")] + crate::low_power::on_wakeup_irq(); + #[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))] let bits = EXTI.pr(0).read().0; #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index b42b674e..ce8afb57 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -5,7 +5,6 @@ use cortex_m::peripheral::SCB; use embassy_executor::*; use crate::interrupt; -use crate::interrupt::typelevel::Interrupt; use crate::rcc::low_power_ready; use crate::time_driver::{get_driver, RtcDriver}; @@ -19,36 +18,20 @@ foreach_interrupt! { (RTC, rtc, $block:ident, WKUP, $irq:ident) => { #[interrupt] unsafe fn $irq() { - unsafe { EXECUTOR.as_mut().unwrap() }.on_wakeup_irq(); + EXECUTOR.as_mut().unwrap().on_wakeup_irq(); } }; } -// pub fn timer_driver_pause_time() { -// pause_time(); -// } +#[allow(dead_code)] +pub(crate) unsafe fn on_wakeup_irq() { + EXECUTOR.as_mut().unwrap().on_wakeup_irq(); +} pub fn stop_with_rtc(rtc: &'static Rtc) { unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc) } -// pub fn start_wakeup_alarm(requested_duration: embassy_time::Duration) { -// let rtc_instant = unsafe { EXECUTOR.as_mut().unwrap() } -// .rtc -// .unwrap() -// .start_wakeup_alarm(requested_duration); -// -// unsafe { EXECUTOR.as_mut().unwrap() }.last_stop = Some(rtc_instant); -// } -// -// pub fn set_sleepdeep() { -// unsafe { EXECUTOR.as_mut().unwrap() }.scb.set_sleepdeep(); -// } -// -// pub fn stop_wakeup_alarm() -> RtcInstant { -// unsafe { EXECUTOR.as_mut().unwrap() }.rtc.unwrap().stop_wakeup_alarm() -// } - /// Thread mode executor, using WFE/SEV. /// /// This is the simplest and most common kind of executor. It runs on @@ -91,27 +74,11 @@ impl Executor { } pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) { - trace!("low power: stop with rtc configured"); - self.time_driver.set_rtc(rtc); - #[cfg(not(stm32l0))] - crate::interrupt::typelevel::RTC_WKUP::unpend(); - - #[cfg(not(stm32l0))] - unsafe { - crate::interrupt::typelevel::RTC_WKUP::enable() - }; - - #[cfg(stm32l0)] - crate::interrupt::typelevel::RTC::unpend(); - - #[cfg(stm32l0)] - unsafe { - crate::interrupt::typelevel::RTC::enable() - }; - rtc.enable_wakeup_line(); + + trace!("low power: stop with rtc configured"); } fn configure_pwr(&mut self) { diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index a1133a80..32a5cc12 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -124,9 +124,6 @@ impl Default for RtcCalibrationCyclePeriod { impl Rtc { pub fn new(_rtc: impl Peripheral
, rtc_config: RtcConfig) -> Self { - #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] - use crate::rcc::get_freqs; - RTC::enable_peripheral_clk(); BackupDomain::enable_rtc(); @@ -135,20 +132,7 @@ impl Rtc { stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), }; - #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] - let freqs = unsafe { get_freqs() }; - - // Load the clock frequency from the rcc mod, if supported - #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] - let frequency = match freqs.rtc { - Some(hertz) => hertz, - None => freqs.rtc_hse.unwrap(), - }; - - // Assume the default value, if not supported - #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))] - let frequency = Hertz(32_768); - + let frequency = Self::frequency(); let async_psc = ((frequency.0 / rtc_config.frequency.0) - 1) as u8; let sync_psc = (rtc_config.frequency.0 - 1) as u16; @@ -157,6 +141,22 @@ impl Rtc { this } + fn frequency() -> Hertz { + #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] + let freqs = unsafe { crate::rcc::get_freqs() }; + + // Load the clock frequency from the rcc mod, if supported + #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] + match freqs.rtc { + Some(hertz) => hertz, + None => freqs.rtc_hse.unwrap(), + } + + // Assume the default value, if not supported + #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))] + Hertz(32_768) + } + /// Set the datetime to a new value. /// /// # Errors @@ -264,6 +264,12 @@ pub(crate) mod sealed { pub trait Instance { const BACKUP_REGISTER_COUNT: usize; + #[cfg(feature = "low-power")] + const EXTI_WAKEUP_LINE: usize; + + #[cfg(feature = "low-power")] + type WakeupInterrupt: crate::interrupt::typelevel::Interrupt; + fn regs() -> Rtc { crate::pac::RTC } diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 726886f1..aa3c31ee 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -67,15 +67,10 @@ impl super::Rtc { pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) { use embassy_time::{Duration, TICK_HZ}; - #[cfg(not(stm32l0))] - use crate::rcc::get_freqs; - - #[cfg(not(stm32l0))] - let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64; - - #[cfg(stm32l0)] - let rtc_hz = 32_768u64; + #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] + unsafe { crate::rcc::get_freqs() }.rtc.unwrap(); + let rtc_hz = Self::frequency().0 as u64; let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ; let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); @@ -112,17 +107,14 @@ impl super::Rtc { #[cfg(feature = "low-power")] pub(crate) fn enable_wakeup_line(&self) { + use crate::interrupt::typelevel::Interrupt; use crate::pac::EXTI; - #[cfg(stm32l0)] - EXTI.rtsr(0).modify(|w| w.set_line(20, true)); - #[cfg(stm32l0)] - EXTI.imr(0).modify(|w| w.set_line(20, true)); +