1
1
use core:: cmp:: min;
2
2
3
+ use cortex_m_semihosting:: hprintln;
4
+ use micromath:: F32Ext ;
5
+
3
6
use crate :: device:: { rcc, FLASH , RCC } ;
4
7
use crate :: time:: Hertz ;
5
8
@@ -106,15 +109,17 @@ pub struct HSEClock {
106
109
107
110
impl HSEClock {
108
111
/// Provide HSE frequence. Must be between 4 and 26 MHz
109
- pub fn freq < F > ( mut self , freq : F ) -> Self
112
+ pub fn new < F > ( freq : F , mode : HSEClockMode ) -> Self
110
113
where
111
114
F : Into < Hertz > ,
112
115
{
113
116
let f: u32 = freq. into ( ) . 0 ;
114
117
115
118
assert ! ( 4_000_000 <= f && f <= 26_000_000 ) ;
116
- self . freq = f;
117
- self
119
+ HSEClock {
120
+ freq : f,
121
+ mode : mode
122
+ }
118
123
}
119
124
}
120
125
@@ -228,7 +233,6 @@ impl CFGR {
228
233
0 => HSI ,
229
234
_ => hse_freq
230
235
} ;
231
- assert ! ( sysclk <= base_clk) ;
232
236
233
237
if sysclk <= base_clk { // We can use the base clock directly
234
238
match & self . hse {
@@ -243,63 +247,40 @@ impl CFGR {
243
247
// must be between 2 and 63. In this case, the condition is always
244
248
// respected. We set it at 2MHz as recommanded by the user manual.
245
249
let pllm = base_clk / 2_000_000 ;
250
+ let pllp_val: u32 ;
246
251
let vco_clkin = base_clk / pllm;
247
252
253
+ // Sysclk output divisor, must result in >= 24MHz and <= 216MHz
254
+ // needs to be the equivalent of 2, 4, 6 or 8
248
255
// We can calculate that:
249
256
// * PLLP = 2 => SYSCLK \in [25*vco_clkin ; 216*vco_clkin]
250
257
// * PLLP = 4 => SYSCLK \in [12,5*vco_clkin ; 108*vco_clkin]
251
258
// * PLLP = 6 => SYSCLK \in [8,33*vco_clkin ; 72*vco_clkin ]
252
259
// * PLLP = 8 => SYSCLK \in [6,25*vco_clkin ; 54*vco_clkin ]
253
- let ( plln, pllp) = if sysclk >= 25 * vco_clkin {
254
- // Main scaler, must result in >= 192MHz and <= 432MHz, min 50, max 432
255
- let plln = ( sysclk / vco_clkin) * 2 ;
256
-
257
- // Sysclk output divisor, must result in >= 24MHz and <= 216MHz
258
- // needs to be the equivalent of 2, 4, 6 or 8
259
- let pllp = 0b00 ;
260
-
261
- // Update sysclk with the real value
262
- sysclk = ( vco_clkin * plln) / 2 ;
263
-
264
- ( plln, pllp)
260
+ let pllp = if sysclk >= 25 * vco_clkin {
261
+ pllp_val = 2 ;
262
+ 0b00
265
263
} else if sysclk >= 13 * vco_clkin {
266
- // Main scaler, must result in >= 192MHz and <= 432MHz, min 50, max 432
267
- let plln = ( sysclk / vco_clkin) * 4 ;
268
-
269
- // Sysclk output divisor, must result in >= 24MHz and <= 216MHz
270
- // needs to be the equivalent of 2, 4, 6 or 8
271
- let pllp = 0b01 ;
272
-
273
- // Update sysclk with the real value
274
- sysclk = ( vco_clkin * plln) / 4 ;
275
-
276
- ( plln, pllp)
264
+ pllp_val = 4 ;
265
+ 0b01
277
266
} else if sysclk >= 9 * vco_clkin {
278
- // Main scaler, must result in >= 192MHz and <= 432MHz, min 50, max 432
279
- let plln = ( sysclk / vco_clkin) * 6 ;
280
-
281
- // Sysclk output divisor, must result in >= 24MHz and <= 216MHz
282
- // needs to be the equivalent of 2, 4, 6 or 8
283
- let pllp = 0b10 ;
284
-
285
- // Update sysclk with the real value
286
- sysclk = ( vco_clkin * plln) / 6 ;
287
-
288
- ( plln, pllp)
267
+ pllp_val = 6 ;
268
+ 0b10
289
269
} else {
290
- // Main scaler, must result in >= 192MHz and <= 432MHz, min 50, max 432
291
- let plln = ( sysclk / vco_clkin) * 8 ;
292
-
293
- // Sysclk output divisor, must result in >= 24MHz and <= 216MHz
294
- // needs to be the equivalent of 2, 4, 6 or 8
295
- let pllp = 0b11 ;
296
-
297
- // Update sysclk with the real value
298
- sysclk = ( vco_clkin * plln) / 8 ;
299
-
300
- ( plln, pllp)
270
+ pllp_val = 8 ;
271
+ 0b11
301
272
} ;
302
273
274
+ // PLLN, main scaler, must result in >= 192MHz and <= 432MHz, min
275
+ // 50, max 432, this constraint is allways respected when vco_clkin
276
+ // = 2 MHz
277
+ let plln = ( sysclk / vco_clkin) * pllp_val;
278
+ // Check that the desired SYSCLK is physically feasible. /1000 is to
279
+ // avoid u32 overflow
280
+ assert ! ( ( base_clk / 1_000 ) * plln >= sysclk / 1_000 ) ;
281
+ // Update sysclk with the real value
282
+ sysclk = ( vco_clkin * plln) / pllp_val;
283
+
303
284
match & self . hse {
304
285
// If HSE is provided
305
286
Some ( hse) => {
@@ -332,29 +313,27 @@ impl CFGR {
332
313
. plln ( ) . bits ( plln as u16 )
333
314
. pllp ( ) . bits ( pllp)
334
315
} ) ;
316
+
335
317
} ,
336
318
} ;
337
319
338
320
// Enable PLL
339
321
rcc. cr . modify ( |_, w| w. pllon ( ) . set_bit ( ) ) ;
340
322
// Wait for PLL to stabilise
341
- while rcc. cr . read ( ) . pllrdy ( ) . is_not_ready ( ) { }
323
+ while rcc. cr . read ( ) . pllrdy ( ) . bit_is_set ( ) { }
342
324
343
325
// Use PLL as SYSCLK
326
+ // rcc.cfgr.modify(|_, w| unsafe { w.sw().bits(0b10 as u8) });
344
327
rcc. cfgr . modify ( |_, w| w. sw ( ) . pll ( ) ) ;
345
328
}
346
329
347
- // HCLK. By default, SYSCLK frequence is chosen
348
- let mut hclk: u32 = self . hclk . unwrap_or ( sysclk) ;
349
- assert ! ( hclk <= sysclk) ;
350
- // PCLK1 (APB1). Must be <= 54 Mhz. By default, min(hclk, 54Mhz) is
351
- // chosen
352
- let mut pclk1: u32 = self . pclk1 . unwrap_or ( min ( 54_000_000 , hclk) ) ;
353
- // PCLK2 (APB2). Must be <= 108 Mhz. By default, min(hclk, 108Mhz) is
354
- // chosen
355
- let mut pclk2: u32 = self . pclk1 . unwrap_or ( min ( 108_000_000 , hclk) ) ;
330
+ // HCLK. By default, SYSCLK frequence is chosen. Because of the method
331
+ // of clock multiplication and division, even if `sysclk` is set to be
332
+ // the same as `hclk`, it can be slighly inferior to `sysclk` after
333
+ // pllm, pllp... calculations
334
+ let mut hclk: u32 = min ( sysclk, self . hclk . unwrap_or ( sysclk) ) ;
356
335
357
- // Configure HPRE
336
+ // Configure HPRE.
358
337
let mut hpre_val: u32 = sysclk / hclk;
359
338
360
339
// The real value of hpre is computed to be as near as possible to the
@@ -374,8 +353,15 @@ impl CFGR {
374
353
// update hclk with the real value
375
354
hclk = sysclk / hpre_val;
376
355
356
+ // PCLK1 (APB1). Must be <= 54 Mhz. By default, min(hclk, 54Mhz) is
357
+ // chosen
358
+ let mut pclk1: u32 = self . pclk1 . unwrap_or ( min ( 54_000_000 , hclk) ) ;
359
+ // PCLK2 (APB2). Must be <= 108 Mhz. By default, min(hclk, 108Mhz) is
360
+ // chosen
361
+ let mut pclk2: u32 = self . pclk2 . unwrap_or ( min ( 108_000_000 , hclk) ) ;
362
+
377
363
// Configure PPRE1
378
- let mut ppre1_val: u32 = hclk / pclk1;
364
+ let mut ppre1_val: u32 = ( hclk as f32 / pclk1 as f32 ) . ceil ( ) as u32 ;
379
365
let ppre1: u32 = match ppre1_val {
380
366
0 => unreachable ! ( ) ,
381
367
1 => { ppre1_val = 1 ; 0b000 } ,
@@ -384,11 +370,11 @@ impl CFGR {
384
370
7 ..=12 => { ppre1_val = 8 ; 0b110 } ,
385
371
_ => { ppre1_val = 16 ; 0b111 } ,
386
372
} ;
387
- // update pclk1 withe the real value
373
+ // update pclk1 with the real value
388
374
pclk1 = hclk / ppre1_val;
389
375
390
376
// Configure PPRE2
391
- let mut ppre2_val: u32 = hclk / pclk2;
377
+ let mut ppre2_val: u32 = ( hclk as f32 / pclk2 as f32 ) . ceil ( ) as u32 ;
392
378
let ppre2: u32 = match ppre2_val {
393
379
0 => unreachable ! ( ) ,
394
380
1 => { ppre2_val = 1 ; 0b000 } ,
@@ -397,7 +383,7 @@ impl CFGR {
397
383
7 ..=12 => { ppre2_val = 8 ; 0b110 } ,
398
384
_ => { ppre2_val = 16 ; 0b111 } ,
399
385
} ;
400
- // update pclk2 withe the real value
386
+ // update pclk2 with the real value
401
387
pclk2 = hclk / ppre2_val;
402
388
403
389
// Configure HCLK, PCLK1, PCLK2
@@ -409,8 +395,8 @@ impl CFGR {
409
395
} ) ;
410
396
411
397
// Assumes TIMPRE bit of RCC_DCKCFGR1 is reset (0)
412
- let timclk1 = if ppre1 == 1 { pclk1} else { 2 * pclk1} ;
413
- let timclk2 = if ppre2 == 1 { pclk2} else { 2 * pclk2} ;
398
+ let timclk1 = if ppre1_val == 1 { pclk1} else { 2 * pclk1} ;
399
+ let timclk2 = if ppre2_val == 1 { pclk2} else { 2 * pclk2} ;
414
400
415
401
// Adjust flash wait states
416
402
flash. acr . write ( |w| {
0 commit comments