aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/Cargo.toml18
-rw-r--r--embassy-nrf/src/buffered_uarte.rs37
-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/ppi.rs248
-rw-r--r--embassy-nrf/src/ppi/dppi.rs74
-rw-r--r--embassy-nrf/src/ppi/mod.rs235
-rw-r--r--embassy-nrf/src/ppi/ppi.rs87
-rw-r--r--embassy-nrf/src/timer.rs5
-rw-r--r--embassy-nrf/src/uarte.rs38
-rw-r--r--examples/nrf/src/bin/ppi.rs22
-rw-r--r--examples/nrf/src/bin/saadc_continuous.rs4
18 files changed, 691 insertions, 537 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index fc1ec6b01..c083978c3 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -18,18 +18,20 @@ defmt-info = [ ]
18defmt-warn = [ ] 18defmt-warn = [ ]
19defmt-error = [ ] 19defmt-error = [ ]
20 20
21nrf52805 = ["nrf52805-pac"] 21nrf52805 = ["nrf52805-pac", "_ppi"]
22nrf52810 = ["nrf52810-pac"] 22nrf52810 = ["nrf52810-pac", "_ppi"]
23nrf52811 = ["nrf52811-pac"] 23nrf52811 = ["nrf52811-pac", "_ppi"]
24nrf52820 = ["nrf52820-pac"] 24nrf52820 = ["nrf52820-pac", "_ppi"]
25nrf52832 = ["nrf52832-pac"] 25nrf52832 = ["nrf52832-pac", "_ppi"]
26nrf52833 = ["nrf52833-pac"] 26nrf52833 = ["nrf52833-pac", "_ppi"]
27nrf52840 = ["nrf52840-pac"] 27nrf52840 = ["nrf52840-pac", "_ppi"]
28nrf9160 = ["nrf9160-pac"] 28nrf9160 = ["nrf9160-pac", "_dppi"]
29 29
30# Features starting with `_` are for internal use only. They're not intended 30# Features starting with `_` are for internal use only. They're not intended
31# to be enabled by other crates, and are not covered by semver guarantees. 31# to be enabled by other crates, and are not covered by semver guarantees.
32_time-driver = ["embassy/time-tick-32768hz"] 32_time-driver = ["embassy/time-tick-32768hz"]
33_ppi = []
34_dppi = []
33 35
34gpiote = [] 36gpiote = []
35time-driver-rtc1 = ["_time-driver"] 37time-driver-rtc1 = ["_time-driver"]
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index cd08875cd..717ada78d 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -5,7 +5,7 @@ use core::pin::Pin;
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7use embassy::interrupt::InterruptExt; 7use embassy::interrupt::InterruptExt;
8use embassy::io::{AsyncBufRead, AsyncWrite, Result}; 8use embassy::io::{AsyncBufRead, AsyncWrite};
9use embassy::util::Unborrow; 9use embassy::util::Unborrow;
10use embassy::waitqueue::WakerRegistration; 10use embassy::waitqueue::WakerRegistration;
11use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 11use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
@@ -45,8 +45,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> {
45struct StateInner<'d, U: UarteInstance, T: TimerInstance> { 45struct StateInner<'d, U: UarteInstance, T: TimerInstance> {
46 phantom: PhantomData<&'d mut U>, 46 phantom: PhantomData<&'d mut U>,
47 timer: Timer<'d, T>, 47 timer: Timer<'d, T>,
48 _ppi_ch1: Ppi<'d, AnyConfigurableChannel>, 48 _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>,
49 _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, 49 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>,
50 50
51 rx: RingBuffer<'d>, 51 rx: RingBuffer<'d>,
52 rx_state: RxState, 52 rx_state: RxState,
@@ -70,8 +70,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
70 state: &'d mut State<'d, U, T>, 70 state: &'d mut State<'d, U, T>,
71 _uarte: impl Unborrow<Target = U> + 'd, 71 _uarte: impl Unborrow<Target = U> + 'd,
72 timer: impl Unborrow<Target = T> + 'd, 72 timer: impl Unborrow<Target = T> + 'd,
73 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel> + 'd, 73 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
74 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel> + 'd, 74 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
75 irq: impl Unborrow<Target = U::Interrupt> + 'd, 75 irq: impl Unborrow<Target = U::Interrupt> + 'd,
76 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 76 rxd: impl Unborrow<Target = impl GpioPin> + 'd,
77 txd: impl Unborrow<Target = impl GpioPin> + 'd, 77 txd: impl Unborrow<Target = impl GpioPin> + 'd,
@@ -144,15 +144,19 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
144 timer.cc(0).short_compare_clear(); 144 timer.cc(0).short_compare_clear();
145 timer.cc(0).short_compare_stop(); 145 timer.cc(0).short_compare_stop();
146 146
147 let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); 147 let mut ppi_ch1 = Ppi::new_one_to_two(
148 ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); 148 ppi_ch1.degrade(),
149 ppi_ch1.set_task(timer.task_clear()); 149 Event::from_reg(&r.events_rxdrdy),
150 ppi_ch1.set_fork_task(timer.task_start()); 150 timer.task_clear(),
151 timer.task_start(),
152 );
151 ppi_ch1.enable(); 153 ppi_ch1.enable();
152 154
153 let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); 155 let mut ppi_ch2 = Ppi::new_one_to_one(
154 ppi_ch2.set_event(timer.cc(0).event_compare()); 156 ppi_ch2.degrade(),
155 ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); 157 timer.cc(0).event_compare(),
158 Task::from_reg(&r.tasks_stoprx),
159 );
156 ppi_ch2.enable(); 160 ppi_ch2.enable();
157 161
158 Self { 162 Self {
@@ -187,7 +191,10 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
187} 191}
188 192
189impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> { 193impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> {
190 fn poll_fill_buf(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { 194 fn poll_fill_buf(
195 mut self: Pin<&mut Self>,
196 cx: &mut Context<'_>,
197 ) -> Poll<embassy::io::Result<&[u8]>> {
191 self.inner.with(|state| { 198 self.inner.with(|state| {
192 // Conservative compiler fence to prevent optimizations that do not 199 // Conservative compiler fence to prevent optimizations that do not
193 // take in to account actions by DMA. The fence has been placed here, 200 // take in to account actions by DMA. The fence has been placed here,
@@ -206,7 +213,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d,
206 213
207 trace!(" empty"); 214 trace!(" empty");
208 state.rx_waker.register(cx.waker()); 215 state.rx_waker.register(cx.waker());
209 Poll::<Result<&[u8]>>::Pending 216 Poll::<embassy::io::Result<&[u8]>>::Pending
210 }) 217 })
211 } 218 }
212 219
@@ -224,7 +231,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U,
224 mut self: Pin<&mut Self>, 231 mut self: Pin<&mut Self>,
225 cx: &mut Context<'_>, 232 cx: &mut Context<'_>,
226 buf: &[u8], 233 buf: &[u8],
227 ) -> Poll<Result<usize>> { 234 ) -> Poll<embassy::io::Result<usize>> {
228 let poll = self.inner.with(|state| { 235 let poll = self.inner.with(|state| {
229 trace!("poll_write: {:?}", buf.len()); 236 trace!("poll_write: {:?}", buf.len());
230 237
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs
index d68697936..689896485 100644
--- a/embassy-nrf/src/chips/nrf52805.rs
+++ b/embassy-nrf/src/chips/nrf52805.rs
@@ -167,28 +167,28 @@ impl_pin!(P0_29, 0, 29);
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, configurable); 170impl_ppi_channel!(PPI_CH0, 0 => configurable);
171impl_ppi_channel!(PPI_CH1, 1, configurable); 171impl_ppi_channel!(PPI_CH1, 1 => configurable);
172impl_ppi_channel!(PPI_CH2, 2, configurable); 172impl_ppi_channel!(PPI_CH2, 2 => configurable);
173impl_ppi_channel!(PPI_CH3, 3, configurable); 173impl_ppi_channel!(PPI_CH3, 3 => configurable);
174impl_ppi_channel!(PPI_CH4, 4, configurable); 174impl_ppi_channel!(PPI_CH4, 4 => configurable);
175impl_ppi_channel!(PPI_CH5, 5, configurable); 175impl_ppi_channel!(PPI_CH5, 5 => configurable);
176impl_ppi_channel!(PPI_CH6, 6, configurable); 176impl_ppi_channel!(PPI_CH6, 6 => configurable);
177impl_ppi_channel!(PPI_CH7, 7, configurable); 177impl_ppi_channel!(PPI_CH7, 7 => configurable);
178impl_ppi_channel!(PPI_CH8, 8, configurable); 178impl_ppi_channel!(PPI_CH8, 8 => configurable);
179impl_ppi_channel!(PPI_CH9, 9, configurable); 179impl_ppi_channel!(PPI_CH9, 9 => configurable);
180impl_ppi_channel!(PPI_CH20, 20); 180impl_ppi_channel!(PPI_CH20, 20 => static);
181impl_ppi_channel!(PPI_CH21, 21); 181impl_ppi_channel!(PPI_CH21, 21 => static);
182impl_ppi_channel!(PPI_CH22, 22); 182impl_ppi_channel!(PPI_CH22, 22 => static);
183impl_ppi_channel!(PPI_CH23, 23); 183impl_ppi_channel!(PPI_CH23, 23 => static);
184impl_ppi_channel!(PPI_CH24, 24); 184impl_ppi_channel!(PPI_CH24, 24 => static);
185impl_ppi_channel!(PPI_CH25, 25); 185impl_ppi_channel!(PPI_CH25, 25 => static);
186impl_ppi_channel!(PPI_CH26, 26); 186impl_ppi_channel!(PPI_CH26, 26 => static);
187impl_ppi_channel!(PPI_CH27, 27); 187impl_ppi_channel!(PPI_CH27, 27 => static);
188impl_ppi_channel!(PPI_CH28, 28); 188impl_ppi_channel!(PPI_CH28, 28 => static);
189impl_ppi_channel!(PPI_CH29, 29); 189impl_ppi_channel!(PPI_CH29, 29 => static);
190impl_ppi_channel!(PPI_CH30, 30); 190impl_ppi_channel!(PPI_CH30, 30 => static);
191impl_ppi_channel!(PPI_CH31, 31); 191impl_ppi_channel!(PPI_CH31, 31 => static);
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 c119e7cdb..b3b3593bb 100644
--- a/embassy-nrf/src/chips/nrf52810.rs
+++ b/embassy-nrf/src/chips/nrf52810.rs
@@ -172,38 +172,38 @@ impl_pin!(P0_29, 0, 29);
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, configurable); 175impl_ppi_channel!(PPI_CH0, 0 => configurable);
176impl_ppi_channel!(PPI_CH1, 1, configurable); 176impl_ppi_channel!(PPI_CH1, 1 => configurable);
177impl_ppi_channel!(PPI_CH2, 2, configurable); 177impl_ppi_channel!(PPI_CH2, 2 => configurable);
178impl_ppi_channel!(PPI_CH3, 3, configurable); 178impl_ppi_channel!(PPI_CH3, 3 => configurable);
179impl_ppi_channel!(PPI_CH4, 4, configurable); 179impl_ppi_channel!(PPI_CH4, 4 => configurable);
180impl_ppi_channel!(PPI_CH5, 5, configurable); 180impl_ppi_channel!(PPI_CH5, 5 => configurable);
181impl_ppi_channel!(PPI_CH6, 6, configurable); 181impl_ppi_channel!(PPI_CH6, 6 => configurable);
182impl_ppi_channel!(PPI_CH7, 7, configurable); 182impl_ppi_channel!(PPI_CH7, 7 => configurable);
183impl_ppi_channel!(PPI_CH8, 8, configurable); 183impl_ppi_channel!(PPI_CH8, 8 => configurable);
184impl_ppi_channel!(PPI_CH9, 9, configurable); 184impl_ppi_channel!(PPI_CH9, 9 => configurable);
185impl_ppi_channel!(PPI_CH10, 10, configurable); 185impl_ppi_channel!(PPI_CH10, 10 => configurable);
186impl_ppi_channel!(PPI_CH11, 11, configurable); 186impl_ppi_channel!(PPI_CH11, 11 => configurable);
187impl_ppi_channel!(PPI_CH12, 12, configurable); 187impl_ppi_channel!(PPI_CH12, 12 => configurable);
188impl_ppi_channel!(PPI_CH13, 13, configurable); 188impl_ppi_channel!(PPI_CH13, 13 => configurable);
189impl_ppi_channel!(PPI_CH14, 14, configurable); 189impl_ppi_channel!(PPI_CH14, 14 => configurable);
190impl_ppi_channel!(PPI_CH15, 15, configurable); 190impl_ppi_channel!(PPI_CH15, 15 => configurable);
191impl_ppi_channel!(PPI_CH16, 16, configurable); 191impl_ppi_channel!(PPI_CH16, 16 => configurable);
192impl_ppi_channel!(PPI_CH17, 17, configurable); 192impl_ppi_channel!(PPI_CH17, 17 => configurable);
193impl_ppi_channel!(PPI_CH18, 18, configurable); 193impl_ppi_channel!(PPI_CH18, 18 => configurable);
194impl_ppi_channel!(PPI_CH19, 19, configurable); 194impl_ppi_channel!(PPI_CH19, 19 => configurable);
195impl_ppi_channel!(PPI_CH20, 20); 195impl_ppi_channel!(PPI_CH20, 20 => static);
196impl_ppi_channel!(PPI_CH21, 21); 196impl_ppi_channel!(PPI_CH21, 21 => static);
197impl_ppi_channel!(PPI_CH22, 22); 197impl_ppi_channel!(PPI_CH22, 22 => static);
198impl_ppi_channel!(PPI_CH23, 23); 198impl_ppi_channel!(PPI_CH23, 23 => static);
199impl_ppi_channel!(PPI_CH24, 24); 199impl_ppi_channel!(PPI_CH24, 24 => static);
200impl_ppi_channel!(PPI_CH25, 25); 200impl_ppi_channel!(PPI_CH25, 25 => static);
201impl_ppi_channel!(PPI_CH26, 26); 201impl_ppi_channel!(PPI_CH26, 26 => static);
202impl_ppi_channel!(PPI_CH27, 27); 202impl_ppi_channel!(PPI_CH27, 27 => static);
203impl_ppi_channel!(PPI_CH28, 28); 203impl_ppi_channel!(PPI_CH28, 28 => static);
204impl_ppi_channel!(PPI_CH29, 29); 204impl_ppi_channel!(PPI_CH29, 29 => static);
205impl_ppi_channel!(PPI_CH30, 30); 205impl_ppi_channel!(PPI_CH30, 30 => static);
206impl_ppi_channel!(PPI_CH31, 31); 206impl_ppi_channel!(PPI_CH31, 31 => static);
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 3c9df40fe..7551492c3 100644
--- a/embassy-nrf/src/chips/nrf52811.rs
+++ b/embassy-nrf/src/chips/nrf52811.rs
@@ -173,38 +173,38 @@ impl_pin!(P0_29, 0, 29);
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, configurable); 176impl_ppi_channel!(PPI_CH0, 0 => configurable);
177impl_ppi_channel!(PPI_CH1, 1, configurable); 177impl_ppi_channel!(PPI_CH1, 1 => configurable);
178impl_ppi_channel!(PPI_CH2, 2, configurable); 178impl_ppi_channel!(PPI_CH2, 2 => configurable);
179impl_ppi_channel!(PPI_CH3, 3, configurable); 179impl_ppi_channel!(PPI_CH3, 3 => configurable);
180impl_ppi_channel!(PPI_CH4, 4, configurable); 180impl_ppi_channel!(PPI_CH4, 4 => configurable);
181impl_ppi_channel!(PPI_CH5, 5, configurable); 181impl_ppi_channel!(PPI_CH5, 5 => configurable);
182impl_ppi_channel!(PPI_CH6, 6, configurable); 182impl_ppi_channel!(PPI_CH6, 6 => configurable);
183impl_ppi_channel!(PPI_CH7, 7, configurable); 183impl_ppi_channel!(PPI_CH7, 7 => configurable);
184impl_ppi_channel!(PPI_CH8, 8, configurable); 184impl_ppi_channel!(PPI_CH8, 8 => configurable);
185impl_ppi_channel!(PPI_CH9, 9, configurable); 185impl_ppi_channel!(PPI_CH9, 9 => configurable);
186impl_ppi_channel!(PPI_CH10, 10, configurable); 186impl_ppi_channel!(PPI_CH10, 10 => configurable);
187impl_ppi_channel!(PPI_CH11, 11, configurable); 187impl_ppi_channel!(PPI_CH11, 11 => configurable);
188impl_ppi_channel!(PPI_CH12, 12, configurable); 188impl_ppi_channel!(PPI_CH12, 12 => configurable);
189impl_ppi_channel!(PPI_CH13, 13, configurable); 189impl_ppi_channel!(PPI_CH13, 13 => configurable);
190impl_ppi_channel!(PPI_CH14, 14, configurable); 190impl_ppi_channel!(PPI_CH14, 14 => configurable);
191impl_ppi_channel!(PPI_CH15, 15, configurable); 191impl_ppi_channel!(PPI_CH15, 15 => configurable);
192impl_ppi_channel!(PPI_CH16, 16, configurable); 192impl_ppi_channel!(PPI_CH16, 16 => configurable);
193impl_ppi_channel!(PPI_CH17, 17, configurable); 193impl_ppi_channel!(PPI_CH17, 17 => configurable);
194impl_ppi_channel!(PPI_CH18, 18, configurable); 194impl_ppi_channel!(PPI_CH18, 18 => configurable);
195impl_ppi_channel!(PPI_CH19, 19, configurable); 195impl_ppi_channel!(PPI_CH19, 19 => configurable);
196impl_ppi_channel!(PPI_CH20, 20); 196impl_ppi_channel!(PPI_CH20, 20 => static);
197impl_ppi_channel!(PPI_CH21, 21); 197impl_ppi_channel!(PPI_CH21, 21 => static);
198impl_ppi_channel!(PPI_CH22, 22); 198impl_ppi_channel!(PPI_CH22, 22 => static);
199impl_ppi_channel!(PPI_CH23, 23); 199impl_ppi_channel!(PPI_CH23, 23 => static);
200impl_ppi_channel!(PPI_CH24, 24); 200impl_ppi_channel!(PPI_CH24, 24 => static);
201impl_ppi_channel!(PPI_CH25, 25); 201impl_ppi_channel!(PPI_CH25, 25 => static);
202impl_ppi_channel!(PPI_CH26, 26); 202impl_ppi_channel!(PPI_CH26, 26 => static);
203impl_ppi_channel!(PPI_CH27, 27); 203impl_ppi_channel!(PPI_CH27, 27 => static);
204impl_ppi_channel!(PPI_CH28, 28); 204impl_ppi_channel!(PPI_CH28, 28 => static);
205impl_ppi_channel!(PPI_CH29, 29); 205impl_ppi_channel!(PPI_CH29, 29 => static);
206impl_ppi_channel!(PPI_CH30, 30); 206impl_ppi_channel!(PPI_CH30, 30 => static);
207impl_ppi_channel!(PPI_CH31, 31); 207impl_ppi_channel!(PPI_CH31, 31 => static);
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 8a8e23a9e..128e1503f 100644
--- a/embassy-nrf/src/chips/nrf52820.rs
+++ b/embassy-nrf/src/chips/nrf52820.rs
@@ -168,38 +168,38 @@ impl_pin!(P0_29, 0, 29);
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, configurable); 171impl_ppi_channel!(PPI_CH0, 0 => configurable);
172impl_ppi_channel!(PPI_CH1, 1, configurable); 172impl_ppi_channel!(PPI_CH1, 1 => configurable);
173impl_ppi_channel!(PPI_CH2, 2, configurable); 173impl_ppi_channel!(PPI_CH2, 2 => configurable);
174impl_ppi_channel!(PPI_CH3, 3, configurable); 174impl_ppi_channel!(PPI_CH3, 3 => configurable);
175impl_ppi_channel!(PPI_CH4, 4, configurable); 175impl_ppi_channel!(PPI_CH4, 4 => configurable);
176impl_ppi_channel!(PPI_CH5, 5, configurable); 176impl_ppi_channel!(PPI_CH5, 5 => configurable);
177impl_ppi_channel!(PPI_CH6, 6, configurable); 177impl_ppi_channel!(PPI_CH6, 6 => configurable);
178impl_ppi_channel!(PPI_CH7, 7, configurable); 178impl_ppi_channel!(PPI_CH7, 7 => configurable);
179impl_ppi_channel!(PPI_CH8, 8, configurable); 179impl_ppi_channel!(PPI_CH8, 8 => configurable);
180impl_ppi_channel!(PPI_CH9, 9, configurable); 180impl_ppi_channel!(PPI_CH9, 9 => configurable);
181impl_ppi_channel!(PPI_CH10, 10, configurable); 181impl_ppi_channel!(PPI_CH10, 10 => configurable);
182impl_ppi_channel!(PPI_CH11, 11, configurable); 182impl_ppi_channel!(PPI_CH11, 11 => configurable);
183impl_ppi_channel!(PPI_CH12, 12, configurable); 183impl_ppi_channel!(PPI_CH12, 12 => configurable);
184impl_ppi_channel!(PPI_CH13, 13, configurable); 184impl_ppi_channel!(PPI_CH13, 13 => configurable);
185impl_ppi_channel!(PPI_CH14, 14, configurable); 185impl_ppi_channel!(PPI_CH14, 14 => configurable);
186impl_ppi_channel!(PPI_CH15, 15, configurable); 186impl_ppi_channel!(PPI_CH15, 15 => configurable);
187impl_ppi_channel!(PPI_CH16, 16, configurable); 187impl_ppi_channel!(PPI_CH16, 16 => configurable);
188impl_ppi_channel!(PPI_CH17, 17, configurable); 188impl_ppi_channel!(PPI_CH17, 17 => configurable);
189impl_ppi_channel!(PPI_CH18, 18, configurable); 189impl_ppi_channel!(PPI_CH18, 18 => configurable);
190impl_ppi_channel!(PPI_CH19, 19, configurable); 190impl_ppi_channel!(PPI_CH19, 19 => configurable);
191impl_ppi_channel!(PPI_CH20, 20); 191impl_ppi_channel!(PPI_CH20, 20 => static);
192impl_ppi_channel!(PPI_CH21, 21); 192impl_ppi_channel!(PPI_CH21, 21 => static);
193impl_ppi_channel!(PPI_CH22, 22); 193impl_ppi_channel!(PPI_CH22, 22 => static);
194impl_ppi_channel!(PPI_CH23, 23); 194impl_ppi_channel!(PPI_CH23, 23 => static);
195impl_ppi_channel!(PPI_CH24, 24); 195impl_ppi_channel!(PPI_CH24, 24 => static);
196impl_ppi_channel!(PPI_CH25, 25); 196impl_ppi_channel!(PPI_CH25, 25 => static);
197impl_ppi_channel!(PPI_CH26, 26); 197impl_ppi_channel!(PPI_CH26, 26 => static);
198impl_ppi_channel!(PPI_CH27, 27); 198impl_ppi_channel!(PPI_CH27, 27 => static);
199impl_ppi_channel!(PPI_CH28, 28); 199impl_ppi_channel!(PPI_CH28, 28 => static);
200impl_ppi_channel!(PPI_CH29, 29); 200impl_ppi_channel!(PPI_CH29, 29 => static);
201impl_ppi_channel!(PPI_CH30, 30); 201impl_ppi_channel!(PPI_CH30, 30 => static);
202impl_ppi_channel!(PPI_CH31, 31); 202impl_ppi_channel!(PPI_CH31, 31 => static);
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 c1b02a0bf..432af143c 100644
--- a/embassy-nrf/src/chips/nrf52832.rs
+++ b/embassy-nrf/src/chips/nrf52832.rs
@@ -190,38 +190,38 @@ impl_pin!(P0_29, 0, 29);
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, configurable); 193impl_ppi_channel!(PPI_CH0, 0 => configurable);
194impl_ppi_channel!(PPI_CH1, 1, configurable); 194impl_ppi_channel!(PPI_CH1, 1 => configurable);
195impl_ppi_channel!(PPI_CH2, 2, configurable); 195impl_ppi_channel!(PPI_CH2, 2 => configurable);
196impl_ppi_channel!(PPI_CH3, 3, configurable); 196impl_ppi_channel!(PPI_CH3, 3 => configurable);
197impl_ppi_channel!(PPI_CH4, 4, configurable); 197impl_ppi_channel!(PPI_CH4, 4 => configurable);
198impl_ppi_channel!(PPI_CH5, 5, configurable); 198impl_ppi_channel!(PPI_CH5, 5 => configurable);
199impl_ppi_channel!(PPI_CH6, 6, configurable); 199impl_ppi_channel!(PPI_CH6, 6 => configurable);
200impl_ppi_channel!(PPI_CH7, 7, configurable); 200impl_ppi_channel!(PPI_CH7, 7 => configurable);
201impl_ppi_channel!(PPI_CH8, 8, configurable); 201impl_ppi_channel!(PPI_CH8, 8 => configurable);
202impl_ppi_channel!(PPI_CH9, 9, configurable); 202impl_ppi_channel!(PPI_CH9, 9 => configurable);
203impl_ppi_channel!(PPI_CH10, 10, configurable); 203impl_ppi_channel!(PPI_CH10, 10 => configurable);
204impl_ppi_channel!(PPI_CH11, 11, configurable); 204impl_ppi_channel!(PPI_CH11, 11 => configurable);
205impl_ppi_channel!(PPI_CH12, 12, configurable); 205impl_ppi_channel!(PPI_CH12, 12 => configurable);
206impl_ppi_channel!(PPI_CH13, 13, configurable); 206impl_ppi_channel!(PPI_CH13, 13 => configurable);
207impl_ppi_channel!(PPI_CH14, 14, configurable); 207impl_ppi_channel!(PPI_CH14, 14 => configurable);
208impl_ppi_channel!(PPI_CH15, 15, configurable); 208impl_ppi_channel!(PPI_CH15, 15 => configurable);
209impl_ppi_channel!(PPI_CH16, 16, configurable); 209impl_ppi_channel!(PPI_CH16, 16 => configurable);
210impl_ppi_channel!(PPI_CH17, 17, configurable); 210impl_ppi_channel!(PPI_CH17, 17 => configurable);
211impl_ppi_channel!(PPI_CH18, 18, configurable); 211impl_ppi_channel!(PPI_CH18, 18 => configurable);
212impl_ppi_channel!(PPI_CH19, 19, configurable); 212impl_ppi_channel!(PPI_CH19, 19 => configurable);
213impl_ppi_channel!(PPI_CH20, 20); 213impl_ppi_channel!(PPI_CH20, 20 => static);
214impl_ppi_channel!(PPI_CH21, 21); 214impl_ppi_channel!(PPI_CH21, 21 => static);
215impl_ppi_channel!(PPI_CH22, 22); 215impl_ppi_channel!(PPI_CH22, 22 => static);
216impl_ppi_channel!(PPI_CH23, 23); 216impl_ppi_channel!(PPI_CH23, 23 => static);
217impl_ppi_channel!(PPI_CH24, 24); 217impl_ppi_channel!(PPI_CH24, 24 => static);
218impl_ppi_channel!(PPI_CH25, 25); 218impl_ppi_channel!(PPI_CH25, 25 => static);
219impl_ppi_channel!(PPI_CH26, 26); 219impl_ppi_channel!(PPI_CH26, 26 => static);
220impl_ppi_channel!(PPI_CH27, 27); 220impl_ppi_channel!(PPI_CH27, 27 => static);
221impl_ppi_channel!(PPI_CH28, 28); 221impl_ppi_channel!(PPI_CH28, 28 => static);
222impl_ppi_channel!(PPI_CH29, 29); 222impl_ppi_channel!(PPI_CH29, 29 => static);
223impl_ppi_channel!(PPI_CH30, 30); 223impl_ppi_channel!(PPI_CH30, 30 => static);
224impl_ppi_channel!(PPI_CH31, 31); 224impl_ppi_channel!(PPI_CH31, 31 => static);
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 4f5c26002..7c7198dfd 100644
--- a/embassy-nrf/src/chips/nrf52833.rs
+++ b/embassy-nrf/src/chips/nrf52833.rs
@@ -226,38 +226,38 @@ impl_pin!(P1_13, 1, 13);
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, configurable); 229impl_ppi_channel!(PPI_CH0, 0 => configurable);
230impl_ppi_channel!(PPI_CH1, 1, configurable); 230impl_ppi_channel!(PPI_CH1, 1 => configurable);
231impl_ppi_channel!(PPI_CH2, 2, configurable); 231impl_ppi_channel!(PPI_CH2, 2 => configurable);
232impl_ppi_channel!(PPI_CH3, 3, configurable); 232impl_ppi_channel!(PPI_CH3, 3 => configurable);
233impl_ppi_channel!(PPI_CH4, 4, configurable); 233impl_ppi_channel!(PPI_CH4, 4 => configurable);
234impl_ppi_channel!(PPI_CH5, 5, configurable); 234impl_ppi_channel!(PPI_CH5, 5 => configurable);
235impl_ppi_channel!(PPI_CH6, 6, configurable); 235impl_ppi_channel!(PPI_CH6, 6 => configurable);
236impl_ppi_channel!(PPI_CH7, 7, configurable); 236impl_ppi_channel!(PPI_CH7, 7 => configurable);
237impl_ppi_channel!(PPI_CH8, 8, configurable); 237impl_ppi_channel!(PPI_CH8, 8 => configurable);
238impl_ppi_channel!(PPI_CH9, 9, configurable); 238impl_ppi_channel!(PPI_CH9, 9 => configurable);
239impl_ppi_channel!(PPI_CH10, 10, configurable); 239impl_ppi_channel!(PPI_CH10, 10 => configurable);
240impl_ppi_channel!(PPI_CH11, 11, configurable); 240impl_ppi_channel!(PPI_CH11, 11 => configurable);
241impl_ppi_channel!(PPI_CH12, 12, configurable); 241impl_ppi_channel!(PPI_CH12, 12 => configurable);
242impl_ppi_channel!(PPI_CH13, 13, configurable); 242impl_ppi_channel!(PPI_CH13, 13 => configurable);
243impl_ppi_channel!(PPI_CH14, 14, configurable); 243impl_ppi_channel!(PPI_CH14, 14 => configurable);
244impl_ppi_channel!(PPI_CH15, 15, configurable); 244impl_ppi_channel!(PPI_CH15, 15 => configurable);
245impl_ppi_channel!(PPI_CH16, 16, configurable); 245impl_ppi_channel!(PPI_CH16, 16 => configurable);
246impl_ppi_channel!(PPI_CH17, 17, configurable); 246impl_ppi_channel!(PPI_CH17, 17 => configurable);
247impl_ppi_channel!(PPI_CH18, 18, configurable); 247impl_ppi_channel!(PPI_CH18, 18 => configurable);
248impl_ppi_channel!(PPI_CH19, 19, configurable); 248impl_ppi_channel!(PPI_CH19, 19 => configurable);
249impl_ppi_channel!(PPI_CH20, 20); 249impl_ppi_channel!(PPI_CH20, 20 => static);
250impl_ppi_channel!(PPI_CH21, 21); 250impl_ppi_channel!(PPI_CH21, 21 => static);
251impl_ppi_channel!(PPI_CH22, 22); 251impl_ppi_channel!(PPI_CH22, 22 => static);
252impl_ppi_channel!(PPI_CH23, 23); 252impl_ppi_channel!(PPI_CH23, 23 => static);
253impl_ppi_channel!(PPI_CH24, 24); 253impl_ppi_channel!(PPI_CH24, 24 => static);
254impl_ppi_channel!(PPI_CH25, 25); 254impl_ppi_channel!(PPI_CH25, 25 => static);
255impl_ppi_channel!(PPI_CH26, 26); 255impl_ppi_channel!(PPI_CH26, 26 => static);
256impl_ppi_channel!(PPI_CH27, 27); 256impl_ppi_channel!(PPI_CH27, 27 => static);
257impl_ppi_channel!(PPI_CH28, 28); 257impl_ppi_channel!(PPI_CH28, 28 => static);
258impl_ppi_channel!(PPI_CH29, 29); 258impl_ppi_channel!(PPI_CH29, 29 => static);
259impl_ppi_channel!(PPI_CH30, 30); 259impl_ppi_channel!(PPI_CH30, 30 => static);
260impl_ppi_channel!(PPI_CH31, 31); 260impl_ppi_channel!(PPI_CH31, 31 => static);
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 1006acd95..f5b90cd5a 100644
--- a/embassy-nrf/src/chips/nrf52840.rs
+++ b/embassy-nrf/src/chips/nrf52840.rs
@@ -231,38 +231,38 @@ impl_pin!(P1_13, 1, 13);
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, configurable); 234impl_ppi_channel!(PPI_CH0, 0 => configurable);
235impl_ppi_channel!(PPI_CH1, 1, configurable); 235impl_ppi_channel!(PPI_CH1, 1 => configurable);
236impl_ppi_channel!(PPI_CH2, 2, configurable); 236impl_ppi_channel!(PPI_CH2, 2 => configurable);
237impl_ppi_channel!(PPI_CH3, 3, configurable); 237impl_ppi_channel!(PPI_CH3, 3 => configurable);
238impl_ppi_channel!(PPI_CH4, 4, configurable); 238impl_ppi_channel!(PPI_CH4, 4 => configurable);
239impl_ppi_channel!(PPI_CH5, 5, configurable); 239impl_ppi_channel!(PPI_CH5, 5 => configurable);
240impl_ppi_channel!(PPI_CH6, 6, configurable); 240impl_ppi_channel!(PPI_CH6, 6 => configurable);
241impl_ppi_channel!(PPI_CH7, 7, configurable); 241impl_ppi_channel!(PPI_CH7, 7 => configurable);
242impl_ppi_channel!(PPI_CH8, 8, configurable); 242impl_ppi_channel!(PPI_CH8, 8 => configurable);
243impl_ppi_channel!(PPI_CH9, 9, configurable); 243impl_ppi_channel!(PPI_CH9, 9 => configurable);
244impl_ppi_channel!(PPI_CH10, 10, configurable); 244impl_ppi_channel!(PPI_CH10, 10 => configurable);
245impl_ppi_channel!(PPI_CH11, 11, configurable); 245impl_ppi_channel!(PPI_CH11, 11 => configurable);
246impl_ppi_channel!(PPI_CH12, 12, configurable); 246impl_ppi_channel!(PPI_CH12, 12 => configurable);
247impl_ppi_channel!(PPI_CH13, 13, configurable); 247impl_ppi_channel!(PPI_CH13, 13 => configurable);
248impl_ppi_channel!(PPI_CH14, 14, configurable); 248impl_ppi_channel!(PPI_CH14, 14 => configurable);
249impl_ppi_channel!(PPI_CH15, 15, configurable); 249impl_ppi_channel!(PPI_CH15, 15 => configurable);
250impl_ppi_channel!(PPI_CH16, 16, configurable); 250impl_ppi_channel!(PPI_CH16, 16 => configurable);
251impl_ppi_channel!(PPI_CH17, 17, configurable); 251impl_ppi_channel!(PPI_CH17, 17 => configurable);
252impl_ppi_channel!(PPI_CH18, 18, configurable); 252impl_ppi_channel!(PPI_CH18, 18 => configurable);
253impl_ppi_channel!(PPI_CH19, 19, configurable); 253impl_ppi_channel!(PPI_CH19, 19 => configurable);
254impl_ppi_channel!(PPI_CH20, 20); 254impl_ppi_channel!(PPI_CH20, 20 => static);
255impl_ppi_channel!(PPI_CH21, 21); 255impl_ppi_channel!(PPI_CH21, 21 => static);
256impl_ppi_channel!(PPI_CH22, 22); 256impl_ppi_channel!(PPI_CH22, 22 => static);
257impl_ppi_channel!(PPI_CH23, 23); 257impl_ppi_channel!(PPI_CH23, 23 => static);
258impl_ppi_channel!(PPI_CH24, 24); 258impl_ppi_channel!(PPI_CH24, 24 => static);
259impl_ppi_channel!(PPI_CH25, 25); 259impl_ppi_channel!(PPI_CH25, 25 => static);
260impl_ppi_channel!(PPI_CH26, 26); 260impl_ppi_channel!(PPI_CH26, 26 => static);
261impl_ppi_channel!(PPI_CH27, 27); 261impl_ppi_channel!(PPI_CH27, 27 => static);
262impl_ppi_channel!(PPI_CH28, 28); 262impl_ppi_channel!(PPI_CH28, 28 => static);
263impl_ppi_channel!(PPI_CH29, 29); 263impl_ppi_channel!(PPI_CH29, 29 => static);
264impl_ppi_channel!(PPI_CH30, 30); 264impl_ppi_channel!(PPI_CH30, 30 => static);
265impl_ppi_channel!(PPI_CH31, 31); 265impl_ppi_channel!(PPI_CH31, 31 => static);
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..6ca918104 100644
--- a/embassy-nrf/src/chips/nrf9160.rs
+++ b/embassy-nrf/src/chips/nrf9160.rs
@@ -184,22 +184,22 @@ impl_pin!(P0_29, 0, 29);
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 => configurable);
188impl_ppi_channel!(PPI_CH1, 1); 188impl_ppi_channel!(PPI_CH1, 1 => configurable);
189impl_ppi_channel!(PPI_CH2, 2); 189impl_ppi_channel!(PPI_CH2, 2 => configurable);
190impl_ppi_channel!(PPI_CH3, 3); 190impl_ppi_channel!(PPI_CH3, 3 => configurable);
191impl_ppi_channel!(PPI_CH4, 4); 191impl_ppi_channel!(PPI_CH4, 4 => configurable);
192impl_ppi_channel!(PPI_CH5, 5); 192impl_ppi_channel!(PPI_CH5, 5 => configurable);
193impl_ppi_channel!(PPI_CH6, 6); 193impl_ppi_channel!(PPI_CH6, 6 => configurable);
194impl_ppi_channel!(PPI_CH7, 7); 194impl_ppi_channel!(PPI_CH7, 7 => configurable);
195impl_ppi_channel!(PPI_CH8, 8); 195impl_ppi_channel!(PPI_CH8, 8 => configurable);
196impl_ppi_channel!(PPI_CH9, 9); 196impl_ppi_channel!(PPI_CH9, 9 => configurable);
197impl_ppi_channel!(PPI_CH10, 10); 197impl_ppi_channel!(PPI_CH10, 10 => configurable);
198impl_ppi_channel!(PPI_CH11, 11); 198impl_ppi_channel!(PPI_CH11, 11 => configurable);
199impl_ppi_channel!(PPI_CH12, 12); 199impl_ppi_channel!(PPI_CH12, 12 => configurable);
200impl_ppi_channel!(PPI_CH13, 13); 200impl_ppi_channel!(PPI_CH13, 13 => configurable);
201impl_ppi_channel!(PPI_CH14, 14); 201impl_ppi_channel!(PPI_CH14, 14 => configurable);
202impl_ppi_channel!(PPI_CH15, 15); 202impl_ppi_channel!(PPI_CH15, 15 => configurable);
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/ppi.rs b/embassy-nrf/src/ppi.rs
deleted file mode 100644
index f5e06c69f..000000000
--- a/embassy-nrf/src/ppi.rs
+++ /dev/null
@@ -1,248 +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
23pub struct Ppi<'d, C: Channel> {
24 ch: C,
25 phantom: PhantomData<&'d mut C>,
26}
27
28impl<'d, C: Channel> Ppi<'d, C> {
29 pub fn new(ch: impl Unborrow<Target = C> + 'd) -> Self {
30 unborrow!(ch);
31
32 #[allow(unused_mut)]
33 let mut this = Self {
34 ch,
35 phantom: PhantomData,
36 };
37 #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
38 this.clear_fork_task();
39 this
40 }
41
42 /// Enables the channel.
43 pub fn enable(&mut self) {
44 let r = unsafe { &*pac::PPI::ptr() };
45 r.chenset
46 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
47 }
48
49 /// Disables the channel.
50 pub fn disable(&mut self) {
51 let r = unsafe { &*pac::PPI::ptr() };
52 r.chenclr
53 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
54 }
55
56 #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
57 /// Sets the fork task that must be triggered when the configured event occurs. The user must
58 /// provide a reference to the task.
59 pub fn set_fork_task(&mut self, task: Task) {
60 let r = unsafe { &*pac::PPI::ptr() };
61 r.fork[self.ch.number()]
62 .tep
63 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
64 }
65
66 #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
67 /// Clear the fork task endpoint. Previously set task will no longer be triggered.
68 pub fn clear_fork_task(&mut self) {
69 let r = unsafe { &*pac::PPI::ptr() };
70 r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) })
71 }
72
73 #[cfg(feature = "nrf9160")]
74 /// Sets the fork task that must be triggered when the configured event occurs. The user must
75 /// provide a reference to the task.
76 pub fn set_fork_task(&mut self, _task: Task) {
77 todo!("Tasks not yet implemented for nrf9160");
78 }
79
80 #[cfg(feature = "nrf9160")]
81 /// Clear the fork task endpoint. Previously set task will no longer be triggered.
82 pub fn clear_fork_task(&mut self) {
83 todo!("Tasks not yet implemented for nrf9160");
84 }
85}
86
87impl<'d, C: Channel> Drop for Ppi<'d, C> {
88 fn drop(&mut self) {
89 self.disable()
90 }
91}
92
93#[cfg(not(feature = "nrf9160"))]
94impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
95 /// Sets the task to be triggered when the configured event occurs.
96 pub fn set_task(&mut self, task: Task) {
97 let r = unsafe { &*pac::PPI::ptr() };
98 r.ch[self.ch.number()]
99 .tep
100 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
101 }
102
103 /// Sets the event that will trigger the chosen task(s).
104 pub fn set_event(&mut self, event: Event) {
105 let r = unsafe { &*pac::PPI::ptr() };
106 r.ch[self.ch.number()]
107 .eep
108 .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) })
109 }
110}
111
112#[cfg(feature = "nrf9160")]
113impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
114 /// Sets the task to be triggered when the configured event occurs.
115 pub fn set_task(&mut self, _task: Task) {
116 todo!("Tasks not yet implemented for nrf9160")
117 }
118
119 /// Sets the event that will trigger the chosen task(s).
120 pub fn set_event(&mut self, _event: Event) {
121 todo!("Events not yet implemented for nrf9160")
122 }
123}
124
125// ======================
126// traits
127
128pub struct Task(pub NonNull<()>);
129impl Task {
130 pub(crate) fn from_reg<T>(reg: &T) -> Self {
131 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut ()) })
132 }
133}
134
135pub struct Event(pub NonNull<()>);
136impl Event {
137 pub(crate) fn from_reg<T>(reg: &T) -> Self {
138 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut ()) })
139 }
140}
141
142pub(crate) mod sealed {
143 pub trait ConfigurableChannel {}
144 pub trait Channel {}
145 pub trait Group {}
146}
147
148pub trait Channel: sealed::Channel + Sized {
149 fn number(&self) -> usize;
150 fn degrade(self) -> AnyChannel {
151 AnyChannel {
152 number: self.number() as u8,
153 }
154 }
155}
156pub trait ConfigurableChannel: Channel + sealed::ConfigurableChannel {
157 fn degrade_configurable(self) -> AnyConfigurableChannel {
158 AnyConfigurableChannel {
159 number: self.number() as u8,
160 }
161 }
162}
163
164pub trait Group: sealed::Group + Sized {
165 fn number(&self) -> usize;
166 fn degrade(self) -> AnyGroup {
167 AnyGroup {
168 number: self.number() as u8,
169 }
170 }
171}
172
173// ======================
174// channels
175
176pub struct AnyChannel {
177 number: u8,
178}
179unsafe_impl_unborrow!(AnyChannel);
180impl sealed::Channel for AnyChannel {}
181impl Channel for AnyChannel {
182 fn number(&self) -> usize {
183 self.number as usize
184 }
185}
186
187pub struct AnyConfigurableChannel {
188 number: u8,
189}
190unsafe_impl_unborrow!(AnyConfigurableChannel);
191impl sealed::Channel for AnyConfigurableChannel {}
192impl sealed::ConfigurableChannel for AnyConfigurableChannel {}
193impl ConfigurableChannel for AnyConfigurableChannel {}
194impl Channel for AnyConfigurableChannel {
195 fn number(&self) -> usize {
196 self.number as usize
197 }
198}
199
200macro_rules! impl_ppi_channel {
201 ($type:ident, $number:expr, configurable) => {
202 impl_ppi_channel!($type, $number);
203 impl crate::ppi::sealed::ConfigurableChannel for peripherals::$type {}
204 impl crate::ppi::ConfigurableChannel for peripherals::$type {}
205 };
206 ($type:ident, $number:expr) => {
207 impl crate::ppi::sealed::Channel for peripherals::$type {}
208 impl crate::ppi::Channel for peripherals::$type {
209 fn number(&self) -> usize {
210 $number
211 }
212 }
213 };
214}
215
216// ======================
217// groups
218
219pub struct AnyGroup {
220 number: u8,
221}
222unsafe_impl_unborrow!(AnyGroup);
223impl sealed::Group for AnyGroup {}
224impl Group for AnyGroup {
225 fn number(&self) -> usize {
226 self.number as usize
227 }
228}
229
230macro_rules! impl_group {
231 ($type:ident, $number:expr) => {
232 impl sealed::Group for peripherals::$type {}
233 impl Group for peripherals::$type {
234 fn number(&self) -> usize {
235 $number
236 }
237 }
238 };
239}
240
241impl_group!(PPI_GROUP0, 0);
242impl_group!(PPI_GROUP1, 1);
243impl_group!(PPI_GROUP2, 2);
244impl_group!(PPI_GROUP3, 3);
245#[cfg(not(feature = "nrf51"))]
246impl_group!(PPI_GROUP4, 4);
247#[cfg(not(feature = "nrf51"))]
248impl_group!(PPI_GROUP5, 5);
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs
new file mode 100644
index 000000000..b3676fca4
--- /dev/null
+++ b/embassy-nrf/src/ppi/dppi.rs
@@ -0,0 +1,74 @@
1use core::marker::PhantomData;
2
3use embassy::util::Unborrow;
4use embassy_hal_common::unborrow;
5
6use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
7
8const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
9const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
10
11impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
12 pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self {
13 Ppi::new_many_to_many(ch, [event], [task])
14 }
15}
16
17impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
18 pub fn new_one_to_two(
19 ch: impl Unborrow<Target = C> + 'd,
20 event: Event,
21 task1: Task,
22 task2: Task,
23 ) -> Self {
24 Ppi::new_many_to_many(ch, [event], [task1, task2])
25 }
26}
27
28impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize>
29 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
30{
31 pub fn new_many_to_many(
32 ch: impl Unborrow<Target = C> + 'd,
33 events: [Event; EVENT_COUNT],
34 tasks: [Task; TASK_COUNT],
35 ) -> Self {
36 unborrow!(ch);
37
38 let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK);
39 for task in tasks {
40 if unsafe { task.subscribe_reg().read_volatile() } != 0 {
41 panic!("Task is already in use");
42 }
43 unsafe { task.subscribe_reg().write_volatile(val) }
44 }
45 for event in events {
46 if unsafe { event.publish_reg().read_volatile() } != 0 {
47 panic!("Event is already in use");
48 }
49 unsafe { event.publish_reg().write_volatile(val) }
50 }
51
52 Self {
53 ch,
54 events,
55 tasks,
56 phantom: PhantomData,
57 }
58 }
59}
60
61impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop
62 for Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
63{
64 fn drop(&mut self) {
65 self.disable();
66
67 for task in self.tasks {
68 unsafe { task.subscribe_reg().write_volatile(0) }
69 }
70 for event in self.events {
71 unsafe { event.publish_reg().write_volatile(0) }
72 }
73 }
74}
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs
new file mode 100644
index 000000000..96f867d18
--- /dev/null
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -0,0 +1,235 @@
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::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 #[cfg(feature = "_dppi")]
32 events: [Event; EVENT_COUNT],
33 #[cfg(feature = "_dppi")]
34 tasks: [Task; TASK_COUNT],
35 phantom: PhantomData<&'d mut C>,
36}
37
38impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize>
39 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
40{
41 /// Enables the channel.
42 pub fn enable(&mut self) {
43 let r = unsafe { &*pac::PPI::ptr() };
44 r.chenset
45 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
46 }
47
48 /// Disables the channel.
49 pub fn disable(&mut self) {
50 let r = unsafe { &*pac::PPI::ptr() };
51 r.chenclr
52 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
53 }
54}
55
56const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
57
58/// Represents a task that a peripheral can do.
59/// When a task is subscribed to a PPI channel it will run when the channel is triggered by
60/// a published event.
61///
62/// The pointer is to a task register
63#[derive(PartialEq, Eq, Clone, Copy)]
64pub struct Task(pub NonNull<u32>);
65impl Task {
66 pub(crate) fn from_reg<T>(reg: &T) -> Self {
67 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
68 }
69
70 pub fn subscribe_reg(&self) -> *mut u32 {
71 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
72 }
73}
74
75/// # Safety
76///
77/// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core.
78unsafe impl Send for Task {}
79
80/// Represents an event that a peripheral can publish.
81/// An event can be set to publish on a PPI channel when the event happens.
82///
83/// The pointer is to an event register
84#[derive(PartialEq, Eq, Clone, Copy)]
85pub struct Event(pub NonNull<u32>);
86impl Event {
87 pub(crate) fn from_reg<T>(reg: &T) -> Self {
88 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
89 }
90
91 pub fn publish_reg(&self) -> *mut u32 {
92 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
93 }
94}
95
96/// # Safety
97///
98/// NonNull is not send, but this event is only allowed to point at registers and those exist in any context on the same core.
99unsafe impl Send for Event {}
100
101// ======================
102// traits
103
104pub(crate) mod sealed {
105 pub trait Channel {}
106 pub trait Group {}
107}
108
109pub trait Channel: sealed::Channel + Unborrow<Target = Self> + Sized {
110 /// Returns the number of the channel
111 fn number(&self) -> usize;
112}
113
114pub trait ConfigurableChannel: Channel {
115 fn degrade(self) -> AnyConfigurableChannel;
116}
117
118pub trait StaticChannel: Channel {
119 fn degrade(self) -> AnyStaticChannel;
120}
121
122pub trait Group: sealed::Group + Sized {
123 fn number(&self) -> usize;
124 fn degrade(self) -> AnyGroup {
125 AnyGroup {
126 number: self.number() as u8,
127 }
128 }
129}
130
131// ======================
132// channels
133
134/// The any channel can represent any static channel at runtime.
135/// This can be used to have fewer generic parameters in some places.
136pub struct AnyStaticChannel {
137 pub(crate) number: u8,
138}
139unsafe_impl_unborrow!(AnyStaticChannel);
140impl sealed::Channel for AnyStaticChannel {}
141impl Channel for AnyStaticChannel {
142 fn number(&self) -> usize {
143 self.number as usize
144 }
145}
146impl StaticChannel for AnyStaticChannel {
147 fn degrade(self) -> AnyStaticChannel {
148 self
149 }
150}
151
152/// The any configurable channel can represent any configurable channel at runtime.
153/// This can be used to have fewer generic parameters in some places.
154pub struct AnyConfigurableChannel {
155 pub(crate) number: u8,
156}
157unsafe_impl_unborrow!(AnyConfigurableChannel);
158impl sealed::Channel for AnyConfigurableChannel {}
159impl Channel for AnyConfigurableChannel {
160 fn number(&self) -> usize {
161 self.number as usize
162 }
163}
164impl ConfigurableChannel for AnyConfigurableChannel {
165 fn degrade(self) -> AnyConfigurableChannel {
166 self
167 }
168}
169
170macro_rules! impl_ppi_channel {
171 ($type:ident, $number:expr) => {
172 impl crate::ppi::sealed::Channel for peripherals::$type {}
173 impl crate::ppi::Channel for peripherals::$type {
174 fn number(&self) -> usize {
175 $number
176 }
177 }
178 };
179 ($type:ident, $number:expr => static) => {
180 impl_ppi_channel!($type, $number);
181 impl crate::ppi::StaticChannel for peripherals::$type {
182 fn degrade(self) -> crate::ppi::AnyStaticChannel {
183 use crate::ppi::Channel;
184 crate::ppi::AnyStaticChannel {
185 number: self.number() as u8,
186 }
187 }
188 }
189 };
190 ($type:ident, $number:expr => configurable) => {
191 impl_ppi_channel!($type, $number);
192 impl crate::ppi::ConfigurableChannel for peripherals::$type {
193 fn degrade(self) -> crate::ppi::AnyConfigurableChannel {
194 use crate::ppi::Channel;
195 crate::ppi::AnyConfigurableChannel {
196 number: self.number() as u8,
197 }
198 }
199 }
200 };
201}
202
203// ======================
204// groups
205
206pub struct AnyGroup {
207 number: u8,
208}
209unsafe_impl_unborrow!(AnyGroup);
210impl sealed::Group for AnyGroup {}
211impl Group for AnyGroup {
212 fn number(&self) -> usize {
213 self.number as usize
214 }
215}
216
217macro_rules! impl_group {
218 ($type:ident, $number:expr) => {
219 impl sealed::Group for peripherals::$type {}
220 impl Group for peripherals::$type {
221 fn number(&self) -> usize {
222 $number
223 }
224 }
225 };
226}
227
228impl_group!(PPI_GROUP0, 0);
229impl_group!(PPI_GROUP1, 1);
230impl_group!(PPI_GROUP2, 2);
231impl_group!(PPI_GROUP3, 3);
232#[cfg(not(feature = "nrf51"))]
233impl_group!(PPI_GROUP4, 4);
234#[cfg(not(feature = "nrf51"))]
235impl_group!(PPI_GROUP5, 5);
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs
new file mode 100644
index 000000000..c1d9794c9
--- /dev/null
+++ b/embassy-nrf/src/ppi/ppi.rs
@@ -0,0 +1,87 @@
1use core::marker::PhantomData;
2
3use embassy::util::Unborrow;
4use embassy_hal_common::unborrow;
5
6use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
7use crate::pac;
8
9impl Task {
10 fn reg_val(&self) -> u32 {
11 self.0.as_ptr() as _
12 }
13}
14impl Event {
15 fn reg_val(&self) -> u32 {
16 self.0.as_ptr() as _
17 }
18}
19
20#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
21impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
22 pub fn new_zero_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self {
23 unborrow!(ch);
24
25 let r = unsafe { &*pac::PPI::ptr() };
26 let n = ch.number();
27 r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
28
29 Self {
30 ch,
31 phantom: PhantomData,
32 }
33 }
34}
35
36impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
37 pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self {
38 unborrow!(ch);
39
40 let r = unsafe { &*pac::PPI::ptr() };
41 let n = ch.number();
42 r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) });
43 r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
44
45 Self {
46 ch,
47 phantom: PhantomData,
48 }
49 }
50}
51
52#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
53impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
54 pub fn new_one_to_two(
55 ch: impl Unborrow<Target = C> + 'd,
56 event: Event,
57 task1: Task,
58 task2: Task,
59 ) -> Self {
60 unborrow!(ch);
61
62 let r = unsafe { &*pac::PPI::ptr() };
63 let n = ch.number();
64 r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) });
65 r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) });
66 r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) });
67
68 Self {
69 ch,
70 phantom: PhantomData,
71 }
72 }
73}
74
75impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop
76 for Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
77{
78 fn drop(&mut self) {
79 self.disable();
80
81 let r = unsafe { &*pac::PPI::ptr() };
82 let n = self.ch.number();
83 r.ch[n].eep.write(|w| unsafe { w.bits(0) });
84 r.ch[n].tep.write(|w| unsafe { w.bits(0) });
85 r.fork[n].tep.write(|w| unsafe { w.bits(0) });
86 }
87}
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index 5690ff0d8..9173338b6 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -12,8 +12,7 @@ use embassy_hal_common::unborrow;
12use futures::future::poll_fn; 12use futures::future::poll_fn;
13 13
14use crate::pac; 14use crate::pac;
15use crate::ppi::Event; 15use crate::ppi::{Event, Task};
16use crate::ppi::Task;
17 16
18pub(crate) mod sealed { 17pub(crate) mod sealed {
19 18
@@ -319,7 +318,7 @@ impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> {
319 /// 318 ///
320 /// 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.
321 pub fn task_capture(&self) -> Task { 320 pub fn task_capture(&self) -> Task {
322 Task::from_reg(&T::regs().tasks_capture[self.n]) 321 Task::from_reg(&T::regs().tasks_capture)
323 } 322 }
324 323
325 /// Returns this CC register's COMPARE event, for use with PPI. 324 /// Returns this CC register's COMPARE event, for use with PPI.
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 63bbe5a77..4bbdec63f 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -7,7 +7,7 @@ use core::marker::PhantomData;
7use core::sync::atomic::{compiler_fence, Ordering}; 7use core::sync::atomic::{compiler_fence, Ordering};
8use core::task::Poll; 8use core::task::Poll;
9use embassy::interrupt::InterruptExt; 9use embassy::interrupt::InterruptExt;
10use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write}; 10use embassy::traits::uart::{Error as TraitError, Read, ReadUntilIdle, Write};
11use embassy::util::Unborrow; 11use embassy::util::Unborrow;
12use embassy_hal_common::drop::OnDrop; 12use embassy_hal_common::drop::OnDrop;
13use embassy_hal_common::unborrow; 13use embassy_hal_common::unborrow;
@@ -219,7 +219,7 @@ impl<'a, T: Instance> Drop for Uarte<'a, T> {
219 219
220impl<'d, T: Instance> Read for Uarte<'d, T> { 220impl<'d, T: Instance> Read for Uarte<'d, T> {
221 #[rustfmt::skip] 221 #[rustfmt::skip]
222 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 222 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
223 223
224 fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 224 fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
225 async move { 225 async move {
@@ -273,7 +273,7 @@ impl<'d, T: Instance> Read for Uarte<'d, T> {
273 273
274impl<'d, T: Instance> Write for Uarte<'d, T> { 274impl<'d, T: Instance> Write for Uarte<'d, T> {
275 #[rustfmt::skip] 275 #[rustfmt::skip]
276 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 276 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
277 277
278 fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { 278 fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> {
279 async move { 279 async move {
@@ -331,8 +331,8 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
331pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { 331pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
332 uarte: Uarte<'d, U>, 332 uarte: Uarte<'d, U>,
333 timer: Timer<'d, T>, 333 timer: Timer<'d, T>,
334 ppi_ch1: Ppi<'d, AnyConfigurableChannel>, 334 ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>,
335 _ppi_ch2: Ppi<'d, AnyConfigurableChannel>, 335 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>,
336} 336}
337 337
338impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { 338impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
@@ -348,8 +348,8 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
348 pub unsafe fn new( 348 pub unsafe fn new(
349 uarte: impl Unborrow<Target = U> + 'd, 349 uarte: impl Unborrow<Target = U> + 'd,
350 timer: impl Unborrow<Target = T> + 'd, 350 timer: impl Unborrow<Target = T> + 'd,
351 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel> + 'd, 351 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
352 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel> + 'd, 352 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
353 irq: impl Unborrow<Target = U::Interrupt> + 'd, 353 irq: impl Unborrow<Target = U::Interrupt> + 'd,
354 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 354 rxd: impl Unborrow<Target = impl GpioPin> + 'd,
355 txd: impl Unborrow<Target = impl GpioPin> + 'd, 355 txd: impl Unborrow<Target = impl GpioPin> + 'd,
@@ -378,15 +378,19 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
378 timer.cc(0).short_compare_clear(); 378 timer.cc(0).short_compare_clear();
379 timer.cc(0).short_compare_stop(); 379 timer.cc(0).short_compare_stop();
380 380
381 let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable()); 381 let mut ppi_ch1 = Ppi::new_one_to_two(
382 ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy)); 382 ppi_ch1.degrade(),
383 ppi_ch1.set_task(timer.task_clear()); 383 Event::from_reg(&r.events_rxdrdy),
384 ppi_ch1.set_fork_task(timer.task_start()); 384 timer.task_clear(),
385 timer.task_start(),
386 );
385 ppi_ch1.enable(); 387 ppi_ch1.enable();
386 388
387 let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable()); 389 let mut ppi_ch2 = Ppi::new_one_to_one(
388 ppi_ch2.set_event(timer.cc(0).event_compare()); 390 ppi_ch2.degrade(),
389 ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); 391 timer.cc(0).event_compare(),
392 Task::from_reg(&r.tasks_stoprx),
393 );
390 ppi_ch2.enable(); 394 ppi_ch2.enable();
391 395
392 Self { 396 Self {
@@ -400,7 +404,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
400 404
401impl<'d, U: Instance, T: TimerInstance> ReadUntilIdle for UarteWithIdle<'d, U, T> { 405impl<'d, U: Instance, T: TimerInstance> ReadUntilIdle for UarteWithIdle<'d, U, T> {
402 #[rustfmt::skip] 406 #[rustfmt::skip]
403 type ReadUntilIdleFuture<'a> where Self: 'a = impl Future<Output = Result<usize, Error>> + 'a; 407 type ReadUntilIdleFuture<'a> where Self: 'a = impl Future<Output = Result<usize, TraitError>> + 'a;
404 fn read_until_idle<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a> { 408 fn read_until_idle<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a> {
405 async move { 409 async move {
406 let ptr = rx_buffer.as_ptr(); 410 let ptr = rx_buffer.as_ptr();
@@ -460,7 +464,7 @@ impl<'d, U: Instance, T: TimerInstance> ReadUntilIdle for UarteWithIdle<'d, U, T
460 464
461impl<'d, U: Instance, T: TimerInstance> Read for UarteWithIdle<'d, U, T> { 465impl<'d, U: Instance, T: TimerInstance> Read for UarteWithIdle<'d, U, T> {
462 #[rustfmt::skip] 466 #[rustfmt::skip]
463 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 467 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
464 fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 468 fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
465 async move { 469 async move {
466 self.ppi_ch1.disable(); 470 self.ppi_ch1.disable();
@@ -473,7 +477,7 @@ impl<'d, U: Instance, T: TimerInstance> Read for UarteWithIdle<'d, U, T> {
473 477
474impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> { 478impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> {
475 #[rustfmt::skip] 479 #[rustfmt::skip]
476 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 480 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), TraitError>> + 'a;
477 481
478 fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { 482 fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> {
479 self.uarte.write(tx_buffer) 483 self.uarte.write(tx_buffer)
diff --git a/examples/nrf/src/bin/ppi.rs b/examples/nrf/src/bin/ppi.rs
index 6ea03ebd0..99246eeda 100644
--- a/examples/nrf/src/bin/ppi.rs
+++ b/examples/nrf/src/bin/ppi.rs
@@ -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.set_event(button1.event_in());
56 ppi.set_task(led1.task_out());
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.set_event(button2.event_in());
61 ppi.set_task(led1.task_clr());
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.set_event(button3.event_in());
66 ppi.set_task(led1.task_set());
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.set_event(button4.event_in()); 64 p.PPI_CH3,
71 ppi.set_task(led1.task_out()); 65 button4.event_in(),
72 ppi.set_fork_task(led2.task_out()); 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/saadc_continuous.rs b/examples/nrf/src/bin/saadc_continuous.rs
index 149b9c60c..a06a01e91 100644
--- a/examples/nrf/src/bin/saadc_continuous.rs
+++ b/examples/nrf/src/bin/saadc_continuous.rs
@@ -32,9 +32,7 @@ async fn main(_spawner: Spawner, mut p: Peripherals) {
32 timer.cc(0).write(100); // We want to sample at 10KHz 32 timer.cc(0).write(100); // We want to sample at 10KHz
33 timer.cc(0).short_compare_clear(); 33 timer.cc(0).short_compare_clear();
34 34
35 let mut ppi = Ppi::new(p.PPI_CH0); 35 let mut ppi = Ppi::new_one_to_one(p.PPI_CH0, timer.cc(0).event_compare(), saadc.task_sample());
36 ppi.set_event(timer.cc(0).event_compare());
37 ppi.set_task(saadc.task_sample());
38 ppi.enable(); 36 ppi.enable();
39 37
40 timer.start(); 38 timer.start();