aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/timer.rs
diff options
context:
space:
mode:
authorLiam Murphy <[email protected]>2021-06-29 10:33:41 +1000
committerLiam Murphy <[email protected]>2021-06-29 10:33:41 +1000
commite7addf094b4d2cfed32ff3728e1d3d816430cf07 (patch)
tree26e4e610312fec75d1c43030e0746bc93340af2a /embassy-nrf/src/timer.rs
parent02781ed744b6e76d3790844f898235088b0fd8aa (diff)
Fix `Cc::wait` never resolving and refactor some APIs
I think the interrupt was getting immediately re-triggered as soon as the handler exited, so I disabled the interrupt in the handler.
Diffstat (limited to 'embassy-nrf/src/timer.rs')
-rw-r--r--embassy-nrf/src/timer.rs94
1 files changed, 38 insertions, 56 deletions
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index 3b2678a0b..d71a5c4e7 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -115,7 +115,7 @@ impl<'d, T: Instance> Timer<'d, T> {
115 // TODO: is there a reason someone would want to set this lower? 115 // TODO: is there a reason someone would want to set this lower?
116 regs.bitmode.write(|w| w.bitmode()._32bit()); 116 regs.bitmode.write(|w| w.bitmode()._32bit());
117 117
118 let this = Self { 118 let mut this = Self {
119 phantom: PhantomData, 119 phantom: PhantomData,
120 }; 120 };
121 121
@@ -125,14 +125,13 @@ impl<'d, T: Instance> Timer<'d, T> {
125 // Initialize the counter at 0. 125 // Initialize the counter at 0.
126 this.clear(); 126 this.clear();
127 127
128 // Initialize all the shorts as disabled.
129 for n in 0..T::CCS { 128 for n in 0..T::CCS {
130 let cc = Cc::<T> { 129 let cc = this.cc(n);
131 n, 130 // Initialize all the shorts as disabled.
132 phantom: PhantomData,
133 };
134 cc.unshort_compare_clear(); 131 cc.unshort_compare_clear();
135 cc.unshort_compare_stop(); 132 cc.unshort_compare_stop();
133 // Initialize the CC registers as 0.
134 cc.write(0);
136 } 135 }
137 136
138 this 137 this
@@ -196,57 +195,36 @@ impl<'d, T: Instance> Timer<'d, T> {
196 .events_compare() 195 .events_compare()
197 .is_generated() 196 .is_generated()
198 { 197 {
198 // Clear the interrupt, otherwise the interrupt will be repeatedly raised as soon as the interrupt handler exits.
199 // We can't clear the event, because it's used to poll whether the future is done or still pending.
200 regs.intenclr.write(|w| match n {
201 0 => w.compare0().clear(),
202 1 => w.compare1().clear(),
203 2 => w.compare2().clear(),
204 3 => w.compare3().clear(),
205 4 => w.compare4().clear(),
206 5 => w.compare5().clear(),
207 _ => unreachable!("No timers have more than 6 CC registers"),
208 });
199 T::waker(n).wake(); 209 T::waker(n).wake();
200 } 210 }
201 } 211 }
202 } 212 }
203 213
204 /// Returns the 0th CC register. 214 /// Returns this timer's `n`th CC register.
205 pub fn cc0<'a>(&'a self) -> Cc<'a, T> { 215 ///
206 Cc { 216 /// # Panics
207 n: 0, 217 /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer).
208 phantom: PhantomData, 218 pub fn cc(&mut self, n: usize) -> Cc<T> {
209 } 219 if n >= T::CCS {
210 } 220 panic!(
211 221 "Cannot get CC register {} of timer with {} CC registers.",
212 /// Returns the 1st CC register. 222 n,
213 pub fn cc1<'a>(&'a self) -> Cc<'a, T> { 223 T::CCS
214 Cc { 224 );
215 n: 1,
216 phantom: PhantomData,
217 }
218 }
219
220 /// Returns the 2nd CC register.
221 pub fn cc2<'a>(&'a self) -> Cc<'a, T> {
222 Cc {
223 n: 2,
224 phantom: PhantomData,
225 }
226 }
227
228 /// Returns the 3rd CC register.
229 pub fn cc3<'a>(&'a self) -> Cc<'a, T> {
230 Cc {
231 n: 3,
232 phantom: PhantomData,
233 }
234 }
235}
236
237impl<'d, T: ExtendedInstance> Timer<'d, T> {
238 /// Returns the 4th CC register.
239 pub fn cc4<'a>(&'a self) -> Cc<'a, T> {
240 Cc {
241 n: 4,
242 phantom: PhantomData,
243 } 225 }
244 }
245
246 /// Returns the 5th CC register.
247 pub fn cc5<'a>(&'a self) -> Cc<'a, T> {
248 Cc { 226 Cc {
249 n: 5, 227 n,
250 phantom: PhantomData, 228 phantom: PhantomData,
251 } 229 }
252 } 230 }
@@ -266,14 +244,14 @@ pub struct Cc<'a, T: Instance> {
266 244
267impl<'a, T: Instance> Cc<'a, T> { 245impl<'a, T: Instance> Cc<'a, T> {
268 /// Get the current value stored in the register. 246 /// Get the current value stored in the register.
269 pub fn value(&self) -> u32 { 247 pub fn read(&self) -> u32 {
270 T::regs().cc[self.n].read().cc().bits() 248 T::regs().cc[self.n].read().cc().bits()
271 } 249 }
272 250
273 /// Set the value stored in the register. 251 /// Set the value stored in the register.
274 /// 252 ///
275 /// `event_compare` will fire when the timer's counter reaches this value. 253 /// `event_compare` will fire when the timer's counter reaches this value.
276 pub fn set(&self, value: u32) { 254 pub fn write(&self, value: u32) {
277 // SAFETY: there are no invalid values for the CC register. 255 // SAFETY: there are no invalid values for the CC register.
278 T::regs().cc[self.n].write(|w| unsafe { w.cc().bits(value) }) 256 T::regs().cc[self.n].write(|w| unsafe { w.cc().bits(value) })
279 } 257 }
@@ -281,7 +259,7 @@ impl<'a, T: Instance> Cc<'a, T> {
281 /// Capture the current value of the timer's counter in this register, and return it. 259 /// Capture the current value of the timer's counter in this register, and return it.
282 pub fn capture(&self) -> u32 { 260 pub fn capture(&self) -> u32 {
283 T::regs().tasks_capture[self.n].write(|w| w.tasks_capture().trigger()); 261 T::regs().tasks_capture[self.n].write(|w| w.tasks_capture().trigger());
284 self.value() 262 self.read()
285 } 263 }
286 264
287 /// Returns this CC register's CAPTURE task, for use with PPI. 265 /// Returns this CC register's CAPTURE task, for use with PPI.
@@ -359,7 +337,9 @@ impl<'a, T: Instance> Cc<'a, T> {
359 } 337 }
360 338
361 /// Wait until the timer's counter reaches the value stored in this register. 339 /// Wait until the timer's counter reaches the value stored in this register.
362 pub async fn wait(&self) { 340 ///
341 /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`.
342 pub async fn wait(&mut self) {
363 let regs = T::regs(); 343 let regs = T::regs();
364 344
365 // Enable the interrupt for this CC's COMPARE event. 345 // Enable the interrupt for this CC's COMPARE event.
@@ -394,6 +374,8 @@ impl<'a, T: Instance> Cc<'a, T> {
394 .events_compare() 374 .events_compare()
395 .is_generated() 375 .is_generated()
396 { 376 {
377 // Reset the register for next time
378 regs.events_compare[self.n].write(|w| w.events_compare().not_generated());
397 Poll::Ready(()) 379 Poll::Ready(())
398 } else { 380 } else {
399 Poll::Pending 381 Poll::Pending
@@ -401,7 +383,7 @@ impl<'a, T: Instance> Cc<'a, T> {
401 }) 383 })
402 .await; 384 .await;
403 385
404 // Trigger the interrupt to be disabled. 386 // The interrupt was already disabled in the interrupt handler, so there's no need to disable it again.
405 drop(on_drop); 387 on_drop.defuse();
406 } 388 }
407} 389}