aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/buffered_uarte.rs54
-rw-r--r--embassy-nrf/src/chips/nrf52805.rs44
-rw-r--r--embassy-nrf/src/chips/nrf52810.rs64
-rw-r--r--embassy-nrf/src/chips/nrf52811.rs64
-rw-r--r--embassy-nrf/src/chips/nrf52820.rs64
-rw-r--r--embassy-nrf/src/chips/nrf52832.rs64
-rw-r--r--embassy-nrf/src/chips/nrf52833.rs64
-rw-r--r--embassy-nrf/src/chips/nrf52840.rs64
-rw-r--r--embassy-nrf/src/chips/nrf9160.rs32
-rw-r--r--embassy-nrf/src/gpiote.rs28
-rw-r--r--embassy-nrf/src/interconnect/dppi.rs47
-rw-r--r--embassy-nrf/src/interconnect/mod.rs318
-rw-r--r--embassy-nrf/src/interconnect/ppi.rs65
-rw-r--r--embassy-nrf/src/lib.rs2
-rw-r--r--embassy-nrf/src/ppi.rs513
-rw-r--r--embassy-nrf/src/timer.rs38
-rw-r--r--embassy-nrf/src/uarte.rs52
-rw-r--r--examples/nrf/src/bin/buffered_uart.rs4
-rw-r--r--examples/nrf/src/bin/ppi.rs24
-rw-r--r--examples/nrf/src/bin/uart_idle.rs4
20 files changed, 729 insertions, 880 deletions
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};
14 14
15use crate::gpio::sealed::Pin as _; 15use crate::gpio::sealed::Pin as _;
16use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; 16use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin};
17use crate::ppi::{AnyChannel, Channel, Event, Ppi, Task}; 17use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task};
18use crate::pac;
18use crate::timer::Instance as TimerInstance; 19use crate::timer::Instance as TimerInstance;
19use crate::timer::{Frequency, Timer}; 20use crate::timer::{Frequency, Timer};
20use crate::uarte::{Config, Instance as UarteInstance}; 21use crate::uarte::{Config, Instance as UarteInstance};
21use crate::{pac, ppi};
22 22
23// Re-export SVD variants to allow user to directly set values 23// Re-export SVD variants to allow user to directly set values
24pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 24pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
25 25
26#[non_exhaustive]
27#[derive(Clone, Debug)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub enum Error {
30 PpiError(ppi::Error),
31}
32
33impl From<ppi::Error> for Error {
34 fn from(e: ppi::Error) -> Self {
35 Self::PpiError(e)
36 }
37}
38
39#[derive(Copy, Clone, Debug, PartialEq)] 26#[derive(Copy, Clone, Debug, PartialEq)]
40enum RxState { 27enum RxState {
41 Idle, 28 Idle,
@@ -58,8 +45,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> {
58struct StateInner<'d, U: UarteInstance, T: TimerInstance> { 45struct StateInner<'d, U: UarteInstance, T: TimerInstance> {
59 phantom: PhantomData<&'d mut U>, 46 phantom: PhantomData<&'d mut U>,
60 timer: Timer<'d, T>, 47 timer: Timer<'d, T>,
61 _ppi_ch1: Ppi<'d, AnyChannel>, 48 _ppi_ch1: Ppi<'d, AnyChannel, 1, 2>,
62 _ppi_ch2: Ppi<'d, AnyChannel>, 49 _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>,
63 50
64 rx: RingBuffer<'d>, 51 rx: RingBuffer<'d>,
65 rx_state: RxState, 52 rx_state: RxState,
@@ -79,15 +66,12 @@ impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {
79 66
80impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { 67impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
81 /// unsafe: may not leak self or futures 68 /// unsafe: may not leak self or futures
82 ///
83 /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned
84 /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned
85 pub unsafe fn new( 69 pub unsafe fn new(
86 state: &'d mut State<'d, U, T>, 70 state: &'d mut State<'d, U, T>,
87 _uarte: impl Unborrow<Target = U> + 'd, 71 _uarte: impl Unborrow<Target = U> + 'd,
88 timer: impl Unborrow<Target = T> + 'd, 72 timer: impl Unborrow<Target = T> + 'd,
89 ppi_ch1: impl Unborrow<Target = impl Channel> + 'd, 73 ppi_ch1: impl Unborrow<Target = impl OneToTwoChannel + 'd> + 'd,
90 ppi_ch2: impl Unborrow<Target = impl Channel> + 'd, 74 ppi_ch2: impl Unborrow<Target = impl OneToOneChannel + 'd> + 'd,
91 irq: impl Unborrow<Target = U::Interrupt> + 'd, 75 irq: impl Unborrow<Target = U::Interrupt> + 'd,
92 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 76 rxd: impl Unborrow<Target = impl GpioPin> + 'd,
93 txd: impl Unborrow<Target = impl GpioPin> + 'd, 77 txd: impl Unborrow<Target = impl GpioPin> + 'd,
@@ -96,7 +80,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
96 config: Config, 80 config: Config,
97 rx_buffer: &'d mut [u8], 81 rx_buffer: &'d mut [u8],
98 tx_buffer: &'d mut [u8], 82 tx_buffer: &'d mut [u8],
99 ) -> Result<Self, Error> { 83 ) -> Self {
100 unborrow!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); 84 unborrow!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts);
101 85
102 let r = U::regs(); 86 let r = U::regs();
@@ -160,18 +144,24 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
160 timer.cc(0).short_compare_clear(); 144 timer.cc(0).short_compare_clear();
161 timer.cc(0).short_compare_stop(); 145 timer.cc(0).short_compare_stop();
162 146
163 let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); 147 let mut ppi_ch1 = Ppi::new_one_to_two(
164 ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; 148 ppi_ch1,
165 ppi_ch1.subscribe(timer.task_clear())?; 149 Event::from_reg(&r.events_rxdrdy),
166 ppi_ch1.subscribe(timer.task_start())?; 150 timer.task_clear(),
151 timer.task_start(),
152 )
153 .degrade();
167 ppi_ch1.enable(); 154 ppi_ch1.enable();
168 155
169 let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); 156 let mut ppi_ch2 = Ppi::new_one_to_one(
170 ppi_ch2.publish(timer.cc(0).event_compare())?; 157 ppi_ch2,
171 ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; 158 timer.cc(0).event_compare(),
159 Task::from_reg(&r.tasks_stoprx),
160 )
161 .degrade();
172 ppi_ch2.enable(); 162 ppi_ch2.enable();
173 163
174 Ok(Self { 164 Self {
175 inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner { 165 inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner {
176 phantom: PhantomData, 166 phantom: PhantomData,
177 timer, 167 timer,
@@ -186,7 +176,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
186 tx_state: TxState::Idle, 176 tx_state: TxState::Idle,
187 tx_waker: WakerRegistration::new(), 177 tx_waker: WakerRegistration::new(),
188 }), 178 }),
189 }) 179 }
190 } 180 }
191 181
192 pub fn set_baudrate(&mut self, baudrate: Baudrate) { 182 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);
167impl_pin!(P0_30, 0, 30); 167impl_pin!(P0_30, 0, 30);
168impl_pin!(P0_31, 0, 31); 168impl_pin!(P0_31, 0, 31);
169 169
170impl_ppi_channel!(PPI_CH0, 0, 2, 1); 170impl_ppi_channel!(PPI_CH0, 0, true, 1, 2);
171impl_ppi_channel!(PPI_CH1, 1, 2, 1); 171impl_ppi_channel!(PPI_CH1, 1, true, 1, 2);
172impl_ppi_channel!(PPI_CH2, 2, 2, 1); 172impl_ppi_channel!(PPI_CH2, 2, true, 1, 2);
173impl_ppi_channel!(PPI_CH3, 3, 2, 1); 173impl_ppi_channel!(PPI_CH3, 3, true, 1, 2);
174impl_ppi_channel!(PPI_CH4, 4, 2, 1); 174impl_ppi_channel!(PPI_CH4, 4, true, 1, 2);
175impl_ppi_channel!(PPI_CH5, 5, 2, 1); 175impl_ppi_channel!(PPI_CH5, 5, true, 1, 2);
176impl_ppi_channel!(PPI_CH6, 6, 2, 1); 176impl_ppi_channel!(PPI_CH6, 6, true, 1, 2);
177impl_ppi_channel!(PPI_CH7, 7, 2, 1); 177impl_ppi_channel!(PPI_CH7, 7, true, 1, 2);
178impl_ppi_channel!(PPI_CH8, 8, 2, 1); 178impl_ppi_channel!(PPI_CH8, 8, true, 1, 2);
179impl_ppi_channel!(PPI_CH9, 9, 2, 1); 179impl_ppi_channel!(PPI_CH9, 9, true, 1, 2);
180impl_ppi_channel!(PPI_CH20, 20, 1, 0); 180impl_ppi_channel!(PPI_CH20, 20, false, 0, 1);
181impl_ppi_channel!(PPI_CH21, 21, 1, 0); 181impl_ppi_channel!(PPI_CH21, 21, false, 0, 1);
182impl_ppi_channel!(PPI_CH22, 22, 1, 0); 182impl_ppi_channel!(PPI_CH22, 22, false, 0, 1);
183impl_ppi_channel!(PPI_CH23, 23, 1, 0); 183impl_ppi_channel!(PPI_CH23, 23, false, 0, 1);
184impl_ppi_channel!(PPI_CH24, 24, 1, 0); 184impl_ppi_channel!(PPI_CH24, 24, false, 0, 1);
185impl_ppi_channel!(PPI_CH25, 25, 1, 0); 185impl_ppi_channel!(PPI_CH25, 25, false, 0, 1);
186impl_ppi_channel!(PPI_CH26, 26, 1, 0); 186impl_ppi_channel!(PPI_CH26, 26, false, 0, 1);
187impl_ppi_channel!(PPI_CH27, 27, 1, 0); 187impl_ppi_channel!(PPI_CH27, 27, false, 0, 1);
188impl_ppi_channel!(PPI_CH28, 28, 1, 0); 188impl_ppi_channel!(PPI_CH28, 28, false, 0, 1);
189impl_ppi_channel!(PPI_CH29, 29, 1, 0); 189impl_ppi_channel!(PPI_CH29, 29, false, 0, 1);
190impl_ppi_channel!(PPI_CH30, 30, 1, 0); 190impl_ppi_channel!(PPI_CH30, 30, false, 0, 1);
191impl_ppi_channel!(PPI_CH31, 31, 1, 0); 191impl_ppi_channel!(PPI_CH31, 31, false, 0, 1);
192 192
193impl_saadc_input!(P0_04, ANALOGINPUT2); 193impl_saadc_input!(P0_04, ANALOGINPUT2);
194impl_saadc_input!(P0_05, ANALOGINPUT3); 194impl_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);
172impl_pin!(P0_30, 0, 30); 172impl_pin!(P0_30, 0, 30);
173impl_pin!(P0_31, 0, 31); 173impl_pin!(P0_31, 0, 31);
174 174
175impl_ppi_channel!(PPI_CH0, 0, 2, 1); 175impl_ppi_channel!(PPI_CH0, 0, true, 1, 2);
176impl_ppi_channel!(PPI_CH1, 1, 2, 1); 176impl_ppi_channel!(PPI_CH1, 1, true, 1, 2);
177impl_ppi_channel!(PPI_CH2, 2, 2, 1); 177impl_ppi_channel!(PPI_CH2, 2, true, 1, 2);
178impl_ppi_channel!(PPI_CH3, 3, 2, 1); 178impl_ppi_channel!(PPI_CH3, 3, true, 1, 2);
179impl_ppi_channel!(PPI_CH4, 4, 2, 1); 179impl_ppi_channel!(PPI_CH4, 4, true, 1, 2);
180impl_ppi_channel!(PPI_CH5, 5, 2, 1); 180impl_ppi_channel!(PPI_CH5, 5, true, 1, 2);
181impl_ppi_channel!(PPI_CH6, 6, 2, 1); 181impl_ppi_channel!(PPI_CH6, 6, true, 1, 2);
182impl_ppi_channel!(PPI_CH7, 7, 2, 1); 182impl_ppi_channel!(PPI_CH7, 7, true, 1, 2);
183impl_ppi_channel!(PPI_CH8, 8, 2, 1); 183impl_ppi_channel!(PPI_CH8, 8, true, 1, 2);
184impl_ppi_channel!(PPI_CH9, 9, 2, 1); 184impl_ppi_channel!(PPI_CH9, 9, true, 1, 2);
185impl_ppi_channel!(PPI_CH10, 10, 2, 1); 185impl_ppi_channel!(PPI_CH10, 10, true, 1, 2);
186impl_ppi_channel!(PPI_CH11, 11, 2, 1); 186impl_ppi_channel!(PPI_CH11, 11, true, 1, 2);
187impl_ppi_channel!(PPI_CH12, 12, 2, 1); 187impl_ppi_channel!(PPI_CH12, 12, true, 1, 2);
188impl_ppi_channel!(PPI_CH13, 13, 2, 1); 188impl_ppi_channel!(PPI_CH13, 13, true, 1, 2);
189impl_ppi_channel!(PPI_CH14, 14, 2, 1); 189impl_ppi_channel!(PPI_CH14, 14, true, 1, 2);
190impl_ppi_channel!(PPI_CH15, 15, 2, 1); 190impl_ppi_channel!(PPI_CH15, 15, true, 1, 2);
191impl_ppi_channel!(PPI_CH16, 16, 2, 1); 191impl_ppi_channel!(PPI_CH16, 16, true, 1, 2);
192impl_ppi_channel!(PPI_CH17, 17, 2, 1); 192impl_ppi_channel!(PPI_CH17, 17, true, 1, 2);
193impl_ppi_channel!(PPI_CH18, 18, 2, 1); 193impl_ppi_channel!(PPI_CH18, 18, true, 1, 2);
194impl_ppi_channel!(PPI_CH19, 19, 2, 1); 194impl_ppi_channel!(PPI_CH19, 19, true, 1, 2);
195impl_ppi_channel!(PPI_CH20, 20, 1, 0); 195impl_ppi_channel!(PPI_CH20, 20, false, 0, 1);
196impl_ppi_channel!(PPI_CH21, 21, 1, 0); 196impl_ppi_channel!(PPI_CH21, 21, false, 0, 1);
197impl_ppi_channel!(PPI_CH22, 22, 1, 0); 197impl_ppi_channel!(PPI_CH22, 22, false, 0, 1);
198impl_ppi_channel!(PPI_CH23, 23, 1, 0); 198impl_ppi_channel!(PPI_CH23, 23, false, 0, 1);
199impl_ppi_channel!(PPI_CH24, 24, 1, 0); 199impl_ppi_channel!(PPI_CH24, 24, false, 0, 1);
200impl_ppi_channel!(PPI_CH25, 25, 1, 0); 200impl_ppi_channel!(PPI_CH25, 25, false, 0, 1);
201impl_ppi_channel!(PPI_CH26, 26, 1, 0); 201impl_ppi_channel!(PPI_CH26, 26, false, 0, 1);
202impl_ppi_channel!(PPI_CH27, 27, 1, 0); 202impl_ppi_channel!(PPI_CH27, 27, false, 0, 1);
203impl_ppi_channel!(PPI_CH28, 28, 1, 0); 203impl_ppi_channel!(PPI_CH28, 28, false, 0, 1);
204impl_ppi_channel!(PPI_CH29, 29, 1, 0); 204impl_ppi_channel!(PPI_CH29, 29, false, 0, 1);
205impl_ppi_channel!(PPI_CH30, 30, 1, 0); 205impl_ppi_channel!(PPI_CH30, 30, false, 0, 1);
206impl_ppi_channel!(PPI_CH31, 31, 1, 0); 206impl_ppi_channel!(PPI_CH31, 31, false, 0, 1);
207 207
208impl_saadc_input!(P0_02, ANALOGINPUT0); 208impl_saadc_input!(P0_02, ANALOGINPUT0);
209impl_saadc_input!(P0_03, ANALOGINPUT1); 209impl_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);
173impl_pin!(P0_30, 0, 30); 173impl_pin!(P0_30, 0, 30);
174impl_pin!(P0_31, 0, 31); 174impl_pin!(P0_31, 0, 31);
175 175
176impl_ppi_channel!(PPI_CH0, 0, 2, 1); 176impl_ppi_channel!(PPI_CH0, 0, true, 1, 2);
177impl_ppi_channel!(PPI_CH1, 1, 2, 1); 177impl_ppi_channel!(PPI_CH1, 1, true, 1, 2);
178impl_ppi_channel!(PPI_CH2, 2, 2, 1); 178impl_ppi_channel!(PPI_CH2, 2, true, 1, 2);
179impl_ppi_channel!(PPI_CH3, 3, 2, 1); 179impl_ppi_channel!(PPI_CH3, 3, true, 1, 2);
180impl_ppi_channel!(PPI_CH4, 4, 2, 1); 180impl_ppi_channel!(PPI_CH4, 4, true, 1, 2);
181impl_ppi_channel!(PPI_CH5, 5, 2, 1); 181impl_ppi_channel!(PPI_CH5, 5, true, 1, 2);
182impl_ppi_channel!(PPI_CH6, 6, 2, 1); 182impl_ppi_channel!(PPI_CH6, 6, true, 1, 2);
183impl_ppi_channel!(PPI_CH7, 7, 2, 1); 183impl_ppi_channel!(PPI_CH7, 7, true, 1, 2);
184impl_ppi_channel!(PPI_CH8, 8, 2, 1); 184impl_ppi_channel!(PPI_CH8, 8, true, 1, 2);
185impl_ppi_channel!(PPI_CH9, 9, 2, 1); 185impl_ppi_channel!(PPI_CH9, 9, true, 1, 2);
186impl_ppi_channel!(PPI_CH10, 10, 2, 1); 186impl_ppi_channel!(PPI_CH10, 10, true, 1, 2);
187impl_ppi_channel!(PPI_CH11, 11, 2, 1); 187impl_ppi_channel!(PPI_CH11, 11, true, 1, 2);
188impl_ppi_channel!(PPI_CH12, 12, 2, 1); 188impl_ppi_channel!(PPI_CH12, 12, true, 1, 2);
189impl_ppi_channel!(PPI_CH13, 13, 2, 1); 189impl_ppi_channel!(PPI_CH13, 13, true, 1, 2);
190impl_ppi_channel!(PPI_CH14, 14, 2, 1); 190impl_ppi_channel!(PPI_CH14, 14, true, 1, 2);
191impl_ppi_channel!(PPI_CH15, 15, 2, 1); 191impl_ppi_channel!(PPI_CH15, 15, true, 1, 2);
192impl_ppi_channel!(PPI_CH16, 16, 2, 1); 192impl_ppi_channel!(PPI_CH16, 16, true, 1, 2);
193impl_ppi_channel!(PPI_CH17, 17, 2, 1); 193impl_ppi_channel!(PPI_CH17, 17, true, 1, 2);
194impl_ppi_channel!(PPI_CH18, 18, 2, 1); 194impl_ppi_channel!(PPI_CH18, 18, true, 1, 2);
195impl_ppi_channel!(PPI_CH19, 19, 2, 1); 195impl_ppi_channel!(PPI_CH19, 19, true, 1, 2);
196impl_ppi_channel!(PPI_CH20, 20, 1, 0); 196impl_ppi_channel!(PPI_CH20, 20, false, 0, 1);
197impl_ppi_channel!(PPI_CH21, 21, 1, 0); 197impl_ppi_channel!(PPI_CH21, 21, false, 0, 1);
198impl_ppi_channel!(PPI_CH22, 22, 1, 0); 198impl_ppi_channel!(PPI_CH22, 22, false, 0, 1);
199impl_ppi_channel!(PPI_CH23, 23, 1, 0); 199impl_ppi_channel!(PPI_CH23, 23, false, 0, 1);
200impl_ppi_channel!(PPI_CH24, 24, 1, 0); 200impl_ppi_channel!(PPI_CH24, 24, false, 0, 1);
201impl_ppi_channel!(PPI_CH25, 25, 1, 0); 201impl_ppi_channel!(PPI_CH25, 25, false, 0, 1);
202impl_ppi_channel!(PPI_CH26, 26, 1, 0); 202impl_ppi_channel!(PPI_CH26, 26, false, 0, 1);
203impl_ppi_channel!(PPI_CH27, 27, 1, 0); 203impl_ppi_channel!(PPI_CH27, 27, false, 0, 1);
204impl_ppi_channel!(PPI_CH28, 28, 1, 0); 204impl_ppi_channel!(PPI_CH28, 28, false, 0, 1);
205impl_ppi_channel!(PPI_CH29, 29, 1, 0); 205impl_ppi_channel!(PPI_CH29, 29, false, 0, 1);
206impl_ppi_channel!(PPI_CH30, 30, 1, 0); 206impl_ppi_channel!(PPI_CH30, 30, false, 0, 1);
207impl_ppi_channel!(PPI_CH31, 31, 1, 0); 207impl_ppi_channel!(PPI_CH31, 31, false, 0, 1);
208 208
209impl_saadc_input!(P0_02, ANALOGINPUT0); 209impl_saadc_input!(P0_02, ANALOGINPUT0);
210impl_saadc_input!(P0_03, ANALOGINPUT1); 210impl_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);
168impl_pin!(P0_30, 0, 30); 168impl_pin!(P0_30, 0, 30);
169impl_pin!(P0_31, 0, 31); 169impl_pin!(P0_31, 0, 31);
170 170
171impl_ppi_channel!(PPI_CH0, 0, 2, 1); 171impl_ppi_channel!(PPI_CH0, 0, true, 1, 2);
172impl_ppi_channel!(PPI_CH1, 1, 2, 1); 172impl_ppi_channel!(PPI_CH1, 1, true, 1, 2);
173impl_ppi_channel!(PPI_CH2, 2, 2, 1); 173impl_ppi_channel!(PPI_CH2, 2, true, 1, 2);
174impl_ppi_channel!(PPI_CH3, 3, 2, 1); 174impl_ppi_channel!(PPI_CH3, 3, true, 1, 2);
175impl_ppi_channel!(PPI_CH4, 4, 2, 1); 175impl_ppi_channel!(PPI_CH4, 4, true, 1, 2);
176impl_ppi_channel!(PPI_CH5, 5, 2, 1); 176impl_ppi_channel!(PPI_CH5, 5, true, 1, 2);
177impl_ppi_channel!(PPI_CH6, 6, 2, 1); 177impl_ppi_channel!(PPI_CH6, 6, true, 1, 2);
178impl_ppi_channel!(PPI_CH7, 7, 2, 1); 178impl_ppi_channel!(PPI_CH7, 7, true, 1, 2);
179impl_ppi_channel!(PPI_CH8, 8, 2, 1); 179impl_ppi_channel!(PPI_CH8, 8, true, 1, 2);
180impl_ppi_channel!(PPI_CH9, 9, 2, 1); 180impl_ppi_channel!(PPI_CH9, 9, true, 1, 2);
181impl_ppi_channel!(PPI_CH10, 10, 2, 1); 181impl_ppi_channel!(PPI_CH10, 10, true, 1, 2);
182impl_ppi_channel!(PPI_CH11, 11, 2, 1); 182impl_ppi_channel!(PPI_CH11, 11, true, 1, 2);
183impl_ppi_channel!(PPI_CH12, 12, 2, 1); 183impl_ppi_channel!(PPI_CH12, 12, true, 1, 2);
184impl_ppi_channel!(PPI_CH13, 13, 2, 1); 184impl_ppi_channel!(PPI_CH13, 13, true, 1, 2);
185impl_ppi_channel!(PPI_CH14, 14, 2, 1); 185impl_ppi_channel!(PPI_CH14, 14, true, 1, 2);
186impl_ppi_channel!(PPI_CH15, 15, 2, 1); 186impl_ppi_channel!(PPI_CH15, 15, true, 1, 2);
187impl_ppi_channel!(PPI_CH16, 16, 2, 1); 187impl_ppi_channel!(PPI_CH16, 16, true, 1, 2);
188impl_ppi_channel!(PPI_CH17, 17, 2, 1); 188impl_ppi_channel!(PPI_CH17, 17, true, 1, 2);
189impl_ppi_channel!(PPI_CH18, 18, 2, 1); 189impl_ppi_channel!(PPI_CH18, 18, true, 1, 2);
190impl_ppi_channel!(PPI_CH19, 19, 2, 1); 190impl_ppi_channel!(PPI_CH19, 19, true, 1, 2);
191impl_ppi_channel!(PPI_CH20, 20, 1, 0); 191impl_ppi_channel!(PPI_CH20, 20, false, 0, 1);
192impl_ppi_channel!(PPI_CH21, 21, 1, 0); 192impl_ppi_channel!(PPI_CH21, 21, false, 0, 1);
193impl_ppi_channel!(PPI_CH22, 22, 1, 0); 193impl_ppi_channel!(PPI_CH22, 22, false, 0, 1);
194impl_ppi_channel!(PPI_CH23, 23, 1, 0); 194impl_ppi_channel!(PPI_CH23, 23, false, 0, 1);
195impl_ppi_channel!(PPI_CH24, 24, 1, 0); 195impl_ppi_channel!(PPI_CH24, 24, false, 0, 1);
196impl_ppi_channel!(PPI_CH25, 25, 1, 0); 196impl_ppi_channel!(PPI_CH25, 25, false, 0, 1);
197impl_ppi_channel!(PPI_CH26, 26, 1, 0); 197impl_ppi_channel!(PPI_CH26, 26, false, 0, 1);
198impl_ppi_channel!(PPI_CH27, 27, 1, 0); 198impl_ppi_channel!(PPI_CH27, 27, false, 0, 1);
199impl_ppi_channel!(PPI_CH28, 28, 1, 0); 199impl_ppi_channel!(PPI_CH28, 28, false, 0, 1);
200impl_ppi_channel!(PPI_CH29, 29, 1, 0); 200impl_ppi_channel!(PPI_CH29, 29, false, 0, 1);
201impl_ppi_channel!(PPI_CH30, 30, 1, 0); 201impl_ppi_channel!(PPI_CH30, 30, false, 0, 1);
202impl_ppi_channel!(PPI_CH31, 31, 1, 0); 202impl_ppi_channel!(PPI_CH31, 31, false, 0, 1);
203 203
204pub mod irqs { 204pub mod irqs {
205 use crate::pac::Interrupt as InterruptEnum; 205 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);
190impl_pin!(P0_30, 0, 30); 190impl_pin!(P0_30, 0, 30);
191impl_pin!(P0_31, 0, 31); 191impl_pin!(P0_31, 0, 31);
192 192
193impl_ppi_channel!(PPI_CH0, 0, 2, 1); 193impl_ppi_channel!(PPI_CH0, 0, true, 1, 2);
194impl_ppi_channel!(PPI_CH1, 1, 2, 1); 194impl_ppi_channel!(PPI_CH1, 1, true, 1, 2);
195impl_ppi_channel!(PPI_CH2, 2, 2, 1); 195impl_ppi_channel!(PPI_CH2, 2, true, 1, 2);
196impl_ppi_channel!(PPI_CH3, 3, 2, 1); 196impl_ppi_channel!(PPI_CH3, 3, true, 1, 2);
197impl_ppi_channel!(PPI_CH4, 4, 2, 1); 197impl_ppi_channel!(PPI_CH4, 4, true, 1, 2);
198impl_ppi_channel!(PPI_CH5, 5, 2, 1); 198impl_ppi_channel!(PPI_CH5, 5, true, 1, 2);
199impl_ppi_channel!(PPI_CH6, 6, 2, 1); 199impl_ppi_channel!(PPI_CH6, 6, true, 1, 2);
200impl_ppi_channel!(PPI_CH7, 7, 2, 1); 200impl_ppi_channel!(PPI_CH7, 7, true, 1, 2);
201impl_ppi_channel!(PPI_CH8, 8, 2, 1); 201impl_ppi_channel!(PPI_CH8, 8, true, 1, 2);
202impl_ppi_channel!(PPI_CH9, 9, 2, 1); 202impl_ppi_channel!(PPI_CH9, 9, true, 1, 2);
203impl_ppi_channel!(PPI_CH10, 10, 2, 1); 203impl_ppi_channel!(PPI_CH10, 10, true, 1, 2);
204impl_ppi_channel!(PPI_CH11, 11, 2, 1); 204impl_ppi_channel!(PPI_CH11, 11, true, 1, 2);
205impl_ppi_channel!(PPI_CH12, 12, 2, 1); 205impl_ppi_channel!(PPI_CH12, 12, true, 1, 2);
206impl_ppi_channel!(PPI_CH13, 13, 2, 1); 206impl_ppi_channel!(PPI_CH13, 13, true, 1, 2);
207impl_ppi_channel!(PPI_CH14, 14, 2, 1); 207impl_ppi_channel!(PPI_CH14, 14, true, 1, 2);
208impl_ppi_channel!(PPI_CH15, 15, 2, 1); 208impl_ppi_channel!(PPI_CH15, 15, true, 1, 2);
209impl_ppi_channel!(PPI_CH16, 16, 2, 1); 209impl_ppi_channel!(PPI_CH16, 16, true, 1, 2);
210impl_ppi_channel!(PPI_CH17, 17, 2, 1); 210impl_ppi_channel!(PPI_CH17, 17, true, 1, 2);
211impl_ppi_channel!(PPI_CH18, 18, 2, 1); 211impl_ppi_channel!(PPI_CH18, 18, true, 1, 2);
212impl_ppi_channel!(PPI_CH19, 19, 2, 1); 212impl_ppi_channel!(PPI_CH19, 19, true, 1, 2);
213impl_ppi_channel!(PPI_CH20, 20, 1, 0); 213impl_ppi_channel!(PPI_CH20, 20, false, 0, 1);
214impl_ppi_channel!(PPI_CH21, 21, 1, 0); 214impl_ppi_channel!(PPI_CH21, 21, false, 0, 1);
215impl_ppi_channel!(PPI_CH22, 22, 1, 0); 215impl_ppi_channel!(PPI_CH22, 22, false, 0, 1);
216impl_ppi_channel!(PPI_CH23, 23, 1, 0); 216impl_ppi_channel!(PPI_CH23, 23, false, 0, 1);
217impl_ppi_channel!(PPI_CH24, 24, 1, 0); 217impl_ppi_channel!(PPI_CH24, 24, false, 0, 1);
218impl_ppi_channel!(PPI_CH25, 25, 1, 0); 218impl_ppi_channel!(PPI_CH25, 25, false, 0, 1);
219impl_ppi_channel!(PPI_CH26, 26, 1, 0); 219impl_ppi_channel!(PPI_CH26, 26, false, 0, 1);
220impl_ppi_channel!(PPI_CH27, 27, 1, 0); 220impl_ppi_channel!(PPI_CH27, 27, false, 0, 1);
221impl_ppi_channel!(PPI_CH28, 28, 1, 0); 221impl_ppi_channel!(PPI_CH28, 28, false, 0, 1);
222impl_ppi_channel!(PPI_CH29, 29, 1, 0); 222impl_ppi_channel!(PPI_CH29, 29, false, 0, 1);
223impl_ppi_channel!(PPI_CH30, 30, 1, 0); 223impl_ppi_channel!(PPI_CH30, 30, false, 0, 1);
224impl_ppi_channel!(PPI_CH31, 31, 1, 0); 224impl_ppi_channel!(PPI_CH31, 31, false, 0, 1);
225 225
226impl_saadc_input!(P0_02, ANALOGINPUT0); 226impl_saadc_input!(P0_02, ANALOGINPUT0);
227impl_saadc_input!(P0_03, ANALOGINPUT1); 227impl_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);
226impl_pin!(P1_14, 1, 14); 226impl_pin!(P1_14, 1, 14);
227impl_pin!(P1_15, 1, 15); 227impl_pin!(P1_15, 1, 15);
228 228
229impl_ppi_channel!(PPI_CH0, 0, 2, 1); 229impl_ppi_channel!(PPI_CH0, 0, true, 1, 2);
230impl_ppi_channel!(PPI_CH1, 1, 2, 1); 230impl_ppi_channel!(PPI_CH1, 1, true, 1, 2);
231impl_ppi_channel!(PPI_CH2, 2, 2, 1); 231impl_ppi_channel!(PPI_CH2, 2, true, 1, 2);
232impl_ppi_channel!(PPI_CH3, 3, 2, 1); 232impl_ppi_channel!(PPI_CH3, 3, true, 1, 2);
233impl_ppi_channel!(PPI_CH4, 4, 2, 1); 233impl_ppi_channel!(PPI_CH4, 4, true, 1, 2);
234impl_ppi_channel!(PPI_CH5, 5, 2, 1); 234impl_ppi_channel!(PPI_CH5, 5, true, 1, 2);
235impl_ppi_channel!(PPI_CH6, 6, 2, 1); 235impl_ppi_channel!(PPI_CH6, 6, true, 1, 2);
236impl_ppi_channel!(PPI_CH7, 7, 2, 1); 236impl_ppi_channel!(PPI_CH7, 7, true, 1, 2);
237impl_ppi_channel!(PPI_CH8, 8, 2, 1); 237impl_ppi_channel!(PPI_CH8, 8, true, 1, 2);
238impl_ppi_channel!(PPI_CH9, 9, 2, 1); 238impl_ppi_channel!(PPI_CH9, 9, true, 1, 2);
239impl_ppi_channel!(PPI_CH10, 10, 2, 1); 239impl_ppi_channel!(PPI_CH10, 10, true, 1, 2);
240impl_ppi_channel!(PPI_CH11, 11, 2, 1); 240impl_ppi_channel!(PPI_CH11, 11, true, 1, 2);
241impl_ppi_channel!(PPI_CH12, 12, 2, 1); 241impl_ppi_channel!(PPI_CH12, 12, true, 1, 2);
242impl_ppi_channel!(PPI_CH13, 13, 2, 1); 242impl_ppi_channel!(PPI_CH13, 13, true, 1, 2);
243impl_ppi_channel!(PPI_CH14, 14, 2, 1); 243impl_ppi_channel!(PPI_CH14, 14, true, 1, 2);
244impl_ppi_channel!(PPI_CH15, 15, 2, 1); 244impl_ppi_channel!(PPI_CH15, 15, true, 1, 2);
245impl_ppi_channel!(PPI_CH16, 16, 2, 1); 245impl_ppi_channel!(PPI_CH16, 16, true, 1, 2);
246impl_ppi_channel!(PPI_CH17, 17, 2, 1); 246impl_ppi_channel!(PPI_CH17, 17, true, 1, 2);
247impl_ppi_channel!(PPI_CH18, 18, 2, 1); 247impl_ppi_channel!(PPI_CH18, 18, true, 1, 2);
248impl_ppi_channel!(PPI_CH19, 19, 2, 1); 248impl_ppi_channel!(PPI_CH19, 19, true, 1, 2);
249impl_ppi_channel!(PPI_CH20, 20, 1, 0); 249impl_ppi_channel!(PPI_CH20, 20, false, 0, 1);
250impl_ppi_channel!(PPI_CH21, 21, 1, 0); 250impl_ppi_channel!(PPI_CH21, 21, false, 0, 1);
251impl_ppi_channel!(PPI_CH22, 22, 1, 0); 251impl_ppi_channel!(PPI_CH22, 22, false, 0, 1);
252impl_ppi_channel!(PPI_CH23, 23, 1, 0); 252impl_ppi_channel!(PPI_CH23, 23, false, 0, 1);
253impl_ppi_channel!(PPI_CH24, 24, 1, 0); 253impl_ppi_channel!(PPI_CH24, 24, false, 0, 1);
254impl_ppi_channel!(PPI_CH25, 25, 1, 0); 254impl_ppi_channel!(PPI_CH25, 25, false, 0, 1);
255impl_ppi_channel!(PPI_CH26, 26, 1, 0); 255impl_ppi_channel!(PPI_CH26, 26, false, 0, 1);
256impl_ppi_channel!(PPI_CH27, 27, 1, 0); 256impl_ppi_channel!(PPI_CH27, 27, false, 0, 1);
257impl_ppi_channel!(PPI_CH28, 28, 1, 0); 257impl_ppi_channel!(PPI_CH28, 28, false, 0, 1);
258impl_ppi_channel!(PPI_CH29, 29, 1, 0); 258impl_ppi_channel!(PPI_CH29, 29, false, 0, 1);
259impl_ppi_channel!(PPI_CH30, 30, 1, 0); 259impl_ppi_channel!(PPI_CH30, 30, false, 0, 1);
260impl_ppi_channel!(PPI_CH31, 31, 1, 0); 260impl_ppi_channel!(PPI_CH31, 31, false, 0, 1);
261 261
262impl_saadc_input!(P0_02, ANALOGINPUT0); 262impl_saadc_input!(P0_02, ANALOGINPUT0);
263impl_saadc_input!(P0_03, ANALOGINPUT1); 263impl_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);
231impl_pin!(P1_14, 1, 14); 231impl_pin!(P1_14, 1, 14);
232impl_pin!(P1_15, 1, 15); 232impl_pin!(P1_15, 1, 15);
233 233
234impl_ppi_channel!(PPI_CH0, 0, 2, 1); 234impl_ppi_channel!(PPI_CH0, 0, true, 1, 2);
235impl_ppi_channel!(PPI_CH1, 1, 2, 1); 235impl_ppi_channel!(PPI_CH1, 1, true, 1, 2);
236impl_ppi_channel!(PPI_CH2, 2, 2, 1); 236impl_ppi_channel!(PPI_CH2, 2, true, 1, 2);
237impl_ppi_channel!(PPI_CH3, 3, 2, 1); 237impl_ppi_channel!(PPI_CH3, 3, true, 1, 2);
238impl_ppi_channel!(PPI_CH4, 4, 2, 1); 238impl_ppi_channel!(PPI_CH4, 4, true, 1, 2);
239impl_ppi_channel!(PPI_CH5, 5, 2, 1); 239impl_ppi_channel!(PPI_CH5, 5, true, 1, 2);
240impl_ppi_channel!(PPI_CH6, 6, 2, 1); 240impl_ppi_channel!(PPI_CH6, 6, true, 1, 2);
241impl_ppi_channel!(PPI_CH7, 7, 2, 1); 241impl_ppi_channel!(PPI_CH7, 7, true, 1, 2);
242impl_ppi_channel!(PPI_CH8, 8, 2, 1); 242impl_ppi_channel!(PPI_CH8, 8, true, 1, 2);
243impl_ppi_channel!(PPI_CH9, 9, 2, 1); 243impl_ppi_channel!(PPI_CH9, 9, true, 1, 2);
244impl_ppi_channel!(PPI_CH10, 10, 2, 1); 244impl_ppi_channel!(PPI_CH10, 10, true, 1, 2);
245impl_ppi_channel!(PPI_CH11, 11, 2, 1); 245impl_ppi_channel!(PPI_CH11, 11, true, 1, 2);
246impl_ppi_channel!(PPI_CH12, 12, 2, 1); 246impl_ppi_channel!(PPI_CH12, 12, true, 1, 2);
247impl_ppi_channel!(PPI_CH13, 13, 2, 1); 247impl_ppi_channel!(PPI_CH13, 13, true, 1, 2);
248impl_ppi_channel!(PPI_CH14, 14, 2, 1); 248impl_ppi_channel!(PPI_CH14, 14, true, 1, 2);
249impl_ppi_channel!(PPI_CH15, 15, 2, 1); 249impl_ppi_channel!(PPI_CH15, 15, true, 1, 2);
250impl_ppi_channel!(PPI_CH16, 16, 2, 1); 250impl_ppi_channel!(PPI_CH16, 16, true, 1, 2);
251impl_ppi_channel!(PPI_CH17, 17, 2, 1); 251impl_ppi_channel!(PPI_CH17, 17, true, 1, 2);
252impl_ppi_channel!(PPI_CH18, 18, 2, 1); 252impl_ppi_channel!(PPI_CH18, 18, true, 1, 2);
253impl_ppi_channel!(PPI_CH19, 19, 2, 1); 253impl_ppi_channel!(PPI_CH19, 19, true, 1, 2);
254impl_ppi_channel!(PPI_CH20, 20, 1, 0); 254impl_ppi_channel!(PPI_CH20, 20, false, 0, 1);
255impl_ppi_channel!(PPI_CH21, 21, 1, 0); 255impl_ppi_channel!(PPI_CH21, 21, false, 0, 1);
256impl_ppi_channel!(PPI_CH22, 22, 1, 0); 256impl_ppi_channel!(PPI_CH22, 22, false, 0, 1);
257impl_ppi_channel!(PPI_CH23, 23, 1, 0); 257impl_ppi_channel!(PPI_CH23, 23, false, 0, 1);
258impl_ppi_channel!(PPI_CH24, 24, 1, 0); 258impl_ppi_channel!(PPI_CH24, 24, false, 0, 1);
259impl_ppi_channel!(PPI_CH25, 25, 1, 0); 259impl_ppi_channel!(PPI_CH25, 25, false, 0, 1);
260impl_ppi_channel!(PPI_CH26, 26, 1, 0); 260impl_ppi_channel!(PPI_CH26, 26, false, 0, 1);
261impl_ppi_channel!(PPI_CH27, 27, 1, 0); 261impl_ppi_channel!(PPI_CH27, 27, false, 0, 1);
262impl_ppi_channel!(PPI_CH28, 28, 1, 0); 262impl_ppi_channel!(PPI_CH28, 28, false, 0, 1);
263impl_ppi_channel!(PPI_CH29, 29, 1, 0); 263impl_ppi_channel!(PPI_CH29, 29, false, 0, 1);
264impl_ppi_channel!(PPI_CH30, 30, 1, 0); 264impl_ppi_channel!(PPI_CH30, 30, false, 0, 1);
265impl_ppi_channel!(PPI_CH31, 31, 1, 0); 265impl_ppi_channel!(PPI_CH31, 31, false, 0, 1);
266 266
267impl_saadc_input!(P0_02, ANALOGINPUT0); 267impl_saadc_input!(P0_02, ANALOGINPUT0);
268impl_saadc_input!(P0_03, ANALOGINPUT1); 268impl_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);
184impl_pin!(P0_30, 0, 30); 184impl_pin!(P0_30, 0, 30);
185impl_pin!(P0_31, 0, 31); 185impl_pin!(P0_31, 0, 31);
186 186
187impl_ppi_channel!(PPI_CH0, 0); 187impl_ppi_channel!(PPI_CH0, 0, true, many, many);
188impl_ppi_channel!(PPI_CH1, 1); 188impl_ppi_channel!(PPI_CH1, 1, true, many, many);
189impl_ppi_channel!(PPI_CH2, 2); 189impl_ppi_channel!(PPI_CH2, 2, true, many, many);
190impl_ppi_channel!(PPI_CH3, 3); 190impl_ppi_channel!(PPI_CH3, 3, true, many, many);
191impl_ppi_channel!(PPI_CH4, 4); 191impl_ppi_channel!(PPI_CH4, 4, true, many, many);
192impl_ppi_channel!(PPI_CH5, 5); 192impl_ppi_channel!(PPI_CH5, 5, true, many, many);
193impl_ppi_channel!(PPI_CH6, 6); 193impl_ppi_channel!(PPI_CH6, 6, true, many, many);
194impl_ppi_channel!(PPI_CH7, 7); 194impl_ppi_channel!(PPI_CH7, 7, true, many, many);
195impl_ppi_channel!(PPI_CH8, 8); 195impl_ppi_channel!(PPI_CH8, 8, true, many, many);
196impl_ppi_channel!(PPI_CH9, 9); 196impl_ppi_channel!(PPI_CH9, 9, true, many, many);
197impl_ppi_channel!(PPI_CH10, 10); 197impl_ppi_channel!(PPI_CH10, 10, true, many, many);
198impl_ppi_channel!(PPI_CH11, 11); 198impl_ppi_channel!(PPI_CH11, 11, true, many, many);
199impl_ppi_channel!(PPI_CH12, 12); 199impl_ppi_channel!(PPI_CH12, 12, true, many, many);
200impl_ppi_channel!(PPI_CH13, 13); 200impl_ppi_channel!(PPI_CH13, 13, true, many, many);
201impl_ppi_channel!(PPI_CH14, 14); 201impl_ppi_channel!(PPI_CH14, 14, true, many, many);
202impl_ppi_channel!(PPI_CH15, 15); 202impl_ppi_channel!(PPI_CH15, 15, true, many, many);
203 203
204impl_saadc_input!(P0_13, ANALOGINPUT0); 204impl_saadc_input!(P0_13, ANALOGINPUT0);
205impl_saadc_input!(P0_14, ANALOGINPUT1); 205impl_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;
11 11
12use crate::gpio::sealed::Pin as _; 12use crate::gpio::sealed::Pin as _;
13use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin}; 13use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin};
14use crate::interconnect::{Event, Task};
14use crate::pac; 15use crate::pac;
15use crate::ppi::{Event, Task};
16use crate::{interrupt, peripherals}; 16use crate::{interrupt, peripherals};
17 17
18pub const CHANNEL_COUNT: usize = 8; 18pub const CHANNEL_COUNT: usize = 8;
@@ -190,13 +190,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> {
190 /// Returns the IN event, for use with PPI. 190 /// Returns the IN event, for use with PPI.
191 pub fn event_in(&self) -> Event { 191 pub fn event_in(&self) -> Event {
192 let g = unsafe { &*pac::GPIOTE::ptr() }; 192 let g = unsafe { &*pac::GPIOTE::ptr() };
193 193 Event::from_reg(&g.events_in[self.ch.number()])
194 #[cfg(feature = "_ppi")]
195 let reg = &g.events_in[self.ch.number()];
196 #[cfg(feature = "_dppi")]
197 let reg = &g.publish_in[self.ch.number()];
198
199 Event::from_reg(reg)
200 } 194 }
201} 195}
202 196
@@ -277,33 +271,21 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
277 /// Returns the OUT task, for use with PPI. 271 /// Returns the OUT task, for use with PPI.
278 pub fn task_out(&self) -> Task { 272 pub fn task_out(&self) -> Task {
279 let g = unsafe { &*pac::GPIOTE::ptr() }; 273 let g = unsafe { &*pac::GPIOTE::ptr() };
280 #[cfg(feature = "_ppi")] 274 Task::from_reg(&g.tasks_out[self.ch.number()])
281 let reg = &g.tasks_out[self.ch.number()];
282 #[cfg(feature = "_dppi")]
283 let reg = &g.subscribe_out[self.ch.number()];
284 Task::from_reg(reg)
285 } 275 }
286 276
287 /// Returns the CLR task, for use with PPI. 277 /// Returns the CLR task, for use with PPI.
288 #[cfg(not(feature = "nrf51"))] 278 #[cfg(not(feature = "nrf51"))]
289 pub fn task_clr(&self) -> Task { 279 pub fn task_clr(&self) -> Task {
290 let g = unsafe { &*pac::GPIOTE::ptr() }; 280 let g = unsafe { &*pac::GPIOTE::ptr() };
291 #[cfg(feature = "_ppi")] 281 Task::from_reg(&g.tasks_clr[self.ch.number()])
292 let reg = &g.tasks_clr[self.ch.number()];
293 #[cfg(feature = "_dppi")]
294 let reg = &g.subscribe_clr[self.ch.number()];
295 Task::from_reg(reg)
296 } 282 }
297 283
298 /// Returns the SET task, for use with PPI. 284 /// Returns the SET task, for use with PPI.
299 #[cfg(not(feature = "nrf51"))] 285 #[cfg(not(feature = "nrf51"))]
300 pub fn task_set(&self) -> Task { 286 pub fn task_set(&self) -> Task {
301 let g = unsafe { &*pac::GPIOTE::ptr() }; 287 let g = unsafe { &*pac::GPIOTE::ptr() };
302 #[cfg(feature = "_ppi")] 288 Task::from_reg(&g.tasks_set[self.ch.number()])
303 let reg = &g.tasks_set[self.ch.number()];
304 #[cfg(feature = "_dppi")]
305 let reg = &g.subscribe_set[self.ch.number()];
306 Task::from_reg(reg)
307 } 289 }
308} 290}
309 291
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 @@
1use super::{Channel, Event, Ppi, Task};
2
3const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
4const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
5const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
6
7impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize>
8 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
9{
10 pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) {
11 unsafe {
12 task.0
13 .as_ptr()
14 .add(REGISTER_DPPI_CONFIG_OFFSET)
15 .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK));
16 }
17 }
18
19 pub(super) fn disable_task(task: &Task, _channel: &C, _index: usize) {
20 unsafe {
21 task.0
22 .as_ptr()
23 .add(REGISTER_DPPI_CONFIG_OFFSET)
24 .write_volatile(0);
25 }
26 }
27
28 pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) {
29 unsafe {
30 event
31 .0
32 .as_ptr()
33 .add(REGISTER_DPPI_CONFIG_OFFSET)
34 .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK));
35 }
36 }
37
38 pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) {
39 unsafe {
40 event
41 .0
42 .as_ptr()
43 .add(REGISTER_DPPI_CONFIG_OFFSET)
44 .write_volatile(0);
45 }
46 }
47}
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 @@
1#![macro_use]
2
3//! HAL interface for the PPI and DPPI peripheral.
4//!
5//! The (Distributed) Programmable Peripheral Interconnect interface allows for an autonomous interoperability
6//! between peripherals through their events and tasks. There are fixed PPI channels and fully
7//! configurable ones. Fixed channels can only connect specific events to specific tasks. For fully
8//! configurable channels, it is possible to choose, via software, the event and the task that it
9//! will triggered by the event.
10//!
11//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task
12//! to be triggered by the same event, even fixed PPI channels have a configurable fork task.
13//!
14//! The DPPI for nRF53 and nRF91 devices works in a different way. Every channel can support infinitely
15//! many tasks and events, but any single task or event can only be coupled with one channel.
16//!
17
18use crate::{pac, peripherals};
19use core::marker::PhantomData;
20use core::ptr::NonNull;
21use embassy::util::Unborrow;
22use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
23
24#[cfg(feature = "_dppi")]
25mod dppi;
26#[cfg(feature = "_ppi")]
27mod ppi;
28
29pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
30 ch: C,
31 events: [Event; EVENT_COUNT],
32 tasks: [Task; TASK_COUNT],
33 phantom: PhantomData<&'d mut C>,
34}
35
36impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize>
37 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
38{
39 pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> {
40 Ppi {
41 ch: AnyChannel {
42 number: self.ch.number() as u8,
43 #[cfg(feature = "_ppi")]
44 has_configurable_task: self.ch.is_task_configurable(),
45 },
46 events: self.events,
47 tasks: self.tasks,
48 phantom: PhantomData,
49 }
50 }
51
52 /// Enables the channel.
53 pub fn enable(&mut self) {
54 let r = unsafe { &*pac::PPI::ptr() };
55 r.chenset
56 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
57 }
58
59 /// Disables the channel.
60 pub fn disable(&mut self) {
61 let r = unsafe { &*pac::PPI::ptr() };
62 r.chenclr
63 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
64 }
65
66 /// Enables all tasks and events
67 fn enable_all(&self) {
68 for (index, task) in self.tasks.iter().enumerate() {
69 Self::enable_task(task, &self.ch, index);
70 }
71 for (index, event) in self.events.iter().enumerate() {
72 Self::enable_event(event, &self.ch, index);
73 }
74 }
75
76 /// Disable all tasks and events
77 fn disable_all(&self) {
78 for (index, task) in self.tasks.iter().enumerate() {
79 Self::disable_task(task, &self.ch, index);
80 }
81 for (index, event) in self.events.iter().enumerate() {
82 Self::disable_event(event, &self.ch, index);
83 }
84 }
85}
86
87impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop
88 for Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
89{
90 fn drop(&mut self) {
91 self.disable();
92 self.disable_all();
93 }
94}
95
96impl<'d, C: StaticToOneChannel> Ppi<'d, C, 0, 1> {
97 pub fn new_static_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self {
98 unborrow!(ch);
99
100 let s = Self {
101 ch,
102 events: [],
103 tasks: [task],
104 phantom: PhantomData,
105 };
106
107 s.enable_all();
108 s
109 }
110}
111
112impl<'d, C: OneToOneChannel> Ppi<'d, C, 1, 1> {
113 pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self {
114 unborrow!(ch);
115
116 let s = Self {
117 ch,
118 events: [event],
119 tasks: [task],
120 phantom: PhantomData,
121 };
122
123 s.enable_all();
124 s
125 }
126}
127
128impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> {
129 pub fn new_one_to_two(
130 ch: impl Unborrow<Target = C> + 'd,
131 event: Event,
132 task1: Task,
133 task2: Task,
134 ) -> Self {
135 unborrow!(ch);
136
137 let s = Self {
138 ch,
139 events: [event],
140 tasks: [task1, task2],
141 phantom: PhantomData,
142 };
143
144 s.enable_all();
145 s
146 }
147}
148
149impl<'d, C: ManyToManyChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize>
150 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
151{
152 pub fn new_many_to_many(
153 ch: impl Unborrow<Target = C> + 'd,
154 events: [Event; EVENT_COUNT],
155 tasks: [Task; TASK_COUNT],
156 ) -> Self {
157 unborrow!(ch);
158
159 let s = Self {
160 ch,
161 events,
162 tasks,
163 phantom: PhantomData,
164 };
165
166 s.enable_all();
167 s
168 }
169}
170
171/// Represents a task that a peripheral can do.
172/// When a task is subscribed to a PPI channel it will run when the channel is triggered by
173/// a published event.
174///
175/// The pointer is to a task register
176#[derive(PartialEq, Eq, Clone, Copy)]
177pub struct Task(pub NonNull<u32>);
178impl Task {
179 pub(crate) fn from_reg<T>(reg: &T) -> Self {
180 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
181 }
182}
183
184/// # Safety
185///
186/// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core.
187unsafe impl Send for Task {}
188
189/// Represents an event that a peripheral can publish.
190/// An event can be set to publish on a PPI channel when the event happens.
191///
192/// The pointer is to an event register
193#[derive(PartialEq, Eq, Clone, Copy)]
194pub struct Event(pub NonNull<u32>);
195impl Event {
196 pub(crate) fn from_reg<T>(reg: &T) -> Self {
197 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
198 }
199}
200
201/// # Safety
202///
203/// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core.
204unsafe impl Send for Event {}
205
206// ======================
207// traits
208
209pub(crate) mod sealed {
210 pub trait Channel {}
211 pub trait Group {}
212}
213
214pub trait Channel: sealed::Channel + Unborrow<Target = Self> + Sized {
215 /// Returns the number of the channel
216 fn number(&self) -> usize;
217 #[cfg(feature = "_ppi")]
218 fn is_task_configurable(&self) -> bool;
219}
220
221pub trait StaticToOneChannel: Channel {}
222pub trait OneToOneChannel: StaticToOneChannel {}
223pub trait OneToTwoChannel: OneToOneChannel {}
224pub trait ManyToManyChannel: OneToTwoChannel {}
225
226pub trait Group: sealed::Group + Sized {
227 fn number(&self) -> usize;
228}
229
230// ======================
231// channels
232
233pub struct AnyChannel {
234 number: u8,
235 #[cfg(feature = "_ppi")]
236 has_configurable_task: bool,
237}
238unsafe_impl_unborrow!(AnyChannel);
239impl sealed::Channel for AnyChannel {}
240impl Channel for AnyChannel {
241 fn number(&self) -> usize {
242 self.number as usize
243 }
244
245 #[cfg(feature = "_ppi")]
246 fn is_task_configurable(&self) -> bool {
247 self.has_configurable_task
248 }
249}
250
251macro_rules! impl_ppi_channel {
252 ($type:ident, $number:expr, $has_configurable_task:expr) => {
253 impl crate::interconnect::sealed::Channel for peripherals::$type {}
254 impl crate::interconnect::Channel for peripherals::$type {
255 fn number(&self) -> usize {
256 $number
257 }
258
259 #[cfg(feature = "_ppi")]
260 fn is_task_configurable(&self) -> bool {
261 $has_configurable_task
262 }
263 }
264 };
265 ($type:ident, $number:expr, $has_configurable_task:expr, 0, 0) => {
266 impl_ppi_channel!($type, $number, $has_configurable_task);
267 };
268 ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => {
269 impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0);
270 impl crate::interconnect::StaticToOneChannel for peripherals::$type {}
271 };
272 ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => {
273 impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1);
274 impl crate::interconnect::OneToOneChannel for peripherals::$type {}
275 };
276 ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => {
277 impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1);
278 impl crate::interconnect::OneToTwoChannel for peripherals::$type {}
279 };
280 ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => {
281 impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2);
282 impl crate::interconnect::ManyToManyChannel for peripherals::$type {}
283 };
284}
285
286// ======================
287// groups
288
289pub struct AnyGroup {
290 number: u8,
291}
292unsafe_impl_unborrow!(AnyGroup);
293impl sealed::Group for AnyGroup {}
294impl Group for AnyGroup {
295 fn number(&self) -> usize {
296 self.number as usize
297 }
298}
299
300macro_rules! impl_group {
301 ($type:ident, $number:expr) => {
302 impl sealed::Group for peripherals::$type {}
303 impl Group for peripherals::$type {
304 fn number(&self) -> usize {
305 $number
306 }
307 }
308 };
309}
310
311impl_group!(PPI_GROUP0, 0);
312impl_group!(PPI_GROUP1, 1);
313impl_group!(PPI_GROUP2, 2);
314impl_group!(PPI_GROUP3, 3);
315#[cfg(not(feature = "nrf51"))]
316impl_group!(PPI_GROUP4, 4);
317#[cfg(not(feature = "nrf51"))]
318impl_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 @@
1use super::{Channel, Event, Ppi, Task};
2use crate::pac;
3
4impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize>
5 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
6{
7 pub(super) fn enable_task(task: &Task, channel: &C, index: usize) {
8 match (index, channel.is_task_configurable()) {
9 (0, false) => Self::set_fork_task(Some(task), channel.number()), // Static channel with fork
10 (0, true) => Self::set_main_task(Some(task), channel.number()), // Configurable channel without fork
11 (1, true) => Self::set_fork_task(Some(task), channel.number()), // Configurable channel with fork
12 _ => unreachable!("{}, {}", index, channel.is_task_configurable()), // Not available with the PPI, so should not be constructable
13 }
14 }
15
16 pub(super) fn disable_task(_task: &Task, channel: &C, index: usize) {
17 match (index, channel.is_task_configurable()) {
18 (0, false) => Self::set_fork_task(None, channel.number()), // Static channel with fork
19 (0, true) => Self::set_main_task(None, channel.number()), // Configurable channel without fork
20 (1, true) => Self::set_fork_task(None, channel.number()), // Configurable channel with fork
21 _ => unreachable!(), // Not available with the PPI, so should not be constructable
22 }
23 }
24
25 pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) {
26 Self::set_event(Some(event), channel.number())
27 }
28
29 pub(super) fn disable_event(_event: &Event, channel: &C, _index: usize) {
30 Self::set_event(None, channel.number())
31 }
32
33 fn set_main_task(task: Option<&Task>, channel: usize) {
34 let r = unsafe { &*pac::PPI::ptr() };
35 if let Some(task) = task {
36 r.ch[channel]
37 .tep
38 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
39 } else {
40 r.ch[channel].tep.write(|w| unsafe { w.bits(0) })
41 }
42 }
43
44 fn set_fork_task(task: Option<&Task>, channel: usize) {
45 let r = unsafe { &*pac::PPI::ptr() };
46 if let Some(task) = task {
47 r.fork[channel]
48 .tep
49 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
50 } else {
51 r.fork[channel].tep.write(|w| unsafe { w.bits(0) })
52 }
53 }
54
55 fn set_event(event: Option<&Event>, channel: usize) {
56 let r = unsafe { &*pac::PPI::ptr() };
57 if let Some(event) = event {
58 r.ch[channel]
59 .eep
60 .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) })
61 } else {
62 r.ch[channel].eep.write(|w| unsafe { w.bits(0) })
63 }
64 }
65}
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;
31pub mod gpiote; 31pub mod gpiote;
32#[cfg(not(feature = "nrf9160"))] 32#[cfg(not(feature = "nrf9160"))]
33pub mod nvmc; 33pub mod nvmc;
34pub mod ppi; 34pub mod interconnect;
35#[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))] 35#[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))]
36pub mod pwm; 36pub mod pwm;
37#[cfg(feature = "nrf52840")] 37#[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 @@
1#![macro_use]
2
3//! HAL interface for the PPI peripheral.
4//!
5//! The Programmable Peripheral Interconnect interface allows for an autonomous interoperability
6//! between peripherals through their events and tasks. There are fixed PPI channels and fully
7//! configurable ones, fixed channels can only connect specific events to specific tasks. For fully
8//! configurable channels, it is possible to choose, via software, the event and the task that it
9//! will triggered by the event.
10//!
11//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task
12//! to be triggered by the same event, even fixed PPI channels have a configurable fork task.
13
14use crate::{pac, peripherals};
15use core::marker::PhantomData;
16use core::ptr::NonNull;
17use embassy::util::Unborrow;
18use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
19
20// ======================
21// driver
22
23/// Error type of the PPI driver
24#[non_exhaustive]
25#[derive(Clone, Debug)]
26#[cfg_attr(feature = "defmt", derive(defmt::Format))]
27pub enum Error {
28 /// There is no capacity to enable this task or event (nRF51 & nRF52 only)
29 NoCapacityLeft,
30 /// This task or event is not in use by the current channel
31 NotInUseByChannel,
32 /// This task or event is already enabled on another channel (nRF53 & nRF91 only)
33 AlreadyInUse,
34}
35
36pub struct Ppi<'d, C: Channel> {
37 ch: C,
38 phantom: PhantomData<&'d mut C>,
39}
40
41impl<'d, C: Channel> Ppi<'d, C> {
42 pub fn new(ch: impl Unborrow<Target = C> + 'd) -> Self {
43 unborrow!(ch);
44
45 Self {
46 ch,
47 phantom: PhantomData,
48 }
49 }
50
51 /// Enables the channel.
52 pub fn enable(&mut self) {
53 let r = unsafe { &*pac::PPI::ptr() };
54 r.chenset
55 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
56 }
57
58 /// Disables the channel.
59 pub fn disable(&mut self) {
60 let r = unsafe { &*pac::PPI::ptr() };
61 r.chenclr
62 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
63 }
64}
65
66#[cfg(feature = "_ppi")]
67impl<'d, C: Channel> Ppi<'d, C> {
68 /// Makes it so that the given task is subscribed to this channel
69 pub fn subscribe(&mut self, task: Task) -> Result<(), Error> {
70 if self.is_main_task_free() {
71 self.set_main_task(Some(task));
72 Ok(())
73 } else if self.is_fork_task_free() {
74 self.set_fork_task(Some(task));
75 Ok(())
76 } else {
77 Err(Error::NoCapacityLeft)
78 }
79 }
80
81 /// Makes it so that the given task is not subscribed to this channel
82 pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> {
83 if self.get_main_task() == Some(task) {
84 // If there is a fork task, we move that to the main task for consistency
85 // If there is no fork task, then the main task is set to 0
86 let fork_task = self.get_fork_task();
87 self.set_main_task(fork_task);
88
89 if self.has_fork_task() {
90 // The fork task was copied to the main task, so reset the fork task
91 self.set_fork_task(None);
92 }
93 Ok(())
94 } else if self.get_fork_task() == Some(task) {
95 // Reset the fork task
96 self.set_fork_task(None);
97 Ok(())
98 } else {
99 Err(Error::NotInUseByChannel)
100 }
101 }
102
103 /// Makes it so that the given event is published on this channel
104 pub fn publish(&mut self, event: Event) -> Result<(), Error> {
105 if self.is_event_free() {
106 self.set_event(Some(event));
107 Ok(())
108 } else {
109 Err(Error::NoCapacityLeft)
110 }
111 }
112
113 /// Makes it so that the given event is not published on this channel
114 pub fn unpublish(&mut self, event: Event) -> Result<(), Error> {
115 if self.get_event() == Some(event) {
116 self.set_event(None);
117 Ok(())
118 } else {
119 Err(Error::NotInUseByChannel)
120 }
121 }
122
123 fn set_main_task(&mut self, task: Option<Task>) {
124 let r = unsafe { &*pac::PPI::ptr() };
125 if let Some(task) = task {
126 r.ch[self.ch.number()]
127 .tep
128 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
129 } else {
130 r.ch[self.ch.number()].tep.write(|w| unsafe { w.bits(0) })
131 }
132 }
133
134 fn get_main_task(&mut self) -> Option<Task> {
135 let r = unsafe { &*pac::PPI::ptr() };
136
137 if !self.has_main_task() {
138 return None;
139 }
140
141 let bits = r.ch[self.ch.number()].tep.read().tep().bits();
142
143 if bits == 0 {
144 None
145 } else {
146 unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) }
147 }
148 }
149
150 fn set_fork_task(&mut self, task: Option<Task>) {
151 let r = unsafe { &*pac::PPI::ptr() };
152 if let Some(task) = task {
153 r.fork[self.ch.number()]
154 .tep
155 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
156 } else {
157 r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) })
158 }
159 }
160
161 fn get_fork_task(&mut self) -> Option<Task> {
162 let r = unsafe { &*pac::PPI::ptr() };
163
164 if !self.has_fork_task() {
165 return None;
166 }
167
168 let bits = r.fork[self.ch.number()].tep.read().tep().bits();
169
170 if bits == 0 {
171 None
172 } else {
173 unsafe { Some(Task(NonNull::new_unchecked(bits as *mut _))) }
174 }
175 }
176
177 fn has_main_task(&self) -> bool {
178 match (self.ch.task_capacity(), self.ch.event_capacity()) {
179 (0, 0) => false, // Static task
180 (1, 0) => false, // Static task with fork
181 (1 | 2, 1) => true, // Configurable task with possibly a fork
182 _ => unreachable!(), // Every PPI config is covered
183 }
184 }
185
186 fn has_fork_task(&self) -> bool {
187 match (self.ch.task_capacity(), self.ch.event_capacity()) {
188 (0, 0) => false, // Static task
189 (1, 0) => true, // Static task with fork
190 (1, 1) => false, // Configurable task without fork
191 (2, 1) => true, // Configurable task with fork
192 _ => unreachable!(), // Every PPI config is covered
193 }
194 }
195
196 fn is_main_task_free(&mut self) -> bool {
197 self.get_main_task().is_none()
198 }
199
200 fn is_fork_task_free(&mut self) -> bool {
201 self.get_fork_task().is_none()
202 }
203
204 fn set_event(&mut self, event: Option<Event>) {
205 let r = unsafe { &*pac::PPI::ptr() };
206 if let Some(event) = event {
207 r.ch[self.ch.number()]
208 .eep
209 .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) })
210 } else {
211 r.ch[self.ch.number()].eep.write(|w| unsafe { w.bits(0) })
212 }
213 }
214
215 fn get_event(&mut self) -> Option<Event> {
216 let r = unsafe { &*pac::PPI::ptr() };
217
218 if !self.has_event() {
219 return None;
220 }
221
222 let bits = r.ch[self.ch.number()].eep.read().eep().bits();
223
224 if bits == 0 {
225 None
226 } else {
227 unsafe { Some(Event(NonNull::new_unchecked(bits as *mut _))) }
228 }
229 }
230
231 fn has_event(&self) -> bool {
232 match (self.ch.task_capacity(), self.ch.event_capacity()) {
233 (_, 0) => false, // Static event
234 (_, 1) => true, // Configurable event
235 _ => unreachable!(), // Every PPI config is covered
236 }
237 }
238
239 fn is_event_free(&mut self) -> bool {
240 self.get_event().is_none()
241 }
242}
243
244#[cfg(feature = "_dppi")]
245const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
246#[cfg(feature = "_dppi")]
247const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
248
249#[cfg(feature = "_dppi")]
250impl<'d, C: Channel> Ppi<'d, C> {
251 /// Makes it so that the given task is subscribed to this channel
252 pub fn subscribe(&mut self, task: Task) -> Result<(), Error> {
253 unsafe {
254 if Self::is_register_enabled(task.0) {
255 Err(Error::AlreadyInUse)
256 } else {
257 Self::set_register_active(task.0, self.ch.number() as u8);
258 Ok(())
259 }
260 }
261 }
262
263 /// Makes it so that the given task is not subscribed to this channel
264 pub fn unsubscribe(&mut self, task: Task) -> Result<(), Error> {
265 unsafe {
266 if Self::get_register_channel(task.0) != self.ch.number() as u8 {
267 Err(Error::NotInUseByChannel)
268 } else {
269 Self::set_register_inactive(task.0);
270 Ok(())
271 }
272 }
273 }
274
275 /// Makes it so that the given event is published on this channel
276 pub fn publish(&mut self, event: Event) -> Result<(), Error> {
277 unsafe {
278 if Self::is_register_enabled(event.0) {
279 Err(Error::AlreadyInUse)
280 } else {
281 Self::set_register_active(event.0, self.ch.number() as u8);
282 Ok(())
283 }
284 }
285 }
286
287 /// Makes it so that the given event is not published on this channel
288 pub fn unpublish(&mut self, event: Event) -> Result<(), Error> {
289 unsafe {
290 if Self::get_register_channel(event.0) != self.ch.number() as u8 {
291 Err(Error::NotInUseByChannel)
292 } else {
293 Self::set_register_inactive(event.0);
294 Ok(())
295 }
296 }
297 }
298
299 /// Checks if the DPPI_ENABLE_BIT is set in the register
300 ///
301 /// # Safety
302 ///
303 /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals
304 unsafe fn is_register_enabled(register: NonNull<u32>) -> bool {
305 let bits = register.as_ptr().read_volatile();
306 bits & DPPI_ENABLE_BIT > 0
307 }
308
309 /// Sets the register to the given channel and enables it
310 ///
311 /// # Safety
312 ///
313 /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals
314 unsafe fn set_register_active(register: NonNull<u32>, channel: u8) {
315 register
316 .as_ptr()
317 .write_volatile(DPPI_ENABLE_BIT | (channel as u32 & DPPI_CHANNEL_MASK));
318 }
319
320 /// Resets the channel number and disables the register
321 ///
322 /// # Safety
323 ///
324 /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals
325 unsafe fn set_register_inactive(register: NonNull<u32>) {
326 register.as_ptr().write_volatile(0);
327 }
328
329 /// Gets the current configured channel number of the register
330 ///
331 /// # Safety
332 ///
333 /// The register pointer must point at one of the many SUBSCRIBE_* or PUBLISH_* registers of the peripherals
334 unsafe fn get_register_channel(register: NonNull<u32>) -> u8 {
335 let bits = register.as_ptr().read_volatile();
336 (bits & DPPI_CHANNEL_MASK) as u8
337 }
338}
339
340impl<'d, C: Channel> Drop for Ppi<'d, C> {
341 fn drop(&mut self) {
342 self.disable()
343 }
344}
345
346/// Represents a task that a peripheral can do.
347/// When a task is subscribed to a PPI channel it will run when the channel is triggered by
348/// a published event.
349///
350/// The pointer in the task can point to two different kinds of register:
351/// - PPI *(nRF51 & nRF52)*: A pointer to a task register of the task of the peripheral that has
352/// to be registered with the PPI to subscribe to a channel
353/// - DPPI *(nRF53 & nRF91)*: A pointer to the subscribe register of the task of the peripheral
354/// that has to have the channel number and enable bit written tp it to subscribe to a channel
355#[derive(PartialEq, Eq, Clone, Copy)]
356pub struct Task(pub NonNull<u32>);
357impl Task {
358 pub(crate) fn from_reg<T>(reg: &T) -> Self {
359 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
360 }
361}
362
363/// Represents an event that a peripheral can publish.
364/// An event can be set to publish on a PPI channel when the event happens.
365///
366/// The pointer in the event can point to two different kinds of register:
367/// - PPI *(nRF51 & nRF52)*: A pointer to an event register of the event of the peripheral that has
368/// to be registered with the PPI to publish to a channel
369/// - DPPI *(nRF53 & nRF91)*: A pointer to the publish register of the event of the peripheral
370/// that has to have the channel number and enable bit written tp it to publish to a channel
371#[derive(PartialEq, Eq, Clone, Copy)]
372pub struct Event(pub NonNull<u32>);
373impl Event {
374 pub(crate) fn from_reg<T>(reg: &T) -> Self {
375 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
376 }
377}
378
379// ======================
380// traits
381
382pub(crate) mod sealed {
383 pub trait Channel {}
384 pub trait Group {}
385}
386
387pub trait Channel: sealed::Channel + Sized {
388 /// Returns the number of the channel
389 fn number(&self) -> usize;
390
391 /// Returns the amount of configurable tasks this channel has.
392 ///
393 /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91)
394 /// - 0 for static channel without fork (nRF51)
395 /// - 1 for static channel with fork (nRF52) or for configurable channel (nRF51)
396 /// - 2 for configurable channel with fork (nRF52)
397 fn task_capacity(&self) -> usize;
398
399 /// Returns the amount of configurable events this channels has
400 ///
401 /// - MAX for DPPI with unlimited capacity (nRF53 & nRF91)
402 /// - 0 for static channel (nRF51 & nRF52)
403 /// - 1 for configurable channel (nRF51 & nRF52)
404 fn event_capacity(&self) -> usize;
405
406 fn degrade(self) -> AnyChannel {
407 pub trait ConfigurableChannel {}
408
409 AnyChannel {
410 number: self.number() as u8,
411 task_capacity: self.task_capacity() as _,
412 event_capacity: self.event_capacity() as _,
413 }
414 }
415}
416
417pub trait Group: sealed::Group + Sized {
418 fn number(&self) -> usize;
419 fn degrade(self) -> AnyGroup {
420 AnyGroup {
421 number: self.number() as u8,
422 }
423 }
424}
425
426// ======================
427// channels
428
429pub struct AnyChannel {
430 number: u8,
431 task_capacity: u8,
432 event_capacity: u8,
433}
434unsafe_impl_unborrow!(AnyChannel);
435impl sealed::Channel for AnyChannel {}
436impl Channel for AnyChannel {
437 fn number(&self) -> usize {
438 self.number as usize
439 }
440
441 fn task_capacity(&self) -> usize {
442 self.task_capacity as _
443 }
444
445 fn event_capacity(&self) -> usize {
446 self.event_capacity as _
447 }
448}
449
450macro_rules! impl_ppi_channel {
451 ($type:ident, $number:expr, $task_capacity:expr, $event_capacity:expr) => {
452 impl crate::ppi::sealed::Channel for peripherals::$type {}
453 impl crate::ppi::Channel for peripherals::$type {
454 fn number(&self) -> usize {
455 $number
456 }
457 fn task_capacity(&self) -> usize {
458 $task_capacity
459 }
460 fn event_capacity(&self) -> usize {
461 $event_capacity
462 }
463 }
464 };
465 ($type:ident, $number:expr) => {
466 impl crate::ppi::sealed::Channel for peripherals::$type {}
467 impl crate::ppi::Channel for peripherals::$type {
468 fn number(&self) -> usize {
469 $number
470 }
471 fn task_capacity(&self) -> usize {
472 usize::MAX
473 }
474 fn event_capacity(&self) -> usize {
475 usize::MAX
476 }
477 }
478 };
479}
480
481// ======================
482// groups
483
484pub struct AnyGroup {
485 number: u8,
486}
487unsafe_impl_unborrow!(AnyGroup);
488impl sealed::Group for AnyGroup {}
489impl Group for AnyGroup {
490 fn number(&self) -> usize {
491 self.number as usize
492 }
493}
494
495macro_rules! impl_group {
496 ($type:ident, $number:expr) => {
497 impl sealed::Group for peripherals::$type {}
498 impl Group for peripherals::$type {
499 fn number(&self) -> usize {
500 $number
501 }
502 }
503 };
504}
505
506impl_group!(PPI_GROUP0, 0);
507impl_group!(PPI_GROUP1, 1);
508impl_group!(PPI_GROUP2, 2);
509impl_group!(PPI_GROUP3, 3);
510#[cfg(not(feature = "nrf51"))]
511impl_group!(PPI_GROUP4, 4);
512#[cfg(not(feature = "nrf51"))]
513impl_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;
11use embassy_hal_common::unborrow; 11use embassy_hal_common::unborrow;
12use futures::future::poll_fn; 12use futures::future::poll_fn;
13 13
14use crate::interconnect::{Event, Task};
14use crate::pac; 15use crate::pac;
15use crate::ppi::Event;
16use crate::ppi::Task;
17 16
18pub(crate) mod sealed { 17pub(crate) mod sealed {
19 18
@@ -184,36 +183,21 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
184 /// 183 ///
185 /// When triggered, this task starts the timer. 184 /// When triggered, this task starts the timer.
186 pub fn task_start(&self) -> Task { 185 pub fn task_start(&self) -> Task {
187 #[cfg(feature = "_ppi")] 186 Task::from_reg(&T::regs().tasks_start)
188 let reg = &T::regs().tasks_start;
189 #[cfg(feature = "_dppi")]
190 let reg = &T::regs().subscribe_start;
191
192 Task::from_reg(reg)
193 } 187 }
194 188
195 /// Returns the STOP task, for use with PPI. 189 /// Returns the STOP task, for use with PPI.
196 /// 190 ///
197 /// When triggered, this task stops the timer. 191 /// When triggered, this task stops the timer.
198 pub fn task_stop(&self) -> Task { 192 pub fn task_stop(&self) -> Task {
199 #[cfg(feature = "_ppi")] 193 Task::from_reg(&T::regs().tasks_stop)
200 let reg = &T::regs().tasks_stop;
201 #[cfg(feature = "_dppi")]
202 let reg = &T::regs().subscribe_stop;
203
204 Task::from_reg(reg)
205 } 194 }
206 195
207 /// Returns the CLEAR task, for use with PPI. 196 /// Returns the CLEAR task, for use with PPI.
208 /// 197 ///
209 /// When triggered, this task resets the timer's counter to 0. 198 /// When triggered, this task resets the timer's counter to 0.
210 pub fn task_clear(&self) -> Task { 199 pub fn task_clear(&self) -> Task {
211 #[cfg(feature = "_ppi")] 200 Task::from_reg(&T::regs().tasks_clear)
212 let reg = &T::regs().tasks_clear;
213 #[cfg(feature = "_dppi")]
214 let reg = &T::regs().subscribe_clear;
215
216 Task::from_reg(reg)
217 } 201 }
218 202
219 /// Change the timer's frequency. 203 /// Change the timer's frequency.
@@ -334,24 +318,14 @@ impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> {
334 /// 318 ///
335 /// When triggered, this task will capture the current value of the timer's counter in this register. 319 /// When triggered, this task will capture the current value of the timer's counter in this register.
336 pub fn task_capture(&self) -> Task { 320 pub fn task_capture(&self) -> Task {
337 #[cfg(feature = "_ppi")] 321 Task::from_reg(&T::regs().tasks_capture)
338 let reg = &T::regs().tasks_capture;
339 #[cfg(feature = "_dppi")]
340 let reg = &T::regs().subscribe_capture;
341
342 Task::from_reg(reg)
343 } 322 }
344 323
345 /// Returns this CC register's COMPARE event, for use with PPI. 324 /// Returns this CC register's COMPARE event, for use with PPI.
346 /// 325 ///
347 /// This event will fire when the timer's counter reaches the value in this CC register. 326 /// This event will fire when the timer's counter reaches the value in this CC register.
348 pub fn event_compare(&self) -> Event { 327 pub fn event_compare(&self) -> Event {
349 #[cfg(feature = "_ppi")] 328 Event::from_reg(&T::regs().events_compare[self.n])
350 let reg = &T::regs().events_compare[self.n];
351 #[cfg(feature = "_dppi")]
352 let reg = &T::regs().publish_compare[self.n];
353
354 Event::from_reg(reg)
355 } 329 }
356 330
357 /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. 331 /// 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,9 +16,9 @@ use futures::future::poll_fn;
16use crate::chip::EASY_DMA_SIZE; 16use crate::chip::EASY_DMA_SIZE;
17use crate::gpio::sealed::Pin as _; 17use crate::gpio::sealed::Pin as _;
18use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; 18use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin};
19use crate::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task};
19use crate::interrupt::Interrupt; 20use crate::interrupt::Interrupt;
20use crate::pac; 21use crate::pac;
21use crate::ppi::{AnyChannel, Channel, Event, Ppi, Task};
22use crate::timer::Instance as TimerInstance; 22use crate::timer::Instance as TimerInstance;
23use crate::timer::{Frequency, Timer}; 23use crate::timer::{Frequency, Timer};
24 24
@@ -26,19 +26,6 @@ use crate::timer::{Frequency, Timer};
26pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 26pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
27 27
28#[non_exhaustive] 28#[non_exhaustive]
29#[derive(Clone, Debug)]
30#[cfg_attr(feature = "defmt", derive(defmt::Format))]
31pub enum Error {
32 PpiError(crate::ppi::Error),
33}
34
35impl From<crate::ppi::Error> for Error {
36 fn from(e: crate::ppi::Error) -> Self {
37 Self::PpiError(e)
38 }
39}
40
41#[non_exhaustive]
42pub struct Config { 29pub struct Config {
43 pub parity: Parity, 30 pub parity: Parity,
44 pub baudrate: Baudrate, 31 pub baudrate: Baudrate,
@@ -344,17 +331,14 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
344pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { 331pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
345 uarte: Uarte<'d, U>, 332 uarte: Uarte<'d, U>,
346 timer: Timer<'d, T>, 333 timer: Timer<'d, T>,
347 ppi_ch1: Ppi<'d, AnyChannel>, 334 ppi_ch1: Ppi<'d, AnyChannel, 1, 2>,
348 _ppi_ch2: Ppi<'d, AnyChannel>, 335 _ppi_ch2: Ppi<'d, AnyChannel, 1, 1>,
349} 336}
350 337
351impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { 338impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
352 /// Creates the interface to a UARTE instance. 339 /// Creates the interface to a UARTE instance.
353 /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. 340 /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral.
354 /// 341 ///
355 /// - *Note:* ppi_ch1 must have at least 1 free event and 2 free tasks or a PPI error is returned
356 /// - *Note:* ppi_ch2 must have at least 1 free event and 1 free tasks or a PPI error is returned
357 ///
358 /// # Safety 342 /// # Safety
359 /// 343 ///
360 /// The returned API is safe unless you use `mem::forget` (or similar safe mechanisms) 344 /// 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> {
364 pub unsafe fn new( 348 pub unsafe fn new(
365 uarte: impl Unborrow<Target = U> + 'd, 349 uarte: impl Unborrow<Target = U> + 'd,
366 timer: impl Unborrow<Target = T> + 'd, 350 timer: impl Unborrow<Target = T> + 'd,
367 ppi_ch1: impl Unborrow<Target = impl Channel> + 'd, 351 ppi_ch1: impl Unborrow<Target = impl OneToTwoChannel + 'd> + 'd,
368 ppi_ch2: impl Unborrow<Target = impl Channel> + 'd, 352 ppi_ch2: impl Unborrow<Target = impl OneToOneChannel + 'd> + 'd,
369 irq: impl Unborrow<Target = U::Interrupt> + 'd, 353 irq: impl Unborrow<Target = U::Interrupt> + 'd,
370 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 354 rxd: impl Unborrow<Target = impl GpioPin> + 'd,
371 txd: impl Unborrow<Target = impl GpioPin> + 'd, 355 txd: impl Unborrow<Target = impl GpioPin> + 'd,
372 cts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, 356 cts: impl Unborrow<Target = impl GpioOptionalPin> + 'd,
373 rts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, 357 rts: impl Unborrow<Target = impl GpioOptionalPin> + 'd,
374 config: Config, 358 config: Config,
375 ) -> Result<Self, Error> { 359 ) -> Self {
376 let baudrate = config.baudrate; 360 let baudrate = config.baudrate;
377 let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); 361 let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config);
378 let mut timer = Timer::new(timer); 362 let mut timer = Timer::new(timer);
@@ -394,23 +378,29 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
394 timer.cc(0).short_compare_clear(); 378 timer.cc(0).short_compare_clear();
395 timer.cc(0).short_compare_stop(); 379 timer.cc(0).short_compare_stop();
396 380
397 let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade()); 381 let mut ppi_ch1 = Ppi::new_one_to_two(
398 ppi_ch1.publish(Event::from_reg(&r.events_rxdrdy))?; 382 ppi_ch1,
399 ppi_ch1.subscribe(timer.task_clear())?; 383 Event::from_reg(&r.events_rxdrdy),
400 ppi_ch1.subscribe(timer.task_start())?; 384 timer.task_clear(),
385 timer.task_start(),
386 )
387 .degrade();
401 ppi_ch1.enable(); 388 ppi_ch1.enable();
402 389
403 let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade()); 390 let mut ppi_ch2 = Ppi::new_one_to_one(
404 ppi_ch2.publish(timer.cc(0).event_compare())?; 391 ppi_ch2,
405 ppi_ch2.subscribe(Task::from_reg(&r.tasks_stoprx))?; 392 timer.cc(0).event_compare(),
393 Task::from_reg(&r.tasks_stoprx),
394 )
395 .degrade();
406 ppi_ch2.enable(); 396 ppi_ch2.enable();
407 397
408 Ok(Self { 398 Self {
409 uarte, 399 uarte,
410 timer, 400 timer,
411 ppi_ch1: ppi_ch1, 401 ppi_ch1: ppi_ch1,
412 _ppi_ch2: ppi_ch2, 402 _ppi_ch2: ppi_ch2,
413 }) 403 }
414 } 404 }
415} 405}
416 406
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) {
26 let irq = interrupt::take!(UARTE0_UART0); 26 let irq = interrupt::take!(UARTE0_UART0);
27 let mut state = State::new(); 27 let mut state = State::new();
28 let u = unsafe { 28 let u = unsafe {
29 unwrap!(BufferedUarte::new( 29 BufferedUarte::new(
30 &mut state, 30 &mut state,
31 p.UARTE0, 31 p.UARTE0,
32 p.TIMER0, 32 p.TIMER0,
@@ -40,7 +40,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
40 config, 40 config,
41 &mut rx_buffer, 41 &mut rx_buffer,
42 &mut tx_buffer, 42 &mut tx_buffer,
43 )) 43 )
44 }; 44 };
45 pin_mut!(u); 45 pin_mut!(u);
46 46
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;
10use embassy::executor::Spawner; 10use embassy::executor::Spawner;
11use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 11use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
12use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; 12use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity};
13use embassy_nrf::ppi::Ppi; 13use embassy_nrf::interconnect::Ppi;
14use embassy_nrf::Peripherals; 14use embassy_nrf::Peripherals;
15use gpiote::{OutputChannel, OutputChannelPolarity}; 15use gpiote::{OutputChannel, OutputChannelPolarity};
16 16
@@ -51,25 +51,21 @@ async fn main(_spawner: Spawner, p: Peripherals) {
51 OutputChannelPolarity::Toggle, 51 OutputChannelPolarity::Toggle,
52 ); 52 );
53 53
54 let mut ppi = Ppi::new(p.PPI_CH0); 54 let mut ppi = Ppi::new_one_to_one(p.PPI_CH0, button1.event_in(), led1.task_out());
55 ppi.publish(button1.event_in()).unwrap();
56 ppi.subscribe(led1.task_out()).unwrap();
57 ppi.enable(); 55 ppi.enable();
58 56
59 let mut ppi = Ppi::new(p.PPI_CH1); 57 let mut ppi = Ppi::new_one_to_one(p.PPI_CH1, button2.event_in(), led1.task_clr());
60 ppi.publish(button2.event_in()).unwrap();
61 ppi.subscribe(led1.task_clr()).unwrap();
62 ppi.enable(); 58 ppi.enable();
63 59
64 let mut ppi = Ppi::new(p.PPI_CH2); 60 let mut ppi = Ppi::new_one_to_one(p.PPI_CH2, button3.event_in(), led1.task_set());
65 ppi.publish(button3.event_in()).unwrap();
66 ppi.subscribe(led1.task_set()).unwrap();
67 ppi.enable(); 61 ppi.enable();
68 62
69 let mut ppi = Ppi::new(p.PPI_CH3); 63 let mut ppi = Ppi::new_one_to_two(
70 ppi.publish(button4.event_in()).unwrap(); 64 p.PPI_CH3,
71 ppi.subscribe(led1.task_out()).unwrap(); 65 button4.event_in(),
72 ppi.subscribe(led2.task_out()).unwrap(); 66 led1.task_out(),
67 led2.task_out(),
68 );
73 ppi.enable(); 69 ppi.enable();
74 70
75 info!("PPI setup!"); 71 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) {
21 21
22 let irq = interrupt::take!(UARTE0_UART0); 22 let irq = interrupt::take!(UARTE0_UART0);
23 let mut uart = unsafe { 23 let mut uart = unsafe {
24 unwrap!(uarte::UarteWithIdle::new( 24 uarte::UarteWithIdle::new(
25 p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config, 25 p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config,
26 )) 26 )
27 }; 27 };
28 28
29 info!("uarte initialized!"); 29 info!("uarte initialized!");