@@ -16,6 +16,7 @@ use crate::time::Hertz;
1616#[ derive( Debug ) ]
1717#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
1818pub 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
1920 ClockError = 0 ,
2021 SeedError = 1 ,
2122}
@@ -35,30 +36,161 @@ fn kernel_clk_unwrap(prec: rec::Rng, clocks: &CoreClocks) -> Hertz {
3536 clocks. pll1_q_ck ( ) . expect ( "RNG: PLL1_Q must be enabled" )
3637 }
3738 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" ) ,
4140 }
4241}
4342
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+ }
44107
45108pub 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 ;
47111}
48112
49113impl 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 ( ) ) ;
52152
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+ }
59155
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 ( ) ) ;
62194
63195 Rng { rb : self }
64196 }
@@ -76,36 +208,20 @@ pub struct Rng {
76208impl Rng {
77209 /// Returns 32 bits of randomness, or error
78210 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( ) )
91212 }
92-
213+
93214 /// Returns 32 bits of randomness, or error
94215 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 )
109225 }
110226 }
111227
@@ -271,4 +387,3 @@ impl rand_core::RngCore for Rng {
271387 } )
272388 }
273389}
274-
0 commit comments