diff options
| author | f_punk <[email protected]> | 2021-09-01 16:16:56 +0200 |
|---|---|---|
| committer | f_punk <[email protected]> | 2021-09-01 16:16:56 +0200 |
| commit | a0c40562eab224d273a972fdcf5029c585974bc7 (patch) | |
| tree | 69d3dc9539d0481252acc1e32d6d850ed638c310 /embassy-nrf/src/timer.rs | |
| parent | ea688afe9b32cfdf10e91805d8c1e5668e0e85cd (diff) | |
added typestate to nrf-Timer
useful for hooking up the PPI to an Event without needing interrupt
tested with buffered_uart example on nRF52840-DK
Diffstat (limited to 'embassy-nrf/src/timer.rs')
| -rw-r--r-- | embassy-nrf/src/timer.rs | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index eab9a1416..939e99ed5 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -27,6 +27,8 @@ pub(crate) mod sealed { | |||
| 27 | fn waker(n: usize) -> &'static AtomicWaker; | 27 | fn waker(n: usize) -> &'static AtomicWaker; |
| 28 | } | 28 | } |
| 29 | pub trait ExtendedInstance {} | 29 | pub trait ExtendedInstance {} |
| 30 | |||
| 31 | pub trait TimerType {} | ||
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { | 34 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { |
| @@ -84,11 +86,25 @@ pub enum Frequency { | |||
| 84 | /// | 86 | /// |
| 85 | /// It has either 4 or 6 Capture/Compare registers, which can be used to capture the current state of the counter | 87 | /// It has either 4 or 6 Capture/Compare registers, which can be used to capture the current state of the counter |
| 86 | /// or trigger an event when the counter reaches a certain value. | 88 | /// or trigger an event when the counter reaches a certain value. |
| 87 | pub struct Timer<'d, T: Instance> { | 89 | |
| 88 | phantom: PhantomData<&'d mut T>, | 90 | pub trait TimerType: sealed::TimerType {} |
| 91 | |||
| 92 | pub enum Awaitable {} | ||
| 93 | pub enum NotAwaitable {} | ||
| 94 | |||
| 95 | impl sealed::TimerType for Awaitable {} | ||
| 96 | impl sealed::TimerType for NotAwaitable {} | ||
| 97 | impl TimerType for Awaitable {} | ||
| 98 | impl TimerType for NotAwaitable {} | ||
| 99 | |||
| 100 | pub type AwaitableTimer<'d, T> = Timer<'d, T, Awaitable>; | ||
| 101 | pub type NotAwaitableTimer<'d, T> = Timer<'d, T, NotAwaitable>; | ||
| 102 | |||
| 103 | pub struct Timer<'d, T: Instance, I: TimerType> { | ||
| 104 | phantom: PhantomData<(&'d mut T, I)>, | ||
| 89 | } | 105 | } |
| 90 | 106 | ||
| 91 | impl<'d, T: Instance> Timer<'d, T> { | 107 | impl<'d, T: Instance> Timer<'d, T, Awaitable> { |
| 92 | pub fn new( | 108 | pub fn new( |
| 93 | timer: impl Unborrow<Target = T> + 'd, | 109 | timer: impl Unborrow<Target = T> + 'd, |
| 94 | irq: impl Unborrow<Target = T::Interrupt> + 'd, | 110 | irq: impl Unborrow<Target = T::Interrupt> + 'd, |
| @@ -101,11 +117,18 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 101 | 117 | ||
| 102 | Self::new_irqless(timer) | 118 | Self::new_irqless(timer) |
| 103 | } | 119 | } |
| 120 | } | ||
| 121 | impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { | ||
| 122 | pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self { | ||
| 123 | Self::new_irqless(timer) | ||
| 124 | } | ||
| 125 | } | ||
| 104 | 126 | ||
| 127 | impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | ||
| 105 | /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. | 128 | /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. |
| 106 | /// | 129 | /// |
| 107 | /// This is used by `Uarte` internally. | 130 | /// This is used by `Uarte` internally. |
| 108 | pub(crate) fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self { | 131 | fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self { |
| 109 | let regs = T::regs(); | 132 | let regs = T::regs(); |
| 110 | 133 | ||
| 111 | let mut this = Self { | 134 | let mut this = Self { |
| @@ -208,7 +231,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 208 | /// | 231 | /// |
| 209 | /// # Panics | 232 | /// # Panics |
| 210 | /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer). | 233 | /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer). |
| 211 | pub fn cc(&mut self, n: usize) -> Cc<T> { | 234 | pub fn cc(&mut self, n: usize) -> Cc<T, I> { |
| 212 | if n >= T::CCS { | 235 | if n >= T::CCS { |
| 213 | panic!( | 236 | panic!( |
| 214 | "Cannot get CC register {} of timer with {} CC registers.", | 237 | "Cannot get CC register {} of timer with {} CC registers.", |
| @@ -219,6 +242,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 219 | Cc { | 242 | Cc { |
| 220 | n, | 243 | n, |
| 221 | phantom: PhantomData, | 244 | phantom: PhantomData, |
| 245 | phantom2: PhantomData, | ||
| 222 | } | 246 | } |
| 223 | } | 247 | } |
| 224 | } | 248 | } |
| @@ -230,12 +254,16 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 230 | /// | 254 | /// |
| 231 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. | 255 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. |
| 232 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register | 256 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register |
| 233 | pub struct Cc<'a, T: Instance> { | 257 | pub struct Cc<'a, T: Instance, I: TimerType> { |
| 234 | n: usize, | 258 | n: usize, |
| 235 | phantom: PhantomData<&'a mut T>, | 259 | phantom: PhantomData<&'a mut T>, |
| 260 | phantom2: PhantomData<I>, | ||
| 236 | } | 261 | } |
| 237 | 262 | ||
| 238 | impl<'a, T: Instance> Cc<'a, T> { | 263 | impl<'a, T: Instance> Cc<'a, T, Awaitable> {} |
| 264 | impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {} | ||
| 265 | |||
| 266 | impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { | ||
| 239 | /// Get the current value stored in the register. | 267 | /// Get the current value stored in the register. |
| 240 | pub fn read(&self) -> u32 { | 268 | pub fn read(&self) -> u32 { |
| 241 | T::regs().cc[self.n].read().cc().bits() | 269 | T::regs().cc[self.n].read().cc().bits() |
