diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs index a5810eb5..95ee1a06 100644 --- a/embassy-nrf/src/rtc.rs +++ b/embassy-nrf/src/rtc.rs @@ -52,15 +52,18 @@ pub struct RTC { period: AtomicU32, /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. - alarm: Mutex>, + alarm: Mutex)>>, } +unsafe impl Send for RTC {} +unsafe impl Sync for RTC {} + impl RTC { pub fn new(rtc: T) -> Self { Self { rtc, period: AtomicU32::new(0), - alarm: Mutex::new(Cell::new(u64::MAX)), + alarm: Mutex::new(Cell::new((u64::MAX, None))), } } @@ -108,7 +111,7 @@ impl RTC { let period = self.period.fetch_add(1, Ordering::Relaxed) + 1; let t = (period as u64) << 23; - let at = self.alarm.borrow(cs).get(); + let (at, _) = self.alarm.borrow(cs).get(); let diff = at - t; if diff < 0xc00000 { @@ -126,22 +129,26 @@ impl RTC { fn trigger_alarm(&self) { self.rtc.intenclr.write(|w| w.compare1().clear()); - interrupt::free(|cs| self.alarm.borrow(cs).set(u64::MAX)); + interrupt::free(|cs| { + let alarm = self.alarm.borrow(cs); + let (_, f) = alarm.get(); + alarm.set((u64::MAX, None)); - // TODO - trace!("ALARM! {:u32}", self.now() as u32); + // Call after clearing alarm, so the callback can set another alarm. + f.map(|f| f()) + }); } - pub fn set_alarm(&self, at: u64) { + fn do_set_alarm(&self, at: u64, f: Option) { interrupt::free(|cs| { + self.alarm.borrow(cs).set((at, f)); + let t = self.now(); if at <= t { self.trigger_alarm(); return; } - self.alarm.borrow(cs).set(at); - let diff = at - t; if diff < 0xc00000 { self.rtc.cc[1].write(|w| unsafe { w.bits(at as u32 & 0xFFFFFF) }); @@ -162,8 +169,12 @@ impl RTC { }) } + pub fn set_alarm(&self, at: u64, f: fn()) { + self.do_set_alarm(at, Some(f)); + } + pub fn clear_alarm(&self) { - self.set_alarm(u64::MAX); + self.do_set_alarm(u64::MAX, None); } } diff --git a/examples/src/bin/rtc_raw.rs b/examples/src/bin/rtc_raw.rs index 041bbaf0..8debf12e 100644 --- a/examples/src/bin/rtc_raw.rs +++ b/examples/src/bin/rtc_raw.rs @@ -31,7 +31,7 @@ fn main() -> ! { }; rtc.start(); - rtc.set_alarm(53719); + rtc.set_alarm(53719, || info!("ALARM TRIGGERED")); info!("initialized!");