Skip to content

Commit a51533c

Browse files
authored
Merge pull request #4896 from xoviat/low-power
low_power: optimize
2 parents 7a7527a + 87c1d21 commit a51533c

File tree

2 files changed

+42
-59
lines changed

2 files changed

+42
-59
lines changed

embassy-stm32/src/low_power.rs

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,13 @@ impl Executor {
228228

229229
fn stop_mode(_cs: CriticalSection) -> Option<StopMode> {
230230
if unsafe { crate::rcc::REFCOUNT_STOP2 == 0 && crate::rcc::REFCOUNT_STOP1 == 0 } {
231+
trace!("low power: stop 2");
231232
Some(StopMode::Stop2)
232233
} else if unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } {
234+
trace!("low power: stop 1");
233235
Some(StopMode::Stop1)
234236
} else {
237+
trace!("low power: not ready to stop");
235238
None
236239
}
237240
}
@@ -258,27 +261,18 @@ impl Executor {
258261

259262
compiler_fence(Ordering::SeqCst);
260263

261-
let stop_mode = critical_section::with(|cs| Self::stop_mode(cs));
262-
263-
if stop_mode.is_none() {
264-
trace!("low power: not ready to stop");
265-
return;
266-
}
267-
268-
if get_driver().pause_time().is_err() {
269-
trace!("low power: failed to pause time");
270-
return;
271-
}
264+
critical_section::with(|cs| {
265+
let stop_mode = Self::stop_mode(cs)?;
266+
let _ = get_driver().pause_time(cs).ok()?;
272267

273-
let stop_mode = stop_mode.unwrap();
274-
match stop_mode {
275-
StopMode::Stop1 => trace!("low power: stop 1"),
276-
StopMode::Stop2 => trace!("low power: stop 2"),
277-
}
278-
self.configure_stop(stop_mode);
268+
Some(stop_mode)
269+
})
270+
.map(|stop_mode| {
271+
self.configure_stop(stop_mode);
279272

280-
#[cfg(not(feature = "low-power-debug-with-sleep"))]
281-
self.scb.set_sleepdeep();
273+
#[cfg(not(feature = "low-power-debug-with-sleep"))]
274+
self.scb.set_sleepdeep();
275+
});
282276
}
283277

284278
/// Run the executor.

embassy-stm32/src/time_driver.rs

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,15 @@ impl RtcDriver {
380380
#[cfg(feature = "low-power")]
381381
/// Stop the wakeup alarm, if enabled, and add the appropriate offset
382382
fn stop_wakeup_alarm(&self, cs: CriticalSection) {
383-
if let Some(offset) = self.rtc.borrow(cs).borrow_mut().as_mut().unwrap().stop_wakeup_alarm(cs) {
383+
if !regs_gp16().cr1().read().cen()
384+
&& let Some(offset) = self.rtc.borrow(cs).borrow_mut().as_mut().unwrap().stop_wakeup_alarm(cs)
385+
{
384386
self.add_time(offset, cs);
385387
}
386388
}
387389

388390
/*
389-
Low-power public functions: all create or require a critical section
391+
Low-power public functions: all require a critical section
390392
*/
391393
#[cfg(feature = "low-power")]
392394
pub(crate) fn set_min_stop_pause(&self, cs: CriticalSection, min_stop_pause: embassy_time::Duration) {
@@ -403,49 +405,36 @@ impl RtcDriver {
403405

404406
#[cfg(feature = "low-power")]
405407
/// Pause the timer if ready; return err if not
406-
pub(crate) fn pause_time(&self) -> Result<(), ()> {
407-
critical_section::with(|cs| {
408-
/*
409-
If the wakeup timer is currently running, then we need to stop it and
410-
add the elapsed time to the current time, as this will impact the result
411-
of `time_until_next_alarm`.
412-
*/
413-
self.stop_wakeup_alarm(cs);
414-
415-
let time_until_next_alarm = self.time_until_next_alarm(cs);
416-
if time_until_next_alarm < self.min_stop_pause.borrow(cs).get() {
417-
trace!(
418-
"time_until_next_alarm < self.min_stop_pause ({})",
419-
time_until_next_alarm
420-
);
421-
Err(())
422-
} else {
423-
self.rtc
424-
.borrow(cs)
425-
.borrow_mut()
426-
.as_mut()
427-
.unwrap()
428-
.start_wakeup_alarm(time_until_next_alarm, cs);
429-
430-
regs_gp16().cr1().modify(|w| w.set_cen(false));
431-
// save the count for the timer as its lost in STOP2 for stm32wlex
432-
#[cfg(stm32wlex)]
433-
self.saved_count
434-
.store(regs_gp16().cnt().read().cnt() as u16, Ordering::SeqCst);
435-
Ok(())
436-
}
437-
})
408+
pub(crate) fn pause_time(&self, cs: CriticalSection) -> Result<(), ()> {
409+
self.stop_wakeup_alarm(cs);
410+
411+
let time_until_next_alarm = self.time_until_next_alarm(cs);
412+
if time_until_next_alarm < self.min_stop_pause.borrow(cs).get() {
413+
trace!(
414+
"time_until_next_alarm < self.min_stop_pause ({})",
415+
time_until_next_alarm
416+
);
417+
Err(())
418+
} else {
419+
self.rtc
420+
.borrow(cs)
421+
.borrow_mut()
422+
.as_mut()
423+
.unwrap()
424+
.start_wakeup_alarm(time_until_next_alarm, cs);
425+
426+
regs_gp16().cr1().modify(|w| w.set_cen(false));
427+
// save the count for the timer as its lost in STOP2 for stm32wlex
428+
#[cfg(stm32wlex)]
429+
self.saved_count
430+
.store(regs_gp16().cnt().read().cnt() as u16, Ordering::SeqCst);
431+
Ok(())
432+
}
438433
}
439434

440435
#[cfg(feature = "low-power")]
441436
/// Resume the timer with the given offset
442437
pub(crate) fn resume_time(&self, cs: CriticalSection) {
443-
if regs_gp16().cr1().read().cen() {
444-
// Time isn't currently stopped
445-
446-
return;
447-
}
448-
449438
self.stop_wakeup_alarm(cs);
450439

451440
regs_gp16().cr1().modify(|w| w.set_cen(true));

0 commit comments

Comments
 (0)