Skip to content

Commit 5d2f276

Browse files
committed
rtc: Fix RTC event handling
Previously there was a race condition: 1. read() to event register happens, event not set 2. event is being set by hardware 3. write(0) clears the event without the user noticing The new API is modelled after the GPIOE API. Thanks to @Dirbaio for helping to investigate on Matrix.
1 parent 47c478c commit 5d2f276

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

nrf-hal-common/src/rtc.rs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -142,41 +142,43 @@ where
142142
}
143143
}
144144

145-
/// Obtain the state of a given interrupt/event, and optionally clear the event
146-
/// if it is set.
147-
pub fn get_event_triggered(&mut self, evt: RtcInterrupt, clear_on_read: bool) -> bool {
148-
let mut orig = 0;
149-
let set_val = if clear_on_read { 0 } else { 1 };
150-
match evt {
151-
RtcInterrupt::Tick => self.periph.events_tick.modify(|r, w| {
152-
orig = r.bits();
153-
unsafe { w.bits(set_val) }
154-
}),
155-
RtcInterrupt::Overflow => self.periph.events_ovrflw.modify(|r, w| {
156-
orig = r.bits();
157-
unsafe { w.bits(set_val) }
158-
}),
159-
RtcInterrupt::Compare0 => self.periph.events_compare[0].modify(|r, w| {
160-
orig = r.bits();
161-
unsafe { w.bits(set_val) }
162-
}),
163-
RtcInterrupt::Compare1 => self.periph.events_compare[1].modify(|r, w| {
164-
orig = r.bits();
165-
unsafe { w.bits(set_val) }
166-
}),
167-
RtcInterrupt::Compare2 => self.periph.events_compare[2].modify(|r, w| {
168-
orig = r.bits();
169-
unsafe { w.bits(set_val) }
170-
}),
171-
RtcInterrupt::Compare3 => self.periph.events_compare[3].modify(|r, w| {
172-
orig = r.bits();
173-
unsafe { w.bits(set_val) }
174-
}),
145+
/// Checks if the given event has been triggered.
146+
pub fn is_event_triggered(&self, evt: RtcInterrupt) -> bool {
147+
let orig = match evt {
148+
RtcInterrupt::Tick => self.periph.events_tick.read().bits(),
149+
RtcInterrupt::Overflow => self.periph.events_ovrflw.read().bits(),
150+
RtcInterrupt::Compare0 => self.periph.events_compare[0].read().bits(),
151+
RtcInterrupt::Compare1 => self.periph.events_compare[1].read().bits(),
152+
RtcInterrupt::Compare2 => self.periph.events_compare[2].read().bits(),
153+
RtcInterrupt::Compare3 => self.periph.events_compare[3].read().bits(),
175154
};
176-
177155
orig == 1
178156
}
179157

158+
/// Resets the given event.
159+
pub fn reset_event(&self, evt: RtcInterrupt) {
160+
match evt {
161+
RtcInterrupt::Tick => {
162+
self.periph.events_tick.write(|w| unsafe { w.bits(0) });
163+
}
164+
RtcInterrupt::Overflow => {
165+
self.periph.events_ovrflw.write(|w| unsafe { w.bits(0) });
166+
}
167+
RtcInterrupt::Compare0 => {
168+
self.periph.events_compare[0].write(|w| unsafe { w.bits(0) });
169+
}
170+
RtcInterrupt::Compare1 => {
171+
self.periph.events_compare[1].write(|w| unsafe { w.bits(0) });
172+
}
173+
RtcInterrupt::Compare2 => {
174+
self.periph.events_compare[2].write(|w| unsafe { w.bits(0) });
175+
}
176+
RtcInterrupt::Compare3 => {
177+
self.periph.events_compare[3].write(|w| unsafe { w.bits(0) });
178+
}
179+
};
180+
}
181+
180182
/// Set the compare value of a given register. The compare registers have a width
181183
/// of 24 bits.
182184
pub fn set_compare(&mut self, reg: RtcCompareReg, val: u32) -> Result<(), Error> {

0 commit comments

Comments
 (0)