aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/exti.rs2
-rw-r--r--embassy-stm32/src/i2c/v2.rs2
-rw-r--r--embassy-stm32/src/low_power.rs46
-rw-r--r--embassy-stm32/src/rcc/mod.rs2
-rw-r--r--embassy-stm32/src/time_driver.rs6
-rw-r--r--embassy-stm32/src/timer/mod.rs4
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
80struct BitIter(u32); 80struct 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)]
176pub enum StopMode { 176pub 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> {
406impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt> for UpdateInterruptHandler<T> { 406impl<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