diff options
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 12 | ||||
| -rw-r--r-- | embassy-nrf/src/timer.rs | 94 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 10 |
3 files changed, 49 insertions, 67 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 39a8cd887..a5a37b982 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -82,7 +82,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 82 | 82 | ||
| 83 | let r = U::regs(); | 83 | let r = U::regs(); |
| 84 | 84 | ||
| 85 | let timer = Timer::new_irqless(timer); | 85 | let mut timer = Timer::new_irqless(timer); |
| 86 | 86 | ||
| 87 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); | 87 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); |
| 88 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); | 88 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); |
| @@ -137,9 +137,9 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 137 | let timeout = 0x8000_0000 / (config.baudrate as u32 / 40); | 137 | let timeout = 0x8000_0000 / (config.baudrate as u32 / 40); |
| 138 | 138 | ||
| 139 | timer.set_frequency(Frequency::F16MHz); | 139 | timer.set_frequency(Frequency::F16MHz); |
| 140 | timer.cc0().set(timeout); | 140 | timer.cc(0).write(timeout); |
| 141 | timer.cc0().short_compare_clear(); | 141 | timer.cc(0).short_compare_clear(); |
| 142 | timer.cc0().short_compare_stop(); | 142 | timer.cc(0).short_compare_stop(); |
| 143 | 143 | ||
| 144 | let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); | 144 | let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); |
| 145 | ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); | 145 | ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); |
| @@ -148,7 +148,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 148 | ppi_ch1.enable(); | 148 | ppi_ch1.enable(); |
| 149 | 149 | ||
| 150 | let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); | 150 | let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); |
| 151 | ppi_ch2.set_event(timer.cc0().event_compare()); | 151 | ppi_ch2.set_event(timer.cc(0).event_compare()); |
| 152 | ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); | 152 | ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); |
| 153 | ppi_ch2.enable(); | 153 | ppi_ch2.enable(); |
| 154 | 154 | ||
| @@ -180,7 +180,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 180 | let r = U::regs(); | 180 | let r = U::regs(); |
| 181 | 181 | ||
| 182 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); | 182 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); |
| 183 | state.timer.cc0().set(timeout); | 183 | state.timer.cc(0).write(timeout); |
| 184 | state.timer.clear(); | 184 | state.timer.clear(); |
| 185 | 185 | ||
| 186 | r.baudrate.write(|w| w.baudrate().variant(baudrate)); | 186 | r.baudrate.write(|w| w.baudrate().variant(baudrate)); |
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 | } |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index d138257c7..67ec5d73f 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -318,7 +318,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | |||
| 318 | ) -> Self { | 318 | ) -> Self { |
| 319 | let baudrate = config.baudrate; | 319 | let baudrate = config.baudrate; |
| 320 | let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); | 320 | let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); |
| 321 | let timer = Timer::new_irqless(timer); | 321 | let mut timer = Timer::new_irqless(timer); |
| 322 | 322 | ||
| 323 | unborrow!(ppi_ch1, ppi_ch2); | 323 | unborrow!(ppi_ch1, ppi_ch2); |
| 324 | 324 | ||
| @@ -333,9 +333,9 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | |||
| 333 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); | 333 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); |
| 334 | 334 | ||
| 335 | timer.set_frequency(Frequency::F16MHz); | 335 | timer.set_frequency(Frequency::F16MHz); |
| 336 | timer.cc0().set(timeout); | 336 | timer.cc(0).write(timeout); |
| 337 | timer.cc0().short_compare_clear(); | 337 | timer.cc(0).short_compare_clear(); |
| 338 | timer.cc0().short_compare_stop(); | 338 | timer.cc(0).short_compare_stop(); |
| 339 | 339 | ||
| 340 | let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); | 340 | let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); |
| 341 | ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); | 341 | ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); |
| @@ -344,7 +344,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | |||
| 344 | ppi_ch1.enable(); | 344 | ppi_ch1.enable(); |
| 345 | 345 | ||
| 346 | let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); | 346 | let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); |
| 347 | ppi_ch2.set_event(timer.cc0().event_compare()); | 347 | ppi_ch2.set_event(timer.cc(0).event_compare()); |
| 348 | ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); | 348 | ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); |
| 349 | ppi_ch2.enable(); | 349 | ppi_ch2.enable(); |
| 350 | 350 | ||
