diff options
| -rw-r--r-- | embassy-stm32/src/exti.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 46 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/time_driver.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/mod.rs | 4 |
6 files changed, 36 insertions, 26 deletions
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 7b7896d46..458174b5d 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs | |||
| @@ -74,7 +74,7 @@ unsafe fn on_irq() { | |||
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | #[cfg(feature = "low-power")] | 76 | #[cfg(feature = "low-power")] |
| 77 | crate::low_power::Executor::on_wakeup_irq(); | 77 | crate::low_power::Executor::on_wakeup_irq_or_event(); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | struct BitIter(u32); | 80 | struct BitIter(u32); |
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 6b213484c..7ad9978b1 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -73,7 +73,7 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() { | |||
| 73 | // restore the clocks to their last configured state as | 73 | // restore the clocks to their last configured state as |
| 74 | // much is lost in STOP modes | 74 | // much is lost in STOP modes |
| 75 | #[cfg(all(feature = "low-power", stm32wlex))] | 75 | #[cfg(all(feature = "low-power", stm32wlex))] |
| 76 | crate::low_power::Executor::on_wakeup_irq(); | 76 | crate::low_power::Executor::on_wakeup_irq_or_event(); |
| 77 | 77 | ||
| 78 | let regs = T::info().regs; | 78 | let regs = T::info().regs; |
| 79 | let isr = regs.isr().read(); | 79 | let isr = regs.isr().read(); |
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index cdf3323fb..94217f07f 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,7 +164,11 @@ 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 | { |
| @@ -172,6 +176,17 @@ impl Executor { | |||
| 172 | use crate::pac::{PWR, RCC}; | 176 | use crate::pac::{PWR, RCC}; |
| 173 | use crate::rcc::init as init_rcc; | 177 | use crate::rcc::init as init_rcc; |
| 174 | 178 | ||
| 179 | let es = crate::pac::PWR.extscr().read(); | ||
| 180 | match (es.c1stopf(), es.c1stop2f()) { | ||
| 181 | (true, false) => debug!("low power: wake from STOP1"), | ||
| 182 | (false, true) => debug!("low power: wake from STOP2"), | ||
| 183 | (true, true) => debug!("low power: wake from STOP1 and STOP2 ???"), | ||
| 184 | (false, false) => trace!("low power: stop mode not entered"), | ||
| 185 | }; | ||
| 186 | crate::pac::PWR.extscr().modify(|w| { | ||
| 187 | w.set_c1cssf(false); | ||
| 188 | }); | ||
| 189 | |||
| 175 | let extscr = PWR.extscr().read(); | 190 | let extscr = PWR.extscr().read(); |
| 176 | if extscr.c1stop2f() || extscr.c1stopf() { | 191 | if extscr.c1stop2f() || extscr.c1stopf() { |
| 177 | // when we wake from any stop mode we need to re-initialize the rcc | 192 | // when we wake from any stop mode we need to re-initialize the rcc |
| @@ -190,7 +205,8 @@ impl Executor { | |||
| 190 | } | 205 | } |
| 191 | } | 206 | } |
| 192 | get_driver().resume_time(cs); | 207 | get_driver().resume_time(cs); |
| 193 | trace!("low power: resume"); | 208 | |
| 209 | trace!("low power: resume time"); | ||
| 194 | }); | 210 | }); |
| 195 | } | 211 | } |
| 196 | 212 | ||
| @@ -201,10 +217,8 @@ impl Executor { | |||
| 201 | fn stop_mode(_cs: CriticalSection) -> Option<StopMode> { | 217 | fn stop_mode(_cs: CriticalSection) -> Option<StopMode> { |
| 202 | // We cannot enter standby because we will lose program state. | 218 | // We cannot enter standby because we will lose program state. |
| 203 | if unsafe { REFCOUNT_STOP2 == 0 && REFCOUNT_STOP1 == 0 } { | 219 | if unsafe { REFCOUNT_STOP2 == 0 && REFCOUNT_STOP1 == 0 } { |
| 204 | trace!("low power: stop 2"); | ||
| 205 | Some(StopMode::Stop2) | 220 | Some(StopMode::Stop2) |
| 206 | } else if unsafe { REFCOUNT_STOP1 == 0 } { | 221 | } else if unsafe { REFCOUNT_STOP1 == 0 } { |
| 207 | trace!("low power: stop 1"); | ||
| 208 | Some(StopMode::Stop1) | 222 | Some(StopMode::Stop1) |
| 209 | } else { | 223 | } else { |
| 210 | trace!("low power: not ready to stop (refcount_stop1: {})", unsafe { | 224 | trace!("low power: not ready to stop (refcount_stop1: {})", unsafe { |
| @@ -305,9 +319,11 @@ impl Executor { | |||
| 305 | get_driver().pause_time(cs).ok()?; | 319 | get_driver().pause_time(cs).ok()?; |
| 306 | self.configure_stop(cs, stop_mode).ok()?; | 320 | self.configure_stop(cs, stop_mode).ok()?; |
| 307 | 321 | ||
| 308 | Some(()) | 322 | Some(stop_mode) |
| 309 | }) | 323 | }) |
| 310 | .map(|_| { | 324 | .map(|stop_mode| { |
| 325 | trace!("low power: enter stop: {}", stop_mode); | ||
| 326 | |||
| 311 | #[cfg(not(feature = "low-power-debug-with-sleep"))] | 327 | #[cfg(not(feature = "low-power-debug-with-sleep"))] |
| 312 | Self::get_scb().set_sleepdeep(); | 328 | Self::get_scb().set_sleepdeep(); |
| 313 | }); | 329 | }); |
| @@ -339,19 +355,7 @@ impl Executor { | |||
| 339 | self.inner.poll(); | 355 | self.inner.poll(); |
| 340 | self.configure_pwr(); | 356 | self.configure_pwr(); |
| 341 | asm!("wfe"); | 357 | asm!("wfe"); |
| 342 | #[cfg(stm32wlex)] | 358 | 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 | }; | 359 | }; |
| 356 | } | 360 | } |
| 357 | } | 361 | } |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 1dd634cfe..5890e68f4 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -172,7 +172,7 @@ pub(crate) struct RccInfo { | |||
| 172 | /// E.g. if `StopMode::Stop1` is selected, the peripheral prevents the chip from entering Stop1 mode. | 172 | /// E.g. if `StopMode::Stop1` is selected, the peripheral prevents the chip from entering Stop1 mode. |
| 173 | #[cfg(feature = "low-power")] | 173 | #[cfg(feature = "low-power")] |
| 174 | #[allow(dead_code)] | 174 | #[allow(dead_code)] |
| 175 | #[derive(Debug, Clone, Copy, PartialEq, Default)] | 175 | #[derive(Debug, Clone, Copy, PartialEq, Default, defmt::Format)] |
| 176 | pub enum StopMode { | 176 | pub enum StopMode { |
| 177 | #[default] | 177 | #[default] |
| 178 | /// Peripheral prevents chip from entering Stop1 or executor will enter Stop1 | 178 | /// Peripheral prevents chip from entering Stop1 or executor will enter Stop1 |
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index cfcf5f3fd..ed5d902bd 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs | |||
| @@ -329,6 +329,12 @@ impl RtcDriver { | |||
| 329 | regs_gp16().cr1().modify(|w| w.set_cen(true)); | 329 | regs_gp16().cr1().modify(|w| w.set_cen(true)); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | #[cfg(feature = "low-power")] | ||
| 333 | /// Returns whether time is currently stopped | ||
| 334 | pub(crate) fn is_stopped(&self) -> bool { | ||
| 335 | !regs_gp16().cr1().read().cen() | ||
| 336 | } | ||
| 337 | |||
| 332 | fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { | 338 | fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { |
| 333 | let r = regs_gp16(); | 339 | let r = regs_gp16(); |
| 334 | 340 | ||
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 74d1c9e77..998e3a6f4 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -406,7 +406,7 @@ pub struct UpdateInterruptHandler<T: CoreInstance> { | |||
| 406 | impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt> for UpdateInterruptHandler<T> { | 406 | impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt> for UpdateInterruptHandler<T> { |
| 407 | unsafe fn on_interrupt() { | 407 | unsafe fn on_interrupt() { |
| 408 | #[cfg(feature = "low-power")] | 408 | #[cfg(feature = "low-power")] |
| 409 | crate::low_power::Executor::on_wakeup_irq(); | 409 | crate::low_power::Executor::on_wakeup_irq_or_event(); |
| 410 | 410 | ||
| 411 | let regs = crate::pac::timer::TimCore::from_ptr(T::regs()); | 411 | let regs = crate::pac::timer::TimCore::from_ptr(T::regs()); |
| 412 | 412 | ||
| @@ -436,7 +436,7 @@ impl<T: GeneralInstance1Channel> interrupt::typelevel::Handler<T::CaptureCompare | |||
| 436 | { | 436 | { |
| 437 | unsafe fn on_interrupt() { | 437 | unsafe fn on_interrupt() { |
| 438 | #[cfg(feature = "low-power")] | 438 | #[cfg(feature = "low-power")] |
| 439 | crate::low_power::Executor::on_wakeup_irq(); | 439 | crate::low_power::Executor::on_wakeup_irq_or_event(); |
| 440 | 440 | ||
| 441 | let regs = crate::pac::timer::TimGp16::from_ptr(T::regs()); | 441 | let regs = crate::pac::timer::TimGp16::from_ptr(T::regs()); |
| 442 | 442 | ||
