aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-05 21:50:15 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commitd113fcfe326bd338df2db7733fcf0ae9f230c594 (patch)
tree3f7ee9082c6185a4e14adeeeffaecc98ef3c86fc
parent96788ac93a1e98ef8d9d5e8d80d5102aef34d45d (diff)
nrf/rng: make available on all chips, use Instance trait, switch to new interrupt binding.
-rw-r--r--embassy-nrf/src/chips/nrf52805.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52810.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52811.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52820.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52832.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52833.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52840.rs2
-rw-r--r--embassy-nrf/src/chips/nrf5340_net.rs5
-rw-r--r--embassy-nrf/src/lib.rs2
-rw-r--r--embassy-nrf/src/rng.rs193
-rw-r--r--examples/nrf52840/src/bin/rng.rs8
-rw-r--r--examples/nrf52840/src/bin/usb_ethernet.rs8
12 files changed, 154 insertions, 76 deletions
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs
index 185cda430..e406c081b 100644
--- a/embassy-nrf/src/chips/nrf52805.rs
+++ b/embassy-nrf/src/chips/nrf52805.rs
@@ -142,6 +142,8 @@ impl_twis!(TWI0, TWIS0, TWIM0_TWIS0_TWI0);
142 142
143impl_qdec!(QDEC, QDEC, QDEC); 143impl_qdec!(QDEC, QDEC, QDEC);
144 144
145impl_rng!(RNG, RNG, RNG);
146
145impl_timer!(TIMER0, TIMER0, TIMER0); 147impl_timer!(TIMER0, TIMER0, TIMER0);
146impl_timer!(TIMER1, TIMER1, TIMER1); 148impl_timer!(TIMER1, TIMER1, TIMER1);
147impl_timer!(TIMER2, TIMER2, TIMER2); 149impl_timer!(TIMER2, TIMER2, TIMER2);
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs
index 1e3c054a4..153795e54 100644
--- a/embassy-nrf/src/chips/nrf52810.rs
+++ b/embassy-nrf/src/chips/nrf52810.rs
@@ -152,6 +152,8 @@ impl_pdm!(PDM, PDM, PDM);
152 152
153impl_qdec!(QDEC, QDEC, QDEC); 153impl_qdec!(QDEC, QDEC, QDEC);
154 154
155impl_rng!(RNG, RNG, RNG);
156
155impl_timer!(TIMER0, TIMER0, TIMER0); 157impl_timer!(TIMER0, TIMER0, TIMER0);
156impl_timer!(TIMER1, TIMER1, TIMER1); 158impl_timer!(TIMER1, TIMER1, TIMER1);
157impl_timer!(TIMER2, TIMER2, TIMER2); 159impl_timer!(TIMER2, TIMER2, TIMER2);
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs
index 3bb44171e..a7a7cf58c 100644
--- a/embassy-nrf/src/chips/nrf52811.rs
+++ b/embassy-nrf/src/chips/nrf52811.rs
@@ -154,6 +154,8 @@ impl_pdm!(PDM, PDM, PDM);
154 154
155impl_qdec!(QDEC, QDEC, QDEC); 155impl_qdec!(QDEC, QDEC, QDEC);
156 156
157impl_rng!(RNG, RNG, RNG);
158
157impl_timer!(TIMER0, TIMER0, TIMER0); 159impl_timer!(TIMER0, TIMER0, TIMER0);
158impl_timer!(TIMER1, TIMER1, TIMER1); 160impl_timer!(TIMER1, TIMER1, TIMER1);
159impl_timer!(TIMER2, TIMER2, TIMER2); 161impl_timer!(TIMER2, TIMER2, TIMER2);
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs
index b28778f33..14a1b8cc9 100644
--- a/embassy-nrf/src/chips/nrf52820.rs
+++ b/embassy-nrf/src/chips/nrf52820.rs
@@ -155,6 +155,8 @@ impl_timer!(TIMER3, TIMER3, TIMER3, extended);
155 155
156impl_qdec!(QDEC, QDEC, QDEC); 156impl_qdec!(QDEC, QDEC, QDEC);
157 157
158impl_rng!(RNG, RNG, RNG);
159
158impl_pin!(P0_00, 0, 0); 160impl_pin!(P0_00, 0, 0);
159impl_pin!(P0_01, 0, 1); 161impl_pin!(P0_01, 0, 1);
160impl_pin!(P0_02, 0, 2); 162impl_pin!(P0_02, 0, 2);
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs
index 00dc9fd8f..83ecd0deb 100644
--- a/embassy-nrf/src/chips/nrf52832.rs
+++ b/embassy-nrf/src/chips/nrf52832.rs
@@ -175,6 +175,8 @@ impl_pdm!(PDM, PDM, PDM);
175 175
176impl_qdec!(QDEC, QDEC, QDEC); 176impl_qdec!(QDEC, QDEC, QDEC);
177 177
178impl_rng!(RNG, RNG, RNG);
179
178impl_timer!(TIMER0, TIMER0, TIMER0); 180impl_timer!(TIMER0, TIMER0, TIMER0);
179impl_timer!(TIMER1, TIMER1, TIMER1); 181impl_timer!(TIMER1, TIMER1, TIMER1);
180impl_timer!(TIMER2, TIMER2, TIMER2); 182impl_timer!(TIMER2, TIMER2, TIMER2);
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs
index 345608c9d..5e5db04de 100644
--- a/embassy-nrf/src/chips/nrf52833.rs
+++ b/embassy-nrf/src/chips/nrf52833.rs
@@ -201,6 +201,8 @@ impl_pdm!(PDM, PDM, PDM);
201 201
202impl_qdec!(QDEC, QDEC, QDEC); 202impl_qdec!(QDEC, QDEC, QDEC);
203 203
204impl_rng!(RNG, RNG, RNG);
205
204impl_timer!(TIMER0, TIMER0, TIMER0); 206impl_timer!(TIMER0, TIMER0, TIMER0);
205impl_timer!(TIMER1, TIMER1, TIMER1); 207impl_timer!(TIMER1, TIMER1, TIMER1);
206impl_timer!(TIMER2, TIMER2, TIMER2); 208impl_timer!(TIMER2, TIMER2, TIMER2);
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs
index 630f01aa9..f6d33f85c 100644
--- a/embassy-nrf/src/chips/nrf52840.rs
+++ b/embassy-nrf/src/chips/nrf52840.rs
@@ -212,6 +212,8 @@ impl_pdm!(PDM, PDM, PDM);
212 212
213impl_qdec!(QDEC, QDEC, QDEC); 213impl_qdec!(QDEC, QDEC, QDEC);
214 214
215impl_rng!(RNG, RNG, RNG);
216
215impl_pin!(P0_00, 0, 0); 217impl_pin!(P0_00, 0, 0);
216impl_pin!(P0_01, 0, 1); 218impl_pin!(P0_01, 0, 1);
217impl_pin!(P0_02, 0, 2); 219impl_pin!(P0_02, 0, 2);
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs
index d7ba6c16c..1e59528cb 100644
--- a/embassy-nrf/src/chips/nrf5340_net.rs
+++ b/embassy-nrf/src/chips/nrf5340_net.rs
@@ -127,6 +127,9 @@ embassy_hal_common::peripherals! {
127 // SAADC 127 // SAADC
128 SAADC, 128 SAADC,
129 129
130 // RNG
131 RNG,
132
130 // PWM 133 // PWM
131 PWM0, 134 PWM0,
132 PWM1, 135 PWM1,
@@ -252,6 +255,8 @@ impl_timer!(TIMER0, TIMER0, TIMER0);
252impl_timer!(TIMER1, TIMER1, TIMER1); 255impl_timer!(TIMER1, TIMER1, TIMER1);
253impl_timer!(TIMER2, TIMER2, TIMER2); 256impl_timer!(TIMER2, TIMER2, TIMER2);
254 257
258impl_rng!(RNG, RNG, RNG);
259
255impl_pin!(P0_00, 0, 0); 260impl_pin!(P0_00, 0, 0);
256impl_pin!(P0_01, 0, 1); 261impl_pin!(P0_01, 0, 1);
257impl_pin!(P0_02, 0, 2); 262impl_pin!(P0_02, 0, 2);
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index feefa2486..ee29ce20b 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -61,7 +61,7 @@ pub mod pwm;
61pub mod qdec; 61pub mod qdec;
62#[cfg(any(feature = "nrf52840", feature = "_nrf5340-app"))] 62#[cfg(any(feature = "nrf52840", feature = "_nrf5340-app"))]
63pub mod qspi; 63pub mod qspi;
64#[cfg(not(any(feature = "_nrf5340", feature = "_nrf9160")))] 64#[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf9160")))]
65pub mod rng; 65pub mod rng;
66#[cfg(not(any(feature = "nrf52820", feature = "_nrf5340-net")))] 66#[cfg(not(any(feature = "nrf52820", feature = "_nrf5340-net")))]
67pub mod saadc; 67pub mod saadc;
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index b0b3a8eb8..a5602248d 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -1,83 +1,48 @@
1//! Random Number Generator (RNG) driver. 1//! Random Number Generator (RNG) driver.
2 2
3#![macro_use]
4
3use core::future::poll_fn; 5use core::future::poll_fn;
6use core::marker::PhantomData;
4use core::ptr; 7use core::ptr;
5use core::sync::atomic::{AtomicPtr, Ordering}; 8use core::sync::atomic::{AtomicPtr, Ordering};
6use core::task::Poll; 9use core::task::Poll;
7 10
11use embassy_cortex_m::interrupt::Interrupt;
8use embassy_hal_common::drop::OnDrop; 12use embassy_hal_common::drop::OnDrop;
9use embassy_hal_common::{into_ref, PeripheralRef}; 13use embassy_hal_common::{into_ref, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 14use embassy_sync::waitqueue::AtomicWaker;
11 15
12use crate::interrupt::InterruptExt; 16use crate::interrupt::InterruptExt;
13use crate::peripherals::RNG; 17use crate::{interrupt, Peripheral};
14use crate::{interrupt, pac, Peripheral};
15
16impl RNG {
17 fn regs() -> &'static pac::rng::RegisterBlock {
18 unsafe { &*pac::RNG::ptr() }
19 }
20}
21
22static STATE: State = State {
23 ptr: AtomicPtr::new(ptr::null_mut()),
24 end: AtomicPtr::new(ptr::null_mut()),
25 waker: AtomicWaker::new(),
26};
27 18
28struct State { 19/// Interrupt handler.
29 ptr: AtomicPtr<u8>, 20pub struct InterruptHandler<T: Instance> {
30 end: AtomicPtr<u8>, 21 _phantom: PhantomData<T>,
31 waker: AtomicWaker,
32} 22}
33 23
34/// A wrapper around an nRF RNG peripheral. 24impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
35/// 25 unsafe fn on_interrupt() {
36/// It has a non-blocking API, and a blocking api through `rand`. 26 let s = T::state();
37pub struct Rng<'d> { 27 let r = T::regs();
38 irq: PeripheralRef<'d, interrupt::RNG>,
39}
40
41impl<'d> Rng<'d> {
42 /// Creates a new RNG driver from the `RNG` peripheral and interrupt.
43 ///
44 /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor,
45 /// e.g. using `mem::forget`.
46 ///
47 /// The synchronous API is safe.
48 pub fn new(_rng: impl Peripheral<P = RNG> + 'd, irq: impl Peripheral<P = interrupt::RNG> + 'd) -> Self {
49 into_ref!(irq);
50
51 let this = Self { irq };
52 28
53 this.stop();
54 this.disable_irq();
55
56 this.irq.set_handler(Self::on_interrupt);
57 this.irq.unpend();
58 this.irq.enable();
59
60 this
61 }
62
63 fn on_interrupt(_: *mut ()) {
64 // Clear the event. 29 // Clear the event.
65 RNG::regs().events_valrdy.reset(); 30 r.events_valrdy.reset();
66 31
67 // Mutate the slice within a critical section, 32 // Mutate the slice within a critical section,
68 // so that the future isn't dropped in between us loading the pointer and actually dereferencing it. 33 // so that the future isn't dropped in between us loading the pointer and actually dereferencing it.
69 let (ptr, end) = critical_section::with(|_| { 34 let (ptr, end) = critical_section::with(|_| {
70 let ptr = STATE.ptr.load(Ordering::Relaxed); 35 let ptr = s.ptr.load(Ordering::Relaxed);
71 // We need to make sure we haven't already filled the whole slice, 36 // We need to make sure we haven't already filled the whole slice,
72 // in case the interrupt fired again before the executor got back to the future. 37 // in case the interrupt fired again before the executor got back to the future.
73 let end = STATE.end.load(Ordering::Relaxed); 38 let end = s.end.load(Ordering::Relaxed);
74 if !ptr.is_null() && ptr != end { 39 if !ptr.is_null() && ptr != end {
75 // If the future was dropped, the pointer would have been set to null, 40 // If the future was dropped, the pointer would have been set to null,
76 // so we're still good to mutate the slice. 41 // so we're still good to mutate the slice.
77 // The safety contract of `Rng::new` means that the future can't have been dropped 42 // The safety contract of `Rng::new` means that the future can't have been dropped
78 // without calling its destructor. 43 // without calling its destructor.
79 unsafe { 44 unsafe {
80 *ptr = RNG::regs().value.read().value().bits(); 45 *ptr = r.value.read().value().bits();
81 } 46 }
82 } 47 }
83 (ptr, end) 48 (ptr, end)
@@ -90,15 +55,15 @@ impl<'d> Rng<'d> {
90 } 55 }
91 56
92 let new_ptr = unsafe { ptr.add(1) }; 57 let new_ptr = unsafe { ptr.add(1) };
93 match STATE 58 match s
94 .ptr 59 .ptr
95 .compare_exchange(ptr, new_ptr, Ordering::Relaxed, Ordering::Relaxed) 60 .compare_exchange(ptr, new_ptr, Ordering::Relaxed, Ordering::Relaxed)
96 { 61 {
97 Ok(_) => { 62 Ok(_) => {
98 let end = STATE.end.load(Ordering::Relaxed); 63 let end = s.end.load(Ordering::Relaxed);
99 // It doesn't matter if `end` was changed under our feet, because then this will just be false. 64 // It doesn't matter if `end` was changed under our feet, because then this will just be false.
100 if new_ptr == end { 65 if new_ptr == end {
101 STATE.waker.wake(); 66 s.waker.wake();
102 } 67 }
103 } 68 }
104 Err(_) => { 69 Err(_) => {
@@ -107,21 +72,53 @@ impl<'d> Rng<'d> {
107 } 72 }
108 } 73 }
109 } 74 }
75}
76
77/// A wrapper around an nRF RNG peripheral.
78///
79/// It has a non-blocking API, and a blocking api through `rand`.
80pub struct Rng<'d, T: Instance> {
81 _peri: PeripheralRef<'d, T>,
82}
83
84impl<'d, T: Instance> Rng<'d, T> {
85 /// Creates a new RNG driver from the `RNG` peripheral and interrupt.
86 ///
87 /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor,
88 /// e.g. using `mem::forget`.
89 ///
90 /// The synchronous API is safe.
91 pub fn new(
92 rng: impl Peripheral<P = T> + 'd,
93 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
94 ) -> Self {
95 into_ref!(rng);
96
97 let this = Self { _peri: rng };
98
99 this.stop();
100 this.disable_irq();
101
102 unsafe { T::Interrupt::steal() }.unpend();
103 unsafe { T::Interrupt::steal() }.enable();
104
105 this
106 }
110 107
111 fn stop(&self) { 108 fn stop(&self) {
112 RNG::regs().tasks_stop.write(|w| unsafe { w.bits(1) }) 109 T::regs().tasks_stop.write(|w| unsafe { w.bits(1) })
113 } 110 }
114 111
115 fn start(&self) { 112 fn start(&self) {
116 RNG::regs().tasks_start.write(|w| unsafe { w.bits(1) }) 113 T::regs().tasks_start.write(|w| unsafe { w.bits(1) })
117 } 114 }
118 115
119 fn enable_irq(&self) { 116 fn enable_irq(&self) {
120 RNG::regs().intenset.write(|w| w.valrdy().set()); 117 T::regs().intenset.write(|w| w.valrdy().set());
121 } 118 }
122 119
123 fn disable_irq(&self) { 120 fn disable_irq(&self) {
124 RNG::regs().intenclr.write(|w| w.valrdy().clear()); 121 T::regs().intenclr.write(|w| w.valrdy().clear());
125 } 122 }
126 123
127 /// Enable or disable the RNG's bias correction. 124 /// Enable or disable the RNG's bias correction.
@@ -131,7 +128,7 @@ impl<'d> Rng<'d> {
131 /// 128 ///
132 /// Defaults to disabled. 129 /// Defaults to disabled.
133 pub fn set_bias_correction(&self, enable: bool) { 130 pub fn set_bias_correction(&self, enable: bool) {
134 RNG::regs().config.write(|w| w.dercen().bit(enable)) 131 T::regs().config.write(|w| w.dercen().bit(enable))
135 } 132 }
136 133
137 /// Fill the buffer with random bytes. 134 /// Fill the buffer with random bytes.
@@ -140,11 +137,13 @@ impl<'d> Rng<'d> {
140 return; // Nothing to fill 137 return; // Nothing to fill
141 } 138 }
142 139
140 let s = T::state();
141
143 let range = dest.as_mut_ptr_range(); 142 let range = dest.as_mut_ptr_range();
144 // Even if we've preempted the interrupt, it can't preempt us again, 143 // Even if we've preempted the interrupt, it can't preempt us again,
145 // so we don't need to worry about the order we write these in. 144 // so we don't need to worry about the order we write these in.
146 STATE.ptr.store(range.start, Ordering::Relaxed); 145 s.ptr.store(range.start, Ordering::Relaxed);
147 STATE.end.store(range.end, Ordering::Relaxed); 146 s.end.store(range.end, Ordering::Relaxed);
148 147
149 self.enable_irq(); 148 self.enable_irq();
150 self.start(); 149 self.start();
@@ -154,16 +153,16 @@ impl<'d> Rng<'d> {
154 self.disable_irq(); 153 self.disable_irq();
155 154
156 // The interrupt is now disabled and can't preempt us anymore, so the order doesn't matter here. 155 // The interrupt is now disabled and can't preempt us anymore, so the order doesn't matter here.
157 STATE.ptr.store(ptr::null_mut(), Ordering::Relaxed); 156 s.ptr.store(ptr::null_mut(), Ordering::Relaxed);
158 STATE.end.store(ptr::null_mut(), Ordering::Relaxed); 157 s.end.store(ptr::null_mut(), Ordering::Relaxed);
159 }); 158 });
160 159
161 poll_fn(|cx| { 160 poll_fn(|cx| {
162 STATE.waker.register(cx.waker()); 161 s.waker.register(cx.waker());
163 162
164 // The interrupt will never modify `end`, so load it first and then get the most up-to-date `ptr`. 163 // The interrupt will never modify `end`, so load it first and then get the most up-to-date `ptr`.
165 let end = STATE.end.load(Ordering::Relaxed); 164 let end = s.end.load(Ordering::Relaxed);
166 let ptr = STATE.ptr.load(Ordering::Relaxed); 165 let ptr = s.ptr.load(Ordering::Relaxed);
167 166
168 if ptr == end { 167 if ptr == end {
169 // We're done. 168 // We're done.
@@ -183,7 +182,7 @@ impl<'d> Rng<'d> {
183 self.start(); 182 self.start();
184 183
185 for byte in dest.iter_mut() { 184 for byte in dest.iter_mut() {
186 let regs = RNG::regs(); 185 let regs = T::regs();
187 while regs.events_valrdy.read().bits() == 0 {} 186 while regs.events_valrdy.read().bits() == 0 {}
188 regs.events_valrdy.reset(); 187 regs.events_valrdy.reset();
189 *byte = regs.value.read().value().bits(); 188 *byte = regs.value.read().value().bits();
@@ -193,13 +192,16 @@ impl<'d> Rng<'d> {
193 } 192 }
194} 193}
195 194
196impl<'d> Drop for Rng<'d> { 195impl<'d, T: Instance> Drop for Rng<'d, T> {
197 fn drop(&mut self) { 196 fn drop(&mut self) {
198 self.irq.disable() 197 self.stop();
198 let s = T::state();
199 s.ptr.store(ptr::null_mut(), Ordering::Relaxed);
200 s.end.store(ptr::null_mut(), Ordering::Relaxed);
199 } 201 }
200} 202}
201 203
202impl<'d> rand_core::RngCore for Rng<'d> { 204impl<'d, T: Instance> rand_core::RngCore for Rng<'d, T> {
203 fn fill_bytes(&mut self, dest: &mut [u8]) { 205 fn fill_bytes(&mut self, dest: &mut [u8]) {
204 self.blocking_fill_bytes(dest); 206 self.blocking_fill_bytes(dest);
205 } 207 }
@@ -223,4 +225,53 @@ impl<'d> rand_core::RngCore for Rng<'d> {
223 } 225 }
224} 226}
225 227
226impl<'d> rand_core::CryptoRng for Rng<'d> {} 228impl<'d, T: Instance> rand_core::CryptoRng for Rng<'d, T> {}
229
230pub(crate) mod sealed {
231 use super::*;
232
233 /// Peripheral static state
234 pub struct State {
235 pub ptr: AtomicPtr<u8>,
236 pub end: AtomicPtr<u8>,
237 pub waker: AtomicWaker,
238 }
239
240 impl State {
241 pub const fn new() -> Self {
242 Self {
243 ptr: AtomicPtr::new(ptr::null_mut()),
244 end: AtomicPtr::new(ptr::null_mut()),
245 waker: AtomicWaker::new(),
246 }
247 }
248 }
249
250 pub trait Instance {
251 fn regs() -> &'static crate::pac::rng::RegisterBlock;
252 fn state() -> &'static State;
253 }
254}
255
256/// RNG peripheral instance.
257pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
258 /// Interrupt for this peripheral.
259 type Interrupt: Interrupt;
260}
261
262macro_rules! impl_rng {
263 ($type:ident, $pac_type:ident, $irq:ident) => {
264 impl crate::rng::sealed::Instance for peripherals::$type {
265 fn regs() -> &'static crate::pac::rng::RegisterBlock {
266 unsafe { &*pac::$pac_type::ptr() }
267 }
268 fn state() -> &'static crate::rng::sealed::State {
269 static STATE: crate::rng::sealed::State = crate::rng::sealed::State::new();
270 &STATE
271 }
272 }
273 impl crate::rng::Instance for peripherals::$type {
274 type Interrupt = crate::interrupt::$irq;
275 }
276 };
277}
diff --git a/examples/nrf52840/src/bin/rng.rs b/examples/nrf52840/src/bin/rng.rs
index 647073949..855743f50 100644
--- a/examples/nrf52840/src/bin/rng.rs
+++ b/examples/nrf52840/src/bin/rng.rs
@@ -3,15 +3,19 @@
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::interrupt;
7use embassy_nrf::rng::Rng; 6use embassy_nrf::rng::Rng;
7use embassy_nrf::{bind_interrupts, peripherals, rng};
8use rand::Rng as _; 8use rand::Rng as _;
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
11bind_interrupts!(struct Irqs {
12 RNG => rng::InterruptHandler<peripherals::RNG>;
13});
14
11#[embassy_executor::main] 15#[embassy_executor::main]
12async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
13 let p = embassy_nrf::init(Default::default()); 17 let p = embassy_nrf::init(Default::default());
14 let mut rng = Rng::new(p.RNG, interrupt::take!(RNG)); 18 let mut rng = Rng::new(p.RNG, Irqs);
15 19
16 // Async API 20 // Async API
17 let mut bytes = [0; 4]; 21 let mut bytes = [0; 4];
diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs
index 979780896..083a1cbb0 100644
--- a/examples/nrf52840/src/bin/usb_ethernet.rs
+++ b/examples/nrf52840/src/bin/usb_ethernet.rs
@@ -10,7 +10,7 @@ use embassy_net::tcp::TcpSocket;
10use embassy_net::{Stack, StackResources}; 10use embassy_net::{Stack, StackResources};
11use embassy_nrf::rng::Rng; 11use embassy_nrf::rng::Rng;
12use embassy_nrf::usb::{Driver, HardwareVbusDetect}; 12use embassy_nrf::usb::{Driver, HardwareVbusDetect};
13use embassy_nrf::{interrupt, pac, peripherals}; 13use embassy_nrf::{bind_interrupts, interrupt, pac, peripherals, rng};
14use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; 14use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState};
15use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; 15use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
16use embassy_usb::{Builder, Config, UsbDevice}; 16use embassy_usb::{Builder, Config, UsbDevice};
@@ -18,6 +18,10 @@ use embedded_io::asynch::Write;
18use static_cell::StaticCell; 18use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20 20
21bind_interrupts!(struct Irqs {
22 RNG => rng::InterruptHandler<peripherals::RNG>;
23});
24
21type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>; 25type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>;
22 26
23macro_rules! singleton { 27macro_rules! singleton {
@@ -108,7 +112,7 @@ async fn main(spawner: Spawner) {
108 //}); 112 //});
109 113
110 // Generate random seed 114 // Generate random seed
111 let mut rng = Rng::new(p.RNG, interrupt::take!(RNG)); 115 let mut rng = Rng::new(p.RNG, Irqs);
112 let mut seed = [0; 8]; 116 let mut seed = [0; 8];
113 rng.blocking_fill_bytes(&mut seed); 117 rng.blocking_fill_bytes(&mut seed);
114 let seed = u64::from_le_bytes(seed); 118 let seed = u64::from_le_bytes(seed);