diff options
Diffstat (limited to 'embassy-nrf/src/timer.rs')
| -rw-r--r-- | embassy-nrf/src/timer.rs | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index c8c36dfae..8deecdc03 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -5,12 +5,12 @@ use core::task::Poll; | |||
| 5 | 5 | ||
| 6 | use embassy::waitqueue::AtomicWaker; | 6 | use embassy::waitqueue::AtomicWaker; |
| 7 | use embassy_hal_common::drop::OnDrop; | 7 | use embassy_hal_common::drop::OnDrop; |
| 8 | use embassy_hal_common::unborrow; | 8 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 9 | use futures::future::poll_fn; | 9 | use futures::future::poll_fn; |
| 10 | 10 | ||
| 11 | use crate::interrupt::{Interrupt, InterruptExt}; | 11 | use crate::interrupt::{Interrupt, InterruptExt}; |
| 12 | use crate::ppi::{Event, Task}; | 12 | use crate::ppi::{Event, Task}; |
| 13 | use crate::{pac, Unborrow}; | 13 | use crate::{pac, Peripheral}; |
| 14 | 14 | ||
| 15 | pub(crate) mod sealed { | 15 | pub(crate) mod sealed { |
| 16 | 16 | ||
| @@ -28,7 +28,7 @@ pub(crate) mod sealed { | |||
| 28 | pub trait TimerType {} | 28 | pub trait TimerType {} |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { | 31 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { |
| 32 | type Interrupt: Interrupt; | 32 | type Interrupt: Interrupt; |
| 33 | } | 33 | } |
| 34 | pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {} | 34 | pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {} |
| @@ -95,15 +95,13 @@ impl TimerType for Awaitable {} | |||
| 95 | impl TimerType for NotAwaitable {} | 95 | impl TimerType for NotAwaitable {} |
| 96 | 96 | ||
| 97 | pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { | 97 | pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { |
| 98 | phantom: PhantomData<(&'d mut T, I)>, | 98 | _p: PeripheralRef<'d, T>, |
| 99 | _i: PhantomData<I>, | ||
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | impl<'d, T: Instance> Timer<'d, T, Awaitable> { | 102 | impl<'d, T: Instance> Timer<'d, T, Awaitable> { |
| 102 | pub fn new_awaitable( | 103 | pub fn new_awaitable(timer: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd) -> Self { |
| 103 | timer: impl Unborrow<Target = T> + 'd, | 104 | into_ref!(irq); |
| 104 | irq: impl Unborrow<Target = T::Interrupt> + 'd, | ||
| 105 | ) -> Self { | ||
| 106 | unborrow!(irq); | ||
| 107 | 105 | ||
| 108 | irq.set_handler(Self::on_interrupt); | 106 | irq.set_handler(Self::on_interrupt); |
| 109 | irq.unpend(); | 107 | irq.unpend(); |
| @@ -117,7 +115,7 @@ impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { | |||
| 117 | /// | 115 | /// |
| 118 | /// This can be useful for triggering tasks via PPI | 116 | /// This can be useful for triggering tasks via PPI |
| 119 | /// `Uarte` uses this internally. | 117 | /// `Uarte` uses this internally. |
| 120 | pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self { | 118 | pub fn new(timer: impl Peripheral<P = T> + 'd) -> Self { |
| 121 | Self::new_irqless(timer) | 119 | Self::new_irqless(timer) |
| 122 | } | 120 | } |
| 123 | } | 121 | } |
| @@ -126,10 +124,15 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | |||
| 126 | /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. | 124 | /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. |
| 127 | /// | 125 | /// |
| 128 | /// This is used by the public constructors. | 126 | /// This is used by the public constructors. |
| 129 | fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self { | 127 | fn new_irqless(timer: impl Peripheral<P = T> + 'd) -> Self { |
| 128 | into_ref!(timer); | ||
| 129 | |||
| 130 | let regs = T::regs(); | 130 | let regs = T::regs(); |
| 131 | 131 | ||
| 132 | let mut this = Self { phantom: PhantomData }; | 132 | let mut this = Self { |
| 133 | _p: timer, | ||
| 134 | _i: PhantomData, | ||
| 135 | }; | ||
| 133 | 136 | ||
| 134 | // Stop the timer before doing anything else, | 137 | // Stop the timer before doing anything else, |
| 135 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. | 138 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. |
| @@ -233,7 +236,8 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | |||
| 233 | } | 236 | } |
| 234 | Cc { | 237 | Cc { |
| 235 | n, | 238 | n, |
| 236 | phantom: PhantomData, | 239 | _p: self._p.reborrow(), |
| 240 | _i: PhantomData, | ||
| 237 | } | 241 | } |
| 238 | } | 242 | } |
| 239 | } | 243 | } |
| @@ -245,12 +249,13 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | |||
| 245 | /// | 249 | /// |
| 246 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. | 250 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. |
| 247 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register | 251 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register |
| 248 | pub struct Cc<'a, T: Instance, I: TimerType = NotAwaitable> { | 252 | pub struct Cc<'d, T: Instance, I: TimerType = NotAwaitable> { |
| 249 | n: usize, | 253 | n: usize, |
| 250 | phantom: PhantomData<(&'a mut T, I)>, | 254 | _p: PeripheralRef<'d, T>, |
| 255 | _i: PhantomData<I>, | ||
| 251 | } | 256 | } |
| 252 | 257 | ||
| 253 | impl<'a, T: Instance> Cc<'a, T, Awaitable> { | 258 | impl<'d, T: Instance> Cc<'d, T, Awaitable> { |
| 254 | /// Wait until the timer's counter reaches the value stored in this register. | 259 | /// Wait until the timer's counter reaches the value stored in this register. |
| 255 | /// | 260 | /// |
| 256 | /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`. | 261 | /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`. |
| @@ -284,9 +289,9 @@ impl<'a, T: Instance> Cc<'a, T, Awaitable> { | |||
| 284 | on_drop.defuse(); | 289 | on_drop.defuse(); |
| 285 | } | 290 | } |
| 286 | } | 291 | } |
| 287 | impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {} | 292 | impl<'d, T: Instance> Cc<'d, T, NotAwaitable> {} |
| 288 | 293 | ||
| 289 | impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { | 294 | impl<'d, T: Instance, I: TimerType> Cc<'d, T, I> { |
| 290 | /// Get the current value stored in the register. | 295 | /// Get the current value stored in the register. |
| 291 | pub fn read(&self) -> u32 { | 296 | pub fn read(&self) -> u32 { |
| 292 | T::regs().cc[self.n].read().cc().bits() | 297 | T::regs().cc[self.n].read().cc().bits() |
