diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8a731620..6c364f7b 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -356,6 +356,8 @@ fn main() { } fn enable() { critical_section::with(|_| { + #[cfg(feature = "low-power")] + crate::rcc::clock_refcount_add(); crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); #after_enable }) @@ -363,6 +365,8 @@ fn main() { fn disable() { critical_section::with(|_| { crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); + #[cfg(feature = "low-power")] + crate::rcc::clock_refcount_sub(); }) } fn reset() { diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index ac9ae9c6..3c75923e 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -26,6 +26,8 @@ use crate::time::Hertz; #[cfg_attr(any(rcc_h5, rcc_h50), path = "h5.rs")] mod _version; pub use _version::*; +#[cfg(feature = "low-power")] +use atomic_polyfill::{AtomicU32, Ordering}; #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -79,6 +81,25 @@ pub struct Clocks { pub rtc: Option, } +#[cfg(feature = "low-power")] +static CLOCK_REFCOUNT: AtomicU32 = AtomicU32::new(0); + +#[cfg(feature = "low-power")] +pub fn low_power_ready() -> bool { + CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0 +} + +#[cfg(feature = "low-power")] +pub(crate) fn clock_refcount_add() { + // We don't check for overflow because constructing more than u32 peripherals is unlikely + CLOCK_REFCOUNT.fetch_add(1, Ordering::Relaxed); +} + +#[cfg(feature = "low-power")] +pub(crate) fn clock_refcount_sub() { + assert!(CLOCK_REFCOUNT.fetch_sub(1, Ordering::Relaxed) != 0); +} + /// Frozen clock frequencies /// /// The existence of this value indicates that the clock configuration can no longer be changed