diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-01-13 03:17:58 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-01-13 03:17:58 +0100 |
| commit | 6963b314a246b245aabe1cedf6e1efec0b91e00b (patch) | |
| tree | ab9f1f17b99dc9efabbbae46279d0d263dc621b2 | |
| parent | 5229a1991c0ac0a4eafa8a321a80aee21af96a2e (diff) | |
nrf/rtc: fix race when setting alarms too close to now.
| -rw-r--r-- | embassy-nrf/src/rtc.rs | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs index f431339ff..015583943 100644 --- a/embassy-nrf/src/rtc.rs +++ b/embassy-nrf/src/rtc.rs | |||
| @@ -182,18 +182,13 @@ impl<T: Instance> RTC<T> { | |||
| 182 | 182 | ||
| 183 | let diff = timestamp - t; | 183 | let diff = timestamp - t; |
| 184 | if diff < 0xc00000 { | 184 | if diff < 0xc00000 { |
| 185 | self.rtc.cc[n].write(|w| unsafe { w.bits(timestamp as u32 & 0xFFFFFF) }); | 185 | // nrf52 docs say: |
| 186 | // If the COUNTER is N, writing N or N+1 to a CC register may not trigger a COMPARE event. | ||
| 187 | // To workaround this, we never write a timestamp smaller than N+3. | ||
| 188 | // N+2 is not safe because rtc can tick from N to N+1 between calling now() and writing cc. | ||
| 189 | let safe_timestamp = timestamp.max(t + 3); | ||
| 190 | self.rtc.cc[n].write(|w| unsafe { w.bits(safe_timestamp as u32 & 0xFFFFFF) }); | ||
| 186 | self.rtc.intenset.write(|w| unsafe { w.bits(compare_n(n)) }); | 191 | self.rtc.intenset.write(|w| unsafe { w.bits(compare_n(n)) }); |
| 187 | |||
| 188 | // We may have been preempted for arbitrary time between checking if `at` is in the past | ||
| 189 | // and setting the cc. In that case, we don't know if the cc has triggered. | ||
| 190 | // So, we check again just in case. | ||
| 191 | |||
| 192 | let t = self.now(); | ||
| 193 | if timestamp <= t { | ||
| 194 | self.trigger_alarm(n, cs); | ||
| 195 | return; | ||
| 196 | } | ||
| 197 | } else { | 192 | } else { |
| 198 | self.rtc.intenclr.write(|w| unsafe { w.bits(compare_n(n)) }); | 193 | self.rtc.intenclr.write(|w| unsafe { w.bits(compare_n(n)) }); |
| 199 | } | 194 | } |
