aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/CHANGELOG.md1
-rw-r--r--embassy-stm32/src/lib.rs5
-rw-r--r--embassy-stm32/src/low_power.rs88
-rw-r--r--embassy-stm32/src/rcc/l.rs43
-rw-r--r--embassy-stm32/src/rcc/mod.rs4
-rw-r--r--embassy-stm32/src/rtc/mod.rs7
-rw-r--r--embassy-stm32/src/time_driver.rs7
-rw-r--r--examples/stm32h5/src/bin/stop.rs12
-rw-r--r--examples/stm32l5/src/bin/stop.rs12
-rw-r--r--examples/stm32wle5/src/bin/adc.rs12
-rw-r--r--examples/stm32wle5/src/bin/blinky.rs12
-rw-r--r--examples/stm32wle5/src/bin/button_exti.rs12
-rw-r--r--examples/stm32wle5/src/bin/i2c.rs13
-rw-r--r--tests/stm32/src/bin/stop.rs14
14 files changed, 72 insertions, 170 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md
index df832d15f..8e3e802a4 100644
--- a/embassy-stm32/CHANGELOG.md
+++ b/embassy-stm32/CHANGELOG.md
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7 7
8## Unreleased - ReleaseDate 8## Unreleased - ReleaseDate
9 9
10- feat: allow embassy_executor::main for low power
10- feat: Add waveform methods to ComplementaryPwm 11- feat: Add waveform methods to ComplementaryPwm
11- fix: Avoid generating timer update events when updating the frequency ([#4890](https://github.com/embassy-rs/embassy/pull/4890)) 12- fix: Avoid generating timer update events when updating the frequency ([#4890](https://github.com/embassy-rs/embassy/pull/4890))
12- chore: cleanup low-power add time 13- chore: cleanup low-power add time
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 6e492946a..7c3770643 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -649,10 +649,7 @@ fn init_hw(config: Config) -> Peripherals {
649 rcc::init_rcc(cs, config.rcc); 649 rcc::init_rcc(cs, config.rcc);
650 650
651 #[cfg(feature = "low-power")] 651 #[cfg(feature = "low-power")]
652 crate::rtc::init_rtc(cs, config.rtc); 652 rtc::init_rtc(cs, config.rtc, config.min_stop_pause);
653
654 #[cfg(feature = "low-power")]
655 crate::time_driver::get_driver().set_min_stop_pause(cs, config.min_stop_pause);
656 } 653 }
657 654
658 p 655 p
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 36c7e2242..cf8f2b393 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -14,7 +14,7 @@
14//! 14//!
15//! Since entering and leaving low-power modes typically incurs a significant latency, the 15//! 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 16//! 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. 17//! [`time_driver::min_stop_pause`] in the future.
18//! 18//!
19//! Currently there is no macro analogous to `embassy_executor::main` for this executor; 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 20//! consequently one must define their entrypoint manually. Moreover, you must relinquish control
@@ -22,21 +22,16 @@
22//! 22//!
23//! ```rust,no_run 23//! ```rust,no_run
24//! use embassy_executor::Spawner; 24//! use embassy_executor::Spawner;
25//! use embassy_stm32::low_power::Executor; 25//! use embassy_stm32::low_power;
26//! use embassy_stm32::rtc::{Rtc, RtcConfig}; 26//! use embassy_stm32::rtc::{Rtc, RtcConfig};
27//! use static_cell::StaticCell; 27//! use embassy_time::Duration;
28//! 28//!
29//! #[cortex_m_rt::entry] 29//! #[embassy_executor::main(executor = "low_power::Executor")]
30//! fn main() -> ! {
31//! Executor::take().run(|spawner| {
32//! spawner.spawn(unwrap!(async_main(spawner)));
33//! });
34//! }
35//!
36//! #[embassy_executor::task]
37//! async fn async_main(spawner: Spawner) { 30//! async fn async_main(spawner: Spawner) {
38//! // initialize the platform... 31//! // initialize the platform...
39//! let mut config = embassy_stm32::Config::default(); 32//! let mut config = embassy_stm32::Config::default();
33//! // the default value, but can be adjusted
34//! config.min_stop_pause = Duration::from_millis(250);
40//! // when enabled the power-consumption is much higher during stop, but debugging and RTT is working 35//! // when enabled the power-consumption is much higher during stop, but debugging and RTT is working
41//! config.enable_debug_during_sleep = false; 36//! config.enable_debug_during_sleep = false;
42//! let p = embassy_stm32::init(config); 37//! let p = embassy_stm32::init(config);
@@ -45,11 +40,9 @@
45//! } 40//! }
46//! ``` 41//! ```
47 42
48// TODO: Usage of `static mut` here is unsound. Fix then remove this `allow`.`
49#![allow(static_mut_refs)]
50
51use core::arch::asm; 43use core::arch::asm;
52use core::marker::PhantomData; 44use core::marker::PhantomData;
45use core::mem;
53use core::sync::atomic::{Ordering, compiler_fence}; 46use core::sync::atomic::{Ordering, compiler_fence};
54 47
55use cortex_m::peripheral::SCB; 48use cortex_m::peripheral::SCB;
@@ -57,11 +50,12 @@ use critical_section::CriticalSection;
57use embassy_executor::*; 50use embassy_executor::*;
58 51
59use crate::interrupt; 52use crate::interrupt;
53use crate::rcc::{REFCOUNT_STOP1, REFCOUNT_STOP2};
60use crate::time_driver::get_driver; 54use crate::time_driver::get_driver;
61 55
62const THREAD_PENDER: usize = usize::MAX; 56const THREAD_PENDER: usize = usize::MAX;
63 57
64static mut EXECUTOR: Option<Executor> = None; 58static mut EXECUTOR_TAKEN: bool = false;
65 59
66/// Prevent the device from going into the stop mode if held 60/// Prevent the device from going into the stop mode if held
67pub struct DeviceBusy(StopMode); 61pub struct DeviceBusy(StopMode);
@@ -182,42 +176,47 @@ impl Into<Lpms> for StopMode {
182pub struct Executor { 176pub struct Executor {
183 inner: raw::Executor, 177 inner: raw::Executor,
184 not_send: PhantomData<*mut ()>, 178 not_send: PhantomData<*mut ()>,
185 scb: SCB,
186} 179}
187 180
188impl Executor { 181impl Executor {
189 /// Create a new Executor. 182 /// Create a new Executor.
190 pub fn take() -> &'static mut Self { 183 pub fn new() -> Self {
191 critical_section::with(|_| unsafe { 184 unsafe {
192 assert!(EXECUTOR.is_none()); 185 if EXECUTOR_TAKEN {
193 186 panic!("Low power executor can only be taken once.");
194 EXECUTOR = Some(Self { 187 } else {
195 inner: raw::Executor::new(THREAD_PENDER as *mut ()), 188 EXECUTOR_TAKEN = true;
196 not_send: PhantomData, 189 }
197 scb: cortex_m::Peripherals::steal().SCB, 190 }
198 });
199
200 let executor = EXECUTOR.as_mut().unwrap();
201 191
202 executor 192 Self {
203 }) 193 inner: raw::Executor::new(THREAD_PENDER as *mut ()),
194 not_send: PhantomData,
195 }
204 } 196 }
205 197
206 pub(crate) unsafe fn on_wakeup_irq() { 198 pub(crate) unsafe fn on_wakeup_irq() {
207 critical_section::with(|cs| { 199 critical_section::with(|cs| {
208 #[cfg(stm32wlex)] 200 #[cfg(stm32wlex)]
209 { 201 {
210 let extscr = crate::pac::PWR.extscr().read(); 202 use crate::pac::rcc::vals::Sw;
203 use crate::pac::{PWR, RCC};
204 use crate::rcc::{RCC_CONFIG, init as init_rcc};
205
206 let extscr = PWR.extscr().read();
211 if extscr.c1stop2f() || extscr.c1stopf() { 207 if extscr.c1stop2f() || extscr.c1stopf() {
212 // when we wake from any stop mode we need to re-initialize the rcc 208 // when we wake from any stop mode we need to re-initialize the rcc
213 crate::rcc::apply_resume_config(); 209 while RCC.cfgr().read().sws() != Sw::MSI {}
210
211 init_rcc(RCC_CONFIG.unwrap());
212
214 if extscr.c1stop2f() { 213 if extscr.c1stop2f() {
215 // when we wake from STOP2, we need to re-initialize the time driver 214 // when we wake from STOP2, we need to re-initialize the time driver
216 crate::time_driver::init_timer(cs); 215 get_driver().init_timer(cs);
217 // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) 216 // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer)
218 // and given that we just woke from STOP2, we can reset them 217 // and given that we just woke from STOP2, we can reset them
219 crate::rcc::REFCOUNT_STOP2 = 0; 218 REFCOUNT_STOP2 = 0;
220 crate::rcc::REFCOUNT_STOP1 = 0; 219 REFCOUNT_STOP1 = 0;
221 } 220 }
222 } 221 }
223 } 222 }
@@ -226,11 +225,15 @@ impl Executor {
226 }); 225 });
227 } 226 }
228 227
228 const fn get_scb() -> SCB {
229 unsafe { mem::transmute(()) }
230 }
231
229 fn stop_mode(_cs: CriticalSection) -> Option<StopMode> { 232 fn stop_mode(_cs: CriticalSection) -> Option<StopMode> {
230 if unsafe { crate::rcc::REFCOUNT_STOP2 == 0 && crate::rcc::REFCOUNT_STOP1 == 0 } { 233 if unsafe { REFCOUNT_STOP2 == 0 && REFCOUNT_STOP1 == 0 } {
231 trace!("low power: stop 2"); 234 trace!("low power: stop 2");
232 Some(StopMode::Stop2) 235 Some(StopMode::Stop2)
233 } else if unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } { 236 } else if unsafe { REFCOUNT_STOP1 == 0 } {
234 trace!("low power: stop 1"); 237 trace!("low power: stop 1");
235 Some(StopMode::Stop1) 238 Some(StopMode::Stop1)
236 } else { 239 } else {
@@ -240,7 +243,7 @@ impl Executor {
240 } 243 }
241 244
242 #[allow(unused_variables)] 245 #[allow(unused_variables)]
243 fn configure_stop(&mut self, stop_mode: StopMode) { 246 fn configure_stop(&self, stop_mode: StopMode) {
244 #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wba, stm32wlex))] 247 #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wba, stm32wlex))]
245 crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); 248 crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into()));
246 #[cfg(stm32h5)] 249 #[cfg(stm32h5)]
@@ -251,8 +254,8 @@ impl Executor {
251 }); 254 });
252 } 255 }
253 256
254 fn configure_pwr(&mut self) { 257 fn configure_pwr(&self) {
255 self.scb.clear_sleepdeep(); 258 Self::get_scb().clear_sleepdeep();
256 // Clear any previous stop flags 259 // Clear any previous stop flags
257 #[cfg(stm32wlex)] 260 #[cfg(stm32wlex)]
258 crate::pac::PWR.extscr().modify(|w| { 261 crate::pac::PWR.extscr().modify(|w| {
@@ -271,7 +274,7 @@ impl Executor {
271 self.configure_stop(stop_mode); 274 self.configure_stop(stop_mode);
272 275
273 #[cfg(not(feature = "low-power-debug-with-sleep"))] 276 #[cfg(not(feature = "low-power-debug-with-sleep"))]
274 self.scb.set_sleepdeep(); 277 Self::get_scb().set_sleepdeep();
275 }); 278 });
276 } 279 }
277 280
@@ -294,12 +297,11 @@ impl Executor {
294 /// 297 ///
295 /// This function never returns. 298 /// This function never returns.
296 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { 299 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
297 let executor = unsafe { EXECUTOR.as_mut().unwrap() }; 300 init(self.inner.spawner());
298 init(executor.inner.spawner());
299 301
300 loop { 302 loop {
301 unsafe { 303 unsafe {
302 executor.inner.poll(); 304 self.inner.poll();
303 self.configure_pwr(); 305 self.configure_pwr();
304 asm!("wfe"); 306 asm!("wfe");
305 #[cfg(stm32wlex)] 307 #[cfg(stm32wlex)]
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs
index 584957c6d..2e1cbd702 100644
--- a/embassy-stm32/src/rcc/l.rs
+++ b/embassy-stm32/src/rcc/l.rs
@@ -1,6 +1,3 @@
1#[cfg(all(feature = "low-power", stm32wlex))]
2use core::mem::MaybeUninit;
3
4#[cfg(any(stm32l0, stm32l1))] 1#[cfg(any(stm32l0, stm32l1))]
5pub use crate::pac::pwr::vals::Vos as VoltageScale; 2pub use crate::pac::pwr::vals::Vos as VoltageScale;
6use crate::pac::rcc::regs::Cfgr; 3use crate::pac::rcc::regs::Cfgr;
@@ -14,42 +11,6 @@ use crate::time::Hertz;
14/// HSI speed 11/// HSI speed
15pub const HSI_FREQ: Hertz = Hertz(16_000_000); 12pub const HSI_FREQ: Hertz = Hertz(16_000_000);
16 13
17/// Saved RCC Config
18///
19/// Used when exiting STOP2 to re-enable clocks to their last configured state
20/// for chips that need it.
21#[cfg(all(feature = "low-power", stm32wlex))]
22static mut RESUME_RCC_CONFIG: MaybeUninit<Config> = MaybeUninit::uninit();
23
24/// Set the rcc config to be restored when exiting STOP2
25///
26/// Safety: Sets a mutable global.
27#[cfg(all(feature = "low-power", stm32wlex))]
28pub(crate) unsafe fn set_resume_config(config: Config) {
29 trace!("rcc set_resume_config()");
30 RESUME_RCC_CONFIG = MaybeUninit::new(config);
31}
32
33/// Get the rcc config to be restored when exiting STOP2
34///
35/// Safety: Reads a mutable global.
36#[cfg(all(feature = "low-power", stm32wlex))]
37pub(crate) unsafe fn get_resume_config() -> Config {
38 *(*core::ptr::addr_of_mut!(RESUME_RCC_CONFIG)).assume_init_ref()
39}
40
41#[cfg(all(feature = "low-power", stm32wlex))]
42/// Safety: should only be called from low power executable just after resuming from STOP2
43pub(crate) unsafe fn apply_resume_config() {
44 trace!("rcc apply_resume_config()");
45
46 while RCC.cfgr().read().sws() != Sysclk::MSI {}
47
48 let config = get_resume_config();
49
50 init(config);
51}
52
53#[derive(Clone, Copy, Eq, PartialEq)] 14#[derive(Clone, Copy, Eq, PartialEq)]
54pub enum HseMode { 15pub enum HseMode {
55 /// crystal/ceramic oscillator (HSEBYP=0) 16 /// crystal/ceramic oscillator (HSEBYP=0)
@@ -193,10 +154,6 @@ fn msi_enable(range: MSIRange) {
193} 154}
194 155
195pub(crate) unsafe fn init(config: Config) { 156pub(crate) unsafe fn init(config: Config) {
196 // save the rcc config because if we enter stop 2 we need to re-apply it on wakeup
197 #[cfg(all(feature = "low-power", stm32wlex))]
198 set_resume_config(config);
199
200 // Switch to MSI to prevent problems with PLL configuration. 157 // Switch to MSI to prevent problems with PLL configuration.
201 if !RCC.cr().read().msion() { 158 if !RCC.cr().read().msion() {
202 // Turn on MSI and configure it to 4MHz. 159 // Turn on MSI and configure it to 4MHz.
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index ca7c28cbc..66ee06e17 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -49,6 +49,9 @@ pub(crate) static mut REFCOUNT_STOP1: u32 = 0;
49/// May be read without a critical section 49/// May be read without a critical section
50pub(crate) static mut REFCOUNT_STOP2: u32 = 0; 50pub(crate) static mut REFCOUNT_STOP2: u32 = 0;
51 51
52#[cfg(feature = "low-power")]
53pub(crate) static mut RCC_CONFIG: Option<Config> = None;
54
52#[cfg(backup_sram)] 55#[cfg(backup_sram)]
53pub(crate) static mut BKSRAM_RETAINED: bool = false; 56pub(crate) static mut BKSRAM_RETAINED: bool = false;
54 57
@@ -408,6 +411,7 @@ pub(crate) fn init_rcc(_cs: CriticalSection, config: Config) {
408 411
409 #[cfg(feature = "low-power")] 412 #[cfg(feature = "low-power")]
410 { 413 {
414 RCC_CONFIG = Some(config);
411 REFCOUNT_STOP2 = 0; 415 REFCOUNT_STOP2 = 0;
412 REFCOUNT_STOP1 = 0; 416 REFCOUNT_STOP1 = 0;
413 } 417 }
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 116b3c7ed..e88bd7ab2 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -379,13 +379,16 @@ trait SealedInstance {
379} 379}
380 380
381#[cfg(feature = "low-power")] 381#[cfg(feature = "low-power")]
382pub(crate) fn init_rtc(cs: CriticalSection, config: RtcConfig) { 382pub(crate) fn init_rtc(cs: CriticalSection, config: RtcConfig, min_stop_pause: embassy_time::Duration) {
383 use crate::time_driver::get_driver;
384
383 #[cfg(feature = "_allow-disable-rtc")] 385 #[cfg(feature = "_allow-disable-rtc")]
384 if config._disable_rtc { 386 if config._disable_rtc {
385 return; 387 return;
386 } 388 }
387 389
388 crate::time_driver::get_driver().set_rtc(cs, Rtc::new_inner(config)); 390 get_driver().set_rtc(cs, Rtc::new_inner(config));
391 get_driver().set_min_stop_pause(cs, min_stop_pause);
389 392
390 trace!("low power: stop with rtc configured"); 393 trace!("low power: stop with rtc configured");
391} 394}
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 6d93b430a..0b75aef92 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -245,7 +245,7 @@ embassy_time_driver::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
245impl RtcDriver { 245impl RtcDriver {
246 /// initialize the timer, but don't start it. Used for chips like stm32wle5 246 /// initialize the timer, but don't start it. Used for chips like stm32wle5
247 /// for low power where the timer config is lost in STOP2. 247 /// for low power where the timer config is lost in STOP2.
248 fn init_timer(&'static self, cs: critical_section::CriticalSection) { 248 pub(crate) fn init_timer(&'static self, cs: critical_section::CriticalSection) {
249 let r = regs_gp16(); 249 let r = regs_gp16();
250 250
251 rcc::enable_and_reset_with_cs::<T>(cs); 251 rcc::enable_and_reset_with_cs::<T>(cs);
@@ -516,8 +516,3 @@ pub(crate) const fn get_driver() -> &'static RtcDriver {
516pub(crate) fn init(cs: CriticalSection) { 516pub(crate) fn init(cs: CriticalSection) {
517 DRIVER.init(cs) 517 DRIVER.init(cs)
518} 518}
519
520#[cfg(all(feature = "low-power", stm32wlex))]
521pub(crate) fn init_timer(cs: CriticalSection) {
522 DRIVER.init_timer(cs)
523}
diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs
index caebc9daf..8d5456b80 100644
--- a/examples/stm32h5/src/bin/stop.rs
+++ b/examples/stm32h5/src/bin/stop.rs
@@ -7,20 +7,12 @@
7use defmt::*; 7use defmt::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; 9use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
10use embassy_stm32::low_power::Executor;
11use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; 10use embassy_stm32::rcc::{HSIPrescaler, LsConfig};
12use embassy_stm32::{Config, Peri}; 11use embassy_stm32::{Config, Peri, low_power};
13use embassy_time::Timer; 12use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
16#[cortex_m_rt::entry] 15#[embassy_executor::main(executor = "low_power::Executor")]
17fn main() -> ! {
18 Executor::take().run(|spawner| {
19 spawner.spawn(unwrap!(async_main(spawner)));
20 })
21}
22
23#[embassy_executor::task]
24async fn async_main(spawner: Spawner) { 16async fn async_main(spawner: Spawner) {
25 defmt::info!("Program Start"); 17 defmt::info!("Program Start");
26 18
diff --git a/examples/stm32l5/src/bin/stop.rs b/examples/stm32l5/src/bin/stop.rs
index 3d119f90f..fde804fb7 100644
--- a/examples/stm32l5/src/bin/stop.rs
+++ b/examples/stm32l5/src/bin/stop.rs
@@ -4,20 +4,12 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; 6use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
7use embassy_stm32::low_power::Executor;
8use embassy_stm32::rcc::LsConfig; 7use embassy_stm32::rcc::LsConfig;
9use embassy_stm32::{Config, Peri}; 8use embassy_stm32::{Config, Peri, low_power};
10use embassy_time::Timer; 9use embassy_time::Timer;
11use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
12 11
13#[cortex_m_rt::entry] 12#[embassy_executor::main(executor = "low_power::Executor")]
14fn main() -> ! {
15 Executor::take().run(|spawner| {
16 spawner.spawn(unwrap!(async_main(spawner)));
17 })
18}
19
20#[embassy_executor::task]
21async fn async_main(spawner: Spawner) { 13async fn async_main(spawner: Spawner) {
22 let mut config = Config::default(); 14 let mut config = Config::default();
23 config.rcc.ls = LsConfig::default_lsi(); 15 config.rcc.ls = LsConfig::default_lsi();
diff --git a/examples/stm32wle5/src/bin/adc.rs b/examples/stm32wle5/src/bin/adc.rs
index 4e0574d97..ea91fb063 100644
--- a/examples/stm32wle5/src/bin/adc.rs
+++ b/examples/stm32wle5/src/bin/adc.rs
@@ -6,20 +6,12 @@ use defmt::*;
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::adc::{Adc, SampleTime}; 8use embassy_stm32::adc::{Adc, SampleTime};
9use embassy_stm32::low_power::Executor; 9use embassy_stm32::low_power;
10use embassy_time::Timer; 10use embassy_time::Timer;
11use panic_probe as _; 11use panic_probe as _;
12use static_cell::StaticCell; 12use static_cell::StaticCell;
13 13
14#[cortex_m_rt::entry] 14#[embassy_executor::main(executor = "low_power::Executor")]
15fn main() -> ! {
16 info!("main: Starting!");
17 Executor::take().run(|spawner| {
18 spawner.spawn(unwrap!(async_main(spawner)));
19 });
20}
21
22#[embassy_executor::task]
23async fn async_main(_spawner: Spawner) { 15async fn async_main(_spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default(); 16 let mut config = embassy_stm32::Config::default();
25 // enable HSI clock 17 // enable HSI clock
diff --git a/examples/stm32wle5/src/bin/blinky.rs b/examples/stm32wle5/src/bin/blinky.rs
index b2745fdaf..9f0c04672 100644
--- a/examples/stm32wle5/src/bin/blinky.rs
+++ b/examples/stm32wle5/src/bin/blinky.rs
@@ -6,20 +6,12 @@ use defmt::*;
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::gpio::{Level, Output, Speed}; 8use embassy_stm32::gpio::{Level, Output, Speed};
9use embassy_stm32::low_power::Executor; 9use embassy_stm32::low_power;
10use embassy_time::Timer; 10use embassy_time::Timer;
11use panic_probe as _; 11use panic_probe as _;
12use static_cell::StaticCell; 12use static_cell::StaticCell;
13 13
14#[cortex_m_rt::entry] 14#[embassy_executor::main(executor = "low_power::Executor")]
15fn main() -> ! {
16 info!("main: Starting!");
17 Executor::take().run(|spawner| {
18 spawner.spawn(unwrap!(async_main(spawner)));
19 });
20}
21
22#[embassy_executor::task]
23async fn async_main(_spawner: Spawner) { 15async fn async_main(_spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default(); 16 let mut config = embassy_stm32::Config::default();
25 // enable HSI clock 17 // enable HSI clock
diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs
index db1bff0be..878eca7d0 100644
--- a/examples/stm32wle5/src/bin/button_exti.rs
+++ b/examples/stm32wle5/src/bin/button_exti.rs
@@ -7,19 +7,11 @@ use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::exti::ExtiInput; 8use embassy_stm32::exti::ExtiInput;
9use embassy_stm32::gpio::Pull; 9use embassy_stm32::gpio::Pull;
10use embassy_stm32::low_power::Executor; 10use embassy_stm32::low_power;
11use panic_probe as _; 11use panic_probe as _;
12use static_cell::StaticCell; 12use static_cell::StaticCell;
13 13
14#[cortex_m_rt::entry] 14#[embassy_executor::main(executor = "low_power::Executor")]
15fn main() -> ! {
16 info!("main: Starting!");
17 Executor::take().run(|spawner| {
18 spawner.spawn(unwrap!(async_main(spawner)));
19 });
20}
21
22#[embassy_executor::task]
23async fn async_main(_spawner: Spawner) { 15async fn async_main(_spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default(); 16 let mut config = embassy_stm32::Config::default();
25 // enable HSI clock 17 // enable HSI clock
diff --git a/examples/stm32wle5/src/bin/i2c.rs b/examples/stm32wle5/src/bin/i2c.rs
index c31c673c9..68c17a672 100644
--- a/examples/stm32wle5/src/bin/i2c.rs
+++ b/examples/stm32wle5/src/bin/i2c.rs
@@ -6,9 +6,8 @@ use defmt::*;
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::i2c::I2c; 8use embassy_stm32::i2c::I2c;
9use embassy_stm32::low_power::Executor;
10use embassy_stm32::time::Hertz; 9use embassy_stm32::time::Hertz;
11use embassy_stm32::{bind_interrupts, i2c, peripherals}; 10use embassy_stm32::{bind_interrupts, i2c, low_power, peripherals};
12use embassy_time::{Duration, Timer}; 11use embassy_time::{Duration, Timer};
13use panic_probe as _; 12use panic_probe as _;
14use static_cell::StaticCell; 13use static_cell::StaticCell;
@@ -18,15 +17,7 @@ bind_interrupts!(struct IrqsI2C{
18 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; 17 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
19}); 18});
20 19
21#[cortex_m_rt::entry] 20#[embassy_executor::main(executor = "low_power::Executor")]
22fn main() -> ! {
23 info!("main: Starting!");
24 Executor::take().run(|spawner| {
25 spawner.spawn(unwrap!(async_main(spawner)));
26 });
27}
28
29#[embassy_executor::task]
30async fn async_main(_spawner: Spawner) { 21async fn async_main(_spawner: Spawner) {
31 let mut config = embassy_stm32::Config::default(); 22 let mut config = embassy_stm32::Config::default();
32 // enable HSI clock 23 // enable HSI clock
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index 1fe65d867..83c375bc5 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -7,21 +7,13 @@ mod common;
7 7
8use chrono::NaiveDate; 8use chrono::NaiveDate;
9use common::*; 9use common::*;
10use cortex_m_rt::entry;
11use embassy_executor::Spawner; 10use embassy_executor::Spawner;
12use embassy_stm32::Config; 11use embassy_stm32::low_power::{StopMode, stop_ready};
13use embassy_stm32::low_power::{Executor, StopMode, stop_ready};
14use embassy_stm32::rcc::LsConfig; 12use embassy_stm32::rcc::LsConfig;
15use embassy_stm32::rtc::Rtc; 13use embassy_stm32::rtc::Rtc;
14use embassy_stm32::{Config, low_power};
16use embassy_time::Timer; 15use embassy_time::Timer;
17 16
18#[entry]
19fn main() -> ! {
20 Executor::take().run(|spawner| {
21 spawner.spawn(unwrap!(async_main(spawner)));
22 });
23}
24
25#[embassy_executor::task] 17#[embassy_executor::task]
26async fn task_1() { 18async fn task_1() {
27 for _ in 0..9 { 19 for _ in 0..9 {
@@ -43,7 +35,7 @@ async fn task_2() {
43 cortex_m::asm::bkpt(); 35 cortex_m::asm::bkpt();
44} 36}
45 37
46#[embassy_executor::task] 38#[embassy_executor::main(executor = "low_power::Executor")]
47async fn async_main(spawner: Spawner) { 39async fn async_main(spawner: Spawner) {
48 let _ = config(); 40 let _ = config();
49 41