1extern crate core;
2#[cfg(feature = "unproven")]
3use core::cmp;
4
5use crate::rcc::{Clocks, Enable, AHB2};
6use crate::stm32::RNG;
7pub use rand_core::{CryptoRng, RngCore};
8
9pub trait RngExt {
11 fn enable(self, ahb2: &mut AHB2, clocks: Clocks) -> Rng;
13}
14
15impl RngExt for RNG {
16 fn enable(self, ahb2: &mut AHB2, clocks: Clocks) -> Rng {
17 let msi = match clocks.msi() {
22 Some(msi) => msi == crate::rcc::MsiFreq::RANGE48M,
23 None => false,
24 };
25 let hsi = clocks.hsi48();
26 assert!(msi || hsi);
27
28 <RNG as Enable>::enable(ahb2);
29 while !RNG::is_enabled() {}
32
33 self.cr.modify(|_, w| w.rngen().set_bit());
34
35 Rng { rng: self }
36 }
37}
38
39pub struct Rng {
41 rng: RNG,
42}
43
44impl Rng {
45 pub fn free(self) -> RNG {
47 self.rng
49 }
50
51 pub fn get_random_data(&self) -> u32 {
56 while !self.is_data_ready() {}
57 self.possibly_invalid_random_data()
58 }
60
61 pub fn is_interrupt_enabled(&self) -> bool {
69 self.rng.cr.read().ie().bit()
70 }
71
72 pub fn is_enabled(&self) -> bool {
73 self.rng.cr.read().rngen().bit()
74 }
75
76 pub fn is_clock_error(&self) -> bool {
78 self.rng.sr.read().cecs().bit()
79 }
80
81 pub fn is_seed_error(&self) -> bool {
82 self.rng.sr.read().secs().bit()
83 }
84
85 pub fn is_data_ready(&self) -> bool {
86 self.rng.sr.read().drdy().bit()
87 }
88
89 pub fn possibly_invalid_random_data(&self) -> u32 {
91 self.rng.dr.read().rndata().bits()
92 }
93}
94
95impl RngCore for Rng {
96 fn next_u32(&mut self) -> u32 {
97 self.get_random_data()
98 }
99
100 fn next_u64(&mut self) -> u64 {
101 rand_core::impls::next_u64_via_u32(self)
102 }
103
104 fn fill_bytes(&mut self, dest: &mut [u8]) {
105 rand_core::impls::fill_bytes_via_next(self, dest)
106 }
107
108 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
109 Ok(self.fill_bytes(dest))
110 }
111}
112
113impl CryptoRng for Rng {}
114
115#[derive(Debug)]
116pub enum Error {}
117
118#[cfg(feature = "unproven")]
119impl crate::hal::blocking::rng::Read for Rng {
120 type Error = Error;
124
125 fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> {
126 let mut i = 0usize;
127 while i < buffer.len() {
128 let random_word: u32 = self.get_random_data();
129 let bytes: [u8; 4] = random_word.to_ne_bytes();
130 let n = cmp::min(4, buffer.len() - i);
131 buffer[i..i + n].copy_from_slice(&bytes[..n]);
132 i += n;
133 }
134
135 Ok(())
136 }
137}