Merge #427
427: New nrf PPI api (with DPPI support for nRF91 & nRF53) r=Dirbaio a=diondokter - Added _ppi and _dppi features 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 My proposal for the new API. Tested on my nRF52840 and nRF9160. Biggest changes for nRF52 is that there's no longer a distinction made between fork task and normal task. You now subscribe tasks to a channel and at runtime it is checked whether or not there's still room for another subscription. Same for events. There are differences between the PPI and DPPI though: - With the PPI you have a limited amount of tasks and events per channel, but a task or event can be used on multiple channels at the same time. - With the DPPI you have an unlimited amount of tasks and events per channel, but every task or event can only be used on 1 channel. This is all checked at runtime. Currently you need to track which tasks and events are assigned to a channel in order to unassign them. For the PPI this data is stored centrally in the registers, so it would be easy to create e.g. `clear_all` and `get_subscribed_tasks` functions. But for the DPPI that data is stored decentrally and so would need some manual tracking. If there are requests for tracking functionality, then it should be able to be made relatively easy. But for now this API is fine I think. Co-authored-by: Dion Dokter <dion@tweedegolf.com> Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
commit
7cb34760c4
18 changed files with 691 additions and 537 deletions
|
@ -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"]
|
||||
|
|
|
@ -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};
|
||||
|
@ -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, AnyConfigurableChannel>,
|
||||
_ppi_ch2: Ppi<'d, AnyConfigurableChannel>,
|
||||
_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<Target = U> + 'd,
|
||||
timer: impl Unborrow<Target = T> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
|
@ -144,15 +144,19 @@ 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_one_to_two(
|
||||
ppi_ch1.degrade(),
|
||||
Event::from_reg(&r.events_rxdrdy),
|
||||
timer.task_clear(),
|
||||
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_one_to_one(
|
||||
ppi_ch2.degrade(),
|
||||
timer.cc(0).event_compare(),
|
||||
Task::from_reg(&r.tasks_stoprx),
|
||||
);
|
||||
ppi_ch2.enable();
|
||||
|
||||
Self {
|
||||
|
@ -187,7 +191,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<Result<&[u8]>> {
|
||||
fn poll_fill_buf(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<embassy::io::Result<&[u8]>> {
|
||||
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 +213,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d,
|
|||
|
||||
trace!(" empty");
|
||||
state.rx_waker.register(cx.waker());
|
||||
Poll::<Result<&[u8]>>::Pending
|
||||
Poll::<embassy::io::Result<&[u8]>>::Pending
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -224,7 +231,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U,
|
|||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<Result<usize>> {
|
||||
) -> Poll<embassy::io::Result<usize>> {
|
||||
let poll = self.inner.with(|state| {
|
||||
trace!("poll_write: {:?}", buf.len());
|
||||
|
||||
|
|
|
@ -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 => 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);
|
||||
|
|
|
@ -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 => 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);
|
||||
|
|
|
@ -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 => 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);
|
||||
|
|
|
@ -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 => 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;
|
||||
|
|
|
@ -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 => 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);
|
||||
|
|
|
@ -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 => 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);
|
||||
|
|
|
@ -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 => 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);
|
||||
|
|
|
@ -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 => 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);
|
||||
|
|
|
@ -1,248 +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
|
||||
|
||||
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<Target = C> + 'd) -> Self {
|
||||
unborrow!(ch);
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut this = Self {
|
||||
ch,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
#[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
|
||||
this.clear_fork_task();
|
||||
this
|
||||
}
|
||||
|
||||
/// 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(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) {
|
||||
let r = unsafe { &*pac::PPI::ptr() };
|
||||
r.fork[self.ch.number()]
|
||||
.tep
|
||||
.write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
|
||||
}
|
||||
|
||||
#[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) {
|
||||
let r = unsafe { &*pac::PPI::ptr() };
|
||||
r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) })
|
||||
}
|
||||
|
||||
#[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");
|
||||
}
|
||||
|
||||
#[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");
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, C: Channel> Drop for Ppi<'d, C> {
|
||||
fn drop(&mut self) {
|
||||
self.disable()
|
||||
}
|
||||
}
|
||||
|
||||
#[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) })
|
||||
}
|
||||
}
|
||||
|
||||
#[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")
|
||||
}
|
||||
}
|
||||
|
||||
// ======================
|
||||
// traits
|
||||
|
||||
pub struct Task(pub NonNull<()>);
|
||||
impl Task {
|
||||
pub(crate) fn from_reg<T>(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<T>(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 degrade(self) -> AnyChannel {
|
||||
AnyChannel {
|
||||
number: self.number() as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub trait ConfigurableChannel: Channel + sealed::ConfigurableChannel {
|
||||
fn degrade_configurable(self) -> AnyConfigurableChannel {
|
||||
AnyConfigurableChannel {
|
||||
number: self.number() as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyChannel);
|
||||
impl sealed::Channel for AnyChannel {}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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) => {
|
||||
impl crate::ppi::sealed::Channel for peripherals::$type {}
|
||||
impl crate::ppi::Channel for peripherals::$type {
|
||||
fn number(&self) -> usize {
|
||||
$number
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ======================
|
||||
// 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);
|
74
embassy-nrf/src/ppi/dppi.rs
Normal file
74
embassy-nrf/src/ppi/dppi.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
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: ConfigurableChannel> Ppi<'d, C, 1, 1> {
|
||||
pub fn new_one_to_one(ch: impl Unborrow<Target = C> + '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<Target = C> + '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 fn new_many_to_many(
|
||||
ch: impl Unborrow<Target = C> + '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");
|
||||
}
|
||||
unsafe { task.subscribe_reg().write_volatile(val) }
|
||||
}
|
||||
for event in events {
|
||||
if unsafe { event.publish_reg().read_volatile() } != 0 {
|
||||
panic!("Event is already in use");
|
||||
}
|
||||
unsafe { event.publish_reg().write_volatile(val) }
|
||||
}
|
||||
|
||||
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) }
|
||||
}
|
||||
}
|
||||
}
|
235
embassy-nrf/src/ppi/mod.rs
Normal file
235
embassy-nrf/src/ppi/mod.rs
Normal file
|
@ -0,0 +1,235 @@
|
|||
#![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::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,
|
||||
#[cfg(feature = "_dppi")]
|
||||
events: [Event; EVENT_COUNT],
|
||||
#[cfg(feature = "_dppi")]
|
||||
tasks: [Task; TASK_COUNT],
|
||||
phantom: PhantomData<&'d mut C>,
|
||||
}
|
||||
|
||||
impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize>
|
||||
Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
|
||||
{
|
||||
/// 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()) });
|
||||
}
|
||||
}
|
||||
|
||||
const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<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 is to a task register
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub struct Task(pub NonNull<u32>);
|
||||
impl Task {
|
||||
pub(crate) fn from_reg<T>(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
|
||||
///
|
||||
/// 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<u32>);
|
||||
impl Event {
|
||||
pub(crate) fn from_reg<T>(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
|
||||
///
|
||||
/// 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<Target = Self> + Sized {
|
||||
/// Returns the number of the channel
|
||||
fn number(&self) -> usize;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/// 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!(AnyStaticChannel);
|
||||
impl sealed::Channel for AnyStaticChannel {}
|
||||
impl Channel for AnyStaticChannel {
|
||||
fn number(&self) -> usize {
|
||||
self.number as usize
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
impl ConfigurableChannel for AnyConfigurableChannel {
|
||||
fn degrade(self) -> AnyConfigurableChannel {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_ppi_channel {
|
||||
($type:ident, $number:expr) => {
|
||||
impl crate::ppi::sealed::Channel for peripherals::$type {}
|
||||
impl crate::ppi::Channel for peripherals::$type {
|
||||
fn number(&self) -> usize {
|
||||
$number
|
||||
}
|
||||
}
|
||||
};
|
||||
($type:ident, $number:expr => static) => {
|
||||
impl_ppi_channel!($type, $number);
|
||||
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 => configurable) => {
|
||||
impl_ppi_channel!($type, $number);
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ======================
|
||||
// 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);
|
87
embassy-nrf/src/ppi/ppi.rs
Normal file
87
embassy-nrf/src/ppi/ppi.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
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 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<Target = C> + 'd, task: Task) -> Self {
|
||||
unborrow!(ch);
|
||||
|
||||
let r = unsafe { &*pac::PPI::ptr() };
|
||||
let n = ch.number();
|
||||
r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
|
||||
|
||||
Self {
|
||||
ch,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
|
||||
pub fn new_one_to_one(ch: impl Unborrow<Target = C> + '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<Target = C> + '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) });
|
||||
}
|
||||
}
|
|
@ -12,8 +12,7 @@ use embassy_hal_common::unborrow;
|
|||
use futures::future::poll_fn;
|
||||
|
||||
use crate::pac;
|
||||
use crate::ppi::Event;
|
||||
use crate::ppi::Task;
|
||||
use crate::ppi::{Event, Task};
|
||||
|
||||
pub(crate) mod sealed {
|
||||
|
||||
|
@ -319,7 +318,7 @@ 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])
|
||||
Task::from_reg(&T::regs().tasks_capture)
|
||||
}
|
||||
|
||||
/// Returns this CC register's COMPARE event, for use with PPI.
|
||||
|
|
|
@ -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;
|
||||
|
@ -219,7 +219,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<Output = Result<(), Error>> + 'a;
|
||||
type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
|
||||
|
||||
fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
async move {
|
||||
|
@ -273,7 +273,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<Output = Result<(), Error>> + 'a;
|
||||
type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
|
||||
|
||||
fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
async move {
|
||||
|
@ -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, AnyConfigurableChannel>,
|
||||
_ppi_ch2: Ppi<'d, AnyConfigurableChannel>,
|
||||
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<Target = U> + 'd,
|
||||
timer: impl Unborrow<Target = T> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
|
@ -378,15 +378,19 @@ 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_one_to_two(
|
||||
ppi_ch1.degrade(),
|
||||
Event::from_reg(&r.events_rxdrdy),
|
||||
timer.task_clear(),
|
||||
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_one_to_one(
|
||||
ppi_ch2.degrade(),
|
||||
timer.cc(0).event_compare(),
|
||||
Task::from_reg(&r.tasks_stoprx),
|
||||
);
|
||||
ppi_ch2.enable();
|
||||
|
||||
Self {
|
||||
|
@ -400,7 +404,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
|||
|
||||
impl<'d, U: Instance, T: TimerInstance> ReadUntilIdle for UarteWithIdle<'d, U, T> {
|
||||
#[rustfmt::skip]
|
||||
type ReadUntilIdleFuture<'a> where Self: 'a = impl Future<Output = Result<usize, Error>> + 'a;
|
||||
type ReadUntilIdleFuture<'a> where Self: 'a = impl Future<Output = Result<usize, TraitError>> + '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 +464,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<Output = Result<(), Error>> + 'a;
|
||||
type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
|
||||
fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
async move {
|
||||
self.ppi_ch1.disable();
|
||||
|
@ -473,7 +477,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<Output = Result<(), Error>> + 'a;
|
||||
type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
|
||||
|
||||
fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.uarte.write(tx_buffer)
|
||||
|
|
|
@ -51,25 +51,21 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||
OutputChannelPolarity::Toggle,
|
||||
);
|
||||
|
||||
let mut ppi = Ppi::new(p.PPI_CH0);
|
||||
ppi.set_event(button1.event_in());
|
||||
ppi.set_task(led1.task_out());
|
||||
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.set_event(button2.event_in());
|
||||
ppi.set_task(led1.task_clr());
|
||||
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.set_event(button3.event_in());
|
||||
ppi.set_task(led1.task_set());
|
||||
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.set_event(button4.event_in());
|
||||
ppi.set_task(led1.task_out());
|
||||
ppi.set_fork_task(led2.task_out());
|
||||
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!");
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue