@@ -16,6 +16,7 @@ use crate::time::Hertz;
16
16
#[ derive( Debug ) ]
17
17
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
18
18
pub enum ErrorKind {
19
+ ///Note: The clock error has no impact on generated random numbers that is the application can still read the RNG_DR register
19
20
ClockError = 0 ,
20
21
SeedError = 1 ,
21
22
}
@@ -35,30 +36,161 @@ fn kernel_clk_unwrap(prec: rec::Rng, clocks: &CoreClocks) -> Hertz {
35
36
clocks. pll1_q_ck ( ) . expect ( "RNG: PLL1_Q must be enabled" )
36
37
}
37
38
RngClkSel :: Lse => unimplemented ! ( ) ,
38
- RngClkSel :: Lsi => {
39
- clocks. lsi_ck ( ) . expect ( "RNG: LSI must be enabled" )
40
- }
39
+ RngClkSel :: Lsi => clocks. lsi_ck ( ) . expect ( "RNG: LSI must be enabled" ) ,
41
40
}
42
41
}
43
42
43
+ fn setup_clocks ( prec : rec:: Rng , clocks : & CoreClocks ) -> Hertz {
44
+ let prec = prec. enable ( ) . reset ( ) ;
45
+
46
+ let hclk = clocks. hclk ( ) ;
47
+ let rng_clk = kernel_clk_unwrap ( prec, clocks) ;
48
+
49
+ // Otherwise clock checker will always flag an error
50
+ // See RM0481 Rev 2 Section 32.3.6
51
+ assert ! ( rng_clk > ( hclk / 32 ) , "RNG: Clock too slow" ) ;
52
+
53
+ rng_clk
54
+ }
55
+
56
+ #[ cfg( any(
57
+ feature = "stm32h562" ,
58
+ feature = "stm32h563" ,
59
+ feature = "stm32h573" ,
60
+ ) ) ]
61
+
62
+ /// This uses the register values specified in AN4230 but have not
63
+ /// performed the verification (buyer beware, users can/should do their own verification)
64
+ /// Requires RNG to be disabled since some register values can only be written when RNGEN = 0
65
+ pub trait RngNist {
66
+ fn rng_nist_st_an4230 ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng ;
67
+ }
68
+
69
+ #[ cfg( any(
70
+ feature = "stm32h562" ,
71
+ feature = "stm32h563" ,
72
+ feature = "stm32h573"
73
+ ) ) ]
74
+ impl RngNist for RNG {
75
+ /// This uses the register values specified in AN4230 but have not
76
+ /// performed the verification (buyer beware, users can/should do their own verification)
77
+ /// Requires RNG to be disabled since some register values can only be written when RNGEN = 0
78
+ fn rng_nist_st_an4230 ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng {
79
+ let rng_clk = setup_clocks ( prec, clocks) ;
80
+
81
+ // ST has tested this configuration only with a RNG clock of 48MHz
82
+ assert_eq ! ( rng_clk, Hertz :: MHz ( 48 ) , "RNG: Clock not 48 MHz" ) ;
83
+
84
+ // Set control register values, also need to write 1 to CONDRST to be able to set the other values
85
+ self . cr ( )
86
+ . write ( |w| unsafe { w. bits ( 0x00F00E00 ) . condrst ( ) . set_bit ( ) } ) ;
87
+
88
+ // Set health test control register values
89
+ self . htcr ( ) . write ( |w| unsafe { w. bits ( 0x6A91 ) } ) ;
90
+
91
+ // Set noise source control register
92
+ self . nscr ( ) . write ( |w| unsafe { w. bits ( 0x3AF66 ) } ) ;
93
+
94
+ // Configuration done, reset CONDRST, its value goes to 0 when the reset process is
95
+ // done. It takes about 2 AHB clock cycles + 2 RNG clock cycles.
96
+ self . cr ( ) . write ( |w| w. condrst ( ) . clear_bit ( ) ) ;
97
+
98
+ // It should take about 2 AHB clock cycles + 2 RNG clock cycles
99
+ while self . cr ( ) . read ( ) . condrst ( ) . bit_is_set ( ) { }
100
+
101
+ // Enable RNG
102
+ self . cr ( ) . modify ( |_, w| w. rngen ( ) . set_bit ( ) ) ;
103
+
104
+ Rng { rb : self }
105
+ }
106
+ }
44
107
45
108
pub trait RngExt {
46
- fn constrain ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng ;
109
+ fn rng ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng ;
110
+ fn rng_fast ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng ;
47
111
}
48
112
49
113
impl RngExt for RNG {
50
- fn constrain ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng {
51
- let prec = prec. enable ( ) . reset ( ) ;
114
+ /// This uses the register values specified in RM0481 Rev 2 section 32.6.2 RNG configuration C
115
+ fn rng ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng {
116
+ setup_clocks ( prec, clocks) ;
117
+
118
+ // Set control register values, also need to write 1 to CONDRST to be able to set the other values
119
+ self . cr ( ) . write ( |w| unsafe {
120
+ w. nistc ( )
121
+ . clear_bit ( )
122
+ . rng_config1 ( )
123
+ . bits ( 0x0F )
124
+ . clkdiv ( )
125
+ . bits ( 0x0 )
126
+ . rng_config2 ( )
127
+ . bits ( 0x0 )
128
+ . rng_config3 ( )
129
+ . bits ( 0xD )
130
+ . ced ( )
131
+ . clear_bit ( )
132
+ . condrst ( )
133
+ . set_bit ( )
134
+ } ) ;
135
+
136
+ // Set health test control register values
137
+ self . htcr ( ) . write ( |w| unsafe { w. bits ( 0xAAC7 ) } ) ;
138
+
139
+ // Set noise source control register
140
+ #[ cfg( not( feature = "stm32h503" ) ) ] // Not available on H503
141
+ self . nscr ( ) . write ( |w| unsafe { w. bits ( 0x0003FFFF ) } ) ;
142
+
143
+ // Configuration done, reset CONDRST, its value goes to 0 when the reset process is
144
+ // done. It takes about 2 AHB clock cycles + 2 RNG clock cycles.
145
+ self . cr ( ) . write ( |w| w. condrst ( ) . clear_bit ( ) ) ;
146
+
147
+ // It should take about 2 AHB clock cycles + 2 RNG clock cycles
148
+ while self . cr ( ) . read ( ) . condrst ( ) . bit_is_set ( ) { }
149
+
150
+ // Enable RNG
151
+ self . cr ( ) . modify ( |_, w| w. rngen ( ) . set_bit ( ) ) ;
52
152
53
- let hclk = clocks. hclk ( ) ;
54
- let rng_clk = kernel_clk_unwrap ( prec, clocks) ;
55
-
56
- // Otherwise clock checker will always flag an error
57
- // See RM0433 Rev 6 Section 33.3.6
58
- assert ! ( rng_clk > hclk / 32 , "RNG: Clock too slow" ) ;
153
+ Rng { rb : self }
154
+ }
59
155
60
- self . cr ( )
61
- . modify ( |_, w| w. ced ( ) . clear_bit ( ) . rngen ( ) . set_bit ( ) ) ;
156
+ /// This uses the register values specified in RM0481 Rev 2 section 32.6.2 RNG configuration B
157
+ fn rng_fast ( self , prec : rec:: Rng , clocks : & CoreClocks ) -> Rng {
158
+ setup_clocks ( prec, clocks) ;
159
+
160
+ // Set control register values, also need to write 1 to CONDRST to be able to set the other values
161
+ self . cr ( ) . write ( |w| unsafe {
162
+ w. nistc ( )
163
+ . set_bit ( )
164
+ . rng_config1 ( )
165
+ . bits ( 0x18 )
166
+ . clkdiv ( )
167
+ . bits ( 0x0 )
168
+ . rng_config2 ( )
169
+ . bits ( 0x0 )
170
+ . rng_config3 ( )
171
+ . bits ( 0x0 )
172
+ . ced ( )
173
+ . clear_bit ( )
174
+ . condrst ( )
175
+ . set_bit ( )
176
+ } ) ;
177
+
178
+ // Set health test control register values
179
+ self . htcr ( ) . write ( |w| unsafe { w. bits ( 0xAAC7 ) } ) ;
180
+
181
+ // Set noise source control register
182
+ #[ cfg( not( feature = "stm32h503" ) ) ] // Not available on H503
183
+ self . nscr ( ) . write ( |w| unsafe { w. bits ( 0x0003FFFF ) } ) ;
184
+
185
+ // Configuration done, reset CONDRST, its value goes to 0 when the reset process is
186
+ // done. It takes about 2 AHB clock cycles + 2 RNG clock cycles.
187
+ self . cr ( ) . write ( |w| w. condrst ( ) . clear_bit ( ) ) ;
188
+
189
+ // It should take about 2 AHB clock cycles + 2 RNG clock cycles
190
+ while self . cr ( ) . read ( ) . condrst ( ) . bit_is_set ( ) { }
191
+
192
+ // Enable RNG
193
+ self . cr ( ) . modify ( |_, w| w. rngen ( ) . set_bit ( ) ) ;
62
194
63
195
Rng { rb : self }
64
196
}
@@ -76,36 +208,20 @@ pub struct Rng {
76
208
impl Rng {
77
209
/// Returns 32 bits of randomness, or error
78
210
pub fn value ( & mut self ) -> Result < u32 , ErrorKind > {
79
- loop {
80
- let status = self . rb . sr ( ) . read ( ) ;
81
- if status. cecs ( ) . bit ( ) {
82
- return Err ( ErrorKind :: ClockError ) ;
83
- }
84
- if status. secs ( ) . bit ( ) {
85
- return Err ( ErrorKind :: SeedError ) ;
86
- }
87
- if status. drdy ( ) . bit ( ) {
88
- return Ok ( self . rb . dr ( ) . read ( ) . rndata ( ) . bits ( ) ) ;
89
- }
90
- }
211
+ nb:: block!( self . nb_value( ) )
91
212
}
92
-
213
+
93
214
/// Returns 32 bits of randomness, or error
94
215
pub fn nb_value ( & mut self ) -> nb:: Result < u32 , ErrorKind > {
95
- loop {
96
- let status = self . rb . sr ( ) . read ( ) ;
97
- if status. cecs ( ) . bit ( ) {
98
- return Err ( ErrorKind :: ClockError ) ;
99
- }
100
- if status. secs ( ) . bit ( ) {
101
- return Err ( ErrorKind :: SeedError ) ;
102
- }
103
- if status. drdy ( ) . bit ( ) {
104
- return Ok ( self . rb . dr ( ) . read ( ) . rndata ( ) . bits ( ) ) ;
105
- }
106
- else {
107
- return Err ( nb:: Error :: WouldBlock ) ;
108
- }
216
+ let status = self . rb . sr ( ) . read ( ) ;
217
+ if status. cecs ( ) . bit ( ) {
218
+ Err ( nb:: Error :: Other ( ErrorKind :: ClockError ) )
219
+ } else if status. secs ( ) . bit ( ) {
220
+ Err ( nb:: Error :: Other ( ErrorKind :: SeedError ) )
221
+ } else if status. drdy ( ) . bit ( ) {
222
+ Ok ( self . rb . dr ( ) . read ( ) . rndata ( ) . bits ( ) )
223
+ } else {
224
+ Err ( nb:: Error :: WouldBlock )
109
225
}
110
226
}
111
227
@@ -271,4 +387,3 @@ impl rand_core::RngCore for Rng {
271
387
} )
272
388
}
273
389
}
274
-
0 commit comments