aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/timer.rs
diff options
context:
space:
mode:
authorf_punk <[email protected]>2021-09-01 16:16:56 +0200
committerf_punk <[email protected]>2021-09-01 16:16:56 +0200
commita0c40562eab224d273a972fdcf5029c585974bc7 (patch)
tree69d3dc9539d0481252acc1e32d6d850ed638c310 /embassy-nrf/src/timer.rs
parentea688afe9b32cfdf10e91805d8c1e5668e0e85cd (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.rs42
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
32pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { 34pub 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.
87pub struct Timer<'d, T: Instance> { 89
88 phantom: PhantomData<&'d mut T>, 90pub trait TimerType: sealed::TimerType {}
91
92pub enum Awaitable {}
93pub enum NotAwaitable {}
94
95impl sealed::TimerType for Awaitable {}
96impl sealed::TimerType for NotAwaitable {}
97impl TimerType for Awaitable {}
98impl TimerType for NotAwaitable {}
99
100pub type AwaitableTimer<'d, T> = Timer<'d, T, Awaitable>;
101pub type NotAwaitableTimer<'d, T> = Timer<'d, T, NotAwaitable>;
102
103pub struct Timer<'d, T: Instance, I: TimerType> {
104 phantom: PhantomData<(&'d mut T, I)>,
89} 105}
90 106
91impl<'d, T: Instance> Timer<'d, T> { 107impl<'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}
121impl<'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
127impl<'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
233pub struct Cc<'a, T: Instance> { 257pub 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
238impl<'a, T: Instance> Cc<'a, T> { 263impl<'a, T: Instance> Cc<'a, T, Awaitable> {}
264impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {}
265
266impl<'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()