diff options
| author | Liam Murphy <[email protected]> | 2021-06-29 10:33:41 +1000 |
|---|---|---|
| committer | Liam Murphy <[email protected]> | 2021-06-29 10:33:41 +1000 |
| commit | e7addf094b4d2cfed32ff3728e1d3d816430cf07 (patch) | |
| tree | 26e4e610312fec75d1c43030e0746bc93340af2a /embassy-nrf/src/timer.rs | |
| parent | 02781ed744b6e76d3790844f898235088b0fd8aa (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.rs | 94 |
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 | |||
| 237 | impl<'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 | ||
| 267 | impl<'a, T: Instance> Cc<'a, T> { | 245 | impl<'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 | } |
