aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/timer.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-07-23 13:15:17 +0000
committerGitHub <[email protected]>2022-07-23 13:15:17 +0000
commite61e36a8158073ec92df1a751cfdd7fce5004cf8 (patch)
tree4a54aee47c0d3881b9e0bc809e075728cee8eeae /embassy-nrf/src/timer.rs
parent96f67671677d8bf7175f98e87c98954dc728286c (diff)
parent709df0dc1dfff577fb79bbc2f67ea84670072456 (diff)
Merge #842
842: WIP: Make unborrow safe to use r=Dirbaio a=GrantM11235 The basic idea is that `Unborrow::unborrow` is now safe to call and returns an `Unborrowed<'a, T>` which impls `Deref` and `DerefMut` ```rust /// This is essentially a `&mut T`, but it is the size of `T` not the size /// of a pointer. This is useful if T is a zero sized type. pub struct Unborrowed<'a, T> { inner: T, _lifetime: PhantomData<&'a mut T>, } ``` ## Todo - [x] Update other crates - [x] embassy-cortex-m - [x] embassy-hal-common - [x] embassy-lora - [x] embassy-nrf - [x] embassy-rp - [x] embassy-stm32 - [x] Remove usage of the unsafe `into_inner` method if possible - [x] Review and amend docs for `Unborrow` and `Unborrowed` Co-authored-by: Grant Miller <[email protected]> Co-authored-by: Dario Nieuwenhuis <[email protected]>
Diffstat (limited to 'embassy-nrf/src/timer.rs')
-rw-r--r--embassy-nrf/src/timer.rs41
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
6use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::drop::OnDrop; 7use embassy_hal_common::drop::OnDrop;
8use embassy_hal_common::unborrow; 8use embassy_hal_common::{into_ref, PeripheralRef};
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10 10
11use crate::interrupt::{Interrupt, InterruptExt}; 11use crate::interrupt::{Interrupt, InterruptExt};
12use crate::ppi::{Event, Task}; 12use crate::ppi::{Event, Task};
13use crate::{pac, Unborrow}; 13use crate::{pac, Peripheral};
14 14
15pub(crate) mod sealed { 15pub(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
31pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { 31pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
32 type Interrupt: Interrupt; 32 type Interrupt: Interrupt;
33} 33}
34pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {} 34pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {}
@@ -95,15 +95,13 @@ impl TimerType for Awaitable {}
95impl TimerType for NotAwaitable {} 95impl TimerType for NotAwaitable {}
96 96
97pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { 97pub 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
101impl<'d, T: Instance> Timer<'d, T, Awaitable> { 102impl<'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
248pub struct Cc<'a, T: Instance, I: TimerType = NotAwaitable> { 252pub 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
253impl<'a, T: Instance> Cc<'a, T, Awaitable> { 258impl<'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}
287impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {} 292impl<'d, T: Instance> Cc<'d, T, NotAwaitable> {}
288 293
289impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { 294impl<'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()