diff options
| author | xoviat <[email protected]> | 2023-10-02 23:56:33 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-02 23:56:33 +0000 |
| commit | 58280048e332fadd73dc8b48588b0112c61b8ff9 (patch) | |
| tree | 5ccc1a454a223dc0782088e86412f603b33c3b0e | |
| parent | 9dc927250c0a767b003aa0ff73b425398156fd5a (diff) | |
| parent | 00824af82ba8bfa5cd8226ee057719595d8d10af (diff) | |
Merge pull request #2002 from embassy-rs/fix-stop
stm32: fix stop
| -rwxr-xr-x | ci.sh | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 26 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2.rs | 31 | ||||
| -rw-r--r-- | embassy-stm32/src/time_driver.rs | 6 | ||||
| -rw-r--r-- | tests/stm32/src/bin/stop.rs | 5 |
6 files changed, 40 insertions, 36 deletions
| @@ -196,8 +196,9 @@ cargo batch \ | |||
| 196 | --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \ | 196 | --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \ |
| 197 | $BUILD_EXTRA | 197 | $BUILD_EXTRA |
| 198 | 198 | ||
| 199 | # temporarily disabled: broken by nightly update and/or clock settings update. | 199 | |
| 200 | rm out/tests/stm32f429zi/stop | 200 | rm out/tests/stm32wb55rg/wpan_mac |
| 201 | rm out/tests/stm32wb55rg/wpan_ble | ||
| 201 | 202 | ||
| 202 | if [[ -z "${TELEPROBE_TOKEN-}" ]]; then | 203 | if [[ -z "${TELEPROBE_TOKEN-}" ]]; then |
| 203 | echo No teleprobe token found, skipping running HIL tests | 204 | echo No teleprobe token found, skipping running HIL tests |
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index ce8afb578..bb714b8ca 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use core::arch::asm; | 1 | use core::arch::asm; |
| 2 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | 3 | ||
| 4 | use atomic_polyfill::{compiler_fence, Ordering}; | ||
| 4 | use cortex_m::peripheral::SCB; | 5 | use cortex_m::peripheral::SCB; |
| 5 | use embassy_executor::*; | 6 | use embassy_executor::*; |
| 6 | 7 | ||
| @@ -67,10 +68,8 @@ impl Executor { | |||
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | unsafe fn on_wakeup_irq(&mut self) { | 70 | unsafe fn on_wakeup_irq(&mut self) { |
| 70 | trace!("low power: on wakeup irq"); | ||
| 71 | |||
| 72 | self.time_driver.resume_time(); | 71 | self.time_driver.resume_time(); |
| 73 | trace!("low power: resume time"); | 72 | trace!("low power: resume"); |
| 74 | } | 73 | } |
| 75 | 74 | ||
| 76 | pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) { | 75 | pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) { |
| @@ -82,21 +81,18 @@ impl Executor { | |||
| 82 | } | 81 | } |
| 83 | 82 | ||
| 84 | fn configure_pwr(&mut self) { | 83 | fn configure_pwr(&mut self) { |
| 85 | trace!("low power: configure_pwr"); | ||
| 86 | |||
| 87 | self.scb.clear_sleepdeep(); | 84 | self.scb.clear_sleepdeep(); |
| 88 | if !low_power_ready() { | ||
| 89 | trace!("low power: configure_pwr: low power not ready"); | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | 85 | ||
| 93 | if self.time_driver.pause_time().is_err() { | 86 | compiler_fence(Ordering::SeqCst); |
| 94 | trace!("low power: configure_pwr: time driver failed to pause"); | ||
| 95 | return; | ||
| 96 | } | ||
| 97 | 87 | ||
| 98 | trace!("low power: enter stop..."); | 88 | if !low_power_ready() { |
| 99 | self.scb.set_sleepdeep(); | 89 | trace!("low power: not ready to stop"); |
| 90 | } else if self.time_driver.pause_time().is_err() { | ||
| 91 | trace!("low power: failed to pause time"); | ||
| 92 | } else { | ||
| 93 | trace!("low power: stop"); | ||
| 94 | self.scb.set_sleepdeep(); | ||
| 95 | } | ||
| 100 | } | 96 | } |
| 101 | 97 | ||
| 102 | /// Run the executor. | 98 | /// Run the executor. |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 9ccf2ac4f..ac9673833 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -111,8 +111,7 @@ static CLOCK_REFCOUNT: AtomicU32 = AtomicU32::new(0); | |||
| 111 | 111 | ||
| 112 | #[cfg(feature = "low-power")] | 112 | #[cfg(feature = "low-power")] |
| 113 | pub fn low_power_ready() -> bool { | 113 | pub fn low_power_ready() -> bool { |
| 114 | trace!("clock refcount: {}", CLOCK_REFCOUNT.load(Ordering::SeqCst)); | 114 | // trace!("clock refcount: {}", CLOCK_REFCOUNT.load(Ordering::SeqCst)); |
| 115 | |||
| 116 | CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0 | 115 | CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0 |
| 117 | } | 116 | } |
| 118 | 117 | ||
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 4608d3114..4974f6ee6 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -112,25 +112,26 @@ impl super::Rtc { | |||
| 112 | pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> { | 112 | pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> { |
| 113 | use crate::interrupt::typelevel::Interrupt; | 113 | use crate::interrupt::typelevel::Interrupt; |
| 114 | 114 | ||
| 115 | trace!("rtc: stop wakeup alarm at {}", self.instant()); | 115 | if RTC::regs().cr().read().wute() { |
| 116 | trace!("rtc: stop wakeup alarm at {}", self.instant()); | ||
| 116 | 117 | ||
| 117 | self.write(false, |regs| { | 118 | self.write(false, |regs| { |
| 118 | regs.cr().modify(|w| w.set_wutie(false)); | 119 | regs.cr().modify(|w| w.set_wutie(false)); |
| 119 | regs.cr().modify(|w| w.set_wute(false)); | 120 | regs.cr().modify(|w| w.set_wute(false)); |
| 120 | regs.isr().modify(|w| w.set_wutf(false)); | 121 | regs.isr().modify(|w| w.set_wutf(false)); |
| 121 | 122 | ||
| 122 | crate::pac::EXTI | 123 | crate::pac::EXTI |
| 123 | .pr(0) | 124 | .pr(0) |
| 124 | .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); | 125 | .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); |
| 125 | |||
| 126 | <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); | ||
| 127 | }); | ||
| 128 | 126 | ||
| 129 | if let Some(stop_time) = self.stop_time.borrow(cs).take() { | 127 | <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); |
| 130 | Some(self.instant() - stop_time) | 128 | }); |
| 131 | } else { | ||
| 132 | None | ||
| 133 | } | 129 | } |
| 130 | |||
| 131 | self.stop_time | ||
| 132 | .borrow(cs) | ||
| 133 | .take() | ||
| 134 | .map(|stop_time| self.instant() - stop_time) | ||
| 134 | } | 135 | } |
| 135 | 136 | ||
| 136 | #[cfg(feature = "low-power")] | 137 | #[cfg(feature = "low-power")] |
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 5b01937f5..917502412 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs | |||
| @@ -340,7 +340,11 @@ impl RtcDriver { | |||
| 340 | #[cfg(feature = "low-power")] | 340 | #[cfg(feature = "low-power")] |
| 341 | /// Set the rtc but panic if it's already been set | 341 | /// Set the rtc but panic if it's already been set |
| 342 | pub(crate) fn set_rtc(&self, rtc: &'static Rtc) { | 342 | pub(crate) fn set_rtc(&self, rtc: &'static Rtc) { |
| 343 | critical_section::with(|cs| assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none())); | 343 | critical_section::with(|cs| { |
| 344 | rtc.stop_wakeup_alarm(cs); | ||
| 345 | |||
| 346 | assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none()) | ||
| 347 | }); | ||
| 344 | } | 348 | } |
| 345 | 349 | ||
| 346 | #[cfg(feature = "low-power")] | 350 | #[cfg(feature = "low-power")] |
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 48d59b794..55c4aa900 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs | |||
| @@ -14,6 +14,7 @@ use embassy_stm32::low_power::{stop_with_rtc, Executor}; | |||
| 14 | use embassy_stm32::rcc::RtcClockSource; | 14 | use embassy_stm32::rcc::RtcClockSource; |
| 15 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 15 | use embassy_stm32::rtc::{Rtc, RtcConfig}; |
| 16 | use embassy_stm32::time::Hertz; | 16 | use embassy_stm32::time::Hertz; |
| 17 | use embassy_stm32::Config; | ||
| 17 | use embassy_time::{Duration, Timer}; | 18 | use embassy_time::{Duration, Timer}; |
| 18 | use static_cell::make_static; | 19 | use static_cell::make_static; |
| 19 | 20 | ||
| @@ -45,7 +46,9 @@ async fn task_2() { | |||
| 45 | 46 | ||
| 46 | #[embassy_executor::task] | 47 | #[embassy_executor::task] |
| 47 | async fn async_main(spawner: Spawner) { | 48 | async fn async_main(spawner: Spawner) { |
| 48 | let mut config = config(); | 49 | let _ = config(); |
| 50 | |||
| 51 | let mut config = Config::default(); | ||
| 49 | 52 | ||
| 50 | config.rcc.lse = Some(Hertz(32_768)); | 53 | config.rcc.lse = Some(Hertz(32_768)); |
| 51 | config.rcc.rtc = Some(RtcClockSource::LSE); | 54 | config.rcc.rtc = Some(RtcClockSource::LSE); |
