Skip to content

Commit 22be238

Browse files
boondocklabsusbalbin
authored andcommitted
Add seed error recovery sequence. Add more comments and documented RngError
1 parent 877b33b commit 22be238

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/rng.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ use rand_core::TryRngCore;
55
use crate::{rcc::Rcc, stm32::RNG};
66
use core::{fmt::Formatter, marker::PhantomData};
77

8+
/// Error type for the RNG peripheral
89
pub enum RngError {
10+
/// The DRDY bit is not set in the status register.
911
NotReady,
12+
/// A noise source seed error was detected. [`seed_error_recovery()`]
13+
/// should be called to recover from the error.
1014
SeedError,
15+
/// A clock error was detected. fRNGCLOCK is less than fHCLK/32
16+
/// The clock error condition is automatically cleared when the clock condition returns to normal.
1117
ClockError,
1218
}
1319

@@ -116,6 +122,27 @@ impl Rng<Running> {
116122
unsafe { (*RNG::ptr()).sr().read().ceis().bit_is_set() }
117123
}
118124

125+
/// Perform recovery sequence of a seed error from RM0440 26.3.7
126+
///
127+
/// The SEIS bit is cleared, and 12 words and read and discarded from the DR register.
128+
///
129+
/// If the recovery sequence was successful, the function returns `Ok(())`.
130+
/// If the SEIS bit is still set after the recovery sequence, [`RngError::SeedError`] is returned.
131+
pub fn seed_error_recovery(&mut self) -> Result<(), RngError> {
132+
// Clear SEIS bit
133+
unsafe { (*RNG::ptr()).sr().clear_bits(|w| w.seis().clear_bit()) };
134+
// Read and discard 12 words from DR register
135+
for _ in 0..12 {
136+
unsafe { (*RNG::ptr()).dr().read() };
137+
}
138+
// Confirm SEIS is still clear
139+
if unsafe { (*RNG::ptr()).sr().read().seis().bit_is_clear() } {
140+
Ok(())
141+
} else {
142+
Err(RngError::SeedError)
143+
}
144+
}
145+
119146
/// Blocking read of a random u32 from the RNG in polling mode.
120147
///
121148
/// Returns an [`RngError`] if the RNG reports an error condition.
@@ -158,7 +185,9 @@ impl Rng<Running> {
158185
}
159186

160187
if status.drdy().bit_is_set() {
161-
// Data is ready. Read the DR register and return the value.
188+
// The data ready bit is set. Read the DR register and check if it is zero.
189+
// A zero read indicates a seed error between reading SR and DR registers
190+
// see RM0440 26.7.3 RNDATA description.
162191
match unsafe { (*RNG::ptr()).dr().read().bits() } {
163192
0 => Err(RngError::SeedError),
164193
data => Ok(data),

0 commit comments

Comments
 (0)