From 65628e1f1538f003c114d97c98970631953e7d6e Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Wed, 13 Oct 2021 16:35:05 +0200 Subject: [PATCH 01/10] - Added _ppi and _dppi to distinguish between the new and the old peripheral. - Removed ConfigurableChannel and added capacity numbers to the channels - Replaced the PPI api with a new one using the DPPI terminology (publish & subscribe) - Updated all tasks and event registers for DPPI --- embassy-nrf/Cargo.toml | 18 +- embassy-nrf/src/buffered_uarte.rs | 58 ++-- embassy-nrf/src/chips/nrf52805.rs | 44 +-- embassy-nrf/src/chips/nrf52810.rs | 64 ++--- embassy-nrf/src/chips/nrf52811.rs | 64 ++--- embassy-nrf/src/chips/nrf52820.rs | 64 ++--- embassy-nrf/src/chips/nrf52832.rs | 64 ++--- embassy-nrf/src/chips/nrf52833.rs | 64 ++--- embassy-nrf/src/chips/nrf52840.rs | 64 ++--- embassy-nrf/src/gpiote.rs | 26 +- embassy-nrf/src/ppi.rs | 426 +++++++++++++++++++++++------- embassy-nrf/src/timer.rs | 35 ++- embassy-nrf/src/uarte.rs | 57 ++-- examples/nrf/src/bin/ppi.rs | 18 +- 14 files changed, 696 insertions(+), 370 deletions(-) diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index fc1ec6b01..c083978c3 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -18,18 +18,20 @@ defmt-info = [ ] defmt-warn = [ ] defmt-error = [ ] -nrf52805 = ["nrf52805-pac"] -nrf52810 = ["nrf52810-pac"] -nrf52811 = ["nrf52811-pac"] -nrf52820 = ["nrf52820-pac"] -nrf52832 = ["nrf52832-pac"] -nrf52833 = ["nrf52833-pac"] -nrf52840 = ["nrf52840-pac"] -nrf9160 = ["nrf9160-pac"] +nrf52805 = ["nrf52805-pac", "_ppi"] +nrf52810 = ["nrf52810-pac", "_ppi"] +nrf52811 = ["nrf52811-pac", "_ppi"] +nrf52820 = ["nrf52820-pac", "_ppi"] +nrf52832 = ["nrf52832-pac", "_ppi"] +nrf52833 = ["nrf52833-pac", "_ppi"] +nrf52840 = ["nrf52840-pac", "_ppi"] +nrf9160 = ["nrf9160-pac", "_dppi"] # Features starting with `_` are for internal use only. They're not intended # to be enabled by other crates, and are not covered by semver guarantees. _time-driver = ["embassy/time-tick-32768hz"] +_ppi = [] +_dppi = [] gpiote = [] time-driver-rtc1 = ["_time-driver"] diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index cd08875cd..f7e55e428 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -5,7 +5,7 @@ use core::pin::Pin; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::{Context, Poll}; use embassy::interrupt::InterruptExt; -use embassy::io::{AsyncBufRead, AsyncWrite, Result}; +use embassy::io::{AsyncBufRead, AsyncWrite}; use embassy::util::Unborrow; use embassy::waitqueue::WakerRegistration; use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; @@ -14,15 +14,27 @@ use embassy_hal_common::{low_power_wait_until, unborrow}; use crate::gpio::sealed::Pin as _; use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; -use crate::pac; -use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; +use crate::ppi::{AnyChannel, Channel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; use crate::uarte::{Config, Instance as UarteInstance}; +use crate::{pac, ppi}; // 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}; +#[non_exhaustive] +#[derive(Clone, Debug)] +pub enum Error { + PpiError(ppi::Error), +} + +impl From for Error { + fn from(e: ppi::Error) -> Self { + Self::PpiError(e) + } +} + #[derive(Copy, Clone, Debug, PartialEq)] enum RxState { Idle, @@ -45,8 +57,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> { struct StateInner<'d, U: UarteInstance, T: TimerInstance> { phantom: PhantomData<&'d mut U>, timer: Timer<'d, T>, - _ppi_ch1: Ppi<'d, AnyConfigurableChannel>, - _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, + _ppi_ch1: Ppi<'d, AnyChannel>, + _ppi_ch2: Ppi<'d, AnyChannel>, rx: RingBuffer<'d>, rx_state: RxState, @@ -66,12 +78,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> { impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { /// unsafe: may not leak self or futures + /// + /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned + /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned pub unsafe fn new( state: &'d mut State<'d, U, T>, _uarte: impl Unborrow + 'd, timer: impl Unborrow + 'd, - ppi_ch1: impl Unborrow + 'd, - ppi_ch2: impl Unborrow + 'd, + ppi_ch1: impl Unborrow + 'd, + ppi_ch2: impl Unborrow + 'd, irq: impl Unborrow + 'd, rxd: impl Unborrow + 'd, txd: impl Unborrow + 'd, @@ -80,7 +95,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { config: Config, rx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8], - ) -> Self { + ) -> Result { unborrow!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); let r = U::regs(); @@ -144,18 +159,18 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { timer.cc(0).short_compare_clear(); timer.cc(0).short_compare_stop(); - let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); - ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); - ppi_ch1.set_task(timer.task_clear()); - ppi_ch1.set_fork_task(timer.task_start()); + let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); + ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; + ppi_ch1.subscribe(timer.task_clear())?; + ppi_ch1.subscribe(timer.task_start())?; ppi_ch1.enable(); - let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); - ppi_ch2.set_event(timer.cc(0).event_compare()); - ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); + let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); + ppi_ch2.publish(timer.cc(0).event_compare())?; + ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; ppi_ch2.enable(); - Self { + Ok(Self { inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner { phantom: PhantomData, timer, @@ -170,7 +185,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { tx_state: TxState::Idle, tx_waker: WakerRegistration::new(), }), - } + }) } pub fn set_baudrate(&mut self, baudrate: Baudrate) { @@ -187,7 +202,10 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { } impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> { - fn poll_fill_buf(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + fn poll_fill_buf( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { self.inner.with(|state| { // Conservative compiler fence to prevent optimizations that do not // take in to account actions by DMA. The fence has been placed here, @@ -206,7 +224,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, trace!(" empty"); state.rx_waker.register(cx.waker()); - Poll::>::Pending + Poll::>::Pending }) } @@ -224,7 +242,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], - ) -> Poll> { + ) -> Poll> { let poll = self.inner.with(|state| { trace!("poll_write: {:?}", buf.len()); diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index d68697936..03fc5f307 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs @@ -167,28 +167,28 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, configurable); -impl_ppi_channel!(PPI_CH1, 1, configurable); -impl_ppi_channel!(PPI_CH2, 2, configurable); -impl_ppi_channel!(PPI_CH3, 3, configurable); -impl_ppi_channel!(PPI_CH4, 4, configurable); -impl_ppi_channel!(PPI_CH5, 5, configurable); -impl_ppi_channel!(PPI_CH6, 6, configurable); -impl_ppi_channel!(PPI_CH7, 7, configurable); -impl_ppi_channel!(PPI_CH8, 8, configurable); -impl_ppi_channel!(PPI_CH9, 9, configurable); -impl_ppi_channel!(PPI_CH20, 20); -impl_ppi_channel!(PPI_CH21, 21); -impl_ppi_channel!(PPI_CH22, 22); -impl_ppi_channel!(PPI_CH23, 23); -impl_ppi_channel!(PPI_CH24, 24); -impl_ppi_channel!(PPI_CH25, 25); -impl_ppi_channel!(PPI_CH26, 26); -impl_ppi_channel!(PPI_CH27, 27); -impl_ppi_channel!(PPI_CH28, 28); -impl_ppi_channel!(PPI_CH29, 29); -impl_ppi_channel!(PPI_CH30, 30); -impl_ppi_channel!(PPI_CH31, 31); +impl_ppi_channel!(PPI_CH0, 0, 2, 1); +impl_ppi_channel!(PPI_CH1, 1, 2, 1); +impl_ppi_channel!(PPI_CH2, 2, 2, 1); +impl_ppi_channel!(PPI_CH3, 3, 2, 1); +impl_ppi_channel!(PPI_CH4, 4, 2, 1); +impl_ppi_channel!(PPI_CH5, 5, 2, 1); +impl_ppi_channel!(PPI_CH6, 6, 2, 1); +impl_ppi_channel!(PPI_CH7, 7, 2, 1); +impl_ppi_channel!(PPI_CH8, 8, 2, 1); +impl_ppi_channel!(PPI_CH9, 9, 2, 1); +impl_ppi_channel!(PPI_CH20, 20, 1, 0); +impl_ppi_channel!(PPI_CH21, 21, 1, 0); +impl_ppi_channel!(PPI_CH22, 22, 1, 0); +impl_ppi_channel!(PPI_CH23, 23, 1, 0); +impl_ppi_channel!(PPI_CH24, 24, 1, 0); +impl_ppi_channel!(PPI_CH25, 25, 1, 0); +impl_ppi_channel!(PPI_CH26, 26, 1, 0); +impl_ppi_channel!(PPI_CH27, 27, 1, 0); +impl_ppi_channel!(PPI_CH28, 28, 1, 0); +impl_ppi_channel!(PPI_CH29, 29, 1, 0); +impl_ppi_channel!(PPI_CH30, 30, 1, 0); +impl_ppi_channel!(PPI_CH31, 31, 1, 0); impl_saadc_input!(P0_04, ANALOGINPUT2); impl_saadc_input!(P0_05, ANALOGINPUT3); diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index c119e7cdb..e317e4c54 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs @@ -172,38 +172,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, configurable); -impl_ppi_channel!(PPI_CH1, 1, configurable); -impl_ppi_channel!(PPI_CH2, 2, configurable); -impl_ppi_channel!(PPI_CH3, 3, configurable); -impl_ppi_channel!(PPI_CH4, 4, configurable); -impl_ppi_channel!(PPI_CH5, 5, configurable); -impl_ppi_channel!(PPI_CH6, 6, configurable); -impl_ppi_channel!(PPI_CH7, 7, configurable); -impl_ppi_channel!(PPI_CH8, 8, configurable); -impl_ppi_channel!(PPI_CH9, 9, configurable); -impl_ppi_channel!(PPI_CH10, 10, configurable); -impl_ppi_channel!(PPI_CH11, 11, configurable); -impl_ppi_channel!(PPI_CH12, 12, configurable); -impl_ppi_channel!(PPI_CH13, 13, configurable); -impl_ppi_channel!(PPI_CH14, 14, configurable); -impl_ppi_channel!(PPI_CH15, 15, configurable); -impl_ppi_channel!(PPI_CH16, 16, configurable); -impl_ppi_channel!(PPI_CH17, 17, configurable); -impl_ppi_channel!(PPI_CH18, 18, configurable); -impl_ppi_channel!(PPI_CH19, 19, configurable); -impl_ppi_channel!(PPI_CH20, 20); -impl_ppi_channel!(PPI_CH21, 21); -impl_ppi_channel!(PPI_CH22, 22); -impl_ppi_channel!(PPI_CH23, 23); -impl_ppi_channel!(PPI_CH24, 24); -impl_ppi_channel!(PPI_CH25, 25); -impl_ppi_channel!(PPI_CH26, 26); -impl_ppi_channel!(PPI_CH27, 27); -impl_ppi_channel!(PPI_CH28, 28); -impl_ppi_channel!(PPI_CH29, 29); -impl_ppi_channel!(PPI_CH30, 30); -impl_ppi_channel!(PPI_CH31, 31); +impl_ppi_channel!(PPI_CH0, 0, 2, 1); +impl_ppi_channel!(PPI_CH1, 1, 2, 1); +impl_ppi_channel!(PPI_CH2, 2, 2, 1); +impl_ppi_channel!(PPI_CH3, 3, 2, 1); +impl_ppi_channel!(PPI_CH4, 4, 2, 1); +impl_ppi_channel!(PPI_CH5, 5, 2, 1); +impl_ppi_channel!(PPI_CH6, 6, 2, 1); +impl_ppi_channel!(PPI_CH7, 7, 2, 1); +impl_ppi_channel!(PPI_CH8, 8, 2, 1); +impl_ppi_channel!(PPI_CH9, 9, 2, 1); +impl_ppi_channel!(PPI_CH10, 10, 2, 1); +impl_ppi_channel!(PPI_CH11, 11, 2, 1); +impl_ppi_channel!(PPI_CH12, 12, 2, 1); +impl_ppi_channel!(PPI_CH13, 13, 2, 1); +impl_ppi_channel!(PPI_CH14, 14, 2, 1); +impl_ppi_channel!(PPI_CH15, 15, 2, 1); +impl_ppi_channel!(PPI_CH16, 16, 2, 1); +impl_ppi_channel!(PPI_CH17, 17, 2, 1); +impl_ppi_channel!(PPI_CH18, 18, 2, 1); +impl_ppi_channel!(PPI_CH19, 19, 2, 1); +impl_ppi_channel!(PPI_CH20, 20, 1, 0); +impl_ppi_channel!(PPI_CH21, 21, 1, 0); +impl_ppi_channel!(PPI_CH22, 22, 1, 0); +impl_ppi_channel!(PPI_CH23, 23, 1, 0); +impl_ppi_channel!(PPI_CH24, 24, 1, 0); +impl_ppi_channel!(PPI_CH25, 25, 1, 0); +impl_ppi_channel!(PPI_CH26, 26, 1, 0); +impl_ppi_channel!(PPI_CH27, 27, 1, 0); +impl_ppi_channel!(PPI_CH28, 28, 1, 0); +impl_ppi_channel!(PPI_CH29, 29, 1, 0); +impl_ppi_channel!(PPI_CH30, 30, 1, 0); +impl_ppi_channel!(PPI_CH31, 31, 1, 0); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 3c9df40fe..748f5f4ba 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs @@ -173,38 +173,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, configurable); -impl_ppi_channel!(PPI_CH1, 1, configurable); -impl_ppi_channel!(PPI_CH2, 2, configurable); -impl_ppi_channel!(PPI_CH3, 3, configurable); -impl_ppi_channel!(PPI_CH4, 4, configurable); -impl_ppi_channel!(PPI_CH5, 5, configurable); -impl_ppi_channel!(PPI_CH6, 6, configurable); -impl_ppi_channel!(PPI_CH7, 7, configurable); -impl_ppi_channel!(PPI_CH8, 8, configurable); -impl_ppi_channel!(PPI_CH9, 9, configurable); -impl_ppi_channel!(PPI_CH10, 10, configurable); -impl_ppi_channel!(PPI_CH11, 11, configurable); -impl_ppi_channel!(PPI_CH12, 12, configurable); -impl_ppi_channel!(PPI_CH13, 13, configurable); -impl_ppi_channel!(PPI_CH14, 14, configurable); -impl_ppi_channel!(PPI_CH15, 15, configurable); -impl_ppi_channel!(PPI_CH16, 16, configurable); -impl_ppi_channel!(PPI_CH17, 17, configurable); -impl_ppi_channel!(PPI_CH18, 18, configurable); -impl_ppi_channel!(PPI_CH19, 19, configurable); -impl_ppi_channel!(PPI_CH20, 20); -impl_ppi_channel!(PPI_CH21, 21); -impl_ppi_channel!(PPI_CH22, 22); -impl_ppi_channel!(PPI_CH23, 23); -impl_ppi_channel!(PPI_CH24, 24); -impl_ppi_channel!(PPI_CH25, 25); -impl_ppi_channel!(PPI_CH26, 26); -impl_ppi_channel!(PPI_CH27, 27); -impl_ppi_channel!(PPI_CH28, 28); -impl_ppi_channel!(PPI_CH29, 29); -impl_ppi_channel!(PPI_CH30, 30); -impl_ppi_channel!(PPI_CH31, 31); +impl_ppi_channel!(PPI_CH0, 0, 2, 1); +impl_ppi_channel!(PPI_CH1, 1, 2, 1); +impl_ppi_channel!(PPI_CH2, 2, 2, 1); +impl_ppi_channel!(PPI_CH3, 3, 2, 1); +impl_ppi_channel!(PPI_CH4, 4, 2, 1); +impl_ppi_channel!(PPI_CH5, 5, 2, 1); +impl_ppi_channel!(PPI_CH6, 6, 2, 1); +impl_ppi_channel!(PPI_CH7, 7, 2, 1); +impl_ppi_channel!(PPI_CH8, 8, 2, 1); +impl_ppi_channel!(PPI_CH9, 9, 2, 1); +impl_ppi_channel!(PPI_CH10, 10, 2, 1); +impl_ppi_channel!(PPI_CH11, 11, 2, 1); +impl_ppi_channel!(PPI_CH12, 12, 2, 1); +impl_ppi_channel!(PPI_CH13, 13, 2, 1); +impl_ppi_channel!(PPI_CH14, 14, 2, 1); +impl_ppi_channel!(PPI_CH15, 15, 2, 1); +impl_ppi_channel!(PPI_CH16, 16, 2, 1); +impl_ppi_channel!(PPI_CH17, 17, 2, 1); +impl_ppi_channel!(PPI_CH18, 18, 2, 1); +impl_ppi_channel!(PPI_CH19, 19, 2, 1); +impl_ppi_channel!(PPI_CH20, 20, 1, 0); +impl_ppi_channel!(PPI_CH21, 21, 1, 0); +impl_ppi_channel!(PPI_CH22, 22, 1, 0); +impl_ppi_channel!(PPI_CH23, 23, 1, 0); +impl_ppi_channel!(PPI_CH24, 24, 1, 0); +impl_ppi_channel!(PPI_CH25, 25, 1, 0); +impl_ppi_channel!(PPI_CH26, 26, 1, 0); +impl_ppi_channel!(PPI_CH27, 27, 1, 0); +impl_ppi_channel!(PPI_CH28, 28, 1, 0); +impl_ppi_channel!(PPI_CH29, 29, 1, 0); +impl_ppi_channel!(PPI_CH30, 30, 1, 0); +impl_ppi_channel!(PPI_CH31, 31, 1, 0); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 8a8e23a9e..02d2c6103 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs @@ -168,38 +168,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, configurable); -impl_ppi_channel!(PPI_CH1, 1, configurable); -impl_ppi_channel!(PPI_CH2, 2, configurable); -impl_ppi_channel!(PPI_CH3, 3, configurable); -impl_ppi_channel!(PPI_CH4, 4, configurable); -impl_ppi_channel!(PPI_CH5, 5, configurable); -impl_ppi_channel!(PPI_CH6, 6, configurable); -impl_ppi_channel!(PPI_CH7, 7, configurable); -impl_ppi_channel!(PPI_CH8, 8, configurable); -impl_ppi_channel!(PPI_CH9, 9, configurable); -impl_ppi_channel!(PPI_CH10, 10, configurable); -impl_ppi_channel!(PPI_CH11, 11, configurable); -impl_ppi_channel!(PPI_CH12, 12, configurable); -impl_ppi_channel!(PPI_CH13, 13, configurable); -impl_ppi_channel!(PPI_CH14, 14, configurable); -impl_ppi_channel!(PPI_CH15, 15, configurable); -impl_ppi_channel!(PPI_CH16, 16, configurable); -impl_ppi_channel!(PPI_CH17, 17, configurable); -impl_ppi_channel!(PPI_CH18, 18, configurable); -impl_ppi_channel!(PPI_CH19, 19, configurable); -impl_ppi_channel!(PPI_CH20, 20); -impl_ppi_channel!(PPI_CH21, 21); -impl_ppi_channel!(PPI_CH22, 22); -impl_ppi_channel!(PPI_CH23, 23); -impl_ppi_channel!(PPI_CH24, 24); -impl_ppi_channel!(PPI_CH25, 25); -impl_ppi_channel!(PPI_CH26, 26); -impl_ppi_channel!(PPI_CH27, 27); -impl_ppi_channel!(PPI_CH28, 28); -impl_ppi_channel!(PPI_CH29, 29); -impl_ppi_channel!(PPI_CH30, 30); -impl_ppi_channel!(PPI_CH31, 31); +impl_ppi_channel!(PPI_CH0, 0, 2, 1); +impl_ppi_channel!(PPI_CH1, 1, 2, 1); +impl_ppi_channel!(PPI_CH2, 2, 2, 1); +impl_ppi_channel!(PPI_CH3, 3, 2, 1); +impl_ppi_channel!(PPI_CH4, 4, 2, 1); +impl_ppi_channel!(PPI_CH5, 5, 2, 1); +impl_ppi_channel!(PPI_CH6, 6, 2, 1); +impl_ppi_channel!(PPI_CH7, 7, 2, 1); +impl_ppi_channel!(PPI_CH8, 8, 2, 1); +impl_ppi_channel!(PPI_CH9, 9, 2, 1); +impl_ppi_channel!(PPI_CH10, 10, 2, 1); +impl_ppi_channel!(PPI_CH11, 11, 2, 1); +impl_ppi_channel!(PPI_CH12, 12, 2, 1); +impl_ppi_channel!(PPI_CH13, 13, 2, 1); +impl_ppi_channel!(PPI_CH14, 14, 2, 1); +impl_ppi_channel!(PPI_CH15, 15, 2, 1); +impl_ppi_channel!(PPI_CH16, 16, 2, 1); +impl_ppi_channel!(PPI_CH17, 17, 2, 1); +impl_ppi_channel!(PPI_CH18, 18, 2, 1); +impl_ppi_channel!(PPI_CH19, 19, 2, 1); +impl_ppi_channel!(PPI_CH20, 20, 1, 0); +impl_ppi_channel!(PPI_CH21, 21, 1, 0); +impl_ppi_channel!(PPI_CH22, 22, 1, 0); +impl_ppi_channel!(PPI_CH23, 23, 1, 0); +impl_ppi_channel!(PPI_CH24, 24, 1, 0); +impl_ppi_channel!(PPI_CH25, 25, 1, 0); +impl_ppi_channel!(PPI_CH26, 26, 1, 0); +impl_ppi_channel!(PPI_CH27, 27, 1, 0); +impl_ppi_channel!(PPI_CH28, 28, 1, 0); +impl_ppi_channel!(PPI_CH29, 29, 1, 0); +impl_ppi_channel!(PPI_CH30, 30, 1, 0); +impl_ppi_channel!(PPI_CH31, 31, 1, 0); pub mod irqs { use crate::pac::Interrupt as InterruptEnum; diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index c1b02a0bf..611dbbd50 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs @@ -190,38 +190,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, configurable); -impl_ppi_channel!(PPI_CH1, 1, configurable); -impl_ppi_channel!(PPI_CH2, 2, configurable); -impl_ppi_channel!(PPI_CH3, 3, configurable); -impl_ppi_channel!(PPI_CH4, 4, configurable); -impl_ppi_channel!(PPI_CH5, 5, configurable); -impl_ppi_channel!(PPI_CH6, 6, configurable); -impl_ppi_channel!(PPI_CH7, 7, configurable); -impl_ppi_channel!(PPI_CH8, 8, configurable); -impl_ppi_channel!(PPI_CH9, 9, configurable); -impl_ppi_channel!(PPI_CH10, 10, configurable); -impl_ppi_channel!(PPI_CH11, 11, configurable); -impl_ppi_channel!(PPI_CH12, 12, configurable); -impl_ppi_channel!(PPI_CH13, 13, configurable); -impl_ppi_channel!(PPI_CH14, 14, configurable); -impl_ppi_channel!(PPI_CH15, 15, configurable); -impl_ppi_channel!(PPI_CH16, 16, configurable); -impl_ppi_channel!(PPI_CH17, 17, configurable); -impl_ppi_channel!(PPI_CH18, 18, configurable); -impl_ppi_channel!(PPI_CH19, 19, configurable); -impl_ppi_channel!(PPI_CH20, 20); -impl_ppi_channel!(PPI_CH21, 21); -impl_ppi_channel!(PPI_CH22, 22); -impl_ppi_channel!(PPI_CH23, 23); -impl_ppi_channel!(PPI_CH24, 24); -impl_ppi_channel!(PPI_CH25, 25); -impl_ppi_channel!(PPI_CH26, 26); -impl_ppi_channel!(PPI_CH27, 27); -impl_ppi_channel!(PPI_CH28, 28); -impl_ppi_channel!(PPI_CH29, 29); -impl_ppi_channel!(PPI_CH30, 30); -impl_ppi_channel!(PPI_CH31, 31); +impl_ppi_channel!(PPI_CH0, 0, 2, 1); +impl_ppi_channel!(PPI_CH1, 1, 2, 1); +impl_ppi_channel!(PPI_CH2, 2, 2, 1); +impl_ppi_channel!(PPI_CH3, 3, 2, 1); +impl_ppi_channel!(PPI_CH4, 4, 2, 1); +impl_ppi_channel!(PPI_CH5, 5, 2, 1); +impl_ppi_channel!(PPI_CH6, 6, 2, 1); +impl_ppi_channel!(PPI_CH7, 7, 2, 1); +impl_ppi_channel!(PPI_CH8, 8, 2, 1); +impl_ppi_channel!(PPI_CH9, 9, 2, 1); +impl_ppi_channel!(PPI_CH10, 10, 2, 1); +impl_ppi_channel!(PPI_CH11, 11, 2, 1); +impl_ppi_channel!(PPI_CH12, 12, 2, 1); +impl_ppi_channel!(PPI_CH13, 13, 2, 1); +impl_ppi_channel!(PPI_CH14, 14, 2, 1); +impl_ppi_channel!(PPI_CH15, 15, 2, 1); +impl_ppi_channel!(PPI_CH16, 16, 2, 1); +impl_ppi_channel!(PPI_CH17, 17, 2, 1); +impl_ppi_channel!(PPI_CH18, 18, 2, 1); +impl_ppi_channel!(PPI_CH19, 19, 2, 1); +impl_ppi_channel!(PPI_CH20, 20, 1, 0); +impl_ppi_channel!(PPI_CH21, 21, 1, 0); +impl_ppi_channel!(PPI_CH22, 22, 1, 0); +impl_ppi_channel!(PPI_CH23, 23, 1, 0); +impl_ppi_channel!(PPI_CH24, 24, 1, 0); +impl_ppi_channel!(PPI_CH25, 25, 1, 0); +impl_ppi_channel!(PPI_CH26, 26, 1, 0); +impl_ppi_channel!(PPI_CH27, 27, 1, 0); +impl_ppi_channel!(PPI_CH28, 28, 1, 0); +impl_ppi_channel!(PPI_CH29, 29, 1, 0); +impl_ppi_channel!(PPI_CH30, 30, 1, 0); +impl_ppi_channel!(PPI_CH31, 31, 1, 0); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 4f5c26002..6f70f2a47 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs @@ -226,38 +226,38 @@ impl_pin!(P1_13, 1, 13); impl_pin!(P1_14, 1, 14); impl_pin!(P1_15, 1, 15); -impl_ppi_channel!(PPI_CH0, 0, configurable); -impl_ppi_channel!(PPI_CH1, 1, configurable); -impl_ppi_channel!(PPI_CH2, 2, configurable); -impl_ppi_channel!(PPI_CH3, 3, configurable); -impl_ppi_channel!(PPI_CH4, 4, configurable); -impl_ppi_channel!(PPI_CH5, 5, configurable); -impl_ppi_channel!(PPI_CH6, 6, configurable); -impl_ppi_channel!(PPI_CH7, 7, configurable); -impl_ppi_channel!(PPI_CH8, 8, configurable); -impl_ppi_channel!(PPI_CH9, 9, configurable); -impl_ppi_channel!(PPI_CH10, 10, configurable); -impl_ppi_channel!(PPI_CH11, 11, configurable); -impl_ppi_channel!(PPI_CH12, 12, configurable); -impl_ppi_channel!(PPI_CH13, 13, configurable); -impl_ppi_channel!(PPI_CH14, 14, configurable); -impl_ppi_channel!(PPI_CH15, 15, configurable); -impl_ppi_channel!(PPI_CH16, 16, configurable); -impl_ppi_channel!(PPI_CH17, 17, configurable); -impl_ppi_channel!(PPI_CH18, 18, configurable); -impl_ppi_channel!(PPI_CH19, 19, configurable); -impl_ppi_channel!(PPI_CH20, 20); -impl_ppi_channel!(PPI_CH21, 21); -impl_ppi_channel!(PPI_CH22, 22); -impl_ppi_channel!(PPI_CH23, 23); -impl_ppi_channel!(PPI_CH24, 24); -impl_ppi_channel!(PPI_CH25, 25); -impl_ppi_channel!(PPI_CH26, 26); -impl_ppi_channel!(PPI_CH27, 27); -impl_ppi_channel!(PPI_CH28, 28); -impl_ppi_channel!(PPI_CH29, 29); -impl_ppi_channel!(PPI_CH30, 30); -impl_ppi_channel!(PPI_CH31, 31); +impl_ppi_channel!(PPI_CH0, 0, 2, 1); +impl_ppi_channel!(PPI_CH1, 1, 2, 1); +impl_ppi_channel!(PPI_CH2, 2, 2, 1); +impl_ppi_channel!(PPI_CH3, 3, 2, 1); +impl_ppi_channel!(PPI_CH4, 4, 2, 1); +impl_ppi_channel!(PPI_CH5, 5, 2, 1); +impl_ppi_channel!(PPI_CH6, 6, 2, 1); +impl_ppi_channel!(PPI_CH7, 7, 2, 1); +impl_ppi_channel!(PPI_CH8, 8, 2, 1); +impl_ppi_channel!(PPI_CH9, 9, 2, 1); +impl_ppi_channel!(PPI_CH10, 10, 2, 1); +impl_ppi_channel!(PPI_CH11, 11, 2, 1); +impl_ppi_channel!(PPI_CH12, 12, 2, 1); +impl_ppi_channel!(PPI_CH13, 13, 2, 1); +impl_ppi_channel!(PPI_CH14, 14, 2, 1); +impl_ppi_channel!(PPI_CH15, 15, 2, 1); +impl_ppi_channel!(PPI_CH16, 16, 2, 1); +impl_ppi_channel!(PPI_CH17, 17, 2, 1); +impl_ppi_channel!(PPI_CH18, 18, 2, 1); +impl_ppi_channel!(PPI_CH19, 19, 2, 1); +impl_ppi_channel!(PPI_CH20, 20, 1, 0); +impl_ppi_channel!(PPI_CH21, 21, 1, 0); +impl_ppi_channel!(PPI_CH22, 22, 1, 0); +impl_ppi_channel!(PPI_CH23, 23, 1, 0); +impl_ppi_channel!(PPI_CH24, 24, 1, 0); +impl_ppi_channel!(PPI_CH25, 25, 1, 0); +impl_ppi_channel!(PPI_CH26, 26, 1, 0); +impl_ppi_channel!(PPI_CH27, 27, 1, 0); +impl_ppi_channel!(PPI_CH28, 28, 1, 0); +impl_ppi_channel!(PPI_CH29, 29, 1, 0); +impl_ppi_channel!(PPI_CH30, 30, 1, 0); +impl_ppi_channel!(PPI_CH31, 31, 1, 0); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 1006acd95..1b9824151 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -231,38 +231,38 @@ impl_pin!(P1_13, 1, 13); impl_pin!(P1_14, 1, 14); impl_pin!(P1_15, 1, 15); -impl_ppi_channel!(PPI_CH0, 0, configurable); -impl_ppi_channel!(PPI_CH1, 1, configurable); -impl_ppi_channel!(PPI_CH2, 2, configurable); -impl_ppi_channel!(PPI_CH3, 3, configurable); -impl_ppi_channel!(PPI_CH4, 4, configurable); -impl_ppi_channel!(PPI_CH5, 5, configurable); -impl_ppi_channel!(PPI_CH6, 6, configurable); -impl_ppi_channel!(PPI_CH7, 7, configurable); -impl_ppi_channel!(PPI_CH8, 8, configurable); -impl_ppi_channel!(PPI_CH9, 9, configurable); -impl_ppi_channel!(PPI_CH10, 10, configurable); -impl_ppi_channel!(PPI_CH11, 11, configurable); -impl_ppi_channel!(PPI_CH12, 12, configurable); -impl_ppi_channel!(PPI_CH13, 13, configurable); -impl_ppi_channel!(PPI_CH14, 14, configurable); -impl_ppi_channel!(PPI_CH15, 15, configurable); -impl_ppi_channel!(PPI_CH16, 16, configurable); -impl_ppi_channel!(PPI_CH17, 17, configurable); -impl_ppi_channel!(PPI_CH18, 18, configurable); -impl_ppi_channel!(PPI_CH19, 19, configurable); -impl_ppi_channel!(PPI_CH20, 20); -impl_ppi_channel!(PPI_CH21, 21); -impl_ppi_channel!(PPI_CH22, 22); -impl_ppi_channel!(PPI_CH23, 23); -impl_ppi_channel!(PPI_CH24, 24); -impl_ppi_channel!(PPI_CH25, 25); -impl_ppi_channel!(PPI_CH26, 26); -impl_ppi_channel!(PPI_CH27, 27); -impl_ppi_channel!(PPI_CH28, 28); -impl_ppi_channel!(PPI_CH29, 29); -impl_ppi_channel!(PPI_CH30, 30); -impl_ppi_channel!(PPI_CH31, 31); +impl_ppi_channel!(PPI_CH0, 0, 2, 1); +impl_ppi_channel!(PPI_CH1, 1, 2, 1); +impl_ppi_channel!(PPI_CH2, 2, 2, 1); +impl_ppi_channel!(PPI_CH3, 3, 2, 1); +impl_ppi_channel!(PPI_CH4, 4, 2, 1); +impl_ppi_channel!(PPI_CH5, 5, 2, 1); +impl_ppi_channel!(PPI_CH6, 6, 2, 1); +impl_ppi_channel!(PPI_CH7, 7, 2, 1); +impl_ppi_channel!(PPI_CH8, 8, 2, 1); +impl_ppi_channel!(PPI_CH9, 9, 2, 1); +impl_ppi_channel!(PPI_CH10, 10, 2, 1); +impl_ppi_channel!(PPI_CH11, 11, 2, 1); +impl_ppi_channel!(PPI_CH12, 12, 2, 1); +impl_ppi_channel!(PPI_CH13, 13, 2, 1); +impl_ppi_channel!(PPI_CH14, 14, 2, 1); +impl_ppi_channel!(PPI_CH15, 15, 2, 1); +impl_ppi_channel!(PPI_CH16, 16, 2, 1); +impl_ppi_channel!(PPI_CH17, 17, 2, 1); +impl_ppi_channel!(PPI_CH18, 18, 2, 1); +impl_ppi_channel!(PPI_CH19, 19, 2, 1); +impl_ppi_channel!(PPI_CH20, 20, 1, 0); +impl_ppi_channel!(PPI_CH21, 21, 1, 0); +impl_ppi_channel!(PPI_CH22, 22, 1, 0); +impl_ppi_channel!(PPI_CH23, 23, 1, 0); +impl_ppi_channel!(PPI_CH24, 24, 1, 0); +impl_ppi_channel!(PPI_CH25, 25, 1, 0); +impl_ppi_channel!(PPI_CH26, 26, 1, 0); +impl_ppi_channel!(PPI_CH27, 27, 1, 0); +impl_ppi_channel!(PPI_CH28, 28, 1, 0); +impl_ppi_channel!(PPI_CH29, 29, 1, 0); +impl_ppi_channel!(PPI_CH30, 30, 1, 0); +impl_ppi_channel!(PPI_CH31, 31, 1, 0); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 7ec072ac8..943ff530b 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -190,7 +190,13 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { /// Returns the IN event, for use with PPI. pub fn event_in(&self) -> Event { let g = unsafe { &*pac::GPIOTE::ptr() }; - Event::from_reg(&g.events_in[self.ch.number()]) + + #[cfg(feature = "_ppi")] + let reg = &g.events_in[self.ch.number()]; + #[cfg(feature = "_dppi")] + let reg = &g.publish_in[self.ch.number()]; + + Event::from_reg(reg) } } @@ -271,21 +277,33 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { /// Returns the OUT task, for use with PPI. pub fn task_out(&self) -> Task { let g = unsafe { &*pac::GPIOTE::ptr() }; - Task::from_reg(&g.tasks_out[self.ch.number()]) + #[cfg(feature = "_ppi")] + let reg = &g.tasks_out[self.ch.number()]; + #[cfg(feature = "_dppi")] + let reg = &g.subscribe_out[self.ch.number()]; + Task::from_reg(reg) } /// Returns the CLR task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_clr(&self) -> Task { let g = unsafe { &*pac::GPIOTE::ptr() }; - Task::from_reg(&g.tasks_clr[self.ch.number()]) + #[cfg(feature = "_ppi")] + let reg = &g.tasks_clr[self.ch.number()]; + #[cfg(feature = "_dppi")] + let reg = &g.subscribe_clr[self.ch.number()]; + Task::from_reg(reg) } /// Returns the SET task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_set(&self) -> Task { let g = unsafe { &*pac::GPIOTE::ptr() }; - Task::from_reg(&g.tasks_set[self.ch.number()]) + #[cfg(feature = "_ppi")] + let reg = &g.tasks_set[self.ch.number()]; + #[cfg(feature = "_dppi")] + let reg = &g.subscribe_set[self.ch.number()]; + Task::from_reg(reg) } } diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs index f5e06c69f..822663ea2 100644 --- a/embassy-nrf/src/ppi.rs +++ b/embassy-nrf/src/ppi.rs @@ -20,6 +20,16 @@ use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; // ====================== // driver +#[non_exhaustive] +#[derive(Clone, Debug)] +pub enum Error { + NoCapacityLeft, + UnknownTask, + TaskAlreadyInUse, + UnknownEvent, + EventAlreadyInUse, +} + pub struct Ppi<'d, C: Channel> { ch: C, phantom: PhantomData<&'d mut C>, @@ -29,14 +39,10 @@ impl<'d, C: Channel> Ppi<'d, C> { pub fn new(ch: impl Unborrow + 'd) -> Self { unborrow!(ch); - #[allow(unused_mut)] - let mut this = Self { + Self { ch, phantom: PhantomData, - }; - #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))] - this.clear_fork_task(); - this + } } /// Enables the channel. @@ -52,35 +58,279 @@ impl<'d, C: Channel> Ppi<'d, C> { r.chenclr .write(|w| unsafe { w.bits(1 << self.ch.number()) }); } +} - #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))] - /// Sets the fork task that must be triggered when the configured event occurs. The user must - /// provide a reference to the task. - pub fn set_fork_task(&mut self, task: Task) { +#[cfg(feature = "_ppi")] +impl<'d, C: Channel> Ppi<'d, C> { + /// Makes it so that the given task is subscribed to this channel + pub fn subscribe(&mut self, task: Task) -> Result<(), Error> { + if self.is_main_task_free() { + self.set_main_task(Some(task)); + Ok(()) + } else if self.is_fork_task_free() { + self.set_fork_task(Some(task)); + Ok(()) + } else { + Err(Error::NoCapacityLeft) + } + } + + /// Makes it so that the given task is not subscribed to this channel + pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> { + if self.get_main_task() == Some(task) { + // If there is a fork task, we move that to the main task for consistency + // If there is no fork task, then the main task is set to 0 + let fork_task = self.get_fork_task(); + self.set_main_task(fork_task); + + if self.has_fork_task() { + // The fork task was copied to the main task, so reset the fork task + self.set_fork_task(None); + } + Ok(()) + } else if self.get_fork_task() == Some(task) { + // Reset the fork task + self.set_fork_task(None); + Ok(()) + } else { + Err(Error::UnknownTask) + } + } + + /// Makes it so that the given event is published on this channel + pub fn publish(&mut self, event: Event) -> Result<(), Error> { + if self.is_event_free() { + self.set_event(Some(event)); + Ok(()) + } else { + Err(Error::NoCapacityLeft) + } + } + + /// Makes it so that the given event is not published on this channel + pub fn unpublish(&mut self, event: Event) -> Result<(), Error> { + if self.get_event() == Some(event) { + self.set_event(None); + Ok(()) + } else { + Err(Error::UnknownEvent) + } + } + + fn set_main_task(&mut self, task: Option) { let r = unsafe { &*pac::PPI::ptr() }; - r.fork[self.ch.number()] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) + if let Some(task) = task { + r.ch[self.ch.number()] + .tep + .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) + } else { + r.ch[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) + } } - #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))] - /// Clear the fork task endpoint. Previously set task will no longer be triggered. - pub fn clear_fork_task(&mut self) { + fn get_main_task(&mut self) -> Option { let r = unsafe { &*pac::PPI::ptr() }; - r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) + + if !self.has_main_task() { + return None; + } + + let bits = r.ch[self.ch.number()].tep.read().tep().bits(); + + if bits == 0 { + None + } else { + unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) } + } } - #[cfg(feature = "nrf9160")] - /// Sets the fork task that must be triggered when the configured event occurs. The user must - /// provide a reference to the task. - pub fn set_fork_task(&mut self, _task: Task) { - todo!("Tasks not yet implemented for nrf9160"); + fn set_fork_task(&mut self, task: Option) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(task) = task { + r.fork[self.ch.number()] + .tep + .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) + } else { + r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) + } } - #[cfg(feature = "nrf9160")] - /// Clear the fork task endpoint. Previously set task will no longer be triggered. - pub fn clear_fork_task(&mut self) { - todo!("Tasks not yet implemented for nrf9160"); + fn get_fork_task(&mut self) -> Option { + let r = unsafe { &*pac::PPI::ptr() }; + + if !self.has_fork_task() { + return None; + } + + let bits = r.fork[self.ch.number()].tep.read().tep().bits(); + + if bits == 0 { + None + } else { + unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) } + } + } + + fn has_main_task(&self) -> bool { + match (self.ch.task_capacity(), self.ch.event_capacity()) { + (0, 0) => false, // Static task + (1, 0) => false, // Static task with fork + (1 | 2, 1) => true, // Configurable task with possibly a fork + _ => unreachable!(), // Every PPI config is covered + } + } + + fn has_fork_task(&self) -> bool { + match (self.ch.task_capacity(), self.ch.event_capacity()) { + (0, 0) => false, // Static task + (1, 0) => true, // Static task with fork + (1, 1) => false, // Configurable task without fork + (2, 1) => true, // Configurable task with fork + _ => unreachable!(), // Every PPI config is covered + } + } + + fn is_main_task_free(&mut self) -> bool { + self.get_main_task().is_none() + } + + fn is_fork_task_free(&mut self) -> bool { + self.get_fork_task().is_none() + } + + fn set_event(&mut self, event: Option) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(event) = event { + r.ch[self.ch.number()] + .eep + .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) + } else { + r.ch[self.ch.number()].eep.write(|w| unsafe { w.bits(0) }) + } + } + + fn get_event(&mut self) -> Option { + let r = unsafe { &*pac::PPI::ptr() }; + + if !self.has_event() { + return None; + } + + let bits = r.ch[self.ch.number()].eep.read().eep().bits(); + + if bits == 0 { + None + } else { + unsafe { Some(Event(NonNull::new_unchecked(bits as *mut _))) } + } + } + + fn has_event(&self) -> bool { + match (self.ch.task_capacity(), self.ch.event_capacity()) { + (_, 0) => false, // Static event + (_, 1) => true, // Configurable event + _ => unreachable!(), // Every PPI config is covered + } + } + + fn is_event_free(&mut self) -> bool { + self.get_event().is_none() + } +} + +#[cfg(feature = "_dppi")] +const DPPI_ENABLE_BIT: u32 = 0x8000_0000; +#[cfg(feature = "_dppi")] +const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; + +#[cfg(feature = "_dppi")] +impl<'d, C: Channel> Ppi<'d, C> { + /// Makes it so that the given task is subscribed to this channel + pub fn subscribe(&mut self, task: Task) -> Result<(), Error> { + unsafe { + if Self::is_register_enabled(task.0) { + Err(Error::TaskAlreadyInUse) + } else { + Self::set_register_active(task.0, self.ch.number() as u8); + Ok(()) + } + } + } + + /// Makes it so that the given task is not subscribed to this channel + pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> { + unsafe { + if Self::get_register_channel(task.0) != self.ch.number() as u8 { + Err(Error::UnknownTask) + } else { + Self::set_register_inactive(task.0); + Ok(()) + } + } + } + + /// Makes it so that the given event is published on this channel + pub fn publish(&mut self, event: Event) -> Result<(), Error> { + unsafe { + if Self::is_register_enabled(event.0) { + Err(Error::TaskAlreadyInUse) + } else { + Self::set_register_active(event.0, self.ch.number() as u8); + Ok(()) + } + } + } + + /// Makes it so that the given event is not published on this channel + pub fn unpublish(&mut self, event: Event) -> Result<(), Error> { + unsafe { + if Self::get_register_channel(event.0) != self.ch.number() as u8 { + Err(Error::UnknownTask) + } else { + Self::set_register_inactive(event.0); + Ok(()) + } + } + } + + /// Checks if the DPPI_ENABLE_BIT is set in the register + /// + /// # Safety + /// + /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals + unsafe fn is_register_enabled(register: NonNull) -> bool { + let bits = register.as_ptr().read_volatile(); + bits & DPPI_ENABLE_BIT > 0 + } + + /// Sets the register to the given channel and enables it + /// + /// # Safety + /// + /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals + unsafe fn set_register_active(register: NonNull, channel: u8) { + register + .as_ptr() + .write_volatile(DPPI_ENABLE_BIT | (channel as u32 & DPPI_CHANNEL_MASK)); + } + + /// Resets the channel number and disables the register + /// + /// # Safety + /// + /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals + unsafe fn set_register_inactive(register: NonNull) { + register.as_ptr().write_volatile(0); + } + + /// Gets the current configured channel number of the register + /// + /// # Safety + /// + /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals + unsafe fn get_register_channel(register: NonNull) -> u8 { + let bits = register.as_ptr().read_volatile(); + (bits & DPPI_CHANNEL_MASK) as u8 } } @@ -90,73 +340,59 @@ impl<'d, C: Channel> Drop for Ppi<'d, C> { } } -#[cfg(not(feature = "nrf9160"))] -impl<'d, C: ConfigurableChannel> Ppi<'d, C> { - /// Sets the task to be triggered when the configured event occurs. - pub fn set_task(&mut self, task: Task) { - let r = unsafe { &*pac::PPI::ptr() }; - r.ch[self.ch.number()] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) - } - - /// Sets the event that will trigger the chosen task(s). - pub fn set_event(&mut self, event: Event) { - let r = unsafe { &*pac::PPI::ptr() }; - r.ch[self.ch.number()] - .eep - .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) +/// Represents a task that a peripheral can do. +/// When a task is subscribed to a PPI channel it will run when the channel is triggered by +/// a published event. +/// +/// The pointer in the task can point to two different kinds of register: +/// - PPI *(nRF51 & nRF52)*: A pointer to a task register of the task of the peripheral that has +/// to be registered with the PPI to subscribe to a channel +/// - DPPI *(nRF53 & nRF91)*: A pointer to the subscribe register of the task of the peripheral +/// that has to have the channel number and enable bit written tp it to subscribe to a channel +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct Task(pub NonNull); +impl Task { + pub(crate) fn from_reg(reg: &T) -> Self { + Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) } } -#[cfg(feature = "nrf9160")] -impl<'d, C: ConfigurableChannel> Ppi<'d, C> { - /// Sets the task to be triggered when the configured event occurs. - pub fn set_task(&mut self, _task: Task) { - todo!("Tasks not yet implemented for nrf9160") - } - - /// Sets the event that will trigger the chosen task(s). - pub fn set_event(&mut self, _event: Event) { - todo!("Events not yet implemented for nrf9160") +/// Represents an event that a peripheral can publish. +/// An event can be set to publish on a PPI channel when the event happens. +/// +/// The pointer in the event can point to two different kinds of register: +/// - PPI *(nRF51 & nRF52)*: A pointer to an event register of the event of the peripheral that has +/// to be registered with the PPI to publish to a channel +/// - DPPI *(nRF53 & nRF91)*: A pointer to the publish register of the event of the peripheral +/// that has to have the channel number and enable bit written tp it to publish to a channel +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct Event(pub NonNull); +impl Event { + pub(crate) fn from_reg(reg: &T) -> Self { + Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) } } // ====================== // traits -pub struct Task(pub NonNull<()>); -impl Task { - pub(crate) fn from_reg(reg: &T) -> Self { - Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut ()) }) - } -} - -pub struct Event(pub NonNull<()>); -impl Event { - pub(crate) fn from_reg(reg: &T) -> Self { - Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut ()) }) - } -} - pub(crate) mod sealed { - pub trait ConfigurableChannel {} pub trait Channel {} pub trait Group {} } pub trait Channel: sealed::Channel + Sized { fn number(&self) -> usize; + fn task_capacity(&self) -> usize; + fn event_capacity(&self) -> usize; + fn degrade(self) -> AnyChannel { + pub trait ConfigurableChannel {} + AnyChannel { number: self.number() as u8, - } - } -} -pub trait ConfigurableChannel: Channel + sealed::ConfigurableChannel { - fn degrade_configurable(self) -> AnyConfigurableChannel { - AnyConfigurableChannel { - number: self.number() as u8, + task_capacity: self.task_capacity() as _, + event_capacity: self.event_capacity() as _, } } } @@ -175,6 +411,8 @@ pub trait Group: sealed::Group + Sized { pub struct AnyChannel { number: u8, + task_capacity: u8, + event_capacity: u8, } unsafe_impl_unborrow!(AnyChannel); impl sealed::Channel for AnyChannel {} @@ -182,26 +420,30 @@ impl Channel for AnyChannel { fn number(&self) -> usize { self.number as usize } -} -pub struct AnyConfigurableChannel { - number: u8, -} -unsafe_impl_unborrow!(AnyConfigurableChannel); -impl sealed::Channel for AnyConfigurableChannel {} -impl sealed::ConfigurableChannel for AnyConfigurableChannel {} -impl ConfigurableChannel for AnyConfigurableChannel {} -impl Channel for AnyConfigurableChannel { - fn number(&self) -> usize { - self.number as usize + fn task_capacity(&self) -> usize { + self.task_capacity as _ + } + + fn event_capacity(&self) -> usize { + self.event_capacity as _ } } macro_rules! impl_ppi_channel { - ($type:ident, $number:expr, configurable) => { - impl_ppi_channel!($type, $number); - impl crate::ppi::sealed::ConfigurableChannel for peripherals::$type {} - impl crate::ppi::ConfigurableChannel for peripherals::$type {} + ($type:ident, $number:expr, $task_capacity:expr, $event_capacity:expr) => { + impl crate::ppi::sealed::Channel for peripherals::$type {} + impl crate::ppi::Channel for peripherals::$type { + fn number(&self) -> usize { + $number + } + fn task_capacity(&self) -> usize { + $task_capacity + } + fn event_capacity(&self) -> usize { + $event_capacity + } + } }; ($type:ident, $number:expr) => { impl crate::ppi::sealed::Channel for peripherals::$type {} @@ -209,6 +451,12 @@ macro_rules! impl_ppi_channel { fn number(&self) -> usize { $number } + fn task_capacity(&self) -> usize { + usize::MAX + } + fn event_capacity(&self) -> usize { + usize::MAX + } } }; } diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 5690ff0d8..e62120aef 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -184,21 +184,36 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { /// /// When triggered, this task starts the timer. pub fn task_start(&self) -> Task { - Task::from_reg(&T::regs().tasks_start) + #[cfg(feature = "_ppi")] + let reg = &T::regs().tasks_start; + #[cfg(feature = "_dppi")] + let reg = &T::regs().subscribe_start; + + Task::from_reg(reg) } /// Returns the STOP task, for use with PPI. /// /// When triggered, this task stops the timer. pub fn task_stop(&self) -> Task { - Task::from_reg(&T::regs().tasks_stop) + #[cfg(feature = "_ppi")] + let reg = &T::regs().tasks_stop; + #[cfg(feature = "_dppi")] + let reg = &T::regs().subscribe_stop; + + Task::from_reg(reg) } /// Returns the CLEAR task, for use with PPI. /// /// When triggered, this task resets the timer's counter to 0. pub fn task_clear(&self) -> Task { - Task::from_reg(&T::regs().tasks_clear) + #[cfg(feature = "_ppi")] + let reg = &T::regs().tasks_clear; + #[cfg(feature = "_dppi")] + let reg = &T::regs().subscribe_clear; + + Task::from_reg(reg) } /// Change the timer's frequency. @@ -319,14 +334,24 @@ impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { /// /// When triggered, this task will capture the current value of the timer's counter in this register. pub fn task_capture(&self) -> Task { - Task::from_reg(&T::regs().tasks_capture[self.n]) + #[cfg(feature = "_ppi")] + let reg = &T::regs().tasks_capture; + #[cfg(feature = "_dppi")] + let reg = &T::regs().subscribe_capture; + + Task::from_reg(reg) } /// Returns this CC register's COMPARE event, for use with PPI. /// /// This event will fire when the timer's counter reaches the value in this CC register. pub fn event_compare(&self) -> Event { - Event::from_reg(&T::regs().events_compare[self.n]) + #[cfg(feature = "_ppi")] + let reg = &T::regs().events_compare[self.n]; + #[cfg(feature = "_dppi")] + let reg = &T::regs().publish_compare[self.n]; + + Event::from_reg(reg) } /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 63bbe5a77..f2bf01f1f 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -7,7 +7,7 @@ use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy::interrupt::InterruptExt; -use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write}; +use embassy::traits::uart::{Error as TraitError, Read, ReadUntilIdle, Write}; use embassy::util::Unborrow; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::unborrow; @@ -18,13 +18,25 @@ use crate::gpio::sealed::Pin as _; use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; use crate::interrupt::Interrupt; use crate::pac; -use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; +use crate::ppi::{AnyChannel, Channel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; // 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}; +#[non_exhaustive] +#[derive(Clone, Debug)] +pub enum Error { + PpiError(crate::ppi::Error), +} + +impl From for Error { + fn from(e: crate::ppi::Error) -> Self { + Self::PpiError(e) + } +} + #[non_exhaustive] pub struct Config { pub parity: Parity, @@ -219,7 +231,7 @@ impl<'a, T: Instance> Drop for Uarte<'a, T> { impl<'d, T: Instance> Read for Uarte<'d, T> { #[rustfmt::skip] - type ReadFuture<'a> where Self: 'a = impl Future> + 'a; + type ReadFuture<'a> where Self: 'a = impl Future> + 'a; fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { async move { @@ -273,7 +285,7 @@ impl<'d, T: Instance> Read for Uarte<'d, T> { impl<'d, T: Instance> Write for Uarte<'d, T> { #[rustfmt::skip] - type WriteFuture<'a> where Self: 'a = impl Future> + 'a; + type WriteFuture<'a> where Self: 'a = impl Future> + 'a; fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { async move { @@ -331,14 +343,17 @@ impl<'d, T: Instance> Write for Uarte<'d, T> { pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { uarte: Uarte<'d, U>, timer: Timer<'d, T>, - ppi_ch1: Ppi<'d, AnyConfigurableChannel>, - _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, + ppi_ch1: Ppi<'d, AnyChannel>, + _ppi_ch2: Ppi<'d, AnyChannel>, } impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { /// Creates the interface to a UARTE instance. /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. /// + /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned + /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned + /// /// # Safety /// /// The returned API is safe unless you use `mem::forget` (or similar safe mechanisms) @@ -348,15 +363,15 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { pub unsafe fn new( uarte: impl Unborrow + 'd, timer: impl Unborrow + 'd, - ppi_ch1: impl Unborrow + 'd, - ppi_ch2: impl Unborrow + 'd, + ppi_ch1: impl Unborrow + 'd, + ppi_ch2: impl Unborrow + 'd, irq: impl Unborrow + 'd, rxd: impl Unborrow + 'd, txd: impl Unborrow + 'd, cts: impl Unborrow + 'd, rts: impl Unborrow + 'd, config: Config, - ) -> Self { + ) -> Result { let baudrate = config.baudrate; let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); let mut timer = Timer::new(timer); @@ -378,29 +393,29 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { timer.cc(0).short_compare_clear(); timer.cc(0).short_compare_stop(); - let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); - ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); - ppi_ch1.set_task(timer.task_clear()); - ppi_ch1.set_fork_task(timer.task_start()); + let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); + ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; + ppi_ch1.subscribe(timer.task_clear())?; + ppi_ch1.subscribe(timer.task_start())?; ppi_ch1.enable(); - let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); - ppi_ch2.set_event(timer.cc(0).event_compare()); - ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); + let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); + ppi_ch2.publish(timer.cc(0).event_compare())?; + ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; ppi_ch2.enable(); - Self { + Ok(Self { uarte, timer, ppi_ch1: ppi_ch1, _ppi_ch2: ppi_ch2, - } + }) } } impl<'d, U: Instance, T: TimerInstance> ReadUntilIdle for UarteWithIdle<'d, U, T> { #[rustfmt::skip] - type ReadUntilIdleFuture<'a> where Self: 'a = impl Future> + 'a; + type ReadUntilIdleFuture<'a> where Self: 'a = impl Future> + 'a; fn read_until_idle<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a> { async move { let ptr = rx_buffer.as_ptr(); @@ -460,7 +475,7 @@ impl<'d, U: Instance, T: TimerInstance> ReadUntilIdle for UarteWithIdle<'d, U, T impl<'d, U: Instance, T: TimerInstance> Read for UarteWithIdle<'d, U, T> { #[rustfmt::skip] - type ReadFuture<'a> where Self: 'a = impl Future> + 'a; + type ReadFuture<'a> where Self: 'a = impl Future> + 'a; fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { async move { self.ppi_ch1.disable(); @@ -473,7 +488,7 @@ impl<'d, U: Instance, T: TimerInstance> Read for UarteWithIdle<'d, U, T> { impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> { #[rustfmt::skip] - type WriteFuture<'a> where Self: 'a = impl Future> + 'a; + type WriteFuture<'a> where Self: 'a = impl Future> + 'a; fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { self.uarte.write(tx_buffer) diff --git a/examples/nrf/src/bin/ppi.rs b/examples/nrf/src/bin/ppi.rs index 6ea03ebd0..550893968 100644 --- a/examples/nrf/src/bin/ppi.rs +++ b/examples/nrf/src/bin/ppi.rs @@ -52,24 +52,24 @@ async fn main(_spawner: Spawner, p: Peripherals) { ); let mut ppi = Ppi::new(p.PPI_CH0); - ppi.set_event(button1.event_in()); - ppi.set_task(led1.task_out()); + ppi.publish(button1.event_in()).unwrap(); + ppi.subscribe(led1.task_out()).unwrap(); ppi.enable(); let mut ppi = Ppi::new(p.PPI_CH1); - ppi.set_event(button2.event_in()); - ppi.set_task(led1.task_clr()); + ppi.publish(button2.event_in()).unwrap(); + ppi.subscribe(led1.task_clr()).unwrap(); ppi.enable(); let mut ppi = Ppi::new(p.PPI_CH2); - ppi.set_event(button3.event_in()); - ppi.set_task(led1.task_set()); + ppi.publish(button3.event_in()).unwrap(); + ppi.subscribe(led1.task_set()).unwrap(); ppi.enable(); let mut ppi = Ppi::new(p.PPI_CH3); - ppi.set_event(button4.event_in()); - ppi.set_task(led1.task_out()); - ppi.set_fork_task(led2.task_out()); + ppi.publish(button4.event_in()).unwrap(); + ppi.subscribe(led1.task_out()).unwrap(); + ppi.subscribe(led2.task_out()).unwrap(); ppi.enable(); info!("PPI setup!"); From 4950682a50c8561124462cd7d774a72626271294 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Thu, 14 Oct 2021 14:45:57 +0200 Subject: [PATCH 02/10] Some extra docs and better naming --- embassy-nrf/src/ppi.rs | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs index 822663ea2..1f825bf47 100644 --- a/embassy-nrf/src/ppi.rs +++ b/embassy-nrf/src/ppi.rs @@ -20,14 +20,16 @@ use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; // ====================== // driver +/// Error type of the PPI driver #[non_exhaustive] #[derive(Clone, Debug)] pub enum Error { + /// There is no capacity to enable this task or event (nRF51 & nRF52 only) NoCapacityLeft, - UnknownTask, - TaskAlreadyInUse, - UnknownEvent, - EventAlreadyInUse, + /// This task or event is not in use by the current channel + NotInUseByChannel, + /// This task or event is already enabled on another channel (nRF53 & nRF91 only) + AlreadyInUse, } pub struct Ppi<'d, C: Channel> { @@ -93,7 +95,7 @@ impl<'d, C: Channel> Ppi<'d, C> { self.set_fork_task(None); Ok(()) } else { - Err(Error::UnknownTask) + Err(Error::NotInUseByChannel) } } @@ -113,7 +115,7 @@ impl<'d, C: Channel> Ppi<'d, C> { self.set_event(None); Ok(()) } else { - Err(Error::UnknownEvent) + Err(Error::NotInUseByChannel) } } @@ -249,7 +251,7 @@ impl<'d, C: Channel> Ppi<'d, C> { pub fn subscribe(&mut self, task: Task) -> Result<(), Error> { unsafe { if Self::is_register_enabled(task.0) { - Err(Error::TaskAlreadyInUse) + Err(Error::AlreadyInUse) } else { Self::set_register_active(task.0, self.ch.number() as u8); Ok(()) @@ -261,7 +263,7 @@ impl<'d, C: Channel> Ppi<'d, C> { pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> { unsafe { if Self::get_register_channel(task.0) != self.ch.number() as u8 { - Err(Error::UnknownTask) + Err(Error::NotInUseByChannel) } else { Self::set_register_inactive(task.0); Ok(()) @@ -273,7 +275,7 @@ impl<'d, C: Channel> Ppi<'d, C> { pub fn publish(&mut self, event: Event) -> Result<(), Error> { unsafe { if Self::is_register_enabled(event.0) { - Err(Error::TaskAlreadyInUse) + Err(Error::AlreadyInUse) } else { Self::set_register_active(event.0, self.ch.number() as u8); Ok(()) @@ -285,7 +287,7 @@ impl<'d, C: Channel> Ppi<'d, C> { pub fn unpublish(&mut self, event: Event) -> Result<(), Error> { unsafe { if Self::get_register_channel(event.0) != self.ch.number() as u8 { - Err(Error::UnknownTask) + Err(Error::NotInUseByChannel) } else { Self::set_register_inactive(event.0); Ok(()) @@ -382,8 +384,22 @@ pub(crate) mod sealed { } pub trait Channel: sealed::Channel + Sized { + /// Returns the number of the channel fn number(&self) -> usize; + + /// Returns the amount of configurable tasks this channel has. + /// + /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91) + /// - 0 for static channel without fork (nRF51) + /// - 1 for static channel with fork (nRF52) or for configurable channel (nRF51) + /// - 2 for configurable channel with fork (nRF52) fn task_capacity(&self) -> usize; + + /// Returns the amount of configurable events this channels has + /// + /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91) + /// - 0 for static channel (nRF51 & nRF52) + /// - 1 for configurable channel (nRF51 & nRF52) fn event_capacity(&self) -> usize; fn degrade(self) -> AnyChannel { From e6ec81b999541cca847b50075ac0d5d826f97dcd Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Thu, 14 Oct 2021 15:13:45 +0200 Subject: [PATCH 03/10] Fixed examples and added defmt format to the new error types --- embassy-nrf/src/buffered_uarte.rs | 1 + embassy-nrf/src/ppi.rs | 1 + embassy-nrf/src/uarte.rs | 1 + examples/nrf/src/bin/buffered_uart.rs | 4 ++-- examples/nrf/src/bin/uart_idle.rs | 4 ++-- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index f7e55e428..8ec0fb2ce 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -25,6 +25,7 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari #[non_exhaustive] #[derive(Clone, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { PpiError(ppi::Error), } diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs index 1f825bf47..7aaf17ee5 100644 --- a/embassy-nrf/src/ppi.rs +++ b/embassy-nrf/src/ppi.rs @@ -23,6 +23,7 @@ use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; /// Error type of the PPI driver #[non_exhaustive] #[derive(Clone, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { /// There is no capacity to enable this task or event (nRF51 & nRF52 only) NoCapacityLeft, diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index f2bf01f1f..71401a561 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -27,6 +27,7 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari #[non_exhaustive] #[derive(Clone, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { PpiError(crate::ppi::Error), } diff --git a/examples/nrf/src/bin/buffered_uart.rs b/examples/nrf/src/bin/buffered_uart.rs index 69c7de93b..b01c83ce3 100644 --- a/examples/nrf/src/bin/buffered_uart.rs +++ b/examples/nrf/src/bin/buffered_uart.rs @@ -26,7 +26,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { let irq = interrupt::take!(UARTE0_UART0); let mut state = State::new(); let u = unsafe { - BufferedUarte::new( + unwrap!(BufferedUarte::new( &mut state, p.UARTE0, p.TIMER0, @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { config, &mut rx_buffer, &mut tx_buffer, - ) + )) }; pin_mut!(u); diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs index e9f4a285a..e04e5cf04 100644 --- a/examples/nrf/src/bin/uart_idle.rs +++ b/examples/nrf/src/bin/uart_idle.rs @@ -21,9 +21,9 @@ async fn main(_spawner: Spawner, p: Peripherals) { let irq = interrupt::take!(UARTE0_UART0); let mut uart = unsafe { - uarte::UarteWithIdle::new( + unwrap!(uarte::UarteWithIdle::new( p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config, - ) + )) }; info!("uarte initialized!"); From 11655af034538b463ff8220714e9b97cf53f8f56 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 18 Oct 2021 16:23:39 +0200 Subject: [PATCH 04/10] Another redo using the feedback. PPI is now split up into PPI and DPPI under the name 'interconnect'. The tasks and events are tracked and reset in the drop function. --- embassy-nrf/src/buffered_uarte.rs | 54 ++- embassy-nrf/src/chips/nrf52805.rs | 44 +-- embassy-nrf/src/chips/nrf52810.rs | 64 ++-- embassy-nrf/src/chips/nrf52811.rs | 64 ++-- embassy-nrf/src/chips/nrf52820.rs | 64 ++-- embassy-nrf/src/chips/nrf52832.rs | 64 ++-- embassy-nrf/src/chips/nrf52833.rs | 64 ++-- embassy-nrf/src/chips/nrf52840.rs | 64 ++-- embassy-nrf/src/chips/nrf9160.rs | 32 +- embassy-nrf/src/gpiote.rs | 28 +- embassy-nrf/src/interconnect/dppi.rs | 47 +++ embassy-nrf/src/interconnect/mod.rs | 318 ++++++++++++++++ embassy-nrf/src/interconnect/ppi.rs | 65 ++++ embassy-nrf/src/lib.rs | 2 +- embassy-nrf/src/ppi.rs | 513 -------------------------- embassy-nrf/src/timer.rs | 38 +- embassy-nrf/src/uarte.rs | 52 ++- examples/nrf/src/bin/buffered_uart.rs | 4 +- examples/nrf/src/bin/ppi.rs | 24 +- examples/nrf/src/bin/uart_idle.rs | 4 +- 20 files changed, 729 insertions(+), 880 deletions(-) create mode 100644 embassy-nrf/src/interconnect/dppi.rs create mode 100644 embassy-nrf/src/interconnect/mod.rs create mode 100644 embassy-nrf/src/interconnect/ppi.rs delete mode 100644 embassy-nrf/src/ppi.rs diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 8ec0fb2ce..7c9a2344e 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -14,28 +14,15 @@ use embassy_hal_common::{low_power_wait_until, unborrow}; use crate::gpio::sealed::Pin as _; use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; -use crate::ppi::{AnyChannel, Channel, Event, Ppi, Task}; +use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; +use crate::pac; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; use crate::uarte::{Config, Instance as UarteInstance}; -use crate::{pac, ppi}; // 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}; -#[non_exhaustive] -#[derive(Clone, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Error { - PpiError(ppi::Error), -} - -impl From for Error { - fn from(e: ppi::Error) -> Self { - Self::PpiError(e) - } -} - #[derive(Copy, Clone, Debug, PartialEq)] enum RxState { Idle, @@ -58,8 +45,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> { struct StateInner<'d, U: UarteInstance, T: TimerInstance> { phantom: PhantomData<&'d mut U>, timer: Timer<'d, T>, - _ppi_ch1: Ppi<'d, AnyChannel>, - _ppi_ch2: Ppi<'d, AnyChannel>, + _ppi_ch1: Ppi<'d, AnyChannel, 1, 2>, + _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>, rx: RingBuffer<'d>, rx_state: RxState, @@ -79,15 +66,12 @@ impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> { impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { /// unsafe: may not leak self or futures - /// - /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned - /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned pub unsafe fn new( state: &'d mut State<'d, U, T>, _uarte: impl Unborrow + 'd, timer: impl Unborrow + 'd, - ppi_ch1: impl Unborrow + 'd, - ppi_ch2: impl Unborrow + 'd, + ppi_ch1: impl Unborrow + 'd, + ppi_ch2: impl Unborrow + 'd, irq: impl Unborrow + 'd, rxd: impl Unborrow + 'd, txd: impl Unborrow + 'd, @@ -96,7 +80,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { config: Config, rx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8], - ) -> Result { + ) -> Self { unborrow!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); let r = U::regs(); @@ -160,18 +144,24 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { timer.cc(0).short_compare_clear(); timer.cc(0).short_compare_stop(); - let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); - ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; - ppi_ch1.subscribe(timer.task_clear())?; - ppi_ch1.subscribe(timer.task_start())?; + let mut ppi_ch1 = Ppi::new_one_to_two( + ppi_ch1, + Event::from_reg(&r.events_rxdrdy), + timer.task_clear(), + timer.task_start(), + ) + .degrade(); ppi_ch1.enable(); - let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); - ppi_ch2.publish(timer.cc(0).event_compare())?; - ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; + let mut ppi_ch2 = Ppi::new_one_to_one( + ppi_ch2, + timer.cc(0).event_compare(), + Task::from_reg(&r.tasks_stoprx), + ) + .degrade(); ppi_ch2.enable(); - Ok(Self { + Self { inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner { phantom: PhantomData, timer, @@ -186,7 +176,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { tx_state: TxState::Idle, tx_waker: WakerRegistration::new(), }), - }) + } } pub fn set_baudrate(&mut self, baudrate: Baudrate) { diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index 03fc5f307..326f4a8be 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs @@ -167,28 +167,28 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, 2, 1); -impl_ppi_channel!(PPI_CH1, 1, 2, 1); -impl_ppi_channel!(PPI_CH2, 2, 2, 1); -impl_ppi_channel!(PPI_CH3, 3, 2, 1); -impl_ppi_channel!(PPI_CH4, 4, 2, 1); -impl_ppi_channel!(PPI_CH5, 5, 2, 1); -impl_ppi_channel!(PPI_CH6, 6, 2, 1); -impl_ppi_channel!(PPI_CH7, 7, 2, 1); -impl_ppi_channel!(PPI_CH8, 8, 2, 1); -impl_ppi_channel!(PPI_CH9, 9, 2, 1); -impl_ppi_channel!(PPI_CH20, 20, 1, 0); -impl_ppi_channel!(PPI_CH21, 21, 1, 0); -impl_ppi_channel!(PPI_CH22, 22, 1, 0); -impl_ppi_channel!(PPI_CH23, 23, 1, 0); -impl_ppi_channel!(PPI_CH24, 24, 1, 0); -impl_ppi_channel!(PPI_CH25, 25, 1, 0); -impl_ppi_channel!(PPI_CH26, 26, 1, 0); -impl_ppi_channel!(PPI_CH27, 27, 1, 0); -impl_ppi_channel!(PPI_CH28, 28, 1, 0); -impl_ppi_channel!(PPI_CH29, 29, 1, 0); -impl_ppi_channel!(PPI_CH30, 30, 1, 0); -impl_ppi_channel!(PPI_CH31, 31, 1, 0); +impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); +impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); +impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); +impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); +impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); +impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); +impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); +impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); +impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); +impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); +impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); +impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); +impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); +impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); +impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); +impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); +impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); +impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); +impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); +impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); +impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); +impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); impl_saadc_input!(P0_04, ANALOGINPUT2); impl_saadc_input!(P0_05, ANALOGINPUT3); diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index e317e4c54..4c16d51a7 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs @@ -172,38 +172,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, 2, 1); -impl_ppi_channel!(PPI_CH1, 1, 2, 1); -impl_ppi_channel!(PPI_CH2, 2, 2, 1); -impl_ppi_channel!(PPI_CH3, 3, 2, 1); -impl_ppi_channel!(PPI_CH4, 4, 2, 1); -impl_ppi_channel!(PPI_CH5, 5, 2, 1); -impl_ppi_channel!(PPI_CH6, 6, 2, 1); -impl_ppi_channel!(PPI_CH7, 7, 2, 1); -impl_ppi_channel!(PPI_CH8, 8, 2, 1); -impl_ppi_channel!(PPI_CH9, 9, 2, 1); -impl_ppi_channel!(PPI_CH10, 10, 2, 1); -impl_ppi_channel!(PPI_CH11, 11, 2, 1); -impl_ppi_channel!(PPI_CH12, 12, 2, 1); -impl_ppi_channel!(PPI_CH13, 13, 2, 1); -impl_ppi_channel!(PPI_CH14, 14, 2, 1); -impl_ppi_channel!(PPI_CH15, 15, 2, 1); -impl_ppi_channel!(PPI_CH16, 16, 2, 1); -impl_ppi_channel!(PPI_CH17, 17, 2, 1); -impl_ppi_channel!(PPI_CH18, 18, 2, 1); -impl_ppi_channel!(PPI_CH19, 19, 2, 1); -impl_ppi_channel!(PPI_CH20, 20, 1, 0); -impl_ppi_channel!(PPI_CH21, 21, 1, 0); -impl_ppi_channel!(PPI_CH22, 22, 1, 0); -impl_ppi_channel!(PPI_CH23, 23, 1, 0); -impl_ppi_channel!(PPI_CH24, 24, 1, 0); -impl_ppi_channel!(PPI_CH25, 25, 1, 0); -impl_ppi_channel!(PPI_CH26, 26, 1, 0); -impl_ppi_channel!(PPI_CH27, 27, 1, 0); -impl_ppi_channel!(PPI_CH28, 28, 1, 0); -impl_ppi_channel!(PPI_CH29, 29, 1, 0); -impl_ppi_channel!(PPI_CH30, 30, 1, 0); -impl_ppi_channel!(PPI_CH31, 31, 1, 0); +impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); +impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); +impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); +impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); +impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); +impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); +impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); +impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); +impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); +impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); +impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); +impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); +impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); +impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); +impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); +impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); +impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); +impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); +impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); +impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); +impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); +impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); +impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); +impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); +impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); +impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); +impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); +impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); +impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); +impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); +impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); +impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 748f5f4ba..0c54d9b9e 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs @@ -173,38 +173,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, 2, 1); -impl_ppi_channel!(PPI_CH1, 1, 2, 1); -impl_ppi_channel!(PPI_CH2, 2, 2, 1); -impl_ppi_channel!(PPI_CH3, 3, 2, 1); -impl_ppi_channel!(PPI_CH4, 4, 2, 1); -impl_ppi_channel!(PPI_CH5, 5, 2, 1); -impl_ppi_channel!(PPI_CH6, 6, 2, 1); -impl_ppi_channel!(PPI_CH7, 7, 2, 1); -impl_ppi_channel!(PPI_CH8, 8, 2, 1); -impl_ppi_channel!(PPI_CH9, 9, 2, 1); -impl_ppi_channel!(PPI_CH10, 10, 2, 1); -impl_ppi_channel!(PPI_CH11, 11, 2, 1); -impl_ppi_channel!(PPI_CH12, 12, 2, 1); -impl_ppi_channel!(PPI_CH13, 13, 2, 1); -impl_ppi_channel!(PPI_CH14, 14, 2, 1); -impl_ppi_channel!(PPI_CH15, 15, 2, 1); -impl_ppi_channel!(PPI_CH16, 16, 2, 1); -impl_ppi_channel!(PPI_CH17, 17, 2, 1); -impl_ppi_channel!(PPI_CH18, 18, 2, 1); -impl_ppi_channel!(PPI_CH19, 19, 2, 1); -impl_ppi_channel!(PPI_CH20, 20, 1, 0); -impl_ppi_channel!(PPI_CH21, 21, 1, 0); -impl_ppi_channel!(PPI_CH22, 22, 1, 0); -impl_ppi_channel!(PPI_CH23, 23, 1, 0); -impl_ppi_channel!(PPI_CH24, 24, 1, 0); -impl_ppi_channel!(PPI_CH25, 25, 1, 0); -impl_ppi_channel!(PPI_CH26, 26, 1, 0); -impl_ppi_channel!(PPI_CH27, 27, 1, 0); -impl_ppi_channel!(PPI_CH28, 28, 1, 0); -impl_ppi_channel!(PPI_CH29, 29, 1, 0); -impl_ppi_channel!(PPI_CH30, 30, 1, 0); -impl_ppi_channel!(PPI_CH31, 31, 1, 0); +impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); +impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); +impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); +impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); +impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); +impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); +impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); +impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); +impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); +impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); +impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); +impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); +impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); +impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); +impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); +impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); +impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); +impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); +impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); +impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); +impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); +impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); +impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); +impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); +impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); +impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); +impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); +impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); +impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); +impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); +impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); +impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 02d2c6103..d52f2f98a 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs @@ -168,38 +168,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, 2, 1); -impl_ppi_channel!(PPI_CH1, 1, 2, 1); -impl_ppi_channel!(PPI_CH2, 2, 2, 1); -impl_ppi_channel!(PPI_CH3, 3, 2, 1); -impl_ppi_channel!(PPI_CH4, 4, 2, 1); -impl_ppi_channel!(PPI_CH5, 5, 2, 1); -impl_ppi_channel!(PPI_CH6, 6, 2, 1); -impl_ppi_channel!(PPI_CH7, 7, 2, 1); -impl_ppi_channel!(PPI_CH8, 8, 2, 1); -impl_ppi_channel!(PPI_CH9, 9, 2, 1); -impl_ppi_channel!(PPI_CH10, 10, 2, 1); -impl_ppi_channel!(PPI_CH11, 11, 2, 1); -impl_ppi_channel!(PPI_CH12, 12, 2, 1); -impl_ppi_channel!(PPI_CH13, 13, 2, 1); -impl_ppi_channel!(PPI_CH14, 14, 2, 1); -impl_ppi_channel!(PPI_CH15, 15, 2, 1); -impl_ppi_channel!(PPI_CH16, 16, 2, 1); -impl_ppi_channel!(PPI_CH17, 17, 2, 1); -impl_ppi_channel!(PPI_CH18, 18, 2, 1); -impl_ppi_channel!(PPI_CH19, 19, 2, 1); -impl_ppi_channel!(PPI_CH20, 20, 1, 0); -impl_ppi_channel!(PPI_CH21, 21, 1, 0); -impl_ppi_channel!(PPI_CH22, 22, 1, 0); -impl_ppi_channel!(PPI_CH23, 23, 1, 0); -impl_ppi_channel!(PPI_CH24, 24, 1, 0); -impl_ppi_channel!(PPI_CH25, 25, 1, 0); -impl_ppi_channel!(PPI_CH26, 26, 1, 0); -impl_ppi_channel!(PPI_CH27, 27, 1, 0); -impl_ppi_channel!(PPI_CH28, 28, 1, 0); -impl_ppi_channel!(PPI_CH29, 29, 1, 0); -impl_ppi_channel!(PPI_CH30, 30, 1, 0); -impl_ppi_channel!(PPI_CH31, 31, 1, 0); +impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); +impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); +impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); +impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); +impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); +impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); +impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); +impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); +impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); +impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); +impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); +impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); +impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); +impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); +impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); +impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); +impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); +impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); +impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); +impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); +impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); +impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); +impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); +impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); +impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); +impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); +impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); +impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); +impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); +impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); +impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); +impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); pub mod irqs { use crate::pac::Interrupt as InterruptEnum; diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index 611dbbd50..d97a65350 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs @@ -190,38 +190,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, 2, 1); -impl_ppi_channel!(PPI_CH1, 1, 2, 1); -impl_ppi_channel!(PPI_CH2, 2, 2, 1); -impl_ppi_channel!(PPI_CH3, 3, 2, 1); -impl_ppi_channel!(PPI_CH4, 4, 2, 1); -impl_ppi_channel!(PPI_CH5, 5, 2, 1); -impl_ppi_channel!(PPI_CH6, 6, 2, 1); -impl_ppi_channel!(PPI_CH7, 7, 2, 1); -impl_ppi_channel!(PPI_CH8, 8, 2, 1); -impl_ppi_channel!(PPI_CH9, 9, 2, 1); -impl_ppi_channel!(PPI_CH10, 10, 2, 1); -impl_ppi_channel!(PPI_CH11, 11, 2, 1); -impl_ppi_channel!(PPI_CH12, 12, 2, 1); -impl_ppi_channel!(PPI_CH13, 13, 2, 1); -impl_ppi_channel!(PPI_CH14, 14, 2, 1); -impl_ppi_channel!(PPI_CH15, 15, 2, 1); -impl_ppi_channel!(PPI_CH16, 16, 2, 1); -impl_ppi_channel!(PPI_CH17, 17, 2, 1); -impl_ppi_channel!(PPI_CH18, 18, 2, 1); -impl_ppi_channel!(PPI_CH19, 19, 2, 1); -impl_ppi_channel!(PPI_CH20, 20, 1, 0); -impl_ppi_channel!(PPI_CH21, 21, 1, 0); -impl_ppi_channel!(PPI_CH22, 22, 1, 0); -impl_ppi_channel!(PPI_CH23, 23, 1, 0); -impl_ppi_channel!(PPI_CH24, 24, 1, 0); -impl_ppi_channel!(PPI_CH25, 25, 1, 0); -impl_ppi_channel!(PPI_CH26, 26, 1, 0); -impl_ppi_channel!(PPI_CH27, 27, 1, 0); -impl_ppi_channel!(PPI_CH28, 28, 1, 0); -impl_ppi_channel!(PPI_CH29, 29, 1, 0); -impl_ppi_channel!(PPI_CH30, 30, 1, 0); -impl_ppi_channel!(PPI_CH31, 31, 1, 0); +impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); +impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); +impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); +impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); +impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); +impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); +impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); +impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); +impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); +impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); +impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); +impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); +impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); +impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); +impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); +impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); +impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); +impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); +impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); +impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); +impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); +impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); +impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); +impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); +impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); +impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); +impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); +impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); +impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); +impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); +impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); +impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 6f70f2a47..9bf370c4b 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs @@ -226,38 +226,38 @@ impl_pin!(P1_13, 1, 13); impl_pin!(P1_14, 1, 14); impl_pin!(P1_15, 1, 15); -impl_ppi_channel!(PPI_CH0, 0, 2, 1); -impl_ppi_channel!(PPI_CH1, 1, 2, 1); -impl_ppi_channel!(PPI_CH2, 2, 2, 1); -impl_ppi_channel!(PPI_CH3, 3, 2, 1); -impl_ppi_channel!(PPI_CH4, 4, 2, 1); -impl_ppi_channel!(PPI_CH5, 5, 2, 1); -impl_ppi_channel!(PPI_CH6, 6, 2, 1); -impl_ppi_channel!(PPI_CH7, 7, 2, 1); -impl_ppi_channel!(PPI_CH8, 8, 2, 1); -impl_ppi_channel!(PPI_CH9, 9, 2, 1); -impl_ppi_channel!(PPI_CH10, 10, 2, 1); -impl_ppi_channel!(PPI_CH11, 11, 2, 1); -impl_ppi_channel!(PPI_CH12, 12, 2, 1); -impl_ppi_channel!(PPI_CH13, 13, 2, 1); -impl_ppi_channel!(PPI_CH14, 14, 2, 1); -impl_ppi_channel!(PPI_CH15, 15, 2, 1); -impl_ppi_channel!(PPI_CH16, 16, 2, 1); -impl_ppi_channel!(PPI_CH17, 17, 2, 1); -impl_ppi_channel!(PPI_CH18, 18, 2, 1); -impl_ppi_channel!(PPI_CH19, 19, 2, 1); -impl_ppi_channel!(PPI_CH20, 20, 1, 0); -impl_ppi_channel!(PPI_CH21, 21, 1, 0); -impl_ppi_channel!(PPI_CH22, 22, 1, 0); -impl_ppi_channel!(PPI_CH23, 23, 1, 0); -impl_ppi_channel!(PPI_CH24, 24, 1, 0); -impl_ppi_channel!(PPI_CH25, 25, 1, 0); -impl_ppi_channel!(PPI_CH26, 26, 1, 0); -impl_ppi_channel!(PPI_CH27, 27, 1, 0); -impl_ppi_channel!(PPI_CH28, 28, 1, 0); -impl_ppi_channel!(PPI_CH29, 29, 1, 0); -impl_ppi_channel!(PPI_CH30, 30, 1, 0); -impl_ppi_channel!(PPI_CH31, 31, 1, 0); +impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); +impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); +impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); +impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); +impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); +impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); +impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); +impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); +impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); +impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); +impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); +impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); +impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); +impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); +impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); +impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); +impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); +impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); +impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); +impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); +impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); +impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); +impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); +impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); +impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); +impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); +impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); +impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); +impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); +impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); +impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); +impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 1b9824151..266328d58 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -231,38 +231,38 @@ impl_pin!(P1_13, 1, 13); impl_pin!(P1_14, 1, 14); impl_pin!(P1_15, 1, 15); -impl_ppi_channel!(PPI_CH0, 0, 2, 1); -impl_ppi_channel!(PPI_CH1, 1, 2, 1); -impl_ppi_channel!(PPI_CH2, 2, 2, 1); -impl_ppi_channel!(PPI_CH3, 3, 2, 1); -impl_ppi_channel!(PPI_CH4, 4, 2, 1); -impl_ppi_channel!(PPI_CH5, 5, 2, 1); -impl_ppi_channel!(PPI_CH6, 6, 2, 1); -impl_ppi_channel!(PPI_CH7, 7, 2, 1); -impl_ppi_channel!(PPI_CH8, 8, 2, 1); -impl_ppi_channel!(PPI_CH9, 9, 2, 1); -impl_ppi_channel!(PPI_CH10, 10, 2, 1); -impl_ppi_channel!(PPI_CH11, 11, 2, 1); -impl_ppi_channel!(PPI_CH12, 12, 2, 1); -impl_ppi_channel!(PPI_CH13, 13, 2, 1); -impl_ppi_channel!(PPI_CH14, 14, 2, 1); -impl_ppi_channel!(PPI_CH15, 15, 2, 1); -impl_ppi_channel!(PPI_CH16, 16, 2, 1); -impl_ppi_channel!(PPI_CH17, 17, 2, 1); -impl_ppi_channel!(PPI_CH18, 18, 2, 1); -impl_ppi_channel!(PPI_CH19, 19, 2, 1); -impl_ppi_channel!(PPI_CH20, 20, 1, 0); -impl_ppi_channel!(PPI_CH21, 21, 1, 0); -impl_ppi_channel!(PPI_CH22, 22, 1, 0); -impl_ppi_channel!(PPI_CH23, 23, 1, 0); -impl_ppi_channel!(PPI_CH24, 24, 1, 0); -impl_ppi_channel!(PPI_CH25, 25, 1, 0); -impl_ppi_channel!(PPI_CH26, 26, 1, 0); -impl_ppi_channel!(PPI_CH27, 27, 1, 0); -impl_ppi_channel!(PPI_CH28, 28, 1, 0); -impl_ppi_channel!(PPI_CH29, 29, 1, 0); -impl_ppi_channel!(PPI_CH30, 30, 1, 0); -impl_ppi_channel!(PPI_CH31, 31, 1, 0); +impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); +impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); +impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); +impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); +impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); +impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); +impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); +impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); +impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); +impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); +impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); +impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); +impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); +impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); +impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); +impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); +impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); +impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); +impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); +impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); +impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); +impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); +impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); +impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); +impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); +impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); +impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); +impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); +impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); +impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); +impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); +impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 42053d081..7357e9e22 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -184,22 +184,22 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0); -impl_ppi_channel!(PPI_CH1, 1); -impl_ppi_channel!(PPI_CH2, 2); -impl_ppi_channel!(PPI_CH3, 3); -impl_ppi_channel!(PPI_CH4, 4); -impl_ppi_channel!(PPI_CH5, 5); -impl_ppi_channel!(PPI_CH6, 6); -impl_ppi_channel!(PPI_CH7, 7); -impl_ppi_channel!(PPI_CH8, 8); -impl_ppi_channel!(PPI_CH9, 9); -impl_ppi_channel!(PPI_CH10, 10); -impl_ppi_channel!(PPI_CH11, 11); -impl_ppi_channel!(PPI_CH12, 12); -impl_ppi_channel!(PPI_CH13, 13); -impl_ppi_channel!(PPI_CH14, 14); -impl_ppi_channel!(PPI_CH15, 15); +impl_ppi_channel!(PPI_CH0, 0, true, many, many); +impl_ppi_channel!(PPI_CH1, 1, true, many, many); +impl_ppi_channel!(PPI_CH2, 2, true, many, many); +impl_ppi_channel!(PPI_CH3, 3, true, many, many); +impl_ppi_channel!(PPI_CH4, 4, true, many, many); +impl_ppi_channel!(PPI_CH5, 5, true, many, many); +impl_ppi_channel!(PPI_CH6, 6, true, many, many); +impl_ppi_channel!(PPI_CH7, 7, true, many, many); +impl_ppi_channel!(PPI_CH8, 8, true, many, many); +impl_ppi_channel!(PPI_CH9, 9, true, many, many); +impl_ppi_channel!(PPI_CH10, 10, true, many, many); +impl_ppi_channel!(PPI_CH11, 11, true, many, many); +impl_ppi_channel!(PPI_CH12, 12, true, many, many); +impl_ppi_channel!(PPI_CH13, 13, true, many, many); +impl_ppi_channel!(PPI_CH14, 14, true, many, many); +impl_ppi_channel!(PPI_CH15, 15, true, many, many); impl_saadc_input!(P0_13, ANALOGINPUT0); impl_saadc_input!(P0_14, ANALOGINPUT1); diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 943ff530b..6703bfc60 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -11,8 +11,8 @@ use futures::future::poll_fn; use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin}; +use crate::interconnect::{Event, Task}; use crate::pac; -use crate::ppi::{Event, Task}; use crate::{interrupt, peripherals}; pub const CHANNEL_COUNT: usize = 8; @@ -190,13 +190,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { /// Returns the IN event, for use with PPI. pub fn event_in(&self) -> Event { let g = unsafe { &*pac::GPIOTE::ptr() }; - - #[cfg(feature = "_ppi")] - let reg = &g.events_in[self.ch.number()]; - #[cfg(feature = "_dppi")] - let reg = &g.publish_in[self.ch.number()]; - - Event::from_reg(reg) + Event::from_reg(&g.events_in[self.ch.number()]) } } @@ -277,33 +271,21 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { /// Returns the OUT task, for use with PPI. pub fn task_out(&self) -> Task { let g = unsafe { &*pac::GPIOTE::ptr() }; - #[cfg(feature = "_ppi")] - let reg = &g.tasks_out[self.ch.number()]; - #[cfg(feature = "_dppi")] - let reg = &g.subscribe_out[self.ch.number()]; - Task::from_reg(reg) + Task::from_reg(&g.tasks_out[self.ch.number()]) } /// Returns the CLR task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_clr(&self) -> Task { let g = unsafe { &*pac::GPIOTE::ptr() }; - #[cfg(feature = "_ppi")] - let reg = &g.tasks_clr[self.ch.number()]; - #[cfg(feature = "_dppi")] - let reg = &g.subscribe_clr[self.ch.number()]; - Task::from_reg(reg) + Task::from_reg(&g.tasks_clr[self.ch.number()]) } /// Returns the SET task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_set(&self) -> Task { let g = unsafe { &*pac::GPIOTE::ptr() }; - #[cfg(feature = "_ppi")] - let reg = &g.tasks_set[self.ch.number()]; - #[cfg(feature = "_dppi")] - let reg = &g.subscribe_set[self.ch.number()]; - Task::from_reg(reg) + Task::from_reg(&g.tasks_set[self.ch.number()]) } } diff --git a/embassy-nrf/src/interconnect/dppi.rs b/embassy-nrf/src/interconnect/dppi.rs new file mode 100644 index 000000000..60f19fca0 --- /dev/null +++ b/embassy-nrf/src/interconnect/dppi.rs @@ -0,0 +1,47 @@ +use super::{Channel, Event, Ppi, Task}; + +const DPPI_ENABLE_BIT: u32 = 0x8000_0000; +const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; +const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::(); + +impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) { + unsafe { + task.0 + .as_ptr() + .add(REGISTER_DPPI_CONFIG_OFFSET) + .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); + } + } + + pub(super) fn disable_task(task: &Task, _channel: &C, _index: usize) { + unsafe { + task.0 + .as_ptr() + .add(REGISTER_DPPI_CONFIG_OFFSET) + .write_volatile(0); + } + } + + pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { + unsafe { + event + .0 + .as_ptr() + .add(REGISTER_DPPI_CONFIG_OFFSET) + .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); + } + } + + pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) { + unsafe { + event + .0 + .as_ptr() + .add(REGISTER_DPPI_CONFIG_OFFSET) + .write_volatile(0); + } + } +} diff --git a/embassy-nrf/src/interconnect/mod.rs b/embassy-nrf/src/interconnect/mod.rs new file mode 100644 index 000000000..23cc45270 --- /dev/null +++ b/embassy-nrf/src/interconnect/mod.rs @@ -0,0 +1,318 @@ +#![macro_use] + +//! HAL interface for the PPI and DPPI peripheral. +//! +//! The (Distributed) Programmable Peripheral Interconnect interface allows for an autonomous interoperability +//! between peripherals through their events and tasks. There are fixed PPI channels and fully +//! configurable ones. Fixed channels can only connect specific events to specific tasks. For fully +//! configurable channels, it is possible to choose, via software, the event and the task that it +//! will triggered by the event. +//! +//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task +//! to be triggered by the same event, even fixed PPI channels have a configurable fork task. +//! +//! The DPPI for nRF53 and nRF91 devices works in a different way. Every channel can support infinitely +//! many tasks and events, but any single task or event can only be coupled with one channel. +//! + +use crate::{pac, peripherals}; +use core::marker::PhantomData; +use core::ptr::NonNull; +use embassy::util::Unborrow; +use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; + +#[cfg(feature = "_dppi")] +mod dppi; +#[cfg(feature = "_ppi")] +mod ppi; + +pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { + ch: C, + events: [Event; EVENT_COUNT], + tasks: [Task; TASK_COUNT], + phantom: PhantomData<&'d mut C>, +} + +impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> { + Ppi { + ch: AnyChannel { + number: self.ch.number() as u8, + #[cfg(feature = "_ppi")] + has_configurable_task: self.ch.is_task_configurable(), + }, + events: self.events, + tasks: self.tasks, + phantom: PhantomData, + } + } + + /// Enables the channel. + pub fn enable(&mut self) { + let r = unsafe { &*pac::PPI::ptr() }; + r.chenset + .write(|w| unsafe { w.bits(1 << self.ch.number()) }); + } + + /// Disables the channel. + pub fn disable(&mut self) { + let r = unsafe { &*pac::PPI::ptr() }; + r.chenclr + .write(|w| unsafe { w.bits(1 << self.ch.number()) }); + } + + /// Enables all tasks and events + fn enable_all(&self) { + for (index, task) in self.tasks.iter().enumerate() { + Self::enable_task(task, &self.ch, index); + } + for (index, event) in self.events.iter().enumerate() { + Self::enable_event(event, &self.ch, index); + } + } + + /// Disable all tasks and events + fn disable_all(&self) { + for (index, task) in self.tasks.iter().enumerate() { + Self::disable_task(task, &self.ch, index); + } + for (index, event) in self.events.iter().enumerate() { + Self::disable_event(event, &self.ch, index); + } + } +} + +impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop + for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + fn drop(&mut self) { + self.disable(); + self.disable_all(); + } +} + +impl<'d, C: StaticToOneChannel> Ppi<'d, C, 0, 1> { + pub fn new_static_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { + unborrow!(ch); + + let s = Self { + ch, + events: [], + tasks: [task], + phantom: PhantomData, + }; + + s.enable_all(); + s + } +} + +impl<'d, C: OneToOneChannel> Ppi<'d, C, 1, 1> { + pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { + unborrow!(ch); + + let s = Self { + ch, + events: [event], + tasks: [task], + phantom: PhantomData, + }; + + s.enable_all(); + s + } +} + +impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> { + pub fn new_one_to_two( + ch: impl Unborrow + 'd, + event: Event, + task1: Task, + task2: Task, + ) -> Self { + unborrow!(ch); + + let s = Self { + ch, + events: [event], + tasks: [task1, task2], + phantom: PhantomData, + }; + + s.enable_all(); + s + } +} + +impl<'d, C: ManyToManyChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + pub fn new_many_to_many( + ch: impl Unborrow + 'd, + events: [Event; EVENT_COUNT], + tasks: [Task; TASK_COUNT], + ) -> Self { + unborrow!(ch); + + let s = Self { + ch, + events, + tasks, + phantom: PhantomData, + }; + + s.enable_all(); + s + } +} + +/// Represents a task that a peripheral can do. +/// When a task is subscribed to a PPI channel it will run when the channel is triggered by +/// a published event. +/// +/// The pointer is to a task register +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct Task(pub NonNull); +impl Task { + pub(crate) fn from_reg(reg: &T) -> Self { + Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) + } +} + +/// # Safety +/// +/// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core. +unsafe impl Send for Task {} + +/// Represents an event that a peripheral can publish. +/// An event can be set to publish on a PPI channel when the event happens. +/// +/// The pointer is to an event register +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct Event(pub NonNull); +impl Event { + pub(crate) fn from_reg(reg: &T) -> Self { + Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) + } +} + +/// # Safety +/// +/// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core. +unsafe impl Send for Event {} + +// ====================== +// traits + +pub(crate) mod sealed { + pub trait Channel {} + pub trait Group {} +} + +pub trait Channel: sealed::Channel + Unborrow + Sized { + /// Returns the number of the channel + fn number(&self) -> usize; + #[cfg(feature = "_ppi")] + fn is_task_configurable(&self) -> bool; +} + +pub trait StaticToOneChannel: Channel {} +pub trait OneToOneChannel: StaticToOneChannel {} +pub trait OneToTwoChannel: OneToOneChannel {} +pub trait ManyToManyChannel: OneToTwoChannel {} + +pub trait Group: sealed::Group + Sized { + fn number(&self) -> usize; +} + +// ====================== +// channels + +pub struct AnyChannel { + number: u8, + #[cfg(feature = "_ppi")] + has_configurable_task: bool, +} +unsafe_impl_unborrow!(AnyChannel); +impl sealed::Channel for AnyChannel {} +impl Channel for AnyChannel { + fn number(&self) -> usize { + self.number as usize + } + + #[cfg(feature = "_ppi")] + fn is_task_configurable(&self) -> bool { + self.has_configurable_task + } +} + +macro_rules! impl_ppi_channel { + ($type:ident, $number:expr, $has_configurable_task:expr) => { + impl crate::interconnect::sealed::Channel for peripherals::$type {} + impl crate::interconnect::Channel for peripherals::$type { + fn number(&self) -> usize { + $number + } + + #[cfg(feature = "_ppi")] + fn is_task_configurable(&self) -> bool { + $has_configurable_task + } + } + }; + ($type:ident, $number:expr, $has_configurable_task:expr, 0, 0) => { + impl_ppi_channel!($type, $number, $has_configurable_task); + }; + ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => { + impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0); + impl crate::interconnect::StaticToOneChannel for peripherals::$type {} + }; + ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => { + impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1); + impl crate::interconnect::OneToOneChannel for peripherals::$type {} + }; + ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => { + impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1); + impl crate::interconnect::OneToTwoChannel for peripherals::$type {} + }; + ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => { + impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2); + impl crate::interconnect::ManyToManyChannel for peripherals::$type {} + }; +} + +// ====================== +// groups + +pub struct AnyGroup { + number: u8, +} +unsafe_impl_unborrow!(AnyGroup); +impl sealed::Group for AnyGroup {} +impl Group for AnyGroup { + fn number(&self) -> usize { + self.number as usize + } +} + +macro_rules! impl_group { + ($type:ident, $number:expr) => { + impl sealed::Group for peripherals::$type {} + impl Group for peripherals::$type { + fn number(&self) -> usize { + $number + } + } + }; +} + +impl_group!(PPI_GROUP0, 0); +impl_group!(PPI_GROUP1, 1); +impl_group!(PPI_GROUP2, 2); +impl_group!(PPI_GROUP3, 3); +#[cfg(not(feature = "nrf51"))] +impl_group!(PPI_GROUP4, 4); +#[cfg(not(feature = "nrf51"))] +impl_group!(PPI_GROUP5, 5); diff --git a/embassy-nrf/src/interconnect/ppi.rs b/embassy-nrf/src/interconnect/ppi.rs new file mode 100644 index 000000000..91ff811fe --- /dev/null +++ b/embassy-nrf/src/interconnect/ppi.rs @@ -0,0 +1,65 @@ +use super::{Channel, Event, Ppi, Task}; +use crate::pac; + +impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + pub(super) fn enable_task(task: &Task, channel: &C, index: usize) { + match (index, channel.is_task_configurable()) { + (0, false) => Self::set_fork_task(Some(task), channel.number()), // Static channel with fork + (0, true) => Self::set_main_task(Some(task), channel.number()), // Configurable channel without fork + (1, true) => Self::set_fork_task(Some(task), channel.number()), // Configurable channel with fork + _ => unreachable!("{}, {}", index, channel.is_task_configurable()), // Not available with the PPI, so should not be constructable + } + } + + pub(super) fn disable_task(_task: &Task, channel: &C, index: usize) { + match (index, channel.is_task_configurable()) { + (0, false) => Self::set_fork_task(None, channel.number()), // Static channel with fork + (0, true) => Self::set_main_task(None, channel.number()), // Configurable channel without fork + (1, true) => Self::set_fork_task(None, channel.number()), // Configurable channel with fork + _ => unreachable!(), // Not available with the PPI, so should not be constructable + } + } + + pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { + Self::set_event(Some(event), channel.number()) + } + + pub(super) fn disable_event(_event: &Event, channel: &C, _index: usize) { + Self::set_event(None, channel.number()) + } + + fn set_main_task(task: Option<&Task>, channel: usize) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(task) = task { + r.ch[channel] + .tep + .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) + } else { + r.ch[channel].tep.write(|w| unsafe { w.bits(0) }) + } + } + + fn set_fork_task(task: Option<&Task>, channel: usize) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(task) = task { + r.fork[channel] + .tep + .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) + } else { + r.fork[channel].tep.write(|w| unsafe { w.bits(0) }) + } + } + + fn set_event(event: Option<&Event>, channel: usize) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(event) = event { + r.ch[channel] + .eep + .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) + } else { + r.ch[channel].eep.write(|w| unsafe { w.bits(0) }) + } + } +} diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index c21c4d398..39f3e4a4a 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -31,7 +31,7 @@ pub mod gpio; pub mod gpiote; #[cfg(not(feature = "nrf9160"))] pub mod nvmc; -pub mod ppi; +pub mod interconnect; #[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))] pub mod pwm; #[cfg(feature = "nrf52840")] diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs deleted file mode 100644 index 7aaf17ee5..000000000 --- a/embassy-nrf/src/ppi.rs +++ /dev/null @@ -1,513 +0,0 @@ -#![macro_use] - -//! HAL interface for the PPI peripheral. -//! -//! The Programmable Peripheral Interconnect interface allows for an autonomous interoperability -//! between peripherals through their events and tasks. There are fixed PPI channels and fully -//! configurable ones, fixed channels can only connect specific events to specific tasks. For fully -//! configurable channels, it is possible to choose, via software, the event and the task that it -//! will triggered by the event. -//! -//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task -//! to be triggered by the same event, even fixed PPI channels have a configurable fork task. - -use crate::{pac, peripherals}; -use core::marker::PhantomData; -use core::ptr::NonNull; -use embassy::util::Unborrow; -use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; - -// ====================== -// driver - -/// Error type of the PPI driver -#[non_exhaustive] -#[derive(Clone, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Error { - /// There is no capacity to enable this task or event (nRF51 & nRF52 only) - NoCapacityLeft, - /// This task or event is not in use by the current channel - NotInUseByChannel, - /// This task or event is already enabled on another channel (nRF53 & nRF91 only) - AlreadyInUse, -} - -pub struct Ppi<'d, C: Channel> { - ch: C, - phantom: PhantomData<&'d mut C>, -} - -impl<'d, C: Channel> Ppi<'d, C> { - pub fn new(ch: impl Unborrow + 'd) -> Self { - unborrow!(ch); - - Self { - ch, - phantom: PhantomData, - } - } - - /// Enables the channel. - pub fn enable(&mut self) { - let r = unsafe { &*pac::PPI::ptr() }; - r.chenset - .write(|w| unsafe { w.bits(1 << self.ch.number()) }); - } - - /// Disables the channel. - pub fn disable(&mut self) { - let r = unsafe { &*pac::PPI::ptr() }; - r.chenclr - .write(|w| unsafe { w.bits(1 << self.ch.number()) }); - } -} - -#[cfg(feature = "_ppi")] -impl<'d, C: Channel> Ppi<'d, C> { - /// Makes it so that the given task is subscribed to this channel - pub fn subscribe(&mut self, task: Task) -> Result<(), Error> { - if self.is_main_task_free() { - self.set_main_task(Some(task)); - Ok(()) - } else if self.is_fork_task_free() { - self.set_fork_task(Some(task)); - Ok(()) - } else { - Err(Error::NoCapacityLeft) - } - } - - /// Makes it so that the given task is not subscribed to this channel - pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> { - if self.get_main_task() == Some(task) { - // If there is a fork task, we move that to the main task for consistency - // If there is no fork task, then the main task is set to 0 - let fork_task = self.get_fork_task(); - self.set_main_task(fork_task); - - if self.has_fork_task() { - // The fork task was copied to the main task, so reset the fork task - self.set_fork_task(None); - } - Ok(()) - } else if self.get_fork_task() == Some(task) { - // Reset the fork task - self.set_fork_task(None); - Ok(()) - } else { - Err(Error::NotInUseByChannel) - } - } - - /// Makes it so that the given event is published on this channel - pub fn publish(&mut self, event: Event) -> Result<(), Error> { - if self.is_event_free() { - self.set_event(Some(event)); - Ok(()) - } else { - Err(Error::NoCapacityLeft) - } - } - - /// Makes it so that the given event is not published on this channel - pub fn unpublish(&mut self, event: Event) -> Result<(), Error> { - if self.get_event() == Some(event) { - self.set_event(None); - Ok(()) - } else { - Err(Error::NotInUseByChannel) - } - } - - fn set_main_task(&mut self, task: Option) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(task) = task { - r.ch[self.ch.number()] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) - } else { - r.ch[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) - } - } - - fn get_main_task(&mut self) -> Option { - let r = unsafe { &*pac::PPI::ptr() }; - - if !self.has_main_task() { - return None; - } - - let bits = r.ch[self.ch.number()].tep.read().tep().bits(); - - if bits == 0 { - None - } else { - unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) } - } - } - - fn set_fork_task(&mut self, task: Option) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(task) = task { - r.fork[self.ch.number()] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) - } else { - r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) - } - } - - fn get_fork_task(&mut self) -> Option { - let r = unsafe { &*pac::PPI::ptr() }; - - if !self.has_fork_task() { - return None; - } - - let bits = r.fork[self.ch.number()].tep.read().tep().bits(); - - if bits == 0 { - None - } else { - unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) } - } - } - - fn has_main_task(&self) -> bool { - match (self.ch.task_capacity(), self.ch.event_capacity()) { - (0, 0) => false, // Static task - (1, 0) => false, // Static task with fork - (1 | 2, 1) => true, // Configurable task with possibly a fork - _ => unreachable!(), // Every PPI config is covered - } - } - - fn has_fork_task(&self) -> bool { - match (self.ch.task_capacity(), self.ch.event_capacity()) { - (0, 0) => false, // Static task - (1, 0) => true, // Static task with fork - (1, 1) => false, // Configurable task without fork - (2, 1) => true, // Configurable task with fork - _ => unreachable!(), // Every PPI config is covered - } - } - - fn is_main_task_free(&mut self) -> bool { - self.get_main_task().is_none() - } - - fn is_fork_task_free(&mut self) -> bool { - self.get_fork_task().is_none() - } - - fn set_event(&mut self, event: Option) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(event) = event { - r.ch[self.ch.number()] - .eep - .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) - } else { - r.ch[self.ch.number()].eep.write(|w| unsafe { w.bits(0) }) - } - } - - fn get_event(&mut self) -> Option { - let r = unsafe { &*pac::PPI::ptr() }; - - if !self.has_event() { - return None; - } - - let bits = r.ch[self.ch.number()].eep.read().eep().bits(); - - if bits == 0 { - None - } else { - unsafe { Some(Event(NonNull::new_unchecked(bits as *mut _))) } - } - } - - fn has_event(&self) -> bool { - match (self.ch.task_capacity(), self.ch.event_capacity()) { - (_, 0) => false, // Static event - (_, 1) => true, // Configurable event - _ => unreachable!(), // Every PPI config is covered - } - } - - fn is_event_free(&mut self) -> bool { - self.get_event().is_none() - } -} - -#[cfg(feature = "_dppi")] -const DPPI_ENABLE_BIT: u32 = 0x8000_0000; -#[cfg(feature = "_dppi")] -const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; - -#[cfg(feature = "_dppi")] -impl<'d, C: Channel> Ppi<'d, C> { - /// Makes it so that the given task is subscribed to this channel - pub fn subscribe(&mut self, task: Task) -> Result<(), Error> { - unsafe { - if Self::is_register_enabled(task.0) { - Err(Error::AlreadyInUse) - } else { - Self::set_register_active(task.0, self.ch.number() as u8); - Ok(()) - } - } - } - - /// Makes it so that the given task is not subscribed to this channel - pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> { - unsafe { - if Self::get_register_channel(task.0) != self.ch.number() as u8 { - Err(Error::NotInUseByChannel) - } else { - Self::set_register_inactive(task.0); - Ok(()) - } - } - } - - /// Makes it so that the given event is published on this channel - pub fn publish(&mut self, event: Event) -> Result<(), Error> { - unsafe { - if Self::is_register_enabled(event.0) { - Err(Error::AlreadyInUse) - } else { - Self::set_register_active(event.0, self.ch.number() as u8); - Ok(()) - } - } - } - - /// Makes it so that the given event is not published on this channel - pub fn unpublish(&mut self, event: Event) -> Result<(), Error> { - unsafe { - if Self::get_register_channel(event.0) != self.ch.number() as u8 { - Err(Error::NotInUseByChannel) - } else { - Self::set_register_inactive(event.0); - Ok(()) - } - } - } - - /// Checks if the DPPI_ENABLE_BIT is set in the register - /// - /// # Safety - /// - /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals - unsafe fn is_register_enabled(register: NonNull) -> bool { - let bits = register.as_ptr().read_volatile(); - bits & DPPI_ENABLE_BIT > 0 - } - - /// Sets the register to the given channel and enables it - /// - /// # Safety - /// - /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals - unsafe fn set_register_active(register: NonNull, channel: u8) { - register - .as_ptr() - .write_volatile(DPPI_ENABLE_BIT | (channel as u32 & DPPI_CHANNEL_MASK)); - } - - /// Resets the channel number and disables the register - /// - /// # Safety - /// - /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals - unsafe fn set_register_inactive(register: NonNull) { - register.as_ptr().write_volatile(0); - } - - /// Gets the current configured channel number of the register - /// - /// # Safety - /// - /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals - unsafe fn get_register_channel(register: NonNull) -> u8 { - let bits = register.as_ptr().read_volatile(); - (bits & DPPI_CHANNEL_MASK) as u8 - } -} - -impl<'d, C: Channel> Drop for Ppi<'d, C> { - fn drop(&mut self) { - self.disable() - } -} - -/// Represents a task that a peripheral can do. -/// When a task is subscribed to a PPI channel it will run when the channel is triggered by -/// a published event. -/// -/// The pointer in the task can point to two different kinds of register: -/// - PPI *(nRF51 & nRF52)*: A pointer to a task register of the task of the peripheral that has -/// to be registered with the PPI to subscribe to a channel -/// - DPPI *(nRF53 & nRF91)*: A pointer to the subscribe register of the task of the peripheral -/// that has to have the channel number and enable bit written tp it to subscribe to a channel -#[derive(PartialEq, Eq, Clone, Copy)] -pub struct Task(pub NonNull); -impl Task { - pub(crate) fn from_reg(reg: &T) -> Self { - Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) - } -} - -/// Represents an event that a peripheral can publish. -/// An event can be set to publish on a PPI channel when the event happens. -/// -/// The pointer in the event can point to two different kinds of register: -/// - PPI *(nRF51 & nRF52)*: A pointer to an event register of the event of the peripheral that has -/// to be registered with the PPI to publish to a channel -/// - DPPI *(nRF53 & nRF91)*: A pointer to the publish register of the event of the peripheral -/// that has to have the channel number and enable bit written tp it to publish to a channel -#[derive(PartialEq, Eq, Clone, Copy)] -pub struct Event(pub NonNull); -impl Event { - pub(crate) fn from_reg(reg: &T) -> Self { - Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) - } -} - -// ====================== -// traits - -pub(crate) mod sealed { - pub trait Channel {} - pub trait Group {} -} - -pub trait Channel: sealed::Channel + Sized { - /// Returns the number of the channel - fn number(&self) -> usize; - - /// Returns the amount of configurable tasks this channel has. - /// - /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91) - /// - 0 for static channel without fork (nRF51) - /// - 1 for static channel with fork (nRF52) or for configurable channel (nRF51) - /// - 2 for configurable channel with fork (nRF52) - fn task_capacity(&self) -> usize; - - /// Returns the amount of configurable events this channels has - /// - /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91) - /// - 0 for static channel (nRF51 & nRF52) - /// - 1 for configurable channel (nRF51 & nRF52) - fn event_capacity(&self) -> usize; - - fn degrade(self) -> AnyChannel { - pub trait ConfigurableChannel {} - - AnyChannel { - number: self.number() as u8, - task_capacity: self.task_capacity() as _, - event_capacity: self.event_capacity() as _, - } - } -} - -pub trait Group: sealed::Group + Sized { - fn number(&self) -> usize; - fn degrade(self) -> AnyGroup { - AnyGroup { - number: self.number() as u8, - } - } -} - -// ====================== -// channels - -pub struct AnyChannel { - number: u8, - task_capacity: u8, - event_capacity: u8, -} -unsafe_impl_unborrow!(AnyChannel); -impl sealed::Channel for AnyChannel {} -impl Channel for AnyChannel { - fn number(&self) -> usize { - self.number as usize - } - - fn task_capacity(&self) -> usize { - self.task_capacity as _ - } - - fn event_capacity(&self) -> usize { - self.event_capacity as _ - } -} - -macro_rules! impl_ppi_channel { - ($type:ident, $number:expr, $task_capacity:expr, $event_capacity:expr) => { - impl crate::ppi::sealed::Channel for peripherals::$type {} - impl crate::ppi::Channel for peripherals::$type { - fn number(&self) -> usize { - $number - } - fn task_capacity(&self) -> usize { - $task_capacity - } - fn event_capacity(&self) -> usize { - $event_capacity - } - } - }; - ($type:ident, $number:expr) => { - impl crate::ppi::sealed::Channel for peripherals::$type {} - impl crate::ppi::Channel for peripherals::$type { - fn number(&self) -> usize { - $number - } - fn task_capacity(&self) -> usize { - usize::MAX - } - fn event_capacity(&self) -> usize { - usize::MAX - } - } - }; -} - -// ====================== -// groups - -pub struct AnyGroup { - number: u8, -} -unsafe_impl_unborrow!(AnyGroup); -impl sealed::Group for AnyGroup {} -impl Group for AnyGroup { - fn number(&self) -> usize { - self.number as usize - } -} - -macro_rules! impl_group { - ($type:ident, $number:expr) => { - impl sealed::Group for peripherals::$type {} - impl Group for peripherals::$type { - fn number(&self) -> usize { - $number - } - } - }; -} - -impl_group!(PPI_GROUP0, 0); -impl_group!(PPI_GROUP1, 1); -impl_group!(PPI_GROUP2, 2); -impl_group!(PPI_GROUP3, 3); -#[cfg(not(feature = "nrf51"))] -impl_group!(PPI_GROUP4, 4); -#[cfg(not(feature = "nrf51"))] -impl_group!(PPI_GROUP5, 5); diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index e62120aef..27f8e715e 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -11,9 +11,8 @@ use embassy_hal_common::drop::OnDrop; use embassy_hal_common::unborrow; use futures::future::poll_fn; +use crate::interconnect::{Event, Task}; use crate::pac; -use crate::ppi::Event; -use crate::ppi::Task; pub(crate) mod sealed { @@ -184,36 +183,21 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { /// /// When triggered, this task starts the timer. pub fn task_start(&self) -> Task { - #[cfg(feature = "_ppi")] - let reg = &T::regs().tasks_start; - #[cfg(feature = "_dppi")] - let reg = &T::regs().subscribe_start; - - Task::from_reg(reg) + Task::from_reg(&T::regs().tasks_start) } /// Returns the STOP task, for use with PPI. /// /// When triggered, this task stops the timer. pub fn task_stop(&self) -> Task { - #[cfg(feature = "_ppi")] - let reg = &T::regs().tasks_stop; - #[cfg(feature = "_dppi")] - let reg = &T::regs().subscribe_stop; - - Task::from_reg(reg) + Task::from_reg(&T::regs().tasks_stop) } /// Returns the CLEAR task, for use with PPI. /// /// When triggered, this task resets the timer's counter to 0. pub fn task_clear(&self) -> Task { - #[cfg(feature = "_ppi")] - let reg = &T::regs().tasks_clear; - #[cfg(feature = "_dppi")] - let reg = &T::regs().subscribe_clear; - - Task::from_reg(reg) + Task::from_reg(&T::regs().tasks_clear) } /// Change the timer's frequency. @@ -334,24 +318,14 @@ impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { /// /// When triggered, this task will capture the current value of the timer's counter in this register. pub fn task_capture(&self) -> Task { - #[cfg(feature = "_ppi")] - let reg = &T::regs().tasks_capture; - #[cfg(feature = "_dppi")] - let reg = &T::regs().subscribe_capture; - - Task::from_reg(reg) + Task::from_reg(&T::regs().tasks_capture) } /// Returns this CC register's COMPARE event, for use with PPI. /// /// This event will fire when the timer's counter reaches the value in this CC register. pub fn event_compare(&self) -> Event { - #[cfg(feature = "_ppi")] - let reg = &T::regs().events_compare[self.n]; - #[cfg(feature = "_dppi")] - let reg = &T::regs().publish_compare[self.n]; - - Event::from_reg(reg) + Event::from_reg(&T::regs().events_compare[self.n]) } /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 71401a561..17e60ce22 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -16,28 +16,15 @@ use futures::future::poll_fn; use crate::chip::EASY_DMA_SIZE; use crate::gpio::sealed::Pin as _; use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; +use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; use crate::interrupt::Interrupt; use crate::pac; -use crate::ppi::{AnyChannel, Channel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; // 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}; -#[non_exhaustive] -#[derive(Clone, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Error { - PpiError(crate::ppi::Error), -} - -impl From for Error { - fn from(e: crate::ppi::Error) -> Self { - Self::PpiError(e) - } -} - #[non_exhaustive] pub struct Config { pub parity: Parity, @@ -344,17 +331,14 @@ impl<'d, T: Instance> Write for Uarte<'d, T> { pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { uarte: Uarte<'d, U>, timer: Timer<'d, T>, - ppi_ch1: Ppi<'d, AnyChannel>, - _ppi_ch2: Ppi<'d, AnyChannel>, + ppi_ch1: Ppi<'d, AnyChannel, 1, 2>, + _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>, } impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { /// Creates the interface to a UARTE instance. /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. /// - /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned - /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned - /// /// # Safety /// /// The returned API is safe unless you use `mem::forget` (or similar safe mechanisms) @@ -364,15 +348,15 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { pub unsafe fn new( uarte: impl Unborrow + 'd, timer: impl Unborrow + 'd, - ppi_ch1: impl Unborrow + 'd, - ppi_ch2: impl Unborrow + 'd, + ppi_ch1: impl Unborrow + 'd, + ppi_ch2: impl Unborrow + 'd, irq: impl Unborrow + 'd, rxd: impl Unborrow + 'd, txd: impl Unborrow + 'd, cts: impl Unborrow + 'd, rts: impl Unborrow + 'd, config: Config, - ) -> Result { + ) -> Self { let baudrate = config.baudrate; let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); let mut timer = Timer::new(timer); @@ -394,23 +378,29 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { timer.cc(0).short_compare_clear(); timer.cc(0).short_compare_stop(); - let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); - ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; - ppi_ch1.subscribe(timer.task_clear())?; - ppi_ch1.subscribe(timer.task_start())?; + let mut ppi_ch1 = Ppi::new_one_to_two( + ppi_ch1, + Event::from_reg(&r.events_rxdrdy), + timer.task_clear(), + timer.task_start(), + ) + .degrade(); ppi_ch1.enable(); - let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); - ppi_ch2.publish(timer.cc(0).event_compare())?; - ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; + let mut ppi_ch2 = Ppi::new_one_to_one( + ppi_ch2, + timer.cc(0).event_compare(), + Task::from_reg(&r.tasks_stoprx), + ) + .degrade(); ppi_ch2.enable(); - Ok(Self { + Self { uarte, timer, ppi_ch1: ppi_ch1, _ppi_ch2: ppi_ch2, - }) + } } } diff --git a/examples/nrf/src/bin/buffered_uart.rs b/examples/nrf/src/bin/buffered_uart.rs index b01c83ce3..69c7de93b 100644 --- a/examples/nrf/src/bin/buffered_uart.rs +++ b/examples/nrf/src/bin/buffered_uart.rs @@ -26,7 +26,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { let irq = interrupt::take!(UARTE0_UART0); let mut state = State::new(); let u = unsafe { - unwrap!(BufferedUarte::new( + BufferedUarte::new( &mut state, p.UARTE0, p.TIMER0, @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { config, &mut rx_buffer, &mut tx_buffer, - )) + ) }; pin_mut!(u); diff --git a/examples/nrf/src/bin/ppi.rs b/examples/nrf/src/bin/ppi.rs index 550893968..4edb5d7c0 100644 --- a/examples/nrf/src/bin/ppi.rs +++ b/examples/nrf/src/bin/ppi.rs @@ -10,7 +10,7 @@ use core::future::pending; use embassy::executor::Spawner; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; -use embassy_nrf::ppi::Ppi; +use embassy_nrf::interconnect::Ppi; use embassy_nrf::Peripherals; use gpiote::{OutputChannel, OutputChannelPolarity}; @@ -51,25 +51,21 @@ async fn main(_spawner: Spawner, p: Peripherals) { OutputChannelPolarity::Toggle, ); - let mut ppi = Ppi::new(p.PPI_CH0); - ppi.publish(button1.event_in()).unwrap(); - ppi.subscribe(led1.task_out()).unwrap(); + let mut ppi = Ppi::new_one_to_one(p.PPI_CH0, button1.event_in(), led1.task_out()); ppi.enable(); - let mut ppi = Ppi::new(p.PPI_CH1); - ppi.publish(button2.event_in()).unwrap(); - ppi.subscribe(led1.task_clr()).unwrap(); + let mut ppi = Ppi::new_one_to_one(p.PPI_CH1, button2.event_in(), led1.task_clr()); ppi.enable(); - let mut ppi = Ppi::new(p.PPI_CH2); - ppi.publish(button3.event_in()).unwrap(); - ppi.subscribe(led1.task_set()).unwrap(); + let mut ppi = Ppi::new_one_to_one(p.PPI_CH2, button3.event_in(), led1.task_set()); ppi.enable(); - let mut ppi = Ppi::new(p.PPI_CH3); - ppi.publish(button4.event_in()).unwrap(); - ppi.subscribe(led1.task_out()).unwrap(); - ppi.subscribe(led2.task_out()).unwrap(); + let mut ppi = Ppi::new_one_to_two( + p.PPI_CH3, + button4.event_in(), + led1.task_out(), + led2.task_out(), + ); ppi.enable(); info!("PPI setup!"); diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs index e04e5cf04..e9f4a285a 100644 --- a/examples/nrf/src/bin/uart_idle.rs +++ b/examples/nrf/src/bin/uart_idle.rs @@ -21,9 +21,9 @@ async fn main(_spawner: Spawner, p: Peripherals) { let irq = interrupt::take!(UARTE0_UART0); let mut uart = unsafe { - unwrap!(uarte::UarteWithIdle::new( + uarte::UarteWithIdle::new( p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config, - )) + ) }; info!("uarte initialized!"); From 531dfcffb3c203dff15dcb53fe25577c121c7784 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 18 Oct 2021 16:26:27 +0200 Subject: [PATCH 05/10] fmt --- embassy-nrf/src/interconnect/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-nrf/src/interconnect/mod.rs b/embassy-nrf/src/interconnect/mod.rs index 23cc45270..8cb505bdc 100644 --- a/embassy-nrf/src/interconnect/mod.rs +++ b/embassy-nrf/src/interconnect/mod.rs @@ -10,10 +10,10 @@ //! //! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task //! to be triggered by the same event, even fixed PPI channels have a configurable fork task. -//! +//! //! The DPPI for nRF53 and nRF91 devices works in a different way. Every channel can support infinitely //! many tasks and events, but any single task or event can only be coupled with one channel. -//! +//! use crate::{pac, peripherals}; use core::marker::PhantomData; From a6c84cb91552fc0442a28126d3fae60031aa6622 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 19 Oct 2021 10:13:08 +0200 Subject: [PATCH 06/10] - Interconnect is now PPI again - Scary pointer math is now contained in the tasks and events - ppi now sets the tasks and events immediately and the struct is now zero-sized - StaticToOne is renamed to ZeroToOne - Used DPPI tasks and events now panic when enabled twice --- embassy-nrf/src/buffered_uarte.rs | 2 +- embassy-nrf/src/gpiote.rs | 2 +- embassy-nrf/src/interconnect/dppi.rs | 47 ------- embassy-nrf/src/interconnect/ppi.rs | 65 ---------- embassy-nrf/src/lib.rs | 2 +- embassy-nrf/src/ppi/dppi.rs | 61 +++++++++ embassy-nrf/src/{interconnect => ppi}/mod.rs | 125 ++++++++++--------- embassy-nrf/src/ppi/ppi.rs | 77 ++++++++++++ embassy-nrf/src/timer.rs | 2 +- embassy-nrf/src/uarte.rs | 2 +- 10 files changed, 209 insertions(+), 176 deletions(-) delete mode 100644 embassy-nrf/src/interconnect/dppi.rs delete mode 100644 embassy-nrf/src/interconnect/ppi.rs create mode 100644 embassy-nrf/src/ppi/dppi.rs rename embassy-nrf/src/{interconnect => ppi}/mod.rs (79%) create mode 100644 embassy-nrf/src/ppi/ppi.rs diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 7c9a2344e..1dc04f4f6 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -14,8 +14,8 @@ use embassy_hal_common::{low_power_wait_until, unborrow}; use crate::gpio::sealed::Pin as _; use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; -use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; use crate::pac; +use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; use crate::uarte::{Config, Instance as UarteInstance}; diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 6703bfc60..7ec072ac8 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -11,8 +11,8 @@ use futures::future::poll_fn; use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin}; -use crate::interconnect::{Event, Task}; use crate::pac; +use crate::ppi::{Event, Task}; use crate::{interrupt, peripherals}; pub const CHANNEL_COUNT: usize = 8; diff --git a/embassy-nrf/src/interconnect/dppi.rs b/embassy-nrf/src/interconnect/dppi.rs deleted file mode 100644 index 60f19fca0..000000000 --- a/embassy-nrf/src/interconnect/dppi.rs +++ /dev/null @@ -1,47 +0,0 @@ -use super::{Channel, Event, Ppi, Task}; - -const DPPI_ENABLE_BIT: u32 = 0x8000_0000; -const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; -const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::(); - -impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> - Ppi<'d, C, EVENT_COUNT, TASK_COUNT> -{ - pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) { - unsafe { - task.0 - .as_ptr() - .add(REGISTER_DPPI_CONFIG_OFFSET) - .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); - } - } - - pub(super) fn disable_task(task: &Task, _channel: &C, _index: usize) { - unsafe { - task.0 - .as_ptr() - .add(REGISTER_DPPI_CONFIG_OFFSET) - .write_volatile(0); - } - } - - pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { - unsafe { - event - .0 - .as_ptr() - .add(REGISTER_DPPI_CONFIG_OFFSET) - .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); - } - } - - pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) { - unsafe { - event - .0 - .as_ptr() - .add(REGISTER_DPPI_CONFIG_OFFSET) - .write_volatile(0); - } - } -} diff --git a/embassy-nrf/src/interconnect/ppi.rs b/embassy-nrf/src/interconnect/ppi.rs deleted file mode 100644 index 91ff811fe..000000000 --- a/embassy-nrf/src/interconnect/ppi.rs +++ /dev/null @@ -1,65 +0,0 @@ -use super::{Channel, Event, Ppi, Task}; -use crate::pac; - -impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> - Ppi<'d, C, EVENT_COUNT, TASK_COUNT> -{ - pub(super) fn enable_task(task: &Task, channel: &C, index: usize) { - match (index, channel.is_task_configurable()) { - (0, false) => Self::set_fork_task(Some(task), channel.number()), // Static channel with fork - (0, true) => Self::set_main_task(Some(task), channel.number()), // Configurable channel without fork - (1, true) => Self::set_fork_task(Some(task), channel.number()), // Configurable channel with fork - _ => unreachable!("{}, {}", index, channel.is_task_configurable()), // Not available with the PPI, so should not be constructable - } - } - - pub(super) fn disable_task(_task: &Task, channel: &C, index: usize) { - match (index, channel.is_task_configurable()) { - (0, false) => Self::set_fork_task(None, channel.number()), // Static channel with fork - (0, true) => Self::set_main_task(None, channel.number()), // Configurable channel without fork - (1, true) => Self::set_fork_task(None, channel.number()), // Configurable channel with fork - _ => unreachable!(), // Not available with the PPI, so should not be constructable - } - } - - pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { - Self::set_event(Some(event), channel.number()) - } - - pub(super) fn disable_event(_event: &Event, channel: &C, _index: usize) { - Self::set_event(None, channel.number()) - } - - fn set_main_task(task: Option<&Task>, channel: usize) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(task) = task { - r.ch[channel] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) - } else { - r.ch[channel].tep.write(|w| unsafe { w.bits(0) }) - } - } - - fn set_fork_task(task: Option<&Task>, channel: usize) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(task) = task { - r.fork[channel] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) - } else { - r.fork[channel].tep.write(|w| unsafe { w.bits(0) }) - } - } - - fn set_event(event: Option<&Event>, channel: usize) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(event) = event { - r.ch[channel] - .eep - .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) - } else { - r.ch[channel].eep.write(|w| unsafe { w.bits(0) }) - } - } -} diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 39f3e4a4a..c21c4d398 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -31,7 +31,7 @@ pub mod gpio; pub mod gpiote; #[cfg(not(feature = "nrf9160"))] pub mod nvmc; -pub mod interconnect; +pub mod ppi; #[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))] pub mod pwm; #[cfg(feature = "nrf52840")] diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs new file mode 100644 index 000000000..083ec858a --- /dev/null +++ b/embassy-nrf/src/ppi/dppi.rs @@ -0,0 +1,61 @@ +use super::{Channel, Event, Ppi, Task}; + +const DPPI_ENABLE_BIT: u32 = 0x8000_0000; +const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; + +impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) { + unsafe { + if task.subscribe_reg().read_volatile() != 0 { + panic!("Task is already in use"); + } + task.subscribe_reg() + .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); + } + } + + pub(super) fn disable_task(task: &Task, _channel: &C, _index: usize) { + unsafe { + task.subscribe_reg().write_volatile(0); + } + } + + pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { + unsafe { + if event.publish_reg().read_volatile() != 0 { + panic!("Task is already in use"); + } + event + .publish_reg() + .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); + } + } + + pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) { + unsafe { + event.publish_reg().write_volatile(0); + } + } + + /// Enables all tasks and events + pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) { + for (index, task) in tasks.iter().enumerate() { + Self::enable_task(task, channel, index); + } + for (index, event) in events.iter().enumerate() { + Self::enable_event(event, channel, index); + } + } + + /// Disable all tasks and events + pub(super) fn disable_all(&self) { + for (index, task) in self.tasks.iter().enumerate() { + Self::disable_task(task, &self.ch, index); + } + for (index, event) in self.events.iter().enumerate() { + Self::disable_event(event, &self.ch, index); + } + } +} diff --git a/embassy-nrf/src/interconnect/mod.rs b/embassy-nrf/src/ppi/mod.rs similarity index 79% rename from embassy-nrf/src/interconnect/mod.rs rename to embassy-nrf/src/ppi/mod.rs index 8cb505bdc..ffb6af020 100644 --- a/embassy-nrf/src/interconnect/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -28,12 +28,14 @@ mod ppi; pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { ch: C, + #[cfg(feature = "_dppi")] events: [Event; EVENT_COUNT], + #[cfg(feature = "_dppi")] tasks: [Task; TASK_COUNT], phantom: PhantomData<&'d mut C>, } -impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> +impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> { @@ -43,7 +45,9 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> #[cfg(feature = "_ppi")] has_configurable_task: self.ch.is_task_configurable(), }, + #[cfg(feature = "_dppi")] events: self.events, + #[cfg(feature = "_dppi")] tasks: self.tasks, phantom: PhantomData, } @@ -62,26 +66,6 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> r.chenclr .write(|w| unsafe { w.bits(1 << self.ch.number()) }); } - - /// Enables all tasks and events - fn enable_all(&self) { - for (index, task) in self.tasks.iter().enumerate() { - Self::enable_task(task, &self.ch, index); - } - for (index, event) in self.events.iter().enumerate() { - Self::enable_event(event, &self.ch, index); - } - } - - /// Disable all tasks and events - fn disable_all(&self) { - for (index, task) in self.tasks.iter().enumerate() { - Self::disable_task(task, &self.ch, index); - } - for (index, event) in self.events.iter().enumerate() { - Self::disable_event(event, &self.ch, index); - } - } } impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop @@ -93,19 +77,23 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop } } -impl<'d, C: StaticToOneChannel> Ppi<'d, C, 0, 1> { +impl<'d, C: ZeroToOneChannel> Ppi<'d, C, 0, 1> { pub fn new_static_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { unborrow!(ch); - let s = Self { - ch, - events: [], - tasks: [task], - phantom: PhantomData, - }; + let events = []; + let tasks = [task]; - s.enable_all(); - s + Self::enable_all(&tasks, &events, &ch); + + Self { + ch, + #[cfg(feature = "_dppi")] + events, + #[cfg(feature = "_dppi")] + tasks, + phantom: PhantomData, + } } } @@ -113,15 +101,19 @@ impl<'d, C: OneToOneChannel> Ppi<'d, C, 1, 1> { pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { unborrow!(ch); - let s = Self { - ch, - events: [event], - tasks: [task], - phantom: PhantomData, - }; + let events = [event]; + let tasks = [task]; - s.enable_all(); - s + Self::enable_all(&tasks, &events, &ch); + + Self { + ch, + #[cfg(feature = "_dppi")] + events, + #[cfg(feature = "_dppi")] + tasks, + phantom: PhantomData, + } } } @@ -134,15 +126,19 @@ impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> { ) -> Self { unborrow!(ch); - let s = Self { - ch, - events: [event], - tasks: [task1, task2], - phantom: PhantomData, - }; + let events = [event]; + let tasks = [task1, task2]; - s.enable_all(); - s + Self::enable_all(&tasks, &events, &ch); + + Self { + ch, + #[cfg(feature = "_dppi")] + events, + #[cfg(feature = "_dppi")] + tasks, + phantom: PhantomData, + } } } @@ -156,18 +152,21 @@ impl<'d, C: ManyToManyChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize ) -> Self { unborrow!(ch); - let s = Self { + Self::enable_all(&tasks, &events, &ch); + + Self { ch, + #[cfg(feature = "_dppi")] events, + #[cfg(feature = "_dppi")] tasks, phantom: PhantomData, - }; - - s.enable_all(); - s + } } } +const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::(); + /// Represents a task that a peripheral can do. /// When a task is subscribed to a PPI channel it will run when the channel is triggered by /// a published event. @@ -179,6 +178,10 @@ impl Task { pub(crate) fn from_reg(reg: &T) -> Self { Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) } + + pub fn subscribe_reg(&self) -> *mut u32 { + unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) } + } } /// # Safety @@ -196,6 +199,10 @@ impl Event { pub(crate) fn from_reg(reg: &T) -> Self { Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) } + + pub fn publish_reg(&self) -> *mut u32 { + unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) } + } } /// # Safety @@ -218,8 +225,8 @@ pub trait Channel: sealed::Channel + Unborrow + Sized { fn is_task_configurable(&self) -> bool; } -pub trait StaticToOneChannel: Channel {} -pub trait OneToOneChannel: StaticToOneChannel {} +pub trait ZeroToOneChannel: Channel {} +pub trait OneToOneChannel: ZeroToOneChannel {} pub trait OneToTwoChannel: OneToOneChannel {} pub trait ManyToManyChannel: OneToTwoChannel {} @@ -250,8 +257,8 @@ impl Channel for AnyChannel { macro_rules! impl_ppi_channel { ($type:ident, $number:expr, $has_configurable_task:expr) => { - impl crate::interconnect::sealed::Channel for peripherals::$type {} - impl crate::interconnect::Channel for peripherals::$type { + impl crate::ppi::sealed::Channel for peripherals::$type {} + impl crate::ppi::Channel for peripherals::$type { fn number(&self) -> usize { $number } @@ -267,19 +274,19 @@ macro_rules! impl_ppi_channel { }; ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => { impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0); - impl crate::interconnect::StaticToOneChannel for peripherals::$type {} + impl crate::ppi::ZeroToOneChannel for peripherals::$type {} }; ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => { impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1); - impl crate::interconnect::OneToOneChannel for peripherals::$type {} + impl crate::ppi::OneToOneChannel for peripherals::$type {} }; ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => { impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1); - impl crate::interconnect::OneToTwoChannel for peripherals::$type {} + impl crate::ppi::OneToTwoChannel for peripherals::$type {} }; ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => { impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2); - impl crate::interconnect::ManyToManyChannel for peripherals::$type {} + impl crate::ppi::ManyToManyChannel for peripherals::$type {} }; } diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs new file mode 100644 index 000000000..67d2086c3 --- /dev/null +++ b/embassy-nrf/src/ppi/ppi.rs @@ -0,0 +1,77 @@ +use super::{Channel, Event, Ppi, Task}; +use crate::pac; + +impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + fn set_main_task(task: Option<&Task>, channel: usize) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(task) = task { + r.ch[channel] + .tep + .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) + } else { + r.ch[channel].tep.write(|w| unsafe { w.bits(0) }) + } + } + + fn set_fork_task(task: Option<&Task>, channel: usize) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(task) = task { + r.fork[channel] + .tep + .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) + } else { + r.fork[channel].tep.write(|w| unsafe { w.bits(0) }) + } + } + + fn set_event(event: Option<&Event>, channel: usize) { + let r = unsafe { &*pac::PPI::ptr() }; + if let Some(event) = event { + r.ch[channel] + .eep + .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) + } else { + r.ch[channel].eep.write(|w| unsafe { w.bits(0) }) + } + } + + /// Enables all tasks and events + pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) { + // One configurable task, no fork + if channel.is_task_configurable() && TASK_COUNT == 1 { + Self::set_main_task(Some(&tasks[0]), channel.number()); + } + + // One configurable task, as fork + if !channel.is_task_configurable() && TASK_COUNT == 1 { + Self::set_fork_task(Some(&tasks[0]), channel.number()); + } + + // Two configurable tasks (main + fork) + if TASK_COUNT == 2 { + Self::set_main_task(Some(&tasks[0]), channel.number()); + Self::set_fork_task(Some(&tasks[1]), channel.number()); + } + + if EVENT_COUNT == 1 { + Self::set_event(Some(&events[0]), channel.number()); + } + } + + /// Disable all tasks and events + pub(super) fn disable_all(&self) { + if self.ch.is_task_configurable() { + Self::set_main_task(None, self.ch.number()); + } + + if TASK_COUNT == 1 && !self.ch.is_task_configurable() || TASK_COUNT == 2 { + Self::set_fork_task(None, self.ch.number()); + } + + if EVENT_COUNT == 1 { + Self::set_event(None, self.ch.number()); + } + } +} diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 27f8e715e..9173338b6 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -11,8 +11,8 @@ use embassy_hal_common::drop::OnDrop; use embassy_hal_common::unborrow; use futures::future::poll_fn; -use crate::interconnect::{Event, Task}; use crate::pac; +use crate::ppi::{Event, Task}; pub(crate) mod sealed { diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 17e60ce22..36cf65d89 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -16,9 +16,9 @@ use futures::future::poll_fn; use crate::chip::EASY_DMA_SIZE; use crate::gpio::sealed::Pin as _; use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; -use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; use crate::interrupt::Interrupt; use crate::pac; +use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; From 6205d6da478be0392beaaee27e2f48e8e223a6ca Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 19 Oct 2021 10:20:22 +0200 Subject: [PATCH 07/10] typo --- embassy-nrf/src/ppi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index ffb6af020..bfbc69b79 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -78,7 +78,7 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop } impl<'d, C: ZeroToOneChannel> Ppi<'d, C, 0, 1> { - pub fn new_static_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { + pub fn new_zero_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { unborrow!(ch); let events = []; From 4d3341dbb980131762d714cb5b5d8dfb11060119 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 19 Oct 2021 10:27:49 +0200 Subject: [PATCH 08/10] Fixed examples --- examples/nrf/src/bin/ppi.rs | 2 +- examples/nrf/src/bin/saadc_continuous.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/nrf/src/bin/ppi.rs b/examples/nrf/src/bin/ppi.rs index 4edb5d7c0..99246eeda 100644 --- a/examples/nrf/src/bin/ppi.rs +++ b/examples/nrf/src/bin/ppi.rs @@ -10,7 +10,7 @@ use core::future::pending; use embassy::executor::Spawner; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; -use embassy_nrf::interconnect::Ppi; +use embassy_nrf::ppi::Ppi; use embassy_nrf::Peripherals; use gpiote::{OutputChannel, OutputChannelPolarity}; diff --git a/examples/nrf/src/bin/saadc_continuous.rs b/examples/nrf/src/bin/saadc_continuous.rs index 149b9c60c..a06a01e91 100644 --- a/examples/nrf/src/bin/saadc_continuous.rs +++ b/examples/nrf/src/bin/saadc_continuous.rs @@ -32,9 +32,7 @@ async fn main(_spawner: Spawner, mut p: Peripherals) { timer.cc(0).write(100); // We want to sample at 10KHz timer.cc(0).short_compare_clear(); - let mut ppi = Ppi::new(p.PPI_CH0); - ppi.set_event(timer.cc(0).event_compare()); - ppi.set_task(saadc.task_sample()); + let mut ppi = Ppi::new_one_to_one(p.PPI_CH0, timer.cc(0).event_compare(), saadc.task_sample()); ppi.enable(); timer.start(); From c63d74720980fcf9acbf5b1d8adbb9dc2031d391 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 26 Oct 2021 09:45:29 +0200 Subject: [PATCH 09/10] Fewer channel traits, more cfg to make the system work --- embassy-nrf/src/buffered_uarte.rs | 20 ++--- embassy-nrf/src/chips/nrf52805.rs | 44 +++++----- embassy-nrf/src/chips/nrf52810.rs | 64 +++++++------- embassy-nrf/src/chips/nrf52811.rs | 64 +++++++------- embassy-nrf/src/chips/nrf52820.rs | 64 +++++++------- embassy-nrf/src/chips/nrf52832.rs | 64 +++++++------- embassy-nrf/src/chips/nrf52833.rs | 64 +++++++------- embassy-nrf/src/chips/nrf52840.rs | 64 +++++++------- embassy-nrf/src/chips/nrf9160.rs | 32 +++---- embassy-nrf/src/ppi/mod.rs | 135 +++++++++++++++++------------- embassy-nrf/src/ppi/ppi.rs | 12 ++- embassy-nrf/src/uarte.rs | 20 ++--- 12 files changed, 335 insertions(+), 312 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 1dc04f4f6..717ada78d 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -15,7 +15,7 @@ use embassy_hal_common::{low_power_wait_until, unborrow}; use crate::gpio::sealed::Pin as _; use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; use crate::pac; -use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; +use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; use crate::uarte::{Config, Instance as UarteInstance}; @@ -45,8 +45,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> { struct StateInner<'d, U: UarteInstance, T: TimerInstance> { phantom: PhantomData<&'d mut U>, timer: Timer<'d, T>, - _ppi_ch1: Ppi<'d, AnyChannel, 1, 2>, - _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>, + _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, + _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, rx: RingBuffer<'d>, rx_state: RxState, @@ -70,8 +70,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { state: &'d mut State<'d, U, T>, _uarte: impl Unborrow + 'd, timer: impl Unborrow + 'd, - ppi_ch1: impl Unborrow + 'd, - ppi_ch2: impl Unborrow + 'd, + ppi_ch1: impl Unborrow + 'd, + ppi_ch2: impl Unborrow + 'd, irq: impl Unborrow + 'd, rxd: impl Unborrow + 'd, txd: impl Unborrow + 'd, @@ -145,20 +145,18 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { timer.cc(0).short_compare_stop(); let mut ppi_ch1 = Ppi::new_one_to_two( - ppi_ch1, + ppi_ch1.degrade(), Event::from_reg(&r.events_rxdrdy), timer.task_clear(), timer.task_start(), - ) - .degrade(); + ); ppi_ch1.enable(); let mut ppi_ch2 = Ppi::new_one_to_one( - ppi_ch2, + ppi_ch2.degrade(), timer.cc(0).event_compare(), Task::from_reg(&r.tasks_stoprx), - ) - .degrade(); + ); ppi_ch2.enable(); Self { diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index 326f4a8be..689896485 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs @@ -167,28 +167,28 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); -impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); -impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); -impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); -impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); -impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); -impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); -impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); -impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); -impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); -impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); -impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); -impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); -impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); -impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); -impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); -impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); -impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); -impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); -impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); -impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); -impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH20, 20 => static); +impl_ppi_channel!(PPI_CH21, 21 => static); +impl_ppi_channel!(PPI_CH22, 22 => static); +impl_ppi_channel!(PPI_CH23, 23 => static); +impl_ppi_channel!(PPI_CH24, 24 => static); +impl_ppi_channel!(PPI_CH25, 25 => static); +impl_ppi_channel!(PPI_CH26, 26 => static); +impl_ppi_channel!(PPI_CH27, 27 => static); +impl_ppi_channel!(PPI_CH28, 28 => static); +impl_ppi_channel!(PPI_CH29, 29 => static); +impl_ppi_channel!(PPI_CH30, 30 => static); +impl_ppi_channel!(PPI_CH31, 31 => static); impl_saadc_input!(P0_04, ANALOGINPUT2); impl_saadc_input!(P0_05, ANALOGINPUT3); diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index 4c16d51a7..b3b3593bb 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs @@ -172,38 +172,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); -impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); -impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); -impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); -impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); -impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); -impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); -impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); -impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); -impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); -impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); -impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); -impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); -impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); -impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); -impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); -impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); -impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); -impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); -impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); -impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); -impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); -impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); -impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); -impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); -impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); -impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); -impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); -impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); -impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); -impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); -impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH10, 10 => configurable); +impl_ppi_channel!(PPI_CH11, 11 => configurable); +impl_ppi_channel!(PPI_CH12, 12 => configurable); +impl_ppi_channel!(PPI_CH13, 13 => configurable); +impl_ppi_channel!(PPI_CH14, 14 => configurable); +impl_ppi_channel!(PPI_CH15, 15 => configurable); +impl_ppi_channel!(PPI_CH16, 16 => configurable); +impl_ppi_channel!(PPI_CH17, 17 => configurable); +impl_ppi_channel!(PPI_CH18, 18 => configurable); +impl_ppi_channel!(PPI_CH19, 19 => configurable); +impl_ppi_channel!(PPI_CH20, 20 => static); +impl_ppi_channel!(PPI_CH21, 21 => static); +impl_ppi_channel!(PPI_CH22, 22 => static); +impl_ppi_channel!(PPI_CH23, 23 => static); +impl_ppi_channel!(PPI_CH24, 24 => static); +impl_ppi_channel!(PPI_CH25, 25 => static); +impl_ppi_channel!(PPI_CH26, 26 => static); +impl_ppi_channel!(PPI_CH27, 27 => static); +impl_ppi_channel!(PPI_CH28, 28 => static); +impl_ppi_channel!(PPI_CH29, 29 => static); +impl_ppi_channel!(PPI_CH30, 30 => static); +impl_ppi_channel!(PPI_CH31, 31 => static); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 0c54d9b9e..7551492c3 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs @@ -173,38 +173,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); -impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); -impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); -impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); -impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); -impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); -impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); -impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); -impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); -impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); -impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); -impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); -impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); -impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); -impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); -impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); -impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); -impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); -impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); -impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); -impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); -impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); -impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); -impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); -impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); -impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); -impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); -impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); -impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); -impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); -impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); -impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH10, 10 => configurable); +impl_ppi_channel!(PPI_CH11, 11 => configurable); +impl_ppi_channel!(PPI_CH12, 12 => configurable); +impl_ppi_channel!(PPI_CH13, 13 => configurable); +impl_ppi_channel!(PPI_CH14, 14 => configurable); +impl_ppi_channel!(PPI_CH15, 15 => configurable); +impl_ppi_channel!(PPI_CH16, 16 => configurable); +impl_ppi_channel!(PPI_CH17, 17 => configurable); +impl_ppi_channel!(PPI_CH18, 18 => configurable); +impl_ppi_channel!(PPI_CH19, 19 => configurable); +impl_ppi_channel!(PPI_CH20, 20 => static); +impl_ppi_channel!(PPI_CH21, 21 => static); +impl_ppi_channel!(PPI_CH22, 22 => static); +impl_ppi_channel!(PPI_CH23, 23 => static); +impl_ppi_channel!(PPI_CH24, 24 => static); +impl_ppi_channel!(PPI_CH25, 25 => static); +impl_ppi_channel!(PPI_CH26, 26 => static); +impl_ppi_channel!(PPI_CH27, 27 => static); +impl_ppi_channel!(PPI_CH28, 28 => static); +impl_ppi_channel!(PPI_CH29, 29 => static); +impl_ppi_channel!(PPI_CH30, 30 => static); +impl_ppi_channel!(PPI_CH31, 31 => static); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index d52f2f98a..128e1503f 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs @@ -168,38 +168,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); -impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); -impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); -impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); -impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); -impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); -impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); -impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); -impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); -impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); -impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); -impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); -impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); -impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); -impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); -impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); -impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); -impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); -impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); -impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); -impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); -impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); -impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); -impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); -impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); -impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); -impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); -impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); -impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); -impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); -impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); -impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH10, 10 => configurable); +impl_ppi_channel!(PPI_CH11, 11 => configurable); +impl_ppi_channel!(PPI_CH12, 12 => configurable); +impl_ppi_channel!(PPI_CH13, 13 => configurable); +impl_ppi_channel!(PPI_CH14, 14 => configurable); +impl_ppi_channel!(PPI_CH15, 15 => configurable); +impl_ppi_channel!(PPI_CH16, 16 => configurable); +impl_ppi_channel!(PPI_CH17, 17 => configurable); +impl_ppi_channel!(PPI_CH18, 18 => configurable); +impl_ppi_channel!(PPI_CH19, 19 => configurable); +impl_ppi_channel!(PPI_CH20, 20 => static); +impl_ppi_channel!(PPI_CH21, 21 => static); +impl_ppi_channel!(PPI_CH22, 22 => static); +impl_ppi_channel!(PPI_CH23, 23 => static); +impl_ppi_channel!(PPI_CH24, 24 => static); +impl_ppi_channel!(PPI_CH25, 25 => static); +impl_ppi_channel!(PPI_CH26, 26 => static); +impl_ppi_channel!(PPI_CH27, 27 => static); +impl_ppi_channel!(PPI_CH28, 28 => static); +impl_ppi_channel!(PPI_CH29, 29 => static); +impl_ppi_channel!(PPI_CH30, 30 => static); +impl_ppi_channel!(PPI_CH31, 31 => static); pub mod irqs { use crate::pac::Interrupt as InterruptEnum; diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index d97a65350..432af143c 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs @@ -190,38 +190,38 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); -impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); -impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); -impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); -impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); -impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); -impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); -impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); -impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); -impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); -impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); -impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); -impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); -impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); -impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); -impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); -impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); -impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); -impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); -impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); -impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); -impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); -impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); -impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); -impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); -impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); -impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); -impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); -impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); -impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); -impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); -impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH10, 10 => configurable); +impl_ppi_channel!(PPI_CH11, 11 => configurable); +impl_ppi_channel!(PPI_CH12, 12 => configurable); +impl_ppi_channel!(PPI_CH13, 13 => configurable); +impl_ppi_channel!(PPI_CH14, 14 => configurable); +impl_ppi_channel!(PPI_CH15, 15 => configurable); +impl_ppi_channel!(PPI_CH16, 16 => configurable); +impl_ppi_channel!(PPI_CH17, 17 => configurable); +impl_ppi_channel!(PPI_CH18, 18 => configurable); +impl_ppi_channel!(PPI_CH19, 19 => configurable); +impl_ppi_channel!(PPI_CH20, 20 => static); +impl_ppi_channel!(PPI_CH21, 21 => static); +impl_ppi_channel!(PPI_CH22, 22 => static); +impl_ppi_channel!(PPI_CH23, 23 => static); +impl_ppi_channel!(PPI_CH24, 24 => static); +impl_ppi_channel!(PPI_CH25, 25 => static); +impl_ppi_channel!(PPI_CH26, 26 => static); +impl_ppi_channel!(PPI_CH27, 27 => static); +impl_ppi_channel!(PPI_CH28, 28 => static); +impl_ppi_channel!(PPI_CH29, 29 => static); +impl_ppi_channel!(PPI_CH30, 30 => static); +impl_ppi_channel!(PPI_CH31, 31 => static); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 9bf370c4b..7c7198dfd 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs @@ -226,38 +226,38 @@ impl_pin!(P1_13, 1, 13); impl_pin!(P1_14, 1, 14); impl_pin!(P1_15, 1, 15); -impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); -impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); -impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); -impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); -impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); -impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); -impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); -impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); -impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); -impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); -impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); -impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); -impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); -impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); -impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); -impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); -impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); -impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); -impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); -impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); -impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); -impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); -impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); -impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); -impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); -impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); -impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); -impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); -impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); -impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); -impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); -impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH10, 10 => configurable); +impl_ppi_channel!(PPI_CH11, 11 => configurable); +impl_ppi_channel!(PPI_CH12, 12 => configurable); +impl_ppi_channel!(PPI_CH13, 13 => configurable); +impl_ppi_channel!(PPI_CH14, 14 => configurable); +impl_ppi_channel!(PPI_CH15, 15 => configurable); +impl_ppi_channel!(PPI_CH16, 16 => configurable); +impl_ppi_channel!(PPI_CH17, 17 => configurable); +impl_ppi_channel!(PPI_CH18, 18 => configurable); +impl_ppi_channel!(PPI_CH19, 19 => configurable); +impl_ppi_channel!(PPI_CH20, 20 => static); +impl_ppi_channel!(PPI_CH21, 21 => static); +impl_ppi_channel!(PPI_CH22, 22 => static); +impl_ppi_channel!(PPI_CH23, 23 => static); +impl_ppi_channel!(PPI_CH24, 24 => static); +impl_ppi_channel!(PPI_CH25, 25 => static); +impl_ppi_channel!(PPI_CH26, 26 => static); +impl_ppi_channel!(PPI_CH27, 27 => static); +impl_ppi_channel!(PPI_CH28, 28 => static); +impl_ppi_channel!(PPI_CH29, 29 => static); +impl_ppi_channel!(PPI_CH30, 30 => static); +impl_ppi_channel!(PPI_CH31, 31 => static); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 266328d58..f5b90cd5a 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -231,38 +231,38 @@ impl_pin!(P1_13, 1, 13); impl_pin!(P1_14, 1, 14); impl_pin!(P1_15, 1, 15); -impl_ppi_channel!(PPI_CH0, 0, true, 1, 2); -impl_ppi_channel!(PPI_CH1, 1, true, 1, 2); -impl_ppi_channel!(PPI_CH2, 2, true, 1, 2); -impl_ppi_channel!(PPI_CH3, 3, true, 1, 2); -impl_ppi_channel!(PPI_CH4, 4, true, 1, 2); -impl_ppi_channel!(PPI_CH5, 5, true, 1, 2); -impl_ppi_channel!(PPI_CH6, 6, true, 1, 2); -impl_ppi_channel!(PPI_CH7, 7, true, 1, 2); -impl_ppi_channel!(PPI_CH8, 8, true, 1, 2); -impl_ppi_channel!(PPI_CH9, 9, true, 1, 2); -impl_ppi_channel!(PPI_CH10, 10, true, 1, 2); -impl_ppi_channel!(PPI_CH11, 11, true, 1, 2); -impl_ppi_channel!(PPI_CH12, 12, true, 1, 2); -impl_ppi_channel!(PPI_CH13, 13, true, 1, 2); -impl_ppi_channel!(PPI_CH14, 14, true, 1, 2); -impl_ppi_channel!(PPI_CH15, 15, true, 1, 2); -impl_ppi_channel!(PPI_CH16, 16, true, 1, 2); -impl_ppi_channel!(PPI_CH17, 17, true, 1, 2); -impl_ppi_channel!(PPI_CH18, 18, true, 1, 2); -impl_ppi_channel!(PPI_CH19, 19, true, 1, 2); -impl_ppi_channel!(PPI_CH20, 20, false, 0, 1); -impl_ppi_channel!(PPI_CH21, 21, false, 0, 1); -impl_ppi_channel!(PPI_CH22, 22, false, 0, 1); -impl_ppi_channel!(PPI_CH23, 23, false, 0, 1); -impl_ppi_channel!(PPI_CH24, 24, false, 0, 1); -impl_ppi_channel!(PPI_CH25, 25, false, 0, 1); -impl_ppi_channel!(PPI_CH26, 26, false, 0, 1); -impl_ppi_channel!(PPI_CH27, 27, false, 0, 1); -impl_ppi_channel!(PPI_CH28, 28, false, 0, 1); -impl_ppi_channel!(PPI_CH29, 29, false, 0, 1); -impl_ppi_channel!(PPI_CH30, 30, false, 0, 1); -impl_ppi_channel!(PPI_CH31, 31, false, 0, 1); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH10, 10 => configurable); +impl_ppi_channel!(PPI_CH11, 11 => configurable); +impl_ppi_channel!(PPI_CH12, 12 => configurable); +impl_ppi_channel!(PPI_CH13, 13 => configurable); +impl_ppi_channel!(PPI_CH14, 14 => configurable); +impl_ppi_channel!(PPI_CH15, 15 => configurable); +impl_ppi_channel!(PPI_CH16, 16 => configurable); +impl_ppi_channel!(PPI_CH17, 17 => configurable); +impl_ppi_channel!(PPI_CH18, 18 => configurable); +impl_ppi_channel!(PPI_CH19, 19 => configurable); +impl_ppi_channel!(PPI_CH20, 20 => static); +impl_ppi_channel!(PPI_CH21, 21 => static); +impl_ppi_channel!(PPI_CH22, 22 => static); +impl_ppi_channel!(PPI_CH23, 23 => static); +impl_ppi_channel!(PPI_CH24, 24 => static); +impl_ppi_channel!(PPI_CH25, 25 => static); +impl_ppi_channel!(PPI_CH26, 26 => static); +impl_ppi_channel!(PPI_CH27, 27 => static); +impl_ppi_channel!(PPI_CH28, 28 => static); +impl_ppi_channel!(PPI_CH29, 29 => static); +impl_ppi_channel!(PPI_CH30, 30 => static); +impl_ppi_channel!(PPI_CH31, 31 => static); impl_saadc_input!(P0_02, ANALOGINPUT0); impl_saadc_input!(P0_03, ANALOGINPUT1); diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 7357e9e22..6ca918104 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -184,22 +184,22 @@ impl_pin!(P0_29, 0, 29); impl_pin!(P0_30, 0, 30); impl_pin!(P0_31, 0, 31); -impl_ppi_channel!(PPI_CH0, 0, true, many, many); -impl_ppi_channel!(PPI_CH1, 1, true, many, many); -impl_ppi_channel!(PPI_CH2, 2, true, many, many); -impl_ppi_channel!(PPI_CH3, 3, true, many, many); -impl_ppi_channel!(PPI_CH4, 4, true, many, many); -impl_ppi_channel!(PPI_CH5, 5, true, many, many); -impl_ppi_channel!(PPI_CH6, 6, true, many, many); -impl_ppi_channel!(PPI_CH7, 7, true, many, many); -impl_ppi_channel!(PPI_CH8, 8, true, many, many); -impl_ppi_channel!(PPI_CH9, 9, true, many, many); -impl_ppi_channel!(PPI_CH10, 10, true, many, many); -impl_ppi_channel!(PPI_CH11, 11, true, many, many); -impl_ppi_channel!(PPI_CH12, 12, true, many, many); -impl_ppi_channel!(PPI_CH13, 13, true, many, many); -impl_ppi_channel!(PPI_CH14, 14, true, many, many); -impl_ppi_channel!(PPI_CH15, 15, true, many, many); +impl_ppi_channel!(PPI_CH0, 0 => configurable); +impl_ppi_channel!(PPI_CH1, 1 => configurable); +impl_ppi_channel!(PPI_CH2, 2 => configurable); +impl_ppi_channel!(PPI_CH3, 3 => configurable); +impl_ppi_channel!(PPI_CH4, 4 => configurable); +impl_ppi_channel!(PPI_CH5, 5 => configurable); +impl_ppi_channel!(PPI_CH6, 6 => configurable); +impl_ppi_channel!(PPI_CH7, 7 => configurable); +impl_ppi_channel!(PPI_CH8, 8 => configurable); +impl_ppi_channel!(PPI_CH9, 9 => configurable); +impl_ppi_channel!(PPI_CH10, 10 => configurable); +impl_ppi_channel!(PPI_CH11, 11 => configurable); +impl_ppi_channel!(PPI_CH12, 12 => configurable); +impl_ppi_channel!(PPI_CH13, 13 => configurable); +impl_ppi_channel!(PPI_CH14, 14 => configurable); +impl_ppi_channel!(PPI_CH15, 15 => configurable); impl_saadc_input!(P0_13, ANALOGINPUT0); impl_saadc_input!(P0_14, ANALOGINPUT1); diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index bfbc69b79..cea8a0e68 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -38,21 +38,6 @@ pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { - pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> { - Ppi { - ch: AnyChannel { - number: self.ch.number() as u8, - #[cfg(feature = "_ppi")] - has_configurable_task: self.ch.is_task_configurable(), - }, - #[cfg(feature = "_dppi")] - events: self.events, - #[cfg(feature = "_dppi")] - tasks: self.tasks, - phantom: PhantomData, - } - } - /// Enables the channel. pub fn enable(&mut self) { let r = unsafe { &*pac::PPI::ptr() }; @@ -77,7 +62,8 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop } } -impl<'d, C: ZeroToOneChannel> Ppi<'d, C, 0, 1> { +#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task +impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> { pub fn new_zero_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { unborrow!(ch); @@ -97,7 +83,7 @@ impl<'d, C: ZeroToOneChannel> Ppi<'d, C, 0, 1> { } } -impl<'d, C: OneToOneChannel> Ppi<'d, C, 1, 1> { +impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { unborrow!(ch); @@ -117,7 +103,8 @@ impl<'d, C: OneToOneChannel> Ppi<'d, C, 1, 1> { } } -impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> { +#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task +impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { pub fn new_one_to_two( ch: impl Unborrow + 'd, event: Event, @@ -142,7 +129,8 @@ impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> { } } -impl<'d, C: ManyToManyChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize> +#[cfg(feature = "_dppi")] +impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { pub fn new_many_to_many( @@ -221,72 +209,107 @@ pub(crate) mod sealed { pub trait Channel: sealed::Channel + Unborrow + Sized { /// Returns the number of the channel fn number(&self) -> usize; - #[cfg(feature = "_ppi")] - fn is_task_configurable(&self) -> bool; + fn configurable() -> bool; } -pub trait ZeroToOneChannel: Channel {} -pub trait OneToOneChannel: ZeroToOneChannel {} -pub trait OneToTwoChannel: OneToOneChannel {} -pub trait ManyToManyChannel: OneToTwoChannel {} +pub trait ConfigurableChannel: Channel { + fn degrade(self) -> AnyConfigurableChannel; +} + +pub trait StaticChannel: Channel { + fn degrade(self) -> AnyStaticChannel; +} pub trait Group: sealed::Group + Sized { fn number(&self) -> usize; + fn degrade(self) -> AnyGroup { + AnyGroup { + number: self.number() as u8, + } + } } // ====================== // channels -pub struct AnyChannel { - number: u8, - #[cfg(feature = "_ppi")] - has_configurable_task: bool, +/// The any channel can represent any static channel at runtime. +/// This can be used to have fewer generic parameters in some places. +pub struct AnyStaticChannel { + pub(crate) number: u8, } -unsafe_impl_unborrow!(AnyChannel); -impl sealed::Channel for AnyChannel {} -impl Channel for AnyChannel { +unsafe_impl_unborrow!(AnyStaticChannel); +impl sealed::Channel for AnyStaticChannel {} +impl Channel for AnyStaticChannel { fn number(&self) -> usize { self.number as usize } - #[cfg(feature = "_ppi")] - fn is_task_configurable(&self) -> bool { - self.has_configurable_task + fn configurable() -> bool { + false + } +} +impl StaticChannel for AnyStaticChannel { + fn degrade(self) -> AnyStaticChannel { + self + } +} + +/// The any configurable channel can represent any configurable channel at runtime. +/// This can be used to have fewer generic parameters in some places. +pub struct AnyConfigurableChannel { + pub(crate) number: u8, +} +unsafe_impl_unborrow!(AnyConfigurableChannel); +impl sealed::Channel for AnyConfigurableChannel {} +impl Channel for AnyConfigurableChannel { + fn number(&self) -> usize { + self.number as usize + } + + fn configurable() -> bool { + true + } +} +impl ConfigurableChannel for AnyConfigurableChannel { + fn degrade(self) -> AnyConfigurableChannel { + self } } macro_rules! impl_ppi_channel { - ($type:ident, $number:expr, $has_configurable_task:expr) => { + ($type:ident, $number:expr, $configurability:expr) => { impl crate::ppi::sealed::Channel for peripherals::$type {} impl crate::ppi::Channel for peripherals::$type { fn number(&self) -> usize { $number } - #[cfg(feature = "_ppi")] - fn is_task_configurable(&self) -> bool { - $has_configurable_task + fn configurable() -> bool { + $configurability } } }; - ($type:ident, $number:expr, $has_configurable_task:expr, 0, 0) => { - impl_ppi_channel!($type, $number, $has_configurable_task); + ($type:ident, $number:expr => static) => { + impl_ppi_channel!($type, $number, false); + impl crate::ppi::StaticChannel for peripherals::$type { + fn degrade(self) -> crate::ppi::AnyStaticChannel { + use crate::ppi::Channel; + crate::ppi::AnyStaticChannel { + number: self.number() as u8, + } + } + } }; - ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => { - impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0); - impl crate::ppi::ZeroToOneChannel for peripherals::$type {} - }; - ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => { - impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1); - impl crate::ppi::OneToOneChannel for peripherals::$type {} - }; - ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => { - impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1); - impl crate::ppi::OneToTwoChannel for peripherals::$type {} - }; - ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => { - impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2); - impl crate::ppi::ManyToManyChannel for peripherals::$type {} + ($type:ident, $number:expr => configurable) => { + impl_ppi_channel!($type, $number, true); + impl crate::ppi::ConfigurableChannel for peripherals::$type { + fn degrade(self) -> crate::ppi::AnyConfigurableChannel { + use crate::ppi::Channel; + crate::ppi::AnyConfigurableChannel { + number: self.number() as u8, + } + } + } }; } diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index 67d2086c3..0bcb3a791 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs @@ -15,6 +15,7 @@ impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> } } + #[cfg(not(feature = "nrf51"))] fn set_fork_task(task: Option<&Task>, channel: usize) { let r = unsafe { &*pac::PPI::ptr() }; if let Some(task) = task { @@ -40,16 +41,18 @@ impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> /// Enables all tasks and events pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) { // One configurable task, no fork - if channel.is_task_configurable() && TASK_COUNT == 1 { + if C::configurable() && TASK_COUNT == 1 { Self::set_main_task(Some(&tasks[0]), channel.number()); } // One configurable task, as fork - if !channel.is_task_configurable() && TASK_COUNT == 1 { + #[cfg(not(feature = "nrf51"))] + if !C::configurable() && TASK_COUNT == 1 { Self::set_fork_task(Some(&tasks[0]), channel.number()); } // Two configurable tasks (main + fork) + #[cfg(not(feature = "nrf51"))] if TASK_COUNT == 2 { Self::set_main_task(Some(&tasks[0]), channel.number()); Self::set_fork_task(Some(&tasks[1]), channel.number()); @@ -62,11 +65,12 @@ impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> /// Disable all tasks and events pub(super) fn disable_all(&self) { - if self.ch.is_task_configurable() { + if C::configurable() { Self::set_main_task(None, self.ch.number()); } - if TASK_COUNT == 1 && !self.ch.is_task_configurable() || TASK_COUNT == 2 { + #[cfg(not(feature = "nrf51"))] + if TASK_COUNT == 1 && !C::configurable() || TASK_COUNT == 2 { Self::set_fork_task(None, self.ch.number()); } diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 36cf65d89..4bbdec63f 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -18,7 +18,7 @@ use crate::gpio::sealed::Pin as _; use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; use crate::interrupt::Interrupt; use crate::pac; -use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task}; +use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; @@ -331,8 +331,8 @@ impl<'d, T: Instance> Write for Uarte<'d, T> { pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { uarte: Uarte<'d, U>, timer: Timer<'d, T>, - ppi_ch1: Ppi<'d, AnyChannel, 1, 2>, - _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>, + ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, + _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, } impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { @@ -348,8 +348,8 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { pub unsafe fn new( uarte: impl Unborrow + 'd, timer: impl Unborrow + 'd, - ppi_ch1: impl Unborrow + 'd, - ppi_ch2: impl Unborrow + 'd, + ppi_ch1: impl Unborrow + 'd, + ppi_ch2: impl Unborrow + 'd, irq: impl Unborrow + 'd, rxd: impl Unborrow + 'd, txd: impl Unborrow + 'd, @@ -379,20 +379,18 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { timer.cc(0).short_compare_stop(); let mut ppi_ch1 = Ppi::new_one_to_two( - ppi_ch1, + ppi_ch1.degrade(), Event::from_reg(&r.events_rxdrdy), timer.task_clear(), timer.task_start(), - ) - .degrade(); + ); ppi_ch1.enable(); let mut ppi_ch2 = Ppi::new_one_to_one( - ppi_ch2, + ppi_ch2.degrade(), timer.cc(0).event_compare(), Task::from_reg(&r.tasks_stoprx), - ) - .degrade(); + ); ppi_ch2.enable(); Self { From 36d3eda2f9d24be5a581e95badd74bce7060572e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 26 Oct 2021 16:10:34 +0200 Subject: [PATCH 10/10] ppi: simplify driver creation. Moving `new_*` to the version-specific mod allows doing the correct register writes right there in `new`, without needing abstractions like `enable_all`/`disable_all`. --- embassy-nrf/src/ppi/dppi.rs | 105 +++++++++++++----------- embassy-nrf/src/ppi/mod.rs | 121 +--------------------------- embassy-nrf/src/ppi/ppi.rs | 154 +++++++++++++++++++----------------- 3 files changed, 143 insertions(+), 237 deletions(-) diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 083ec858a..b3676fca4 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs @@ -1,61 +1,74 @@ -use super::{Channel, Event, Ppi, Task}; +use core::marker::PhantomData; + +use embassy::util::Unborrow; +use embassy_hal_common::unborrow; + +use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; const DPPI_ENABLE_BIT: u32 = 0x8000_0000; const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; -impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> +impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { + pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { + Ppi::new_many_to_many(ch, [event], [task]) + } +} + +impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { + pub fn new_one_to_two( + ch: impl Unborrow + 'd, + event: Event, + task1: Task, + task2: Task, + ) -> Self { + Ppi::new_many_to_many(ch, [event], [task1, task2]) + } +} + +impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { - pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) { - unsafe { - if task.subscribe_reg().read_volatile() != 0 { + pub fn new_many_to_many( + ch: impl Unborrow + 'd, + events: [Event; EVENT_COUNT], + tasks: [Task; TASK_COUNT], + ) -> Self { + unborrow!(ch); + + let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK); + for task in tasks { + if unsafe { task.subscribe_reg().read_volatile() } != 0 { panic!("Task is already in use"); } - task.subscribe_reg() - .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); + unsafe { task.subscribe_reg().write_volatile(val) } } - } - - pub(super) fn disable_task(task: &Task, _channel: &C, _index: usize) { - unsafe { - task.subscribe_reg().write_volatile(0); - } - } - - pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) { - unsafe { - if event.publish_reg().read_volatile() != 0 { - panic!("Task is already in use"); + for event in events { + if unsafe { event.publish_reg().read_volatile() } != 0 { + panic!("Event is already in use"); } - event - .publish_reg() - .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK)); + unsafe { event.publish_reg().write_volatile(val) } } - } - pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) { - unsafe { - event.publish_reg().write_volatile(0); - } - } - - /// Enables all tasks and events - pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) { - for (index, task) in tasks.iter().enumerate() { - Self::enable_task(task, channel, index); - } - for (index, event) in events.iter().enumerate() { - Self::enable_event(event, channel, index); - } - } - - /// Disable all tasks and events - pub(super) fn disable_all(&self) { - for (index, task) in self.tasks.iter().enumerate() { - Self::disable_task(task, &self.ch, index); - } - for (index, event) in self.events.iter().enumerate() { - Self::disable_event(event, &self.ch, index); + Self { + ch, + events, + tasks, + phantom: PhantomData, + } + } +} + +impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop + for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + fn drop(&mut self) { + self.disable(); + + for task in self.tasks { + unsafe { task.subscribe_reg().write_volatile(0) } + } + for event in self.events { + unsafe { event.publish_reg().write_volatile(0) } } } } diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index cea8a0e68..96f867d18 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -19,7 +19,7 @@ use crate::{pac, peripherals}; use core::marker::PhantomData; use core::ptr::NonNull; use embassy::util::Unborrow; -use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; +use embassy_hal_common::unsafe_impl_unborrow; #[cfg(feature = "_dppi")] mod dppi; @@ -53,106 +53,6 @@ impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> } } -impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop - for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> -{ - fn drop(&mut self) { - self.disable(); - self.disable_all(); - } -} - -#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task -impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> { - pub fn new_zero_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { - unborrow!(ch); - - let events = []; - let tasks = [task]; - - Self::enable_all(&tasks, &events, &ch); - - Self { - ch, - #[cfg(feature = "_dppi")] - events, - #[cfg(feature = "_dppi")] - tasks, - phantom: PhantomData, - } - } -} - -impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { - pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { - unborrow!(ch); - - let events = [event]; - let tasks = [task]; - - Self::enable_all(&tasks, &events, &ch); - - Self { - ch, - #[cfg(feature = "_dppi")] - events, - #[cfg(feature = "_dppi")] - tasks, - phantom: PhantomData, - } - } -} - -#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task -impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { - pub fn new_one_to_two( - ch: impl Unborrow + 'd, - event: Event, - task1: Task, - task2: Task, - ) -> Self { - unborrow!(ch); - - let events = [event]; - let tasks = [task1, task2]; - - Self::enable_all(&tasks, &events, &ch); - - Self { - ch, - #[cfg(feature = "_dppi")] - events, - #[cfg(feature = "_dppi")] - tasks, - phantom: PhantomData, - } - } -} - -#[cfg(feature = "_dppi")] -impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize> - Ppi<'d, C, EVENT_COUNT, TASK_COUNT> -{ - pub fn new_many_to_many( - ch: impl Unborrow + 'd, - events: [Event; EVENT_COUNT], - tasks: [Task; TASK_COUNT], - ) -> Self { - unborrow!(ch); - - Self::enable_all(&tasks, &events, &ch); - - Self { - ch, - #[cfg(feature = "_dppi")] - events, - #[cfg(feature = "_dppi")] - tasks, - phantom: PhantomData, - } - } -} - const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::(); /// Represents a task that a peripheral can do. @@ -209,7 +109,6 @@ pub(crate) mod sealed { pub trait Channel: sealed::Channel + Unborrow + Sized { /// Returns the number of the channel fn number(&self) -> usize; - fn configurable() -> bool; } pub trait ConfigurableChannel: Channel { @@ -243,10 +142,6 @@ impl Channel for AnyStaticChannel { fn number(&self) -> usize { self.number as usize } - - fn configurable() -> bool { - false - } } impl StaticChannel for AnyStaticChannel { fn degrade(self) -> AnyStaticChannel { @@ -265,10 +160,6 @@ impl Channel for AnyConfigurableChannel { fn number(&self) -> usize { self.number as usize } - - fn configurable() -> bool { - true - } } impl ConfigurableChannel for AnyConfigurableChannel { fn degrade(self) -> AnyConfigurableChannel { @@ -277,20 +168,16 @@ impl ConfigurableChannel for AnyConfigurableChannel { } macro_rules! impl_ppi_channel { - ($type:ident, $number:expr, $configurability:expr) => { + ($type:ident, $number:expr) => { impl crate::ppi::sealed::Channel for peripherals::$type {} impl crate::ppi::Channel for peripherals::$type { fn number(&self) -> usize { $number } - - fn configurable() -> bool { - $configurability - } } }; ($type:ident, $number:expr => static) => { - impl_ppi_channel!($type, $number, false); + impl_ppi_channel!($type, $number); impl crate::ppi::StaticChannel for peripherals::$type { fn degrade(self) -> crate::ppi::AnyStaticChannel { use crate::ppi::Channel; @@ -301,7 +188,7 @@ macro_rules! impl_ppi_channel { } }; ($type:ident, $number:expr => configurable) => { - impl_ppi_channel!($type, $number, true); + impl_ppi_channel!($type, $number); impl crate::ppi::ConfigurableChannel for peripherals::$type { fn degrade(self) -> crate::ppi::AnyConfigurableChannel { use crate::ppi::Channel; diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index 0bcb3a791..c1d9794c9 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs @@ -1,81 +1,87 @@ -use super::{Channel, Event, Ppi, Task}; +use core::marker::PhantomData; + +use embassy::util::Unborrow; +use embassy_hal_common::unborrow; + +use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task}; use crate::pac; -impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> - Ppi<'d, C, EVENT_COUNT, TASK_COUNT> -{ - fn set_main_task(task: Option<&Task>, channel: usize) { +impl Task { + fn reg_val(&self) -> u32 { + self.0.as_ptr() as _ + } +} +impl Event { + fn reg_val(&self) -> u32 { + self.0.as_ptr() as _ + } +} + +#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task +impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> { + pub fn new_zero_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { + unborrow!(ch); + let r = unsafe { &*pac::PPI::ptr() }; - if let Some(task) = task { - r.ch[channel] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) - } else { - r.ch[channel].tep.write(|w| unsafe { w.bits(0) }) - } - } + let n = ch.number(); + r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); - #[cfg(not(feature = "nrf51"))] - fn set_fork_task(task: Option<&Task>, channel: usize) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(task) = task { - r.fork[channel] - .tep - .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) - } else { - r.fork[channel].tep.write(|w| unsafe { w.bits(0) }) - } - } - - fn set_event(event: Option<&Event>, channel: usize) { - let r = unsafe { &*pac::PPI::ptr() }; - if let Some(event) = event { - r.ch[channel] - .eep - .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) - } else { - r.ch[channel].eep.write(|w| unsafe { w.bits(0) }) - } - } - - /// Enables all tasks and events - pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) { - // One configurable task, no fork - if C::configurable() && TASK_COUNT == 1 { - Self::set_main_task(Some(&tasks[0]), channel.number()); - } - - // One configurable task, as fork - #[cfg(not(feature = "nrf51"))] - if !C::configurable() && TASK_COUNT == 1 { - Self::set_fork_task(Some(&tasks[0]), channel.number()); - } - - // Two configurable tasks (main + fork) - #[cfg(not(feature = "nrf51"))] - if TASK_COUNT == 2 { - Self::set_main_task(Some(&tasks[0]), channel.number()); - Self::set_fork_task(Some(&tasks[1]), channel.number()); - } - - if EVENT_COUNT == 1 { - Self::set_event(Some(&events[0]), channel.number()); - } - } - - /// Disable all tasks and events - pub(super) fn disable_all(&self) { - if C::configurable() { - Self::set_main_task(None, self.ch.number()); - } - - #[cfg(not(feature = "nrf51"))] - if TASK_COUNT == 1 && !C::configurable() || TASK_COUNT == 2 { - Self::set_fork_task(None, self.ch.number()); - } - - if EVENT_COUNT == 1 { - Self::set_event(None, self.ch.number()); + Self { + ch, + phantom: PhantomData, } } } + +impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { + pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { + unborrow!(ch); + + let r = unsafe { &*pac::PPI::ptr() }; + let n = ch.number(); + r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); + r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); + + Self { + ch, + phantom: PhantomData, + } + } +} + +#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task +impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { + pub fn new_one_to_two( + ch: impl Unborrow + 'd, + event: Event, + task1: Task, + task2: Task, + ) -> Self { + unborrow!(ch); + + let r = unsafe { &*pac::PPI::ptr() }; + let n = ch.number(); + r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); + r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) }); + r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) }); + + Self { + ch, + phantom: PhantomData, + } + } +} + +impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop + for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + fn drop(&mut self) { + self.disable(); + + let r = unsafe { &*pac::PPI::ptr() }; + let n = self.ch.number(); + r.ch[n].eep.write(|w| unsafe { w.bits(0) }); + r.ch[n].tep.write(|w| unsafe { w.bits(0) }); + r.fork[n].tep.write(|w| unsafe { w.bits(0) }); + } +}