aboutsummaryrefslogtreecommitdiff
path: root/rtic-monotonics
diff options
context:
space:
mode:
Diffstat (limited to 'rtic-monotonics')
-rw-r--r--rtic-monotonics/src/nrf/rtc.rs7
-rw-r--r--rtic-monotonics/src/nrf/timer.rs17
2 files changed, 20 insertions, 4 deletions
diff --git a/rtic-monotonics/src/nrf/rtc.rs b/rtic-monotonics/src/nrf/rtc.rs
index 03610c0..2e23389 100644
--- a/rtic-monotonics/src/nrf/rtc.rs
+++ b/rtic-monotonics/src/nrf/rtc.rs
@@ -189,13 +189,18 @@ macro_rules! make_rtc {
// and the flag here.
critical_section::with(|_| {
let rtc = unsafe { &*$rtc::PTR };
- let cnt = rtc.counter.read().bits() as u64;
+ let cnt = rtc.counter.read().bits();
+ // OVERFLOW HAPPENS HERE race needs to be handled
let ovf = if Self::is_overflow() {
$overflow.load(Ordering::Relaxed) + 1
} else {
$overflow.load(Ordering::Relaxed)
} as u64;
+ // Check and fix if above race happened
+ let new_cnt = rtc.counter.read().bits();
+ let cnt = if new_cnt >= cnt { cnt } else { new_cnt } as u64;
+
Self::Instant::from_ticks((ovf << 24) | cnt)
})
}
diff --git a/rtic-monotonics/src/nrf/timer.rs b/rtic-monotonics/src/nrf/timer.rs
index db5316f..5e8fe93 100644
--- a/rtic-monotonics/src/nrf/timer.rs
+++ b/rtic-monotonics/src/nrf/timer.rs
@@ -182,6 +182,12 @@ macro_rules! make_timer {
pub async fn delay_until(instant: <Self as Monotonic>::Instant) {
$tq.delay_until(instant).await;
}
+
+ #[inline(always)]
+ fn is_overflow() -> bool {
+ let timer = unsafe { &*$timer::PTR };
+ timer.events_compare[1].read().bits() & 1 != 0
+ }
}
#[cfg(feature = "embedded-hal-async")]
@@ -213,17 +219,22 @@ macro_rules! make_timer {
critical_section::with(|_| {
let timer = unsafe { &*$timer::PTR };
timer.tasks_capture[2].write(|w| unsafe { w.bits(1) });
+ let cnt = timer.cc[2].read().bits();
- let unhandled_overflow = if timer.events_compare[1].read().bits() & 1 != 0 {
+ let unhandled_overflow = if Self::is_overflow() {
// The overflow has not been handled yet, so add an extra to the read overflow.
1
} else {
0
};
+ timer.tasks_capture[2].write(|w| unsafe { w.bits(1) });
+ let new_cnt = timer.cc[2].read().bits();
+ let cnt = if new_cnt >= cnt { cnt } else { new_cnt } as u64;
+
Self::Instant::from_ticks(
(unhandled_overflow + $overflow.load(Ordering::Relaxed) as u64) << 32
- | timer.cc[2].read().bits() as u64,
+ | cnt as u64,
)
})
}
@@ -232,7 +243,7 @@ macro_rules! make_timer {
let timer = unsafe { &*$timer::PTR };
// If there is a compare match on channel 1, it is an overflow
- if timer.events_compare[1].read().bits() & 1 != 0 {
+ if Self::is_overflow() {
timer.events_compare[1].write(|w| w);
$overflow.fetch_add(1, Ordering::SeqCst);
}