diff options
Diffstat (limited to 'embassy-stm32/src/low_power.rs')
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index cdf3323fb..2388abe3c 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -88,7 +88,7 @@ foreach_interrupt! { | |||
| 88 | #[interrupt] | 88 | #[interrupt] |
| 89 | #[allow(non_snake_case)] | 89 | #[allow(non_snake_case)] |
| 90 | unsafe fn $irq() { | 90 | unsafe fn $irq() { |
| 91 | Executor::on_wakeup_irq(); | 91 | Executor::on_wakeup_irq_or_event(); |
| 92 | } | 92 | } |
| 93 | }; | 93 | }; |
| 94 | } | 94 | } |
| @@ -99,7 +99,7 @@ foreach_interrupt! { | |||
| 99 | #[interrupt] | 99 | #[interrupt] |
| 100 | #[allow(non_snake_case)] | 100 | #[allow(non_snake_case)] |
| 101 | unsafe fn $irq() { | 101 | unsafe fn $irq() { |
| 102 | Executor::on_wakeup_irq(); | 102 | Executor::on_wakeup_irq_or_event(); |
| 103 | } | 103 | } |
| 104 | }; | 104 | }; |
| 105 | } | 105 | } |
| @@ -164,22 +164,30 @@ impl Executor { | |||
| 164 | } | 164 | } |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | pub(crate) unsafe fn on_wakeup_irq() { | 167 | pub(crate) unsafe fn on_wakeup_irq_or_event() { |
| 168 | if !get_driver().is_stopped() { | ||
| 169 | return; | ||
| 170 | } | ||
| 171 | |||
| 168 | critical_section::with(|cs| { | 172 | critical_section::with(|cs| { |
| 169 | #[cfg(stm32wlex)] | 173 | #[cfg(stm32wlex)] |
| 170 | { | 174 | { |
| 171 | use crate::pac::rcc::vals::Sw; | 175 | let es = crate::pac::PWR.extscr().read(); |
| 172 | use crate::pac::{PWR, RCC}; | 176 | match (es.c1stopf(), es.c1stop2f()) { |
| 173 | use crate::rcc::init as init_rcc; | 177 | (true, false) => debug!("low power: wake from STOP1"), |
| 174 | 178 | (false, true) => debug!("low power: wake from STOP2"), | |
| 175 | let extscr = PWR.extscr().read(); | 179 | (true, true) => debug!("low power: wake from STOP1 and STOP2 ???"), |
| 176 | if extscr.c1stop2f() || extscr.c1stopf() { | 180 | (false, false) => trace!("low power: stop mode not entered"), |
| 181 | }; | ||
| 182 | crate::pac::PWR.extscr().modify(|w| { | ||
| 183 | w.set_c1cssf(false); | ||
| 184 | }); | ||
| 185 | |||
| 186 | if es.c1stop2f() || es.c1stopf() { | ||
| 177 | // when we wake from any stop mode we need to re-initialize the rcc | 187 | // when we wake from any stop mode we need to re-initialize the rcc |
| 178 | while RCC.cfgr().read().sws() != Sw::MSI {} | 188 | crate::rcc::init(RCC_CONFIG.unwrap()); |
| 179 | |||
| 180 | init_rcc(RCC_CONFIG.unwrap()); | ||
| 181 | 189 | ||
| 182 | if extscr.c1stop2f() { | 190 | if es.c1stop2f() { |
| 183 | // when we wake from STOP2, we need to re-initialize the time driver | 191 | // when we wake from STOP2, we need to re-initialize the time driver |
| 184 | get_driver().init_timer(cs); | 192 | get_driver().init_timer(cs); |
| 185 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) | 193 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) |
| @@ -190,7 +198,8 @@ impl Executor { | |||
| 190 | } | 198 | } |
| 191 | } | 199 | } |
| 192 | get_driver().resume_time(cs); | 200 | get_driver().resume_time(cs); |
| 193 | trace!("low power: resume"); | 201 | |
| 202 | trace!("low power: resume time"); | ||
| 194 | }); | 203 | }); |
| 195 | } | 204 | } |
| 196 | 205 | ||
| @@ -201,10 +210,8 @@ impl Executor { | |||
| 201 | fn stop_mode(_cs: CriticalSection) -> Option<StopMode> { | 210 | fn stop_mode(_cs: CriticalSection) -> Option<StopMode> { |
| 202 | // We cannot enter standby because we will lose program state. | 211 | // We cannot enter standby because we will lose program state. |
| 203 | if unsafe { REFCOUNT_STOP2 == 0 && REFCOUNT_STOP1 == 0 } { | 212 | if unsafe { REFCOUNT_STOP2 == 0 && REFCOUNT_STOP1 == 0 } { |
| 204 | trace!("low power: stop 2"); | ||
| 205 | Some(StopMode::Stop2) | 213 | Some(StopMode::Stop2) |
| 206 | } else if unsafe { REFCOUNT_STOP1 == 0 } { | 214 | } else if unsafe { REFCOUNT_STOP1 == 0 } { |
| 207 | trace!("low power: stop 1"); | ||
| 208 | Some(StopMode::Stop1) | 215 | Some(StopMode::Stop1) |
| 209 | } else { | 216 | } else { |
| 210 | trace!("low power: not ready to stop (refcount_stop1: {})", unsafe { | 217 | trace!("low power: not ready to stop (refcount_stop1: {})", unsafe { |
| @@ -305,9 +312,11 @@ impl Executor { | |||
| 305 | get_driver().pause_time(cs).ok()?; | 312 | get_driver().pause_time(cs).ok()?; |
| 306 | self.configure_stop(cs, stop_mode).ok()?; | 313 | self.configure_stop(cs, stop_mode).ok()?; |
| 307 | 314 | ||
| 308 | Some(()) | 315 | Some(stop_mode) |
| 309 | }) | 316 | }) |
| 310 | .map(|_| { | 317 | .map(|stop_mode| { |
| 318 | trace!("low power: enter stop: {}", stop_mode); | ||
| 319 | |||
| 311 | #[cfg(not(feature = "low-power-debug-with-sleep"))] | 320 | #[cfg(not(feature = "low-power-debug-with-sleep"))] |
| 312 | Self::get_scb().set_sleepdeep(); | 321 | Self::get_scb().set_sleepdeep(); |
| 313 | }); | 322 | }); |
| @@ -338,20 +347,10 @@ impl Executor { | |||
| 338 | unsafe { | 347 | unsafe { |
| 339 | self.inner.poll(); | 348 | self.inner.poll(); |
| 340 | self.configure_pwr(); | 349 | self.configure_pwr(); |
| 350 | #[cfg(feature = "defmt")] | ||
| 351 | defmt::flush(); | ||
| 341 | asm!("wfe"); | 352 | asm!("wfe"); |
| 342 | #[cfg(stm32wlex)] | 353 | Self::on_wakeup_irq_or_event(); |
| 343 | { | ||
| 344 | let es = crate::pac::PWR.extscr().read(); | ||
| 345 | match (es.c1stopf(), es.c1stop2f()) { | ||
| 346 | (true, false) => debug!("low power: wake from STOP1"), | ||
| 347 | (false, true) => debug!("low power: wake from STOP2"), | ||
| 348 | (true, true) => debug!("low power: wake from STOP1 and STOP2 ???"), | ||
| 349 | (false, false) => trace!("low power: stop mode not entered"), | ||
| 350 | }; | ||
| 351 | crate::pac::PWR.extscr().modify(|w| { | ||
| 352 | w.set_c1cssf(false); | ||
| 353 | }); | ||
| 354 | } | ||
| 355 | }; | 354 | }; |
| 356 | } | 355 | } |
| 357 | } | 356 | } |
