aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-06-18 11:25:51 +0000
committerGitHub <[email protected]>2024-06-18 11:25:51 +0000
commita0231ed74ce1713c527f2574118c42e1a90cf18d (patch)
tree7c3e437e5bef17d885b7ebc3f418cf69595848c4
parent94af383809f6991bf02e836d6b6e4b0e35a0b30e (diff)
parent91476eea12998aa3a622710962e0d1b0f60819e1 (diff)
Merge pull request #3091 from embassy-rs/nrf-egu-peri
add HAL and example for using nRF EGU peripheral
-rw-r--r--embassy-nrf/src/chips/nrf52805.rs7
-rw-r--r--embassy-nrf/src/chips/nrf52810.rs7
-rw-r--r--embassy-nrf/src/chips/nrf52811.rs7
-rw-r--r--embassy-nrf/src/chips/nrf52820.rs15
-rw-r--r--embassy-nrf/src/chips/nrf52832.rs15
-rw-r--r--embassy-nrf/src/chips/nrf52833.rs15
-rw-r--r--embassy-nrf/src/chips/nrf52840.rs15
-rw-r--r--embassy-nrf/src/chips/nrf5340_app.rs15
-rw-r--r--embassy-nrf/src/chips/nrf5340_net.rs5
-rw-r--r--embassy-nrf/src/chips/nrf9160.rs15
-rw-r--r--embassy-nrf/src/egu.rs103
-rw-r--r--embassy-nrf/src/lib.rs2
-rw-r--r--examples/nrf52840/src/bin/egu.rs43
13 files changed, 264 insertions, 0 deletions
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs
index 14c3f9b1a..b51b0c93e 100644
--- a/embassy-nrf/src/chips/nrf52805.rs
+++ b/embassy-nrf/src/chips/nrf52805.rs
@@ -132,6 +132,10 @@ embassy_hal_internal::peripherals! {
132 132
133 // Radio 133 // Radio
134 RADIO, 134 RADIO,
135
136 // EGU
137 EGU0,
138 EGU1,
135} 139}
136 140
137impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); 141impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -214,6 +218,9 @@ impl_saadc_input!(P0_05, ANALOG_INPUT3);
214 218
215impl_radio!(RADIO, RADIO, RADIO); 219impl_radio!(RADIO, RADIO, RADIO);
216 220
221impl_egu!(EGU0, EGU0, SWI0_EGU0);
222impl_egu!(EGU1, EGU1, SWI1_EGU1);
223
217embassy_hal_internal::interrupt_mod!( 224embassy_hal_internal::interrupt_mod!(
218 POWER_CLOCK, 225 POWER_CLOCK,
219 RADIO, 226 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs
index c607586db..273098d9b 100644
--- a/embassy-nrf/src/chips/nrf52810.rs
+++ b/embassy-nrf/src/chips/nrf52810.rs
@@ -138,6 +138,10 @@ embassy_hal_internal::peripherals! {
138 138
139 // Radio 139 // Radio
140 RADIO, 140 RADIO,
141
142 // EGU
143 EGU0,
144 EGU1,
141} 145}
142 146
143impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); 147impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -240,6 +244,9 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
240 244
241impl_radio!(RADIO, RADIO, RADIO); 245impl_radio!(RADIO, RADIO, RADIO);
242 246
247impl_egu!(EGU0, EGU0, SWI0_EGU0);
248impl_egu!(EGU1, EGU1, SWI1_EGU1);
249
243embassy_hal_internal::interrupt_mod!( 250embassy_hal_internal::interrupt_mod!(
244 POWER_CLOCK, 251 POWER_CLOCK,
245 RADIO, 252 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs
index 5f70365b4..9bce38636 100644
--- a/embassy-nrf/src/chips/nrf52811.rs
+++ b/embassy-nrf/src/chips/nrf52811.rs
@@ -138,6 +138,10 @@ embassy_hal_internal::peripherals! {
138 138
139 // Radio 139 // Radio
140 RADIO, 140 RADIO,
141
142 // EGU
143 EGU0,
144 EGU1,
141} 145}
142 146
143impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); 147impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -242,6 +246,9 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
242 246
243impl_radio!(RADIO, RADIO, RADIO); 247impl_radio!(RADIO, RADIO, RADIO);
244 248
249impl_egu!(EGU0, EGU0, SWI0_EGU0);
250impl_egu!(EGU1, EGU1, SWI1_EGU1);
251
245embassy_hal_internal::interrupt_mod!( 252embassy_hal_internal::interrupt_mod!(
246 POWER_CLOCK, 253 POWER_CLOCK,
247 RADIO, 254 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs
index 82d097407..2acae2c8f 100644
--- a/embassy-nrf/src/chips/nrf52820.rs
+++ b/embassy-nrf/src/chips/nrf52820.rs
@@ -133,6 +133,14 @@ embassy_hal_internal::peripherals! {
133 133
134 // Radio 134 // Radio
135 RADIO, 135 RADIO,
136
137 // EGU
138 EGU0,
139 EGU1,
140 EGU2,
141 EGU3,
142 EGU4,
143 EGU5,
136} 144}
137 145
138impl_usb!(USBD, USBD, USBD); 146impl_usb!(USBD, USBD, USBD);
@@ -229,6 +237,13 @@ impl_ppi_channel!(PPI_CH31, 31 => static);
229 237
230impl_radio!(RADIO, RADIO, RADIO); 238impl_radio!(RADIO, RADIO, RADIO);
231 239
240impl_egu!(EGU0, EGU0, SWI0_EGU0);
241impl_egu!(EGU1, EGU1, SWI1_EGU1);
242impl_egu!(EGU2, EGU2, SWI2_EGU2);
243impl_egu!(EGU3, EGU3, SWI3_EGU3);
244impl_egu!(EGU4, EGU4, SWI4_EGU4);
245impl_egu!(EGU5, EGU5, SWI5_EGU5);
246
232embassy_hal_internal::interrupt_mod!( 247embassy_hal_internal::interrupt_mod!(
233 POWER_CLOCK, 248 POWER_CLOCK,
234 RADIO, 249 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs
index 67b32fe5f..94b373ab3 100644
--- a/embassy-nrf/src/chips/nrf52832.rs
+++ b/embassy-nrf/src/chips/nrf52832.rs
@@ -153,6 +153,14 @@ embassy_hal_internal::peripherals! {
153 153
154 // Radio 154 // Radio
155 RADIO, 155 RADIO,
156
157 // EGU
158 EGU0,
159 EGU1,
160 EGU2,
161 EGU3,
162 EGU4,
163 EGU5,
156} 164}
157 165
158impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); 166impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -269,6 +277,13 @@ impl_i2s!(I2S, I2S, I2S);
269 277
270impl_radio!(RADIO, RADIO, RADIO); 278impl_radio!(RADIO, RADIO, RADIO);
271 279
280impl_egu!(EGU0, EGU0, SWI0_EGU0);
281impl_egu!(EGU1, EGU1, SWI1_EGU1);
282impl_egu!(EGU2, EGU2, SWI2_EGU2);
283impl_egu!(EGU3, EGU3, SWI3_EGU3);
284impl_egu!(EGU4, EGU4, SWI4_EGU4);
285impl_egu!(EGU5, EGU5, SWI5_EGU5);
286
272embassy_hal_internal::interrupt_mod!( 287embassy_hal_internal::interrupt_mod!(
273 POWER_CLOCK, 288 POWER_CLOCK,
274 RADIO, 289 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs
index 20f14e2d6..09cde1ac1 100644
--- a/embassy-nrf/src/chips/nrf52833.rs
+++ b/embassy-nrf/src/chips/nrf52833.rs
@@ -173,6 +173,14 @@ embassy_hal_internal::peripherals! {
173 173
174 // Radio 174 // Radio
175 RADIO, 175 RADIO,
176
177 // EGU
178 EGU0,
179 EGU1,
180 EGU2,
181 EGU3,
182 EGU4,
183 EGU5,
176} 184}
177 185
178impl_usb!(USBD, USBD, USBD); 186impl_usb!(USBD, USBD, USBD);
@@ -311,6 +319,13 @@ impl_i2s!(I2S, I2S, I2S);
311 319
312impl_radio!(RADIO, RADIO, RADIO); 320impl_radio!(RADIO, RADIO, RADIO);
313 321
322impl_egu!(EGU0, EGU0, SWI0_EGU0);
323impl_egu!(EGU1, EGU1, SWI1_EGU1);
324impl_egu!(EGU2, EGU2, SWI2_EGU2);
325impl_egu!(EGU3, EGU3, SWI3_EGU3);
326impl_egu!(EGU4, EGU4, SWI4_EGU4);
327impl_egu!(EGU5, EGU5, SWI5_EGU5);
328
314embassy_hal_internal::interrupt_mod!( 329embassy_hal_internal::interrupt_mod!(
315 POWER_CLOCK, 330 POWER_CLOCK,
316 RADIO, 331 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs
index d3272b2e8..0f3d1b250 100644
--- a/embassy-nrf/src/chips/nrf52840.rs
+++ b/embassy-nrf/src/chips/nrf52840.rs
@@ -176,6 +176,14 @@ embassy_hal_internal::peripherals! {
176 176
177 // Radio 177 // Radio
178 RADIO, 178 RADIO,
179
180 // EGU
181 EGU0,
182 EGU1,
183 EGU2,
184 EGU3,
185 EGU4,
186 EGU5,
179} 187}
180 188
181impl_usb!(USBD, USBD, USBD); 189impl_usb!(USBD, USBD, USBD);
@@ -316,6 +324,13 @@ impl_i2s!(I2S, I2S, I2S);
316 324
317impl_radio!(RADIO, RADIO, RADIO); 325impl_radio!(RADIO, RADIO, RADIO);
318 326
327impl_egu!(EGU0, EGU0, SWI0_EGU0);
328impl_egu!(EGU1, EGU1, SWI1_EGU1);
329impl_egu!(EGU2, EGU2, SWI2_EGU2);
330impl_egu!(EGU3, EGU3, SWI3_EGU3);
331impl_egu!(EGU4, EGU4, SWI4_EGU4);
332impl_egu!(EGU5, EGU5, SWI5_EGU5);
333
319embassy_hal_internal::interrupt_mod!( 334embassy_hal_internal::interrupt_mod!(
320 POWER_CLOCK, 335 POWER_CLOCK,
321 RADIO, 336 RADIO,
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs
index 62c74bb6f..584f6e43c 100644
--- a/embassy-nrf/src/chips/nrf5340_app.rs
+++ b/embassy-nrf/src/chips/nrf5340_app.rs
@@ -380,6 +380,14 @@ embassy_hal_internal::peripherals! {
380 P1_13, 380 P1_13,
381 P1_14, 381 P1_14,
382 P1_15, 382 P1_15,
383
384 // EGU
385 EGU0,
386 EGU1,
387 EGU2,
388 EGU3,
389 EGU4,
390 EGU5,
383} 391}
384 392
385impl_usb!(USBD, USBD, USBD); 393impl_usb!(USBD, USBD, USBD);
@@ -519,6 +527,13 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
519impl_saadc_input!(P0_19, ANALOG_INPUT6); 527impl_saadc_input!(P0_19, ANALOG_INPUT6);
520impl_saadc_input!(P0_20, ANALOG_INPUT7); 528impl_saadc_input!(P0_20, ANALOG_INPUT7);
521 529
530impl_egu!(EGU0, EGU0, EGU0);
531impl_egu!(EGU1, EGU1, EGU1);
532impl_egu!(EGU2, EGU2, EGU2);
533impl_egu!(EGU3, EGU3, EGU3);
534impl_egu!(EGU4, EGU4, EGU4);
535impl_egu!(EGU5, EGU5, EGU5);
536
522embassy_hal_internal::interrupt_mod!( 537embassy_hal_internal::interrupt_mod!(
523 FPU, 538 FPU,
524 CACHE, 539 CACHE,
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs
index 65e8f9653..d772c9a49 100644
--- a/embassy-nrf/src/chips/nrf5340_net.rs
+++ b/embassy-nrf/src/chips/nrf5340_net.rs
@@ -251,6 +251,9 @@ embassy_hal_internal::peripherals! {
251 251
252 // Radio 252 // Radio
253 RADIO, 253 RADIO,
254
255 // EGU
256 EGU0,
254} 257}
255 258
256impl_uarte!(SERIAL0, UARTE0, SERIAL0); 259impl_uarte!(SERIAL0, UARTE0, SERIAL0);
@@ -350,6 +353,8 @@ impl_ppi_channel!(PPI_CH31, 31 => configurable);
350 353
351impl_radio!(RADIO, RADIO, RADIO); 354impl_radio!(RADIO, RADIO, RADIO);
352 355
356impl_egu!(EGU0, EGU0, EGU0);
357
353embassy_hal_internal::interrupt_mod!( 358embassy_hal_internal::interrupt_mod!(
354 CLOCK_POWER, 359 CLOCK_POWER,
355 RADIO, 360 RADIO,
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs
index 8b1356ef8..8107ca175 100644
--- a/embassy-nrf/src/chips/nrf9160.rs
+++ b/embassy-nrf/src/chips/nrf9160.rs
@@ -283,6 +283,14 @@ embassy_hal_internal::peripherals! {
283 283
284 // PDM 284 // PDM
285 PDM, 285 PDM,
286
287 // EGU
288 EGU0,
289 EGU1,
290 EGU2,
291 EGU3,
292 EGU4,
293 EGU5,
286} 294}
287 295
288impl_uarte!(SERIAL0, UARTE0, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); 296impl_uarte!(SERIAL0, UARTE0, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
@@ -380,6 +388,13 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
380impl_saadc_input!(P0_19, ANALOG_INPUT6); 388impl_saadc_input!(P0_19, ANALOG_INPUT6);
381impl_saadc_input!(P0_20, ANALOG_INPUT7); 389impl_saadc_input!(P0_20, ANALOG_INPUT7);
382 390
391impl_egu!(EGU0, EGU0, EGU0);
392impl_egu!(EGU1, EGU1, EGU1);
393impl_egu!(EGU2, EGU2, EGU2);
394impl_egu!(EGU3, EGU3, EGU3);
395impl_egu!(EGU4, EGU4, EGU4);
396impl_egu!(EGU5, EGU5, EGU5);
397
383embassy_hal_internal::interrupt_mod!( 398embassy_hal_internal::interrupt_mod!(
384 SPU, 399 SPU,
385 CLOCK_POWER, 400 CLOCK_POWER,
diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs
new file mode 100644
index 000000000..c0cde8330
--- /dev/null
+++ b/embassy-nrf/src/egu.rs
@@ -0,0 +1,103 @@
1//! EGU driver.
2//!
3//! The event generator driver provides a higher level API for task triggering
4//! and events to use with PPI.
5
6#![macro_use]
7
8use core::marker::PhantomData;
9
10use embassy_hal_internal::into_ref;
11
12use crate::ppi::{Event, Task};
13use crate::{interrupt, pac, Peripheral, PeripheralRef};
14
15/// An instance of the EGU.
16pub struct Egu<'d, T: Instance> {
17 _p: PeripheralRef<'d, T>,
18}
19
20impl<'d, T: Instance> Egu<'d, T> {
21 /// Create a new EGU instance.
22 pub fn new(_p: impl Peripheral<P = T> + 'd) -> Self {
23 into_ref!(_p);
24 Self { _p }
25 }
26
27 /// Get a handle to a trigger for the EGU.
28 pub fn trigger(&mut self, number: TriggerNumber) -> Trigger<'d, T> {
29 Trigger {
30 number,
31 _p: PhantomData,
32 }
33 }
34}
35
36pub(crate) trait SealedInstance {
37 fn regs() -> &'static pac::egu0::RegisterBlock;
38}
39
40/// Basic Egu instance.
41#[allow(private_bounds)]
42pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
43 /// Interrupt for this peripheral.
44 type Interrupt: interrupt::typelevel::Interrupt;
45}
46
47macro_rules! impl_egu {
48 ($type:ident, $pac_type:ident, $irq:ident) => {
49 impl crate::egu::SealedInstance for peripherals::$type {
50 fn regs() -> &'static pac::egu0::RegisterBlock {
51 unsafe { &*pac::$pac_type::ptr() }
52 }
53 }
54 impl crate::egu::Instance for peripherals::$type {
55 type Interrupt = crate::interrupt::typelevel::$irq;
56 }
57 };
58}
59
60/// Represents a trigger within the EGU.
61pub struct Trigger<'d, T: Instance> {
62 number: TriggerNumber,
63 _p: PhantomData<&'d T>,
64}
65
66impl<'d, T: Instance> Trigger<'d, T> {
67 /// Get task for this trigger to use with PPI.
68 pub fn task(&self) -> Task<'d> {
69 let nr = self.number as usize;
70 let regs = T::regs();
71 Task::from_reg(&regs.tasks_trigger[nr])
72 }
73
74 /// Get event for this trigger to use with PPI.
75 pub fn event(&self) -> Event<'d> {
76 let nr = self.number as usize;
77 let regs = T::regs();
78 Event::from_reg(&regs.events_triggered[nr])
79 }
80}
81
82/// Represents a trigger within an EGU.
83#[allow(missing_docs)]
84#[derive(Clone, Copy, PartialEq)]
85#[repr(u8)]
86pub enum TriggerNumber {
87 Trigger0 = 0,
88 Trigger1 = 1,
89 Trigger2 = 2,
90 Trigger3 = 3,
91 Trigger4 = 4,
92 Trigger5 = 5,
93 Trigger6 = 6,
94 Trigger7 = 7,
95 Trigger8 = 8,
96 Trigger9 = 9,
97 Trigger10 = 10,
98 Trigger11 = 11,
99 Trigger12 = 12,
100 Trigger13 = 13,
101 Trigger14 = 14,
102 Trigger15 = 15,
103}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 3457dd933..05b52f687 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -50,6 +50,8 @@ pub mod gpiote;
50#[cfg(not(any(feature = "_nrf9160", feature = "_nrf5340-app")))] 50#[cfg(not(any(feature = "_nrf9160", feature = "_nrf5340-app")))]
51pub mod radio; 51pub mod radio;
52 52
53#[cfg(not(feature = "nrf51"))]
54pub mod egu;
53#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] 55#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
54pub mod i2s; 56pub mod i2s;
55pub mod nvmc; 57pub mod nvmc;
diff --git a/examples/nrf52840/src/bin/egu.rs b/examples/nrf52840/src/bin/egu.rs
new file mode 100644
index 000000000..8bf712697
--- /dev/null
+++ b/examples/nrf52840/src/bin/egu.rs
@@ -0,0 +1,43 @@
1//! This example shows the use of the EGU peripheral combined with PPI.
2//!
3//! It chains events from button -> egu0-trigger0 -> egu0-trigger1 -> led
4#![no_std]
5#![no_main]
6
7use embassy_executor::Spawner;
8use embassy_nrf::egu::{Egu, TriggerNumber};
9use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
10use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity, OutputChannel, OutputChannelPolarity};
11use embassy_nrf::peripherals::{PPI_CH0, PPI_CH1, PPI_CH2};
12use embassy_nrf::ppi::Ppi;
13use embassy_time::{Duration, Timer};
14use {defmt_rtt as _, panic_probe as _};
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let p = embassy_nrf::init(Default::default());
19
20 let led1 = Output::new(p.P0_13, Level::High, OutputDrive::Standard);
21 let btn1 = Input::new(p.P0_11, Pull::Up);
22
23 let mut egu1 = Egu::new(p.EGU0);
24 let led1 = OutputChannel::new(p.GPIOTE_CH0, led1, OutputChannelPolarity::Toggle);
25 let btn1 = InputChannel::new(p.GPIOTE_CH1, btn1, InputChannelPolarity::LoToHi);
26
27 let trigger0 = egu1.trigger(TriggerNumber::Trigger0);
28 let trigger1 = egu1.trigger(TriggerNumber::Trigger1);
29
30 let mut ppi1: Ppi<PPI_CH0, 1, 1> = Ppi::new_one_to_one(p.PPI_CH0, btn1.event_in(), trigger0.task());
31 ppi1.enable();
32
33 let mut ppi2: Ppi<PPI_CH1, 1, 1> = Ppi::new_one_to_one(p.PPI_CH1, trigger0.event(), trigger1.task());
34 ppi2.enable();
35
36 let mut ppi3: Ppi<PPI_CH2, 1, 1> = Ppi::new_one_to_one(p.PPI_CH2, trigger1.event(), led1.task_out());
37 ppi3.enable();
38
39 defmt::info!("Push the button to toggle the LED");
40 loop {
41 Timer::after(Duration::from_secs(60)).await;
42 }
43}