aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/lib.rs48
-rw-r--r--embassy-nrf/src/ppi.rs143
2 files changed, 191 insertions, 0 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 9e5132c59..1bcaf5483 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -97,6 +97,7 @@ pub mod buffered_uarte;
97pub mod gpio; 97pub mod gpio;
98pub mod gpiote; 98pub mod gpiote;
99pub mod interrupt; 99pub mod interrupt;
100pub mod ppi;
100#[cfg(feature = "52840")] 101#[cfg(feature = "52840")]
101pub mod qspi; 102pub mod qspi;
102pub mod rtc; 103pub mod rtc;
@@ -145,6 +146,53 @@ embassy_extras::peripherals! {
145 GPIOTE_CH6, 146 GPIOTE_CH6,
146 GPIOTE_CH7, 147 GPIOTE_CH7,
147 148
149 // PPI
150 PPI_CH0,
151 PPI_CH1,
152 PPI_CH2,
153 PPI_CH3,
154 PPI_CH4,
155 PPI_CH5,
156 PPI_CH6,
157 PPI_CH7,
158 PPI_CH8,
159 PPI_CH9,
160 PPI_CH10,
161 PPI_CH11,
162 PPI_CH12,
163 PPI_CH13,
164 PPI_CH14,
165 PPI_CH15,
166 #[cfg(not(feature = "51"))]
167 PPI_CH16,
168 #[cfg(not(feature = "51"))]
169 PPI_CH17,
170 #[cfg(not(feature = "51"))]
171 PPI_CH18,
172 #[cfg(not(feature = "51"))]
173 PPI_CH19,
174 PPI_CH20,
175 PPI_CH21,
176 PPI_CH22,
177 PPI_CH23,
178 PPI_CH24,
179 PPI_CH25,
180 PPI_CH26,
181 PPI_CH27,
182 PPI_CH28,
183 PPI_CH29,
184 PPI_CH30,
185 PPI_CH31,
186
187 PPI_GROUP0,
188 PPI_GROUP1,
189 PPI_GROUP2,
190 PPI_GROUP3,
191 #[cfg(not(feature = "51"))]
192 PPI_GROUP4,
193 #[cfg(not(feature = "51"))]
194 PPI_GROUP5,
195
148 // GPIO port 0 196 // GPIO port 0
149 P0_00, 197 P0_00,
150 P0_01, 198 P0_01,
diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs
new file mode 100644
index 000000000..c06b212c1
--- /dev/null
+++ b/embassy-nrf/src/ppi.rs
@@ -0,0 +1,143 @@
1//! HAL interface for the PPI peripheral.
2//!
3//! The Programmable Peripheral Interconnect interface allows for an autonomous interoperability
4//! between peripherals through their events and tasks. There are fixed PPI channels and fully
5//! configurable ones, fixed channels can only connect specific events to specific tasks. For fully
6//! configurable channels, it is possible to choose, via software, the event and the task that it
7//! will triggered by the event.
8//!
9//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task
10//! to be triggered by the same event, even fixed PPI channels have a configurable fork task.
11
12use embassy_extras::impl_unborrow;
13
14use crate::peripherals;
15
16// ======================
17// traits
18
19mod sealed {
20 pub trait ConfigurableChannel {}
21 pub trait Channel {}
22 pub trait Group {}
23}
24
25pub trait Channel: sealed::Channel + Sized {
26 fn number(&self) -> usize;
27 fn degrade(self) -> AnyChannel {
28 AnyChannel {
29 number: self.number() as u8,
30 }
31 }
32}
33pub trait ConfigurableChannel: Channel + sealed::ConfigurableChannel {}
34
35pub trait Group: sealed::Group + Sized {
36 fn number(&self) -> usize;
37 fn degrade(self) -> AnyGroup {
38 AnyGroup {
39 number: self.number() as u8,
40 }
41 }
42}
43
44// ======================
45// channels
46
47pub struct AnyChannel {
48 number: u8,
49}
50impl_unborrow!(AnyChannel);
51impl sealed::Channel for AnyChannel {}
52impl Channel for AnyChannel {
53 fn number(&self) -> usize {
54 self.number as usize
55 }
56}
57
58macro_rules! impl_channel {
59 ($type:ident, $number:expr, configurable) => {
60 impl_channel!($type, $number);
61 impl sealed::ConfigurableChannel for peripherals::$type {}
62 impl ConfigurableChannel for peripherals::$type {}
63 };
64 ($type:ident, $number:expr) => {
65 impl sealed::Channel for peripherals::$type {}
66 impl Channel for peripherals::$type {
67 fn number(&self) -> usize {
68 $number
69 }
70 }
71 };
72}
73
74impl_channel!(PPI_CH0, 0, configurable);
75impl_channel!(PPI_CH1, 1, configurable);
76impl_channel!(PPI_CH2, 2, configurable);
77impl_channel!(PPI_CH3, 3, configurable);
78impl_channel!(PPI_CH4, 4, configurable);
79impl_channel!(PPI_CH5, 5, configurable);
80impl_channel!(PPI_CH6, 6, configurable);
81impl_channel!(PPI_CH7, 7, configurable);
82impl_channel!(PPI_CH8, 8, configurable);
83impl_channel!(PPI_CH9, 9, configurable);
84impl_channel!(PPI_CH10, 10, configurable);
85impl_channel!(PPI_CH11, 11, configurable);
86impl_channel!(PPI_CH12, 12, configurable);
87impl_channel!(PPI_CH13, 13, configurable);
88impl_channel!(PPI_CH14, 14, configurable);
89impl_channel!(PPI_CH15, 15, configurable);
90#[cfg(not(feature = "51"))]
91impl_channel!(PPI_CH16, 16, configurable);
92#[cfg(not(feature = "51"))]
93impl_channel!(PPI_CH17, 17, configurable);
94#[cfg(not(feature = "51"))]
95impl_channel!(PPI_CH18, 18, configurable);
96#[cfg(not(feature = "51"))]
97impl_channel!(PPI_CH19, 19, configurable);
98impl_channel!(PPI_CH20, 20);
99impl_channel!(PPI_CH21, 21);
100impl_channel!(PPI_CH22, 22);
101impl_channel!(PPI_CH23, 23);
102impl_channel!(PPI_CH24, 24);
103impl_channel!(PPI_CH25, 25);
104impl_channel!(PPI_CH26, 26);
105impl_channel!(PPI_CH27, 27);
106impl_channel!(PPI_CH28, 28);
107impl_channel!(PPI_CH29, 29);
108impl_channel!(PPI_CH30, 30);
109impl_channel!(PPI_CH31, 31);
110
111// ======================
112// groups
113
114pub struct AnyGroup {
115 number: u8,
116}
117impl_unborrow!(AnyGroup);
118impl sealed::Group for AnyGroup {}
119impl Group for AnyGroup {
120 fn number(&self) -> usize {
121 self.number as usize
122 }
123}
124
125macro_rules! impl_group {
126 ($type:ident, $number:expr) => {
127 impl sealed::Group for peripherals::$type {}
128 impl Group for peripherals::$type {
129 fn number(&self) -> usize {
130 $number
131 }
132 }
133 };
134}
135
136impl_group!(PPI_GROUP0, 0);
137impl_group!(PPI_GROUP1, 1);
138impl_group!(PPI_GROUP2, 2);
139impl_group!(PPI_GROUP3, 3);
140#[cfg(not(feature = "51"))]
141impl_group!(PPI_GROUP4, 4);
142#[cfg(not(feature = "51"))]
143impl_group!(PPI_GROUP5, 5);