1
+ use crate :: stm32:: rcc:: cfgr:: SWW ;
1
2
use crate :: time:: Hertz ;
2
3
3
4
/// Extension trait that constrains the `RCC` peripheral
@@ -14,8 +15,7 @@ impl RccExt for crate::stm32::RCC {
14
15
hclk : None ,
15
16
pclk : None ,
16
17
sysclk : None ,
17
- enable_hsi : true ,
18
- enable_hsi48 : false ,
18
+ clock_src : SysClkSource :: HSI ,
19
19
} ,
20
20
}
21
21
}
@@ -26,38 +26,34 @@ pub struct Rcc {
26
26
pub cfgr : CFGR ,
27
27
}
28
28
29
- #[ allow( unused) ]
30
29
const HSI : u32 = 8_000_000 ; // Hz
31
- #[ allow( unused) ]
32
30
const HSI48 : u32 = 48_000_000 ; // Hz - (available on STM32F04x, STM32F07x and STM32F09x devices only)
33
31
34
32
#[ allow( unused) ]
35
33
enum SysClkSource {
36
- HSI = 0b00 ,
37
- HSE = 0b01 ,
38
- PLL = 0b10 ,
39
- HSI48 = 0b11 ,
40
- }
41
-
42
- #[ allow( unused) ]
43
- enum PllSource {
44
- HSI_DIV2 = 0b00 ,
45
- HSI = 0b01 ,
46
- HSE = 0b10 ,
47
- HSI48 = 0b11 ,
34
+ HSI ,
35
+ HSE ( u32 ) ,
36
+ HSI48 ,
48
37
}
49
38
50
39
#[ allow( unused) ]
51
40
pub struct CFGR {
52
41
hclk : Option < u32 > ,
53
42
pclk : Option < u32 > ,
54
43
sysclk : Option < u32 > ,
55
- enable_hsi : bool ,
56
- enable_hsi48 : bool ,
44
+ clock_src : SysClkSource ,
57
45
}
58
46
59
47
#[ cfg( feature = "device-selected" ) ]
60
48
impl CFGR {
49
+ pub fn hse < F > ( mut self , freq : F ) -> Self
50
+ where
51
+ F : Into < Hertz > ,
52
+ {
53
+ self . clock_src = SysClkSource :: HSE ( freq. into ( ) . 0 ) ;
54
+ self
55
+ }
56
+
61
57
pub fn hclk < F > ( mut self , freq : F ) -> Self
62
58
where
63
59
F : Into < Hertz > ,
@@ -82,35 +78,21 @@ impl CFGR {
82
78
self
83
79
}
84
80
85
- pub fn enable_hsi ( mut self , is_enabled : bool ) -> Self {
86
- self . enable_hsi = is_enabled;
87
- self
88
- }
89
-
90
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f091" ) ) ]
91
- pub fn enable_hsi48 ( mut self , is_enabled : bool ) -> Self {
92
- self . enable_hsi48 = is_enabled;
93
- self
94
- }
95
-
96
81
pub fn freeze ( self ) -> Clocks {
97
82
// Default to lowest frequency clock on all systems.
98
83
let sysclk = self . sysclk . unwrap_or ( HSI ) ;
99
84
100
85
let r_sysclk; // The "real" sysclock value, calculated below
101
- let src_clk_freq; // Frequency of source clock for PLL and etc, HSI, or HSI48 on supported systems.
102
86
let pllmul_bits;
103
87
104
88
// Select clock source based on user input and capability
105
89
// Highest selected frequency source available takes precedent.
106
90
// For F04x, F07x, F09x parts, use HSI48 if requested.
107
- if self . enable_hsi48 {
108
- src_clk_freq = HSI48 ; // Use HSI48 if requested and available.
109
- } else if self . enable_hsi {
110
- src_clk_freq = HSI ; // HSI if requested
111
- } else {
112
- src_clk_freq = HSI ; // If no clock source is selected use HSI.
113
- }
91
+ let src_clk_freq = match self . clock_src {
92
+ SysClkSource :: HSE ( freq) => freq,
93
+ SysClkSource :: HSI48 => HSI48 ,
94
+ _ => HSI ,
95
+ } ;
114
96
115
97
// Pll check
116
98
if sysclk == src_clk_freq {
@@ -165,6 +147,8 @@ impl CFGR {
165
147
let ppre: u8 = 1 << ( ppre_bits - 0b011 ) ;
166
148
let pclk = hclk / cast:: u32 ( ppre) ;
167
149
150
+ let rcc = unsafe { & * crate :: stm32:: RCC :: ptr ( ) } ;
151
+
168
152
// adjust flash wait states
169
153
unsafe {
170
154
let flash = & * crate :: stm32:: FLASH :: ptr ( ) ;
@@ -179,81 +163,62 @@ impl CFGR {
179
163
} )
180
164
}
181
165
166
+ // Enable the requested clock
167
+ match self . clock_src {
168
+ SysClkSource :: HSE ( _) => {
169
+ rcc. cr
170
+ . modify ( |_, w| w. csson ( ) . on ( ) . hseon ( ) . on ( ) . hsebyp ( ) . not_bypassed ( ) ) ;
171
+
172
+ while !rcc. cr . read ( ) . hserdy ( ) . bit_is_set ( ) { }
173
+ }
174
+ SysClkSource :: HSI48 => {
175
+ rcc. cr2 . modify ( |_, w| w. hsi48on ( ) . set_bit ( ) ) ;
176
+ while rcc. cr2 . read ( ) . hsi48rdy ( ) . bit_is_clear ( ) { }
177
+ }
178
+ SysClkSource :: HSI => {
179
+ rcc. cr . write ( |w| w. hsion ( ) . set_bit ( ) ) ;
180
+ while rcc. cr . read ( ) . hsirdy ( ) . bit_is_clear ( ) { }
181
+ }
182
+ } ;
183
+
182
184
let rcc = unsafe { & * crate :: stm32:: RCC :: ptr ( ) } ;
183
185
184
186
// Set up rcc based on above calculated configuration.
185
187
186
- // Enable requested clock sources
187
- // HSI
188
- if self . enable_hsi {
189
- rcc. cr . write ( |w| w. hsion ( ) . set_bit ( ) ) ;
190
- while rcc. cr . read ( ) . hsirdy ( ) . bit_is_clear ( ) { }
191
- }
192
- // HSI48
193
- if self . enable_hsi48 {
194
- rcc. cr2 . modify ( |_, w| w. hsi48on ( ) . set_bit ( ) ) ;
195
- while rcc. cr2 . read ( ) . hsi48rdy ( ) . bit_is_clear ( ) { }
196
- }
197
-
198
188
// Enable PLL
199
189
if let Some ( pllmul_bits) = pllmul_bits {
200
- rcc. cfgr . write ( |w| unsafe { w. pllmul ( ) . bits ( pllmul_bits) } ) ;
201
-
202
- // Set PLL source based on configuration.
203
- if self . enable_hsi48 {
204
- rcc. cfgr
205
- . modify ( |_, w| w. pllsrc ( ) . bits ( PllSource :: HSI48 as u8 ) ) ;
206
- } else if self . enable_hsi {
207
- rcc. cfgr
208
- . modify ( |_, w| w. pllsrc ( ) . bits ( PllSource :: HSI_DIV2 as u8 ) ) ;
209
- } else {
210
- rcc. cfgr
211
- . modify ( |_, w| w. pllsrc ( ) . bits ( PllSource :: HSI_DIV2 as u8 ) ) ;
212
- }
190
+ let pllsrc_bit: u8 = match self . clock_src {
191
+ SysClkSource :: HSI => 0b00 ,
192
+ SysClkSource :: HSI48 => 0b11 ,
193
+ SysClkSource :: HSE ( _) => 0b01 ,
194
+ } ;
195
+
196
+ // Set PLL source and multiplier
197
+ rcc. cfgr
198
+ . write ( |w| unsafe { w. pllsrc ( ) . bits ( pllsrc_bit) . pllmul ( ) . bits ( pllmul_bits) } ) ;
213
199
214
200
rcc. cr . write ( |w| w. pllon ( ) . set_bit ( ) ) ;
215
201
while rcc. cr . read ( ) . pllrdy ( ) . bit_is_clear ( ) { }
216
202
217
203
rcc. cfgr . modify ( |_, w| unsafe {
204
+ w. ppre ( ) . bits ( ppre_bits) . hpre ( ) . bits ( hpre_bits) . sw ( ) . pll ( )
205
+ } ) ;
206
+ } else {
207
+ let sw_var = match self . clock_src {
208
+ SysClkSource :: HSI => SWW :: HSI ,
209
+ SysClkSource :: HSI48 => SWW :: HSI48 ,
210
+ SysClkSource :: HSE ( _) => SWW :: HSE ,
211
+ } ;
212
+
213
+ // use HSI as source
214
+ rcc. cfgr . write ( |w| unsafe {
218
215
w. ppre ( )
219
216
. bits ( ppre_bits)
220
217
. hpre ( )
221
218
. bits ( hpre_bits)
222
219
. sw ( )
223
- . bits ( SysClkSource :: PLL as u8 )
220
+ . variant ( sw_var )
224
221
} ) ;
225
- } else {
226
- // No PLL required.
227
- // Setup requested clocks.
228
- if self . enable_hsi48 {
229
- rcc. cfgr . modify ( |_, w| unsafe {
230
- w. ppre ( )
231
- . bits ( ppre_bits)
232
- . hpre ( )
233
- . bits ( hpre_bits)
234
- . sw ( )
235
- . bits ( SysClkSource :: HSI48 as u8 )
236
- } ) ;
237
- } else if self . enable_hsi {
238
- rcc. cfgr . modify ( |_, w| unsafe {
239
- w. ppre ( )
240
- . bits ( ppre_bits)
241
- . hpre ( )
242
- . bits ( hpre_bits)
243
- . sw ( )
244
- . bits ( SysClkSource :: HSI as u8 )
245
- } ) ;
246
- } else {
247
- // Default to HSI
248
- rcc. cfgr . modify ( |_, w| unsafe {
249
- w. ppre ( )
250
- . bits ( ppre_bits)
251
- . hpre ( )
252
- . bits ( hpre_bits)
253
- . sw ( )
254
- . bits ( SysClkSource :: HSI as u8 )
255
- } ) ;
256
- }
257
222
}
258
223
259
224
Clocks {
0 commit comments