diff options
author | 2023-12-06 19:36:06 +0100 | |
---|---|---|
committer | 2023-12-06 18:36:06 +0000 | |
commit | f377471e440d8be0b2f9e9c8877ed015f62dc19e (patch) | |
tree | 2f63c1c079bf95cd8468ba2de91cb01032966aab /rtic-monotonics/src/nrf/rtc.rs | |
parent | 89160b7cb9b3623e0a50f6745296d470fa7ea79d (diff) | |
download | rtic-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.rs | 26 |
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() { |