diff options
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 6 | ||||
| -rw-r--r-- | embassy-nrf/src/timer.rs | 19 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 6 | ||||
| -rw-r--r-- | examples/nrf/src/bin/awaitable_timer.rs | 29 |
4 files changed, 44 insertions, 16 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 5c9f4270b..90ce49582 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -16,7 +16,7 @@ use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; | |||
| 16 | use crate::pac; | 16 | use crate::pac; |
| 17 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; | 17 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; |
| 18 | use crate::timer::Instance as TimerInstance; | 18 | use crate::timer::Instance as TimerInstance; |
| 19 | use crate::timer::{Frequency, NotAwaitableTimer}; | 19 | use crate::timer::{Frequency, Timer}; |
| 20 | use crate::uarte::{Config, Instance as UarteInstance}; | 20 | use crate::uarte::{Config, Instance as UarteInstance}; |
| 21 | 21 | ||
| 22 | // Re-export SVD variants to allow user to directly set values | 22 | // Re-export SVD variants to allow user to directly set values |
| @@ -43,7 +43,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> { | |||
| 43 | 43 | ||
| 44 | struct StateInner<'d, U: UarteInstance, T: TimerInstance> { | 44 | struct StateInner<'d, U: UarteInstance, T: TimerInstance> { |
| 45 | phantom: PhantomData<&'d mut U>, | 45 | phantom: PhantomData<&'d mut U>, |
| 46 | timer: NotAwaitableTimer<'d, T>, | 46 | timer: Timer<'d, T>, |
| 47 | _ppi_ch1: Ppi<'d, AnyConfigurableChannel>, | 47 | _ppi_ch1: Ppi<'d, AnyConfigurableChannel>, |
| 48 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, | 48 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, |
| 49 | 49 | ||
| @@ -84,7 +84,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 84 | 84 | ||
| 85 | let r = U::regs(); | 85 | let r = U::regs(); |
| 86 | 86 | ||
| 87 | let mut timer = NotAwaitableTimer::new(timer); | 87 | let mut timer = Timer::new(timer); |
| 88 | 88 | ||
| 89 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); | 89 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); |
| 90 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); | 90 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); |
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 14a2f7b35..638fd8229 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -97,15 +97,12 @@ impl sealed::TimerType for NotAwaitable {} | |||
| 97 | impl TimerType for Awaitable {} | 97 | impl TimerType for Awaitable {} |
| 98 | impl TimerType for NotAwaitable {} | 98 | impl TimerType for NotAwaitable {} |
| 99 | 99 | ||
| 100 | pub type AwaitableTimer<'d, T> = Timer<'d, T, Awaitable>; | 100 | pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { |
| 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)>, | 101 | phantom: PhantomData<(&'d mut T, I)>, |
| 105 | } | 102 | } |
| 106 | 103 | ||
| 107 | impl<'d, T: Instance> Timer<'d, T, Awaitable> { | 104 | impl<'d, T: Instance> Timer<'d, T, Awaitable> { |
| 108 | pub fn new( | 105 | pub fn new_awaitable( |
| 109 | timer: impl Unborrow<Target = T> + 'd, | 106 | timer: impl Unborrow<Target = T> + 'd, |
| 110 | irq: impl Unborrow<Target = T::Interrupt> + 'd, | 107 | irq: impl Unborrow<Target = T::Interrupt> + 'd, |
| 111 | ) -> Self { | 108 | ) -> Self { |
| @@ -119,6 +116,10 @@ impl<'d, T: Instance> Timer<'d, T, Awaitable> { | |||
| 119 | } | 116 | } |
| 120 | } | 117 | } |
| 121 | impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { | 118 | impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { |
| 119 | /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. | ||
| 120 | /// | ||
| 121 | /// This can be useful for triggering tasks via PPI | ||
| 122 | /// `Uarte` uses this internally. | ||
| 122 | pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self { | 123 | pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self { |
| 123 | Self::new_irqless(timer) | 124 | Self::new_irqless(timer) |
| 124 | } | 125 | } |
| @@ -127,7 +128,7 @@ impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { | |||
| 127 | impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | 128 | impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { |
| 128 | /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. | 129 | /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. |
| 129 | /// | 130 | /// |
| 130 | /// This is used by `Uarte` internally. | 131 | /// This is used by the public constructors. |
| 131 | fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self { | 132 | fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self { |
| 132 | let regs = T::regs(); | 133 | let regs = T::regs(); |
| 133 | 134 | ||
| @@ -242,7 +243,6 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | |||
| 242 | Cc { | 243 | Cc { |
| 243 | n, | 244 | n, |
| 244 | phantom: PhantomData, | 245 | phantom: PhantomData, |
| 245 | phantom2: PhantomData, | ||
| 246 | } | 246 | } |
| 247 | } | 247 | } |
| 248 | } | 248 | } |
| @@ -254,10 +254,9 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { | |||
| 254 | /// | 254 | /// |
| 255 | /// 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. |
| 256 | /// 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 |
| 257 | pub struct Cc<'a, T: Instance, I: TimerType> { | 257 | pub struct Cc<'a, T: Instance, I: TimerType = NotAwaitable> { |
| 258 | n: usize, | 258 | n: usize, |
| 259 | phantom: PhantomData<&'a mut T>, | 259 | phantom: PhantomData<(&'a mut T, I)>, |
| 260 | phantom2: PhantomData<I>, | ||
| 261 | } | 260 | } |
| 262 | 261 | ||
| 263 | impl<'a, T: Instance> Cc<'a, T, Awaitable> { | 262 | impl<'a, T: Instance> Cc<'a, T, Awaitable> { |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index d164ebcbc..a6909be68 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -19,7 +19,7 @@ use crate::interrupt::Interrupt; | |||
| 19 | use crate::pac; | 19 | use crate::pac; |
| 20 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; | 20 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; |
| 21 | use crate::timer::Instance as TimerInstance; | 21 | use crate::timer::Instance as TimerInstance; |
| 22 | use crate::timer::{Frequency, NotAwaitableTimer}; | 22 | use crate::timer::{Frequency, Timer}; |
| 23 | 23 | ||
| 24 | // Re-export SVD variants to allow user to directly set values. | 24 | // Re-export SVD variants to allow user to directly set values. |
| 25 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 25 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; |
| @@ -288,7 +288,7 @@ impl<'d, T: Instance> Write for Uarte<'d, T> { | |||
| 288 | /// allowing it to implement the ReadUntilIdle trait. | 288 | /// allowing it to implement the ReadUntilIdle trait. |
| 289 | pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { | 289 | pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { |
| 290 | uarte: Uarte<'d, U>, | 290 | uarte: Uarte<'d, U>, |
| 291 | timer: NotAwaitableTimer<'d, T>, | 291 | timer: Timer<'d, T>, |
| 292 | ppi_ch1: Ppi<'d, AnyConfigurableChannel>, | 292 | ppi_ch1: Ppi<'d, AnyConfigurableChannel>, |
| 293 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, | 293 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, |
| 294 | } | 294 | } |
| @@ -317,7 +317,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | |||
| 317 | ) -> Self { | 317 | ) -> Self { |
| 318 | let baudrate = config.baudrate; | 318 | let baudrate = config.baudrate; |
| 319 | let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); | 319 | let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); |
| 320 | let mut timer = NotAwaitableTimer::new(timer); | 320 | let mut timer = Timer::new(timer); |
| 321 | 321 | ||
| 322 | unborrow!(ppi_ch1, ppi_ch2); | 322 | unborrow!(ppi_ch1, ppi_ch2); |
| 323 | 323 | ||
diff --git a/examples/nrf/src/bin/awaitable_timer.rs b/examples/nrf/src/bin/awaitable_timer.rs new file mode 100644 index 000000000..289a33c71 --- /dev/null +++ b/examples/nrf/src/bin/awaitable_timer.rs | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | #![allow(incomplete_features)] | ||
| 5 | |||
| 6 | #[path = "../example_common.rs"] | ||
| 7 | mod example_common; | ||
| 8 | use embassy_nrf::interrupt; | ||
| 9 | use embassy_nrf::timer::Timer; | ||
| 10 | use embassy_nrf::Peripherals; | ||
| 11 | use example_common::info; | ||
| 12 | |||
| 13 | use embassy::executor::Spawner; | ||
| 14 | |||
| 15 | #[embassy::main] | ||
| 16 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 17 | let mut t = Timer::new_awaitable(p.TIMER0, interrupt::take!(TIMER0)); | ||
| 18 | // default frequency is 1MHz, so this triggers every second | ||
| 19 | t.cc(0).write(1_000_000); | ||
| 20 | // clear the timer value on cc[0] compare match | ||
| 21 | t.cc(0).short_compare_clear(); | ||
| 22 | t.start(); | ||
| 23 | |||
| 24 | loop { | ||
| 25 | // wait for compare match | ||
| 26 | t.cc(0).wait().await; | ||
| 27 | info!("hardware timer tick"); | ||
| 28 | } | ||
| 29 | } | ||
