@@ -5,9 +5,15 @@ use rand_core::TryRngCore;
5
5
use crate :: { rcc:: Rcc , stm32:: RNG } ;
6
6
use core:: { fmt:: Formatter , marker:: PhantomData } ;
7
7
8
+ /// Error type for the RNG peripheral
8
9
pub enum RngError {
10
+ /// The DRDY bit is not set in the status register.
9
11
NotReady ,
12
+ /// A noise source seed error was detected. [`seed_error_recovery()`]
13
+ /// should be called to recover from the error.
10
14
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.
11
17
ClockError ,
12
18
}
13
19
@@ -116,6 +122,27 @@ impl Rng<Running> {
116
122
unsafe { ( * RNG :: ptr ( ) ) . sr ( ) . read ( ) . ceis ( ) . bit_is_set ( ) }
117
123
}
118
124
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
+
119
146
/// Blocking read of a random u32 from the RNG in polling mode.
120
147
///
121
148
/// Returns an [`RngError`] if the RNG reports an error condition.
@@ -158,7 +185,9 @@ impl Rng<Running> {
158
185
}
159
186
160
187
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.
162
191
match unsafe { ( * RNG :: ptr ( ) ) . dr ( ) . read ( ) . bits ( ) } {
163
192
0 => Err ( RngError :: SeedError ) ,
164
193
data => Ok ( data) ,
0 commit comments