aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/time_driver.rs
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-14 14:53:09 -0600
committerxoviat <[email protected]>2025-11-14 14:53:09 -0600
commitb97b6d409c1b042b5d5f1b17dd2c8dfec50acdfc (patch)
tree01e5ff837363f828fa425e0926ae001d3a17a8d0 /embassy-stm32/src/time_driver.rs
parenta6d392b24c5f010a8b5b2a00326c04b05a4ab0f0 (diff)
low_power: cleanup add_time
Diffstat (limited to 'embassy-stm32/src/time_driver.rs')
-rw-r--r--embassy-stm32/src/time_driver.rs33
1 files changed, 7 insertions, 26 deletions
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 7db51d72e..bc34892ee 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -196,6 +196,11 @@ fn calc_now(period: u32, counter: u16) -> u64 {
196 ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) 196 ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
197} 197}
198 198
199#[cfg(feature = "low-power")]
200fn calc_period_counter(ticks: u64) -> (u32, u16) {
201 (2 * (ticks >> 16) as u32 + (ticks as u16 >= 0x8000) as u32, ticks as u16)
202}
203
199struct AlarmState { 204struct AlarmState {
200 timestamp: Cell<u64>, 205 timestamp: Cell<u64>,
201} 206}
@@ -358,34 +363,10 @@ impl RtcDriver {
358 #[cfg(feature = "low-power")] 363 #[cfg(feature = "low-power")]
359 /// Add the given offset to the current time 364 /// Add the given offset to the current time
360 fn add_time(&self, offset: embassy_time::Duration, cs: CriticalSection) { 365 fn add_time(&self, offset: embassy_time::Duration, cs: CriticalSection) {
361 let offset = offset.as_ticks(); 366 let (period, counter) = calc_period_counter(self.now() + offset.as_ticks());
362 let cnt = regs_gp16().cnt().read().cnt() as u32;
363 let period = self.period.load(Ordering::SeqCst);
364
365 // Correct the race, if it exists
366 let period = if period & 1 == 1 && cnt < u16::MAX as u32 / 2 {
367 period + 1
368 } else {
369 period
370 };
371
372 // Normalize to the full overflow
373 let period = (period / 2) * 2;
374
375 // Add the offset
376 let period = period + 2 * (offset / u16::MAX as u64) as u32;
377 let cnt = cnt + (offset % u16::MAX as u64) as u32;
378
379 let (cnt, period) = if cnt > u16::MAX as u32 {
380 (cnt - u16::MAX as u32, period + 2)
381 } else {
382 (cnt, period)
383 };
384
385 let period = if cnt > u16::MAX as u32 / 2 { period + 1 } else { period };
386 367
387 self.period.store(period, Ordering::SeqCst); 368 self.period.store(period, Ordering::SeqCst);
388 regs_gp16().cnt().write(|w| w.set_cnt(cnt as u16)); 369 regs_gp16().cnt().write(|w| w.set_cnt(counter));
389 370
390 // Now, recompute alarm 371 // Now, recompute alarm
391 let alarm = self.alarm.borrow(cs); 372 let alarm = self.alarm.borrow(cs);