removed type aliases

NotAwaitable as default generic param
added awaitable_timer example
This commit is contained in:
f_punk 2021-09-02 12:02:31 +02:00
parent 1cef7134d4
commit 34c66fa78d
4 changed files with 44 additions and 16 deletions

View File

@ -16,7 +16,7 @@ use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin};
use crate::pac; use crate::pac;
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
use crate::timer::Instance as TimerInstance; use crate::timer::Instance as TimerInstance;
use crate::timer::{Frequency, NotAwaitableTimer}; use crate::timer::{Frequency, Timer};
use crate::uarte::{Config, Instance as UarteInstance}; use crate::uarte::{Config, Instance as UarteInstance};
// Re-export SVD variants to allow user to directly set values // 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> {
struct StateInner<'d, U: UarteInstance, T: TimerInstance> { struct StateInner<'d, U: UarteInstance, T: TimerInstance> {
phantom: PhantomData<&'d mut U>, phantom: PhantomData<&'d mut U>,
timer: NotAwaitableTimer<'d, T>, timer: Timer<'d, T>,
_ppi_ch1: Ppi<'d, AnyConfigurableChannel>, _ppi_ch1: Ppi<'d, AnyConfigurableChannel>,
_ppi_ch2: Ppi<'d, AnyConfigurableChannel>, _ppi_ch2: Ppi<'d, AnyConfigurableChannel>,
@ -84,7 +84,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
let r = U::regs(); let r = U::regs();
let mut timer = NotAwaitableTimer::new(timer); let mut timer = Timer::new(timer);
rxd.conf().write(|w| w.input().connect().drive().h0h1()); rxd.conf().write(|w| w.input().connect().drive().h0h1());
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });

View File

@ -97,15 +97,12 @@ impl sealed::TimerType for NotAwaitable {}
impl TimerType for Awaitable {} impl TimerType for Awaitable {}
impl TimerType for NotAwaitable {} impl TimerType for NotAwaitable {}
pub type AwaitableTimer<'d, T> = Timer<'d, T, Awaitable>; pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> {
pub type NotAwaitableTimer<'d, T> = Timer<'d, T, NotAwaitable>;
pub struct Timer<'d, T: Instance, I: TimerType> {
phantom: PhantomData<(&'d mut T, I)>, phantom: PhantomData<(&'d mut T, I)>,
} }
impl<'d, T: Instance> Timer<'d, T, Awaitable> { impl<'d, T: Instance> Timer<'d, T, Awaitable> {
pub fn new( pub fn new_awaitable(
timer: impl Unborrow<Target = T> + 'd, timer: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
) -> Self { ) -> Self {
@ -119,6 +116,10 @@ impl<'d, T: Instance> Timer<'d, T, Awaitable> {
} }
} }
impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { impl<'d, T: Instance> Timer<'d, T, NotAwaitable> {
/// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work.
///
/// This can be useful for triggering tasks via PPI
/// `Uarte` uses this internally.
pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self { pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self {
Self::new_irqless(timer) Self::new_irqless(timer)
} }
@ -127,7 +128,7 @@ impl<'d, T: Instance> Timer<'d, T, NotAwaitable> {
impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
/// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work.
/// ///
/// This is used by `Uarte` internally. /// This is used by the public constructors.
fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self { fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self {
let regs = T::regs(); let regs = T::regs();
@ -242,7 +243,6 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
Cc { Cc {
n, n,
phantom: PhantomData, phantom: PhantomData,
phantom2: PhantomData,
} }
} }
} }
@ -254,10 +254,9 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
/// ///
/// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register.
/// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register
pub struct Cc<'a, T: Instance, I: TimerType> { pub struct Cc<'a, T: Instance, I: TimerType = NotAwaitable> {
n: usize, n: usize,
phantom: PhantomData<&'a mut T>, phantom: PhantomData<(&'a mut T, I)>,
phantom2: PhantomData<I>,
} }
impl<'a, T: Instance> Cc<'a, T, Awaitable> { impl<'a, T: Instance> Cc<'a, T, Awaitable> {

View File

@ -19,7 +19,7 @@ use crate::interrupt::Interrupt;
use crate::pac; use crate::pac;
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
use crate::timer::Instance as TimerInstance; use crate::timer::Instance as TimerInstance;
use crate::timer::{Frequency, NotAwaitableTimer}; use crate::timer::{Frequency, Timer};
// Re-export SVD variants to allow user to directly set values. // Re-export SVD variants to allow user to directly set values.
pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 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> {
/// allowing it to implement the ReadUntilIdle trait. /// allowing it to implement the ReadUntilIdle trait.
pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
uarte: Uarte<'d, U>, uarte: Uarte<'d, U>,
timer: NotAwaitableTimer<'d, T>, timer: Timer<'d, T>,
ppi_ch1: Ppi<'d, AnyConfigurableChannel>, ppi_ch1: Ppi<'d, AnyConfigurableChannel>,
_ppi_ch2: Ppi<'d, AnyConfigurableChannel>, _ppi_ch2: Ppi<'d, AnyConfigurableChannel>,
} }
@ -317,7 +317,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
) -> Self { ) -> Self {
let baudrate = config.baudrate; let baudrate = config.baudrate;
let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config);
let mut timer = NotAwaitableTimer::new(timer); let mut timer = Timer::new(timer);
unborrow!(ppi_ch1, ppi_ch2); unborrow!(ppi_ch1, ppi_ch2);

View File

@ -0,0 +1,29 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
#![allow(incomplete_features)]
#[path = "../example_common.rs"]
mod example_common;
use embassy_nrf::interrupt;
use embassy_nrf::timer::Timer;
use embassy_nrf::Peripherals;
use example_common::info;
use embassy::executor::Spawner;
#[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) {
let mut t = Timer::new_awaitable(p.TIMER0, interrupt::take!(TIMER0));
// default frequency is 1MHz, so this triggers every second
t.cc(0).write(1_000_000);
// clear the timer value on cc[0] compare match
t.cc(0).short_compare_clear();
t.start();
loop {
// wait for compare match
t.cc(0).wait().await;
info!("hardware timer tick");
}
}