1use core::cmp;
4use core::mem;
5
6use crate::pac::{RCC, RNG};
7use crate::rcc::{Enable, Reset};
8use core::num::NonZeroU32;
9use core::ops::Shl;
10use embedded_hal::blocking::rng::Read;
11use rand_core::RngCore;
12
13#[derive(Debug)]
14pub enum ErrorKind {
15 ClockError = 2,
18 SeedError = 4,
22}
23
24impl From<ErrorKind> for rand_core::Error {
25 fn from(err: ErrorKind) -> rand_core::Error {
26 let err_code = NonZeroU32::new(rand_core::Error::CUSTOM_START + err as u32).unwrap();
27 rand_core::Error::from(err_code)
28 }
29}
30
31pub trait RngExt {
32 fn init(self) -> Rng;
33}
34
35impl RngExt for RNG {
36 fn init(self) -> Rng {
40 cortex_m::interrupt::free(|_| {
41 let rcc = unsafe { &*RCC::ptr() };
42
43 if rcc.cr.read().pllrdy().bit_is_clear() {
45 rcc.cr.modify(|_, w| w.pllon().set_bit());
46 while rcc.cr.read().pllrdy().bit_is_clear() {}
48 }
49 unsafe {
50 RNG::enable_unchecked();
52 RNG::is_enabled();
54 RNG::reset_unchecked();
56 }
57
58 self.cr.modify(|_, w| w.rngen().set_bit());
60 while !self.sr.read().drdy().bit() {
65 assert!(!self.sr.read().cecs().bit());
66 }
67 });
68
69 Rng { rb: self }
70 }
71}
72
73pub struct Rng {
74 rb: RNG,
75}
76
77impl Rng {
78 pub fn get_rand(&mut self) -> Result<u32, ErrorKind> {
81 loop {
82 let status = self.rb.sr.read();
83 if status.cecs().bit() {
84 return Err(ErrorKind::ClockError);
85 }
86 if status.secs().bit() {
87 return Err(ErrorKind::SeedError);
88 }
89 if status.drdy().bit() {
90 return Ok(self.rb.dr.read().rndata().bits());
91 }
92 }
93 }
94
95 pub fn release(self) -> RNG {
96 self.rb
97 }
98}
99
100impl Read for Rng {
101 type Error = rand_core::Error;
102
103 fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> {
104 self.try_fill_bytes(buffer)
105 }
106}
107
108impl RngCore for Rng {
109 fn next_u32(&mut self) -> u32 {
110 self.get_rand().unwrap()
111 }
112
113 fn next_u64(&mut self) -> u64 {
114 let w1 = self.next_u32();
115 let w2 = self.next_u32();
116 (w1 as u64).shl(32) | (w2 as u64)
117 }
118
119 fn fill_bytes(&mut self, dest: &mut [u8]) {
120 self.try_fill_bytes(dest).unwrap()
121 }
122
123 fn try_fill_bytes(&mut self, buffer: &mut [u8]) -> Result<(), rand_core::Error> {
125 const BATCH_SIZE: usize = 4 / mem::size_of::<u8>();
126 let mut i = 0_usize;
127 while i < buffer.len() {
128 let random_word = self.get_rand()?;
129 let bytes = random_word.to_ne_bytes();
130 let n = cmp::min(BATCH_SIZE, buffer.len() - i);
131 buffer[i..i + n].copy_from_slice(&bytes[..n]);
132 i += n;
133 }
134 Ok(())
135 }
136}