aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-12-18 07:00:59 -0600
committerxoviat <[email protected]>2025-12-18 07:00:59 -0600
commitd113772136548e2bb50cecf1749f73bef72a0fe9 (patch)
tree9fa0e3bb56a967503a16d6dbfd5c7c383de75649 /embassy-stm32/src
parent10630047153a8246573191d53d5ac571a3750117 (diff)
stm32: cleanup low-power features
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/lib.rs3
-rw-r--r--embassy-stm32/src/low_power.rs29
2 files changed, 18 insertions, 14 deletions
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 2f783bf64..a0b2f045c 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -138,6 +138,9 @@ pub mod wdg;
138#[cfg(xspi)] 138#[cfg(xspi)]
139pub mod xspi; 139pub mod xspi;
140 140
141#[cfg(feature = "low-power")]
142pub use low_power::Executor;
143
141// This must go last, so that it sees all the impl_foo! macros defined earlier. 144// This must go last, so that it sees all the impl_foo! macros defined earlier.
142pub(crate) mod _generated { 145pub(crate) mod _generated {
143 #![allow(dead_code)] 146 #![allow(dead_code)]
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 5c10c1a5d..02116e08a 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -3,31 +3,31 @@
3//! The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating 3//! The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating
4//! to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which 4//! to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which
5//! can use knowledge of which peripherals are currently blocked upon to transparently and safely 5//! can use knowledge of which peripherals are currently blocked upon to transparently and safely
6//! enter such low-power modes (currently, only `STOP2`) when idle. 6//! enter such low-power modes including `STOP1` and `STOP2` when idle.
7//! 7//!
8//! The executor determines which peripherals are active by their RCC state; consequently, 8//! The executor determines which peripherals are active by their RCC state; consequently,
9//! low-power states can only be entered if all peripherals have been `drop`'d. There are a few 9//! low-power states can only be entered if peripherals which block stop have been `drop`'d and if
10//! exceptions to this rule: 10//! peripherals that do not block stop are busy. Peripherals which never block stop include:
11//! 11//!
12//! * `GPIO` 12//! * `GPIO`
13//! * `RTC` 13//! * `RTC`
14//! 14//!
15//! Other peripherals which block stop when busy include (this list may be stale):
16//!
17//! * `I2C`
18//! * `USART`
19//!
15//! Since entering and leaving low-power modes typically incurs a significant latency, the 20//! Since entering and leaving low-power modes typically incurs a significant latency, the
16//! low-power executor will only attempt to enter when the next timer event is at least 21//! low-power executor will only attempt to enter when the next timer event is at least
17//! [`time_driver::min_stop_pause`] in the future. 22//! [`config.min_stop_pause`] in the future.
18//! 23//!
19//! Currently there is no macro analogous to `embassy_executor::main` for this executor;
20//! consequently one must define their entrypoint manually. Moreover, you must relinquish control
21//! of the `RTC` peripheral to the executor. This will typically look like
22//! 24//!
23//! ```rust,no_run 25//! ```rust,no_run
24//! use embassy_executor::Spawner; 26//! use embassy_executor::Spawner;
25//! use embassy_stm32::low_power;
26//! use embassy_stm32::rtc::{Rtc, RtcConfig};
27//! use embassy_time::Duration; 27//! use embassy_time::Duration;
28//! 28//!
29//! #[embassy_executor::main(executor = "low_power::Executor")] 29//! #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")]
30//! async fn async_main(spawner: Spawner) { 30//! async fn main(spawner: Spawner) {
31//! // initialize the platform... 31//! // initialize the platform...
32//! let mut config = embassy_stm32::Config::default(); 32//! let mut config = embassy_stm32::Config::default();
33//! // the default value, but can be adjusted 33//! // the default value, but can be adjusted
@@ -210,7 +210,7 @@ impl Executor {
210 w.set_c1cssf(false); 210 w.set_c1cssf(false);
211 }); 211 });
212 212
213 let has_stopped2 = { 213 let _has_stopped2 = {
214 #[cfg(stm32wb)] 214 #[cfg(stm32wb)]
215 { 215 {
216 es.c2stopf() 216 es.c2stopf()
@@ -222,10 +222,11 @@ impl Executor {
222 } 222 }
223 }; 223 };
224 224
225 if es.c1stopf() || has_stopped2 { 225 #[cfg(not(stm32wb))]
226 if es.c1stopf() || _has_stopped2 {
226 // when we wake from any stop mode we need to re-initialize the rcc 227 // when we wake from any stop mode we need to re-initialize the rcc
227 crate::rcc::init(RCC_CONFIG.unwrap()); 228 crate::rcc::init(RCC_CONFIG.unwrap());
228 if has_stopped2 { 229 if _has_stopped2 {
229 // when we wake from STOP2, we need to re-initialize the time driver 230 // when we wake from STOP2, we need to re-initialize the time driver
230 get_driver().init_timer(cs); 231 get_driver().init_timer(cs);
231 // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) 232 // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer)