diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 3b0d2f1c..a9487a9f 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -6,15 +6,9 @@ #![macro_use] -use core::future::poll_fn; -use core::marker::PhantomData; -use core::task::Poll; - -use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{into_ref, PeripheralRef}; -use embassy_sync::waitqueue::AtomicWaker; -use crate::interrupt::{Interrupt, InterruptExt}; +use crate::interrupt::Interrupt; use crate::ppi::{Event, Task}; use crate::{pac, Peripheral}; @@ -26,8 +20,6 @@ pub(crate) mod sealed { /// The number of CC registers this instance has. const CCS: usize; fn regs() -> &'static pac::timer0::RegisterBlock; - /// Storage for the waker for CC register `n`. - fn waker(n: usize) -> &'static AtomicWaker; } pub trait ExtendedInstance {} @@ -50,12 +42,6 @@ macro_rules! impl_timer { fn regs() -> &'static pac::timer0::RegisterBlock { unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } } - fn waker(n: usize) -> &'static ::embassy_sync::waitqueue::AtomicWaker { - use ::embassy_sync::waitqueue::AtomicWaker; - const NEW_AW: AtomicWaker = AtomicWaker::new(); - static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs]; - &WAKERS[n] - } } impl crate::timer::Instance for peripherals::$type { type Interrupt = crate::interrupt::$irq; @@ -99,59 +85,18 @@ pub enum Frequency { /// nRF Timer driver. /// /// The timer has an internal counter, which is incremented for every tick of the timer. -/// The counter is 32-bit, so it wraps back to 0 at 4294967296. +/// The counter is 32-bit, so it wraps back to 0 when it reaches 2^32. /// /// It has either 4 or 6 Capture/Compare registers, which can be used to capture the current state of the counter /// or trigger an event when the counter reaches a certain value. -pub trait TimerType: sealed::TimerType {} - -/// Marker type indicating the timer driver can await expiration (it owns the timer interrupt). -pub enum Awaitable {} - -/// Marker type indicating the timer driver cannot await expiration (it does not own the timer interrupt). -pub enum NotAwaitable {} - -impl sealed::TimerType for Awaitable {} -impl sealed::TimerType for NotAwaitable {} -impl TimerType for Awaitable {} -impl TimerType for NotAwaitable {} - /// Timer driver. -pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { +pub struct Timer<'d, T: Instance> { _p: PeripheralRef<'d, T>, - _i: PhantomData, } -impl<'d, T: Instance> Timer<'d, T, Awaitable> { - /// Create a new async-capable timer driver. - pub fn new_awaitable(timer: impl Peripheral
+ 'd, irq: impl Peripheral
+ 'd) -> Self { - into_ref!(irq); - - irq.set_handler(Self::on_interrupt); - irq.unpend(); - irq.enable(); - - Self::new_inner(timer, false) - } - - /// Create a new async-capable timer driver in counter mode. - pub fn new_awaitable_counter( - timer: impl Peripheral
+ 'd, - irq: impl Peripheral
+ 'd, - ) -> Self { - into_ref!(irq); - - irq.set_handler(Self::on_interrupt); - irq.unpend(); - irq.enable(); - - Self::new_inner(timer, true) - } -} - -impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { - /// Create a `Timer` driver without an interrupt, meaning `Cc::wait` won't work. +impl<'d, T: Instance> Timer<'d, T> { + /// Create a new `Timer` driver. /// /// This can be useful for triggering tasks via PPI /// `Uarte` uses this internally. @@ -159,28 +104,20 @@ impl<'d, T: Instance> Timer<'d, T, NotAwaitable> { Self::new_inner(timer, false) } - /// Create a `Timer` driver in counter mode without an interrupt, meaning `Cc::wait` won't work. + /// Create a new `Timer` driver in counter mode. /// /// This can be useful for triggering tasks via PPI /// `Uarte` uses this internally. pub fn new_counter(timer: impl Peripheral
+ 'd) -> Self { Self::new_inner(timer, true) } -} -impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { - /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. - /// - /// This is used by the public constructors. fn new_inner(timer: impl Peripheral
+ 'd, is_counter: bool) -> Self {
into_ref!(timer);
let regs = T::regs();
- let mut this = Self {
- _p: timer,
- _i: PhantomData,
- };
+ let mut this = Self { _p: timer };
// Stop the timer before doing anything else,
// since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification.
@@ -272,31 +209,17 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
.write(|w| unsafe { w.prescaler().bits(frequency as u8) })
}
- fn on_interrupt(_: *mut ()) {
- let regs = T::regs();
- for n in 0..T::CCS {
- if regs.events_compare[n].read().bits() != 0 {
- // Clear the interrupt, otherwise the interrupt will be repeatedly raised as soon as the interrupt handler exits.
- // We can't clear the event, because it's used to poll whether the future is done or still pending.
- regs.intenclr
- .modify(|r, w| unsafe { w.bits(r.bits() | (1 << (16 + n))) });
- T::waker(n).wake();
- }
- }
- }
-
/// Returns this timer's `n`th CC register.
///
/// # Panics
/// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer).
- pub fn cc(&mut self, n: usize) -> Cc