aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2020-09-26 00:35:25 +0200
committerDario Nieuwenhuis <[email protected]>2020-09-26 00:35:25 +0200
commit37d2b440fff05fc94ff28dccc1955d94f48af8df (patch)
tree9698cf20d6d0b94e3e12c78585039d15675df34b /embassy-nrf
parentf88f233e39f1edef04a51b888a47b9e231fc228f (diff)
Fix rtc using multiple alarms at the same time.
Diffstat (limited to 'embassy-nrf')
-rw-r--r--embassy-nrf/src/rtc.rs31
1 files changed, 18 insertions, 13 deletions
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs
index ae8d0dbc1..29c06b860 100644
--- a/embassy-nrf/src/rtc.rs
+++ b/embassy-nrf/src/rtc.rs
@@ -17,6 +17,10 @@ fn calc_now(period: u32, counter: u32) -> u64 {
17 ((period as u64) << 23) + counter_shifted as u64 - 0x400000 17 ((period as u64) << 23) + counter_shifted as u64 - 0x400000
18} 18}
19 19
20fn compare_n(n: usize) -> u32 {
21 1 << (n + 16)
22}
23
20mod test { 24mod test {
21 use super::*; 25 use super::*;
22 26
@@ -84,11 +88,11 @@ impl<T: Instance> RTC<T> {
84 } 88 }
85 89
86 pub fn start(&'static self) { 90 pub fn start(&'static self) {
87 self.rtc.cc[0].write(|w| unsafe { w.bits(0x800000) }); 91 self.rtc.cc[3].write(|w| unsafe { w.bits(0x800000) });
88 92
89 self.rtc.intenset.write(|w| { 93 self.rtc.intenset.write(|w| {
90 let w = w.ovrflw().set(); 94 let w = w.ovrflw().set();
91 let w = w.compare0().set(); 95 let w = w.compare3().set();
92 w 96 w
93 }); 97 });
94 98
@@ -108,14 +112,14 @@ impl<T: Instance> RTC<T> {
108 self.next_period(); 112 self.next_period();
109 } 113 }
110 114
111 if self.rtc.events_compare[0].read().bits() == 1 { 115 if self.rtc.events_compare[3].read().bits() == 1 {
112 self.rtc.events_compare[0].write(|w| w); 116 self.rtc.events_compare[3].write(|w| w);
113 self.next_period(); 117 self.next_period();
114 } 118 }
115 119
116 for n in 0..ALARM_COUNT { 120 for n in 0..ALARM_COUNT {
117 if self.rtc.events_compare[n + 1].read().bits() == 1 { 121 if self.rtc.events_compare[n].read().bits() == 1 {
118 self.rtc.events_compare[n + 1].write(|w| w); 122 self.rtc.events_compare[n].write(|w| w);
119 interrupt::free(|cs| { 123 interrupt::free(|cs| {
120 self.trigger_alarm(n, cs); 124 self.trigger_alarm(n, cs);
121 }) 125 })
@@ -128,20 +132,21 @@ impl<T: Instance> RTC<T> {
128 let period = self.period.fetch_add(1, Ordering::Relaxed) + 1; 132 let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
129 let t = (period as u64) << 23; 133 let t = (period as u64) << 23;
130 134
131 for alarm in self.alarms.borrow(cs) { 135 for n in 0..ALARM_COUNT {
136 let alarm = &self.alarms.borrow(cs)[n];
132 let at = alarm.timestamp.get(); 137 let at = alarm.timestamp.get();
133 138
134 let diff = at - t; 139 let diff = at - t;
135 if diff < 0xc00000 { 140 if diff < 0xc00000 {
136 self.rtc.cc[1].write(|w| unsafe { w.bits(at as u32 & 0xFFFFFF) }); 141 self.rtc.cc[n].write(|w| unsafe { w.bits(at as u32 & 0xFFFFFF) });
137 self.rtc.intenset.write(|w| w.compare1().set()); 142 self.rtc.intenset.write(|w| unsafe { w.bits(compare_n(n)) });
138 } 143 }
139 } 144 }
140 }) 145 })
141 } 146 }
142 147
143 fn trigger_alarm(&self, n: usize, cs: &CriticalSection) { 148 fn trigger_alarm(&self, n: usize, cs: &CriticalSection) {
144 self.rtc.intenclr.write(|w| w.compare1().clear()); 149 self.rtc.intenclr.write(|w| unsafe { w.bits(compare_n(n)) });
145 150
146 let alarm = &self.alarms.borrow(cs)[n]; 151 let alarm = &self.alarms.borrow(cs)[n];
147 alarm.timestamp.set(u64::MAX); 152 alarm.timestamp.set(u64::MAX);
@@ -170,8 +175,8 @@ impl<T: Instance> RTC<T> {
170 175
171 let diff = timestamp - t; 176 let diff = timestamp - t;
172 if diff < 0xc00000 { 177 if diff < 0xc00000 {
173 self.rtc.cc[1].write(|w| unsafe { w.bits(timestamp as u32 & 0xFFFFFF) }); 178 self.rtc.cc[n].write(|w| unsafe { w.bits(timestamp as u32 & 0xFFFFFF) });
174 self.rtc.intenset.write(|w| w.compare1().set()); 179 self.rtc.intenset.write(|w| unsafe { w.bits(compare_n(n)) });
175 180
176 // We may have been preempted for arbitrary time between checking if `at` is in the past 181 // We may have been preempted for arbitrary time between checking if `at` is in the past
177 // and setting the cc. In that case, we don't know if the cc has triggered. 182 // and setting the cc. In that case, we don't know if the cc has triggered.
@@ -183,7 +188,7 @@ impl<T: Instance> RTC<T> {
183 return; 188 return;
184 } 189 }
185 } else { 190 } else {
186 self.rtc.intenclr.write(|w| w.compare1().clear()); 191 self.rtc.intenclr.write(|w| unsafe { w.bits(compare_n(n)) });
187 } 192 }
188 }) 193 })
189 } 194 }