aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/low_power.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/low_power.rs')
-rw-r--r--embassy-stm32/src/low_power.rs61
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 }