aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/buffered_uarte.rs6
-rw-r--r--embassy-nrf/src/timer.rs19
-rw-r--r--embassy-nrf/src/uarte.rs6
-rw-r--r--examples/nrf/src/bin/awaitable_timer.rs29
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};
16use crate::pac; 16use crate::pac;
17use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; 17use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
18use crate::timer::Instance as TimerInstance; 18use crate::timer::Instance as TimerInstance;
19use crate::timer::{Frequency, NotAwaitableTimer}; 19use crate::timer::{Frequency, Timer};
20use crate::uarte::{Config, Instance as UarteInstance}; 20use 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
44struct StateInner<'d, U: UarteInstance, T: TimerInstance> { 44struct 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 {}
97impl TimerType for Awaitable {} 97impl TimerType for Awaitable {}
98impl TimerType for NotAwaitable {} 98impl TimerType for NotAwaitable {}
99 99
100pub type AwaitableTimer<'d, T> = Timer<'d, T, Awaitable>; 100pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> {
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)>, 101 phantom: PhantomData<(&'d mut T, I)>,
105} 102}
106 103
107impl<'d, T: Instance> Timer<'d, T, Awaitable> { 104impl<'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}
121impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { 118impl<'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> {
127impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { 128impl<'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
257pub struct Cc<'a, T: Instance, I: TimerType> { 257pub 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
263impl<'a, T: Instance> Cc<'a, T, Awaitable> { 262impl<'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;
19use crate::pac; 19use crate::pac;
20use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; 20use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
21use crate::timer::Instance as TimerInstance; 21use crate::timer::Instance as TimerInstance;
22use crate::timer::{Frequency, NotAwaitableTimer}; 22use 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.
25pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 25pub 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.
289pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { 289pub 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"]
7mod example_common;
8use embassy_nrf::interrupt;
9use embassy_nrf::timer::Timer;
10use embassy_nrf::Peripherals;
11use example_common::info;
12
13use embassy::executor::Spawner;
14
15#[embassy::main]
16async 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}