aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDion Dokter <[email protected]>2021-10-18 16:23:39 +0200
committerDario Nieuwenhuis <[email protected]>2021-10-26 14:47:12 +0200
commit11655af034538b463ff8220714e9b97cf53f8f56 (patch)
treeb22cd986313293328f472bb8c9637c59b654af65
parente6ec81b999541cca847b50075ac0d5d826f97dcd (diff)
Another redo using the feedback.
PPI is now split up into PPI and DPPI under the name 'interconnect'. The tasks and events are tracked and reset in the drop function.
-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!");