aboutsummaryrefslogtreecommitdiff
path: root/rtic-monotonics/src/nrf/rtc.rs
diff options
context:
space:
mode:
authorGravatar Finomnis <Finomnis@users.noreply.github.com> 2023-12-06 19:36:06 +0100
committerGravatar GitHub <noreply@github.com> 2023-12-06 18:36:06 +0000
commitf377471e440d8be0b2f9e9c8877ed015f62dc19e (patch)
tree2f63c1c079bf95cd8468ba2de91cb01032966aab /rtic-monotonics/src/nrf/rtc.rs
parent89160b7cb9b3623e0a50f6745296d470fa7ea79d (diff)
downloadrtic-f377471e440d8be0b2f9e9c8877ed015f62dc19e.tar.gz
rtic-f377471e440d8be0b2f9e9c8877ed015f62dc19e.tar.zst
rtic-f377471e440d8be0b2f9e9c8877ed015f62dc19e.zip
Fix `nrf::rtc` errata workaround (#858)
* Deprecate `should_dequeue_check` * Fix errata by delaying the wakeup point * Add changelog * Fix changelog typos
Diffstat (limited to 'rtic-monotonics/src/nrf/rtc.rs')
-rw-r--r--rtic-monotonics/src/nrf/rtc.rs26
1 files changed, 18 insertions, 8 deletions
diff --git a/rtic-monotonics/src/nrf/rtc.rs b/rtic-monotonics/src/nrf/rtc.rs
index 884b523a..643d8bdb 100644
--- a/rtic-monotonics/src/nrf/rtc.rs
+++ b/rtic-monotonics/src/nrf/rtc.rs
@@ -243,19 +243,29 @@ macro_rules! make_rtc {
}
}
- // NOTE: To fix errata for RTC, if the release time is within 4 ticks
- // we release as the RTC will not generate a compare interrupt...
- fn should_dequeue_check(release_at: Self::Instant) -> bool {
- Self::now() + <Self as Monotonic>::Duration::from_ticks(4) >= release_at
- }
-
fn enable_timer() {}
fn disable_timer() {}
- fn set_compare(instant: Self::Instant) {
+ fn set_compare(mut instant: Self::Instant) {
let rtc = unsafe { &*$rtc::PTR };
- unsafe { rtc.cc[0].write(|w| w.bits(instant.ticks() as u32 & 0xff_ffff)) };
+
+ // Disable interrupts because this section is timing critical.
+ // We rely on the fact that this entire section runs within one
+ // RTC clock tick. (which it will do easily if it doesn't get
+ // interrupted)
+ critical_section::with(|_|{
+ let now = Self::now();
+ if let Some(diff) = instant.checked_duration_since(now) {
+ // Errata: Timer interrupts don't fire if they are scheduled less than
+ // two ticks in the future. Make it three, because the timer could
+ // tick right now.
+ if diff.ticks() < 3 {
+ instant = Self::Instant::from_ticks(now.ticks().wrapping_add(3));
+ }
+ unsafe { rtc.cc[0].write(|w| w.bits(instant.ticks() as u32 & 0xff_ffff)) };
+ }
+ });
}
fn clear_compare_flag() {