diff options
| author | xoviat <[email protected]> | 2025-12-18 07:00:59 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2025-12-18 07:00:59 -0600 |
| commit | d113772136548e2bb50cecf1749f73bef72a0fe9 (patch) | |
| tree | 9fa0e3bb56a967503a16d6dbfd5c7c383de75649 | |
| parent | 10630047153a8246573191d53d5ac571a3750117 (diff) | |
stm32: cleanup low-power features
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 29 | ||||
| -rw-r--r-- | examples/stm32wb/Cargo.toml | 4 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/blinky.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/button_exti.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/eddystone_beacon.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/gatt_server.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/mac_ffd.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/mac_ffd_net.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/mac_rfd.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/tl_mbox.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/tl_mbox_ble.rs | 2 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/tl_mbox_mac.rs | 2 |
14 files changed, 32 insertions, 28 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index e96933b78..880df5f33 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -242,8 +242,8 @@ chrono = ["dep:chrono"] | |||
| 242 | 242 | ||
| 243 | exti = [] | 243 | exti = [] |
| 244 | low-power = [ "dep:embassy-executor", "time" ] | 244 | low-power = [ "dep:embassy-executor", "time" ] |
| 245 | low-power-pender = [ ] | 245 | low-power-pender = [ "low-power" ] |
| 246 | low-power-debug-with-sleep = [] | 246 | low-power-debug-with-sleep = [ "low-power" ] |
| 247 | 247 | ||
| 248 | ## Automatically generate `memory.x` file based on the memory map from [`stm32-metapac`](https://docs.rs/stm32-metapac/) | 248 | ## Automatically generate `memory.x` file based on the memory map from [`stm32-metapac`](https://docs.rs/stm32-metapac/) |
| 249 | memory-x = [] | 249 | memory-x = [] |
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)] |
| 139 | pub mod xspi; | 139 | pub mod xspi; |
| 140 | 140 | ||
| 141 | #[cfg(feature = "low-power")] | ||
| 142 | pub 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. |
| 142 | pub(crate) mod _generated { | 145 | pub(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) |
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 83f7cb56b..496500f75 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml | |||
| @@ -7,10 +7,10 @@ publish = false | |||
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | # Change stm32wb55rg to your chip name in both dependencies, if necessary. | 9 | # Change stm32wb55rg to your chip name in both dependencies, if necessary. |
| 10 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti", "low-power"] } | 10 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti", "low-power-pender"] } |
| 11 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } | 11 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } |
| 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 13 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | 13 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["defmt"] } |
| 14 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 14 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 15 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true } | 15 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true } |
| 16 | 16 | ||
diff --git a/examples/stm32wb/src/bin/blinky.rs b/examples/stm32wb/src/bin/blinky.rs index f37e8b1d8..e2737fcd5 100644 --- a/examples/stm32wb/src/bin/blinky.rs +++ b/examples/stm32wb/src/bin/blinky.rs | |||
| @@ -7,7 +7,7 @@ use embassy_stm32::gpio::{Level, Output, Speed}; | |||
| 7 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 11 | async fn main(_spawner: Spawner) { | 11 | async fn main(_spawner: Spawner) { |
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs index 3c58eb556..37a207519 100644 --- a/examples/stm32wb/src/bin/button_exti.rs +++ b/examples/stm32wb/src/bin/button_exti.rs | |||
| @@ -13,7 +13,7 @@ bind_interrupts!( | |||
| 13 | EXTI4 => exti::InterruptHandler<interrupt::typelevel::EXTI4>; | 13 | EXTI4 => exti::InterruptHandler<interrupt::typelevel::EXTI4>; |
| 14 | }); | 14 | }); |
| 15 | 15 | ||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let p = embassy_stm32::init(Default::default()); | 18 | let p = embassy_stm32::init(Default::default()); |
| 19 | info!("Hello World!"); | 19 | info!("Hello World!"); |
diff --git a/examples/stm32wb/src/bin/eddystone_beacon.rs b/examples/stm32wb/src/bin/eddystone_beacon.rs index 413b1ac8f..a679e6fb1 100644 --- a/examples/stm32wb/src/bin/eddystone_beacon.rs +++ b/examples/stm32wb/src/bin/eddystone_beacon.rs | |||
| @@ -26,7 +26,7 @@ bind_interrupts!(struct Irqs{ | |||
| 26 | 26 | ||
| 27 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; | 27 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; |
| 28 | 28 | ||
| 29 | #[embassy_executor::main] | 29 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 30 | async fn main(_spawner: Spawner) { | 30 | async fn main(_spawner: Spawner) { |
| 31 | /* | 31 | /* |
| 32 | How to make this work: | 32 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/gatt_server.rs b/examples/stm32wb/src/bin/gatt_server.rs index 3484f1844..10c7fd0ba 100644 --- a/examples/stm32wb/src/bin/gatt_server.rs +++ b/examples/stm32wb/src/bin/gatt_server.rs | |||
| @@ -38,7 +38,7 @@ bind_interrupts!(struct Irqs{ | |||
| 38 | 38 | ||
| 39 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; | 39 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; |
| 40 | 40 | ||
| 41 | #[embassy_executor::main] | 41 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 42 | async fn main(spawner: Spawner) { | 42 | async fn main(spawner: Spawner) { |
| 43 | /* | 43 | /* |
| 44 | How to make this work: | 44 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs index 4bab6ea9f..cd15968d2 100644 --- a/examples/stm32wb/src/bin/mac_ffd.rs +++ b/examples/stm32wb/src/bin/mac_ffd.rs | |||
| @@ -23,7 +23,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 23 | memory_manager.run_queue().await; | 23 | memory_manager.run_queue().await; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | #[embassy_executor::main] | 26 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 27 | async fn main(spawner: Spawner) { | 27 | async fn main(spawner: Spawner) { |
| 28 | /* | 28 | /* |
| 29 | How to make this work: | 29 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs index b4789e3ee..244b35243 100644 --- a/examples/stm32wb/src/bin/mac_ffd_net.rs +++ b/examples/stm32wb/src/bin/mac_ffd_net.rs | |||
| @@ -41,7 +41,7 @@ async fn run_net(mut runner: embassy_net::Runner<'static, Driver<'static>>) -> ! | |||
| 41 | runner.run().await | 41 | runner.run().await |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | #[embassy_executor::main] | 44 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 45 | async fn main(spawner: Spawner) { | 45 | async fn main(spawner: Spawner) { |
| 46 | /* | 46 | /* |
| 47 | How to make this work: | 47 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs index dae3c5200..f3e65c66b 100644 --- a/examples/stm32wb/src/bin/mac_rfd.rs +++ b/examples/stm32wb/src/bin/mac_rfd.rs | |||
| @@ -25,7 +25,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 25 | memory_manager.run_queue().await; | 25 | memory_manager.run_queue().await; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | #[embassy_executor::main] | 28 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 29 | async fn main(spawner: Spawner) { | 29 | async fn main(spawner: Spawner) { |
| 30 | /* | 30 | /* |
| 31 | How to make this work: | 31 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index 0902e28e8..adb6eff7b 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs | |||
| @@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs{ | |||
| 15 | IPCC_C1_TX => TransmitInterruptHandler; | 15 | IPCC_C1_TX => TransmitInterruptHandler; |
| 16 | }); | 16 | }); |
| 17 | 17 | ||
| 18 | #[embassy_executor::main] | 18 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 19 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner) { |
| 20 | /* | 20 | /* |
| 21 | How to make this work: | 21 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/tl_mbox_ble.rs b/examples/stm32wb/src/bin/tl_mbox_ble.rs index 763dc32cd..376b808de 100644 --- a/examples/stm32wb/src/bin/tl_mbox_ble.rs +++ b/examples/stm32wb/src/bin/tl_mbox_ble.rs | |||
| @@ -20,7 +20,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 20 | memory_manager.run_queue().await; | 20 | memory_manager.run_queue().await; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | #[embassy_executor::main] | 23 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 24 | async fn main(spawner: Spawner) { | 24 | async fn main(spawner: Spawner) { |
| 25 | /* | 25 | /* |
| 26 | How to make this work: | 26 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs index 235a48241..697e061c1 100644 --- a/examples/stm32wb/src/bin/tl_mbox_mac.rs +++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs | |||
| @@ -20,7 +20,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 20 | memory_manager.run_queue().await; | 20 | memory_manager.run_queue().await; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | #[embassy_executor::main] | 23 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 24 | async fn main(spawner: Spawner) { | 24 | async fn main(spawner: Spawner) { |
| 25 | /* | 25 | /* |
| 26 | How to make this work: | 26 | How to make this work: |
