1#![macro_use]
3
4use core::future::poll_fn;
5use core::marker::PhantomData;
6use core::task::Poll;
7
8use embassy_hal_internal::PeripheralType;
9use embassy_sync::waitqueue::AtomicWaker;
10
11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, pac, peripherals, rcc, Peri};
13
14static RNG_WAKER: AtomicWaker = AtomicWaker::new();
15
16#[derive(Debug, PartialEq, Eq, Clone, Copy)]
18#[cfg_attr(feature = "defmt", derive(defmt::Format))]
19pub enum Error {
20 SeedError,
22 ClockError,
26}
27
28pub struct InterruptHandler<T: Instance> {
30 _phantom: PhantomData<T>,
31}
32
33impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
34 unsafe fn on_interrupt() {
35 let bits = T::regs().sr().read();
36 if bits.drdy() || bits.seis() || bits.ceis() {
37 T::regs().cr().modify(|reg| reg.set_ie(false));
38 RNG_WAKER.wake();
39 }
40 }
41}
42
43pub struct Rng<'d, T: Instance> {
45 _inner: Peri<'d, T>,
46}
47
48impl<'d, T: Instance> Rng<'d, T> {
49 pub fn new(
51 inner: Peri<'d, T>,
52 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
53 ) -> Self {
54 rcc::enable_and_reset::<T>();
55 let mut random = Self { _inner: inner };
56 random.reset();
57
58 T::Interrupt::unpend();
59 unsafe { T::Interrupt::enable() };
60
61 random
62 }
63
64 #[cfg(rng_v1)]
66 pub fn reset(&mut self) {
67 T::regs().cr().write(|reg| {
68 reg.set_rngen(false);
69 });
70 T::regs().sr().modify(|reg| {
71 reg.set_seis(false);
72 reg.set_ceis(false);
73 });
74 T::regs().cr().modify(|reg| {
75 reg.set_rngen(true);
76 });
77 let _ = self.next_u32();
79 }
80
81 #[cfg(not(rng_v1))]
83 pub fn reset(&mut self) {
84 T::regs().cr().write(|reg| {
85 reg.set_condrst(true);
86 reg.set_nistc(pac::rng::vals::Nistc::CUSTOM);
87 reg.set_rng_config1(pac::rng::vals::RngConfig1::CONFIG_A);
90 reg.set_clkdiv(pac::rng::vals::Clkdiv::NO_DIV);
91 reg.set_rng_config2(pac::rng::vals::RngConfig2::CONFIG_A_B);
92 reg.set_rng_config3(pac::rng::vals::RngConfig3::CONFIG_A);
93 reg.set_ced(true);
94 reg.set_ie(false);
95 reg.set_rngen(true);
96 });
97 T::regs().cr().modify(|reg| {
98 reg.set_ced(false);
99 });
100 while !T::regs().cr().read().condrst() {}
102
103 #[cfg(not(rng_wba6))]
105 {
106 T::regs().htcr().write(|w| w.set_htcfg(pac::rng::vals::Htcfg::MAGIC));
108 T::regs()
111 .htcr()
112 .write(|w| w.set_htcfg(pac::rng::vals::Htcfg::RECOMMENDED));
113 }
114
115 T::regs().cr().modify(|reg| {
117 reg.set_rngen(true);
118 reg.set_condrst(false);
119 });
120 while T::regs().cr().read().condrst() {}
122 }
123
124 pub fn recover_seed_error(&mut self) {
126 self.reset();
127 if T::regs().sr().read().seis() {
129 warn!("recovering from seed error failed");
130 return;
131 }
132 while T::regs().sr().read().secs() {}
134 }
135
136 pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
138 for chunk in dest.chunks_mut(4) {
139 let mut bits = T::regs().sr().read();
140 if !bits.seis() && !bits.ceis() && !bits.drdy() {
141 poll_fn(|cx| {
143 let bits = T::regs().sr().read();
145 if bits.drdy() || bits.seis() || bits.ceis() {
146 return Poll::Ready(());
147 }
148 RNG_WAKER.register(cx.waker());
149 T::regs().cr().modify(|reg| reg.set_ie(true));
150 let bits = T::regs().sr().read();
153 if bits.drdy() || bits.seis() || bits.ceis() {
154 Poll::Ready(())
155 } else {
156 Poll::Pending
157 }
158 })
159 .await;
160
161 bits = T::regs().sr().read()
163 }
164 if bits.seis() {
165 self.recover_seed_error();
169 return Err(Error::SeedError);
170 } else if bits.ceis() {
171 T::regs().sr().modify(|sr| sr.set_ceis(false));
174 return Err(Error::ClockError);
175 } else if bits.drdy() {
176 let random_word = T::regs().dr().read();
179 if random_word == 0 {
181 return Err(Error::SeedError);
182 }
183 for (dest, src) in chunk.iter_mut().zip(random_word.to_ne_bytes().iter()) {
185 *dest = *src
186 }
187 }
188 }
189
190 Ok(())
191 }
192
193 pub fn next_u32(&mut self) -> u32 {
195 loop {
196 let sr = T::regs().sr().read();
197 if sr.seis() | sr.ceis() {
198 self.reset();
199 } else if sr.drdy() {
200 return T::regs().dr().read();
201 }
202 }
203 }
204
205 pub fn next_u64(&mut self) -> u64 {
207 let mut rand = self.next_u32() as u64;
208 rand |= (self.next_u32() as u64) << 32;
209 rand
210 }
211
212 pub fn fill_bytes(&mut self, dest: &mut [u8]) {
214 for chunk in dest.chunks_mut(4) {
215 let rand = self.next_u32();
216 for (slot, num) in chunk.iter_mut().zip(rand.to_ne_bytes().iter()) {
217 *slot = *num
218 }
219 }
220 }
221}
222
223impl<'d, T: Instance> Drop for Rng<'d, T> {
224 fn drop(&mut self) {
225 T::regs().cr().modify(|reg| {
226 reg.set_rngen(false);
227 });
228 rcc::disable::<T>();
229 }
230}
231
232impl<'d, T: Instance> rand_core_06::RngCore for Rng<'d, T> {
233 fn next_u32(&mut self) -> u32 {
234 self.next_u32()
235 }
236
237 fn next_u64(&mut self) -> u64 {
238 self.next_u64()
239 }
240
241 fn fill_bytes(&mut self, dest: &mut [u8]) {
242 self.fill_bytes(dest);
243 }
244
245 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
246 self.fill_bytes(dest);
247 Ok(())
248 }
249}
250
251impl<'d, T: Instance> rand_core_06::CryptoRng for Rng<'d, T> {}
252
253impl<'d, T: Instance> rand_core_09::RngCore for Rng<'d, T> {
254 fn next_u32(&mut self) -> u32 {
255 self.next_u32()
256 }
257
258 fn next_u64(&mut self) -> u64 {
259 self.next_u64()
260 }
261
262 fn fill_bytes(&mut self, dest: &mut [u8]) {
263 self.fill_bytes(dest);
264 }
265}
266
267impl<'d, T: Instance> rand_core_09::CryptoRng for Rng<'d, T> {}
268
269trait SealedInstance {
270 fn regs() -> pac::rng::Rng;
271}
272
273#[allow(private_bounds)]
275pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send {
276 type Interrupt: interrupt::typelevel::Interrupt;
278}
279
280foreach_interrupt!(
281 ($inst:ident, rng, RNG, GLOBAL, $irq:ident) => {
282 impl Instance for peripherals::$inst {
283 type Interrupt = crate::interrupt::typelevel::$irq;
284 }
285
286 impl SealedInstance for peripherals::$inst {
287 fn regs() -> crate::pac::rng::Rng {
288 crate::pac::$inst
289 }
290 }
291 };
292);