aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDion Dokter <[email protected]>2021-10-19 10:13:08 +0200
committerDario Nieuwenhuis <[email protected]>2021-10-26 14:47:31 +0200
commita6c84cb91552fc0442a28126d3fae60031aa6622 (patch)
tree260555ec0c58eb5e2053f4031889b4260bb9ebea
parent531dfcffb3c203dff15dcb53fe25577c121c7784 (diff)
- Interconnect is now PPI again
- Scary pointer math is now contained in the tasks and events - ppi now sets the tasks and events immediately and the struct is now zero-sized - StaticToOne is renamed to ZeroToOne - Used DPPI tasks and events now panic when enabled twice
-rw-r--r--embassy-nrf/src/buffered_uarte.rs2
-rw-r--r--embassy-nrf/src/gpiote.rs2
-rw-r--r--embassy-nrf/src/interconnect/dppi.rs47
-rw-r--r--embassy-nrf/src/interconnect/ppi.rs65
-rw-r--r--embassy-nrf/src/lib.rs2
-rw-r--r--embassy-nrf/src/ppi/dppi.rs61
-rw-r--r--embassy-nrf/src/ppi/mod.rs (renamed from embassy-nrf/src/interconnect/mod.rs)119
-rw-r--r--embassy-nrf/src/ppi/ppi.rs77
-rw-r--r--embassy-nrf/src/timer.rs2
-rw-r--r--embassy-nrf/src/uarte.rs2
10 files changed, 206 insertions, 173 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 7c9a2344e..1dc04f4f6 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -14,8 +14,8 @@ use embassy_hal_common::{low_power_wait_until, unborrow};
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::interconnect::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task};
18use crate::pac; 17use crate::pac;
18use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, Ppi, Task};
19use crate::timer::Instance as TimerInstance; 19use crate::timer::Instance as TimerInstance;
20use crate::timer::{Frequency, Timer}; 20use crate::timer::{Frequency, Timer};
21use crate::uarte::{Config, Instance as UarteInstance}; 21use crate::uarte::{Config, Instance as UarteInstance};
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 6703bfc60..7ec072ac8 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -11,8 +11,8 @@ use futures::future::poll_fn;
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};
15use crate::pac; 14use 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;
diff --git a/embassy-nrf/src/interconnect/dppi.rs b/embassy-nrf/src/interconnect/dppi.rs
deleted file mode 100644
index 60f19fca0..000000000
--- a/embassy-nrf/src/interconnect/dppi.rs
+++ /dev/null
@@ -1,47 +0,0 @@
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/ppi.rs b/embassy-nrf/src/interconnect/ppi.rs
deleted file mode 100644
index 91ff811fe..000000000
--- a/embassy-nrf/src/interconnect/ppi.rs
+++ /dev/null
@@ -1,65 +0,0 @@
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 39f3e4a4a..c21c4d398 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 interconnect; 34pub mod ppi;
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/dppi.rs b/embassy-nrf/src/ppi/dppi.rs
new file mode 100644
index 000000000..083ec858a
--- /dev/null
+++ b/embassy-nrf/src/ppi/dppi.rs
@@ -0,0 +1,61 @@
1use super::{Channel, Event, Ppi, Task};
2
3const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
4const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
5
6impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize>
7 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
8{
9 pub(super) fn enable_task(task: &Task, channel: &C, _index: usize) {
10 unsafe {
11 if task.subscribe_reg().read_volatile() != 0 {
12 panic!("Task is already in use");
13 }
14 task.subscribe_reg()
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.subscribe_reg().write_volatile(0);
22 }
23 }
24
25 pub(super) fn enable_event(event: &Event, channel: &C, _index: usize) {
26 unsafe {
27 if event.publish_reg().read_volatile() != 0 {
28 panic!("Task is already in use");
29 }
30 event
31 .publish_reg()
32 .write_volatile(DPPI_ENABLE_BIT | (channel.number() as u32 & DPPI_CHANNEL_MASK));
33 }
34 }
35
36 pub(super) fn disable_event(event: &Event, _channel: &C, _index: usize) {
37 unsafe {
38 event.publish_reg().write_volatile(0);
39 }
40 }
41
42 /// Enables all tasks and events
43 pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) {
44 for (index, task) in tasks.iter().enumerate() {
45 Self::enable_task(task, channel, index);
46 }
47 for (index, event) in events.iter().enumerate() {
48 Self::enable_event(event, channel, index);
49 }
50 }
51
52 /// Disable all tasks and events
53 pub(super) fn disable_all(&self) {
54 for (index, task) in self.tasks.iter().enumerate() {
55 Self::disable_task(task, &self.ch, index);
56 }
57 for (index, event) in self.events.iter().enumerate() {
58 Self::disable_event(event, &self.ch, index);
59 }
60 }
61}
diff --git a/embassy-nrf/src/interconnect/mod.rs b/embassy-nrf/src/ppi/mod.rs
index 8cb505bdc..ffb6af020 100644
--- a/embassy-nrf/src/interconnect/mod.rs
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -28,12 +28,14 @@ mod ppi;
28 28
29pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { 29pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
30 ch: C, 30 ch: C,
31 #[cfg(feature = "_dppi")]
31 events: [Event; EVENT_COUNT], 32 events: [Event; EVENT_COUNT],
33 #[cfg(feature = "_dppi")]
32 tasks: [Task; TASK_COUNT], 34 tasks: [Task; TASK_COUNT],
33 phantom: PhantomData<&'d mut C>, 35 phantom: PhantomData<&'d mut C>,
34} 36}
35 37
36impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> 38impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize>
37 Ppi<'d, C, EVENT_COUNT, TASK_COUNT> 39 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
38{ 40{
39 pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> { 41 pub fn degrade(self) -> Ppi<'d, AnyChannel, EVENT_COUNT, TASK_COUNT> {
@@ -43,7 +45,9 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize>
43 #[cfg(feature = "_ppi")] 45 #[cfg(feature = "_ppi")]
44 has_configurable_task: self.ch.is_task_configurable(), 46 has_configurable_task: self.ch.is_task_configurable(),
45 }, 47 },
48 #[cfg(feature = "_dppi")]
46 events: self.events, 49 events: self.events,
50 #[cfg(feature = "_dppi")]
47 tasks: self.tasks, 51 tasks: self.tasks,
48 phantom: PhantomData, 52 phantom: PhantomData,
49 } 53 }
@@ -62,26 +66,6 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize>
62 r.chenclr 66 r.chenclr
63 .write(|w| unsafe { w.bits(1 << self.ch.number()) }); 67 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
64 } 68 }
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} 69}
86 70
87impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop 71impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop
@@ -93,19 +77,23 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop
93 } 77 }
94} 78}
95 79
96impl<'d, C: StaticToOneChannel> Ppi<'d, C, 0, 1> { 80impl<'d, C: ZeroToOneChannel> Ppi<'d, C, 0, 1> {
97 pub fn new_static_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self { 81 pub fn new_static_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self {
98 unborrow!(ch); 82 unborrow!(ch);
99 83
100 let s = Self { 84 let events = [];
85 let tasks = [task];
86
87 Self::enable_all(&tasks, &events, &ch);
88
89 Self {
101 ch, 90 ch,
102 events: [], 91 #[cfg(feature = "_dppi")]
103 tasks: [task], 92 events,
93 #[cfg(feature = "_dppi")]
94 tasks,
104 phantom: PhantomData, 95 phantom: PhantomData,
105 }; 96 }
106
107 s.enable_all();
108 s
109 } 97 }
110} 98}
111 99
@@ -113,15 +101,19 @@ impl<'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 { 101 pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self {
114 unborrow!(ch); 102 unborrow!(ch);
115 103
116 let s = Self { 104 let events = [event];
105 let tasks = [task];
106
107 Self::enable_all(&tasks, &events, &ch);
108
109 Self {
117 ch, 110 ch,
118 events: [event], 111 #[cfg(feature = "_dppi")]
119 tasks: [task], 112 events,
113 #[cfg(feature = "_dppi")]
114 tasks,
120 phantom: PhantomData, 115 phantom: PhantomData,
121 }; 116 }
122
123 s.enable_all();
124 s
125 } 117 }
126} 118}
127 119
@@ -134,15 +126,19 @@ impl<'d, C: OneToTwoChannel> Ppi<'d, C, 1, 2> {
134 ) -> Self { 126 ) -> Self {
135 unborrow!(ch); 127 unborrow!(ch);
136 128
137 let s = Self { 129 let events = [event];
130 let tasks = [task1, task2];
131
132 Self::enable_all(&tasks, &events, &ch);
133
134 Self {
138 ch, 135 ch,
139 events: [event], 136 #[cfg(feature = "_dppi")]
140 tasks: [task1, task2], 137 events,
138 #[cfg(feature = "_dppi")]
139 tasks,
141 phantom: PhantomData, 140 phantom: PhantomData,
142 }; 141 }
143
144 s.enable_all();
145 s
146 } 142 }
147} 143}
148 144
@@ -156,18 +152,21 @@ impl<'d, C: ManyToManyChannel, const EVENT_COUNT: usize, const TASK_COUNT: usize
156 ) -> Self { 152 ) -> Self {
157 unborrow!(ch); 153 unborrow!(ch);
158 154
159 let s = Self { 155 Self::enable_all(&tasks, &events, &ch);
156
157 Self {
160 ch, 158 ch,
159 #[cfg(feature = "_dppi")]
161 events, 160 events,
161 #[cfg(feature = "_dppi")]
162 tasks, 162 tasks,
163 phantom: PhantomData, 163 phantom: PhantomData,
164 }; 164 }
165
166 s.enable_all();
167 s
168 } 165 }
169} 166}
170 167
168const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
169
171/// Represents a task that a peripheral can do. 170/// 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 171/// When a task is subscribed to a PPI channel it will run when the channel is triggered by
173/// a published event. 172/// a published event.
@@ -179,6 +178,10 @@ impl Task {
179 pub(crate) fn from_reg<T>(reg: &T) -> Self { 178 pub(crate) fn from_reg<T>(reg: &T) -> Self {
180 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) 179 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
181 } 180 }
181
182 pub fn subscribe_reg(&self) -> *mut u32 {
183 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
184 }
182} 185}
183 186
184/// # Safety 187/// # Safety
@@ -196,6 +199,10 @@ impl Event {
196 pub(crate) fn from_reg<T>(reg: &T) -> Self { 199 pub(crate) fn from_reg<T>(reg: &T) -> Self {
197 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) 200 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
198 } 201 }
202
203 pub fn publish_reg(&self) -> *mut u32 {
204 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
205 }
199} 206}
200 207
201/// # Safety 208/// # Safety
@@ -218,8 +225,8 @@ pub trait Channel: sealed::Channel + Unborrow<Target = Self> + Sized {
218 fn is_task_configurable(&self) -> bool; 225 fn is_task_configurable(&self) -> bool;
219} 226}
220 227
221pub trait StaticToOneChannel: Channel {} 228pub trait ZeroToOneChannel: Channel {}
222pub trait OneToOneChannel: StaticToOneChannel {} 229pub trait OneToOneChannel: ZeroToOneChannel {}
223pub trait OneToTwoChannel: OneToOneChannel {} 230pub trait OneToTwoChannel: OneToOneChannel {}
224pub trait ManyToManyChannel: OneToTwoChannel {} 231pub trait ManyToManyChannel: OneToTwoChannel {}
225 232
@@ -250,8 +257,8 @@ impl Channel for AnyChannel {
250 257
251macro_rules! impl_ppi_channel { 258macro_rules! impl_ppi_channel {
252 ($type:ident, $number:expr, $has_configurable_task:expr) => { 259 ($type:ident, $number:expr, $has_configurable_task:expr) => {
253 impl crate::interconnect::sealed::Channel for peripherals::$type {} 260 impl crate::ppi::sealed::Channel for peripherals::$type {}
254 impl crate::interconnect::Channel for peripherals::$type { 261 impl crate::ppi::Channel for peripherals::$type {
255 fn number(&self) -> usize { 262 fn number(&self) -> usize {
256 $number 263 $number
257 } 264 }
@@ -267,19 +274,19 @@ macro_rules! impl_ppi_channel {
267 }; 274 };
268 ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => { 275 ($type:ident, $number:expr, $has_configurable_task:expr, 0, 1) => {
269 impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0); 276 impl_ppi_channel!($type, $number, $has_configurable_task, 0, 0);
270 impl crate::interconnect::StaticToOneChannel for peripherals::$type {} 277 impl crate::ppi::ZeroToOneChannel for peripherals::$type {}
271 }; 278 };
272 ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => { 279 ($type:ident, $number:expr, $has_configurable_task:expr, 1, 1) => {
273 impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1); 280 impl_ppi_channel!($type, $number, $has_configurable_task, 0, 1);
274 impl crate::interconnect::OneToOneChannel for peripherals::$type {} 281 impl crate::ppi::OneToOneChannel for peripherals::$type {}
275 }; 282 };
276 ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => { 283 ($type:ident, $number:expr, $has_configurable_task:expr, 1, 2) => {
277 impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1); 284 impl_ppi_channel!($type, $number, $has_configurable_task, 1, 1);
278 impl crate::interconnect::OneToTwoChannel for peripherals::$type {} 285 impl crate::ppi::OneToTwoChannel for peripherals::$type {}
279 }; 286 };
280 ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => { 287 ($type:ident, $number:expr, $has_configurable_task:expr, many, many) => {
281 impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2); 288 impl_ppi_channel!($type, $number, $has_configurable_task, 1, 2);
282 impl crate::interconnect::ManyToManyChannel for peripherals::$type {} 289 impl crate::ppi::ManyToManyChannel for peripherals::$type {}
283 }; 290 };
284} 291}
285 292
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs
new file mode 100644
index 000000000..67d2086c3
--- /dev/null
+++ b/embassy-nrf/src/ppi/ppi.rs
@@ -0,0 +1,77 @@
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 fn set_main_task(task: Option<&Task>, channel: usize) {
8 let r = unsafe { &*pac::PPI::ptr() };
9 if let Some(task) = task {
10 r.ch[channel]
11 .tep
12 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
13 } else {
14 r.ch[channel].tep.write(|w| unsafe { w.bits(0) })
15 }
16 }
17
18 fn set_fork_task(task: Option<&Task>, channel: usize) {
19 let r = unsafe { &*pac::PPI::ptr() };
20 if let Some(task) = task {
21 r.fork[channel]
22 .tep
23 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
24 } else {
25 r.fork[channel].tep.write(|w| unsafe { w.bits(0) })
26 }
27 }
28
29 fn set_event(event: Option<&Event>, channel: usize) {
30 let r = unsafe { &*pac::PPI::ptr() };
31 if let Some(event) = event {
32 r.ch[channel]
33 .eep
34 .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) })
35 } else {
36 r.ch[channel].eep.write(|w| unsafe { w.bits(0) })
37 }
38 }
39
40 /// Enables all tasks and events
41 pub(super) fn enable_all(tasks: &[Task], events: &[Event], channel: &C) {
42 // One configurable task, no fork
43 if channel.is_task_configurable() && TASK_COUNT == 1 {
44 Self::set_main_task(Some(&tasks[0]), channel.number());
45 }
46
47 // One configurable task, as fork
48 if !channel.is_task_configurable() && TASK_COUNT == 1 {
49 Self::set_fork_task(Some(&tasks[0]), channel.number());
50 }
51
52 // Two configurable tasks (main + fork)
53 if TASK_COUNT == 2 {
54 Self::set_main_task(Some(&tasks[0]), channel.number());
55 Self::set_fork_task(Some(&tasks[1]), channel.number());
56 }
57
58 if EVENT_COUNT == 1 {
59 Self::set_event(Some(&events[0]), channel.number());
60 }
61 }
62
63 /// Disable all tasks and events
64 pub(super) fn disable_all(&self) {
65 if self.ch.is_task_configurable() {
66 Self::set_main_task(None, self.ch.number());
67 }
68
69 if TASK_COUNT == 1 && !self.ch.is_task_configurable() || TASK_COUNT == 2 {
70 Self::set_fork_task(None, self.ch.number());
71 }
72
73 if EVENT_COUNT == 1 {
74 Self::set_event(None, self.ch.number());
75 }
76 }
77}
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index 27f8e715e..9173338b6 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -11,8 +11,8 @@ use embassy_hal_common::drop::OnDrop;
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};
15use crate::pac; 14use crate::pac;
15use crate::ppi::{Event, Task};
16 16
17pub(crate) mod sealed { 17pub(crate) mod sealed {
18 18
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 17e60ce22..36cf65d89 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -16,9 +16,9 @@ use futures::future::poll_fn;
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};
20use crate::interrupt::Interrupt; 19use crate::interrupt::Interrupt;
21use crate::pac; 20use crate::pac;
21use crate::ppi::{AnyChannel, Event, OneToOneChannel, OneToTwoChannel, 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