1use core::ops::RangeInclusive;
2
3use crate::pac;
4pub use crate::pac::rcc::vals::{
5 Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk,
6};
7use crate::pac::rcc::vals::{Pllrge, Pllvcosel, Timpre};
8use crate::pac::{FLASH, PWR, RCC};
9use crate::time::Hertz;
10
11pub const HSI_FREQ: Hertz = Hertz(64_000_000);
13
14pub const CSI_FREQ: Hertz = Hertz(4_000_000);
16
17const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000);
18#[cfg(any(stm32h5, pwr_h7rm0455))]
19const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000);
20#[cfg(pwr_h7rm0468)]
21const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(836_000_000);
22#[cfg(any(pwr_h7rm0399, pwr_h7rm0433))]
23const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(960_000_000);
24#[cfg(any(stm32h7rs))]
25const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(384_000_000)..=Hertz(1672_000_000);
26
27pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
28
29#[cfg(any(stm32h5, stm32h7))]
30#[derive(Clone, Copy, Eq, PartialEq)]
31pub enum VoltageScale {
32 Scale0,
33 Scale1,
34 Scale2,
35 Scale3,
36}
37#[cfg(stm32h7rs)]
38pub use crate::pac::pwr::vals::Vos as VoltageScale;
39#[cfg(all(stm32h7rs, peri_usb_otg_hs))]
40pub use crate::pac::rcc::vals::{Usbphycsel, Usbrefcksel};
41
42#[derive(Clone, Copy, Eq, PartialEq)]
43pub enum HseMode {
44 Oscillator,
46 Bypass,
48 #[cfg(any(rcc_h5, rcc_h50, rcc_h7rs))]
50 BypassDigital,
51}
52
53#[derive(Clone, Copy, Eq, PartialEq)]
54pub struct Hse {
55 pub freq: Hertz,
57 pub mode: HseMode,
59}
60
61#[derive(Clone, Copy)]
62pub struct Pll {
63 pub source: PllSource,
65
66 pub prediv: PllPreDiv,
68
69 pub mul: PllMul,
71
72 pub divp: Option<PllDiv>,
77 pub divq: Option<PllDiv>,
79 pub divr: Option<PllDiv>,
81}
82
83fn apb_div_tim(apb: &APBPrescaler, clk: Hertz, tim: TimerPrescaler) -> Hertz {
84 match (tim, apb) {
85 (TimerPrescaler::DefaultX2, APBPrescaler::DIV1) => clk,
86 (TimerPrescaler::DefaultX2, APBPrescaler::DIV2) => clk,
87 (TimerPrescaler::DefaultX2, APBPrescaler::DIV4) => clk / 2u32,
88 (TimerPrescaler::DefaultX2, APBPrescaler::DIV8) => clk / 4u32,
89 (TimerPrescaler::DefaultX2, APBPrescaler::DIV16) => clk / 8u32,
90
91 (TimerPrescaler::DefaultX4, APBPrescaler::DIV1) => clk,
92 (TimerPrescaler::DefaultX4, APBPrescaler::DIV2) => clk,
93 (TimerPrescaler::DefaultX4, APBPrescaler::DIV4) => clk,
94 (TimerPrescaler::DefaultX4, APBPrescaler::DIV8) => clk / 2u32,
95 (TimerPrescaler::DefaultX4, APBPrescaler::DIV16) => clk / 4u32,
96
97 _ => unreachable!(),
98 }
99}
100
101#[derive(Clone, Copy, Eq, PartialEq)]
103pub enum TimerPrescaler {
104 DefaultX2,
107
108 DefaultX4,
111}
112
113impl From<TimerPrescaler> for Timpre {
114 fn from(value: TimerPrescaler) -> Self {
115 match value {
116 TimerPrescaler::DefaultX2 => Timpre::DEFAULT_X2,
117 TimerPrescaler::DefaultX4 => Timpre::DEFAULT_X4,
118 }
119 }
120}
121
122#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
125#[derive(Clone, Copy, PartialEq)]
126pub enum SupplyConfig {
127 Default,
131
132 LDO,
137
138 DirectSMPS,
143
144 SMPSLDO(SMPSSupplyVoltage),
150
151 SMPSExternalLDO(SMPSSupplyVoltage),
157
158 SMPSExternalLDOBypass(SMPSSupplyVoltage),
163
164 SMPSDisabledLDOBypass,
168}
169
170#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
174#[derive(Clone, Copy, Eq, PartialEq, Debug)]
175pub enum SMPSSupplyVoltage {
176 V1_8,
178 #[cfg(not(pwr_h7rs))]
180 V2_5,
181}
182
183#[non_exhaustive]
185#[derive(Clone, Copy)]
186pub struct Config {
187 pub hsi: Option<HSIPrescaler>,
188 pub hse: Option<Hse>,
189 pub csi: bool,
190 pub hsi48: Option<super::Hsi48Config>,
191 pub sys: Sysclk,
192
193 pub pll1: Option<Pll>,
194 pub pll2: Option<Pll>,
195 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
196 pub pll3: Option<Pll>,
197
198 #[cfg(any(stm32h7, stm32h7rs))]
199 pub d1c_pre: AHBPrescaler,
200 pub ahb_pre: AHBPrescaler,
201 pub apb1_pre: APBPrescaler,
202 pub apb2_pre: APBPrescaler,
203 #[cfg(not(stm32h7rs))]
204 pub apb3_pre: APBPrescaler,
205 #[cfg(any(stm32h7, stm32h7rs))]
206 pub apb4_pre: APBPrescaler,
207 #[cfg(stm32h7rs)]
208 pub apb5_pre: APBPrescaler,
209
210 pub timer_prescaler: TimerPrescaler,
211 pub voltage_scale: VoltageScale,
212 pub ls: super::LsConfig,
213
214 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
215 pub supply_config: SupplyConfig,
216
217 pub mux: super::mux::ClockMux,
219}
220
221impl Default for Config {
222 fn default() -> Self {
223 Self {
224 hsi: Some(HSIPrescaler::DIV1),
225 hse: None,
226 csi: false,
227 hsi48: Some(Default::default()),
228 sys: Sysclk::HSI,
229 pll1: None,
230 pll2: None,
231 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
232 pll3: None,
233
234 #[cfg(any(stm32h7, stm32h7rs))]
235 d1c_pre: AHBPrescaler::DIV1,
236 ahb_pre: AHBPrescaler::DIV1,
237 apb1_pre: APBPrescaler::DIV1,
238 apb2_pre: APBPrescaler::DIV1,
239 #[cfg(not(stm32h7rs))]
240 apb3_pre: APBPrescaler::DIV1,
241 #[cfg(any(stm32h7, stm32h7rs))]
242 apb4_pre: APBPrescaler::DIV1,
243 #[cfg(stm32h7rs)]
244 apb5_pre: APBPrescaler::DIV1,
245
246 timer_prescaler: TimerPrescaler::DefaultX2,
247 #[cfg(not(rcc_h7rs))]
248 voltage_scale: VoltageScale::Scale0,
249 #[cfg(rcc_h7rs)]
250 voltage_scale: VoltageScale::HIGH,
251 ls: Default::default(),
252
253 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
254 supply_config: SupplyConfig::LDO,
255
256 mux: Default::default(),
257 }
258 }
259}
260
261pub(crate) unsafe fn init(config: Config) {
262 #[cfg(any(stm32h7))]
263 let pwr_reg = PWR.cr3();
264 #[cfg(any(stm32h7rs))]
265 let pwr_reg = PWR.csr2();
266
267 #[cfg(pwr_h7rm0433)]
273 pwr_reg.modify(|w| {
274 w.set_scuen(true);
275 w.set_ldoen(true);
276 w.set_bypass(false);
277 });
278
279 #[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468, pwr_h7rs))]
280 {
281 use pac::pwr::vals::Sdlevel;
282 match config.supply_config {
283 SupplyConfig::Default => {
284 pwr_reg.modify(|w| {
285 w.set_sdlevel(Sdlevel::RESET);
286 w.set_sdexthp(false);
287 w.set_sden(true);
288 w.set_ldoen(true);
289 w.set_bypass(false);
290 });
291 }
292 SupplyConfig::LDO => {
293 pwr_reg.modify(|w| {
294 w.set_sden(false);
295 w.set_ldoen(true);
296 w.set_bypass(false);
297 });
298 }
299 SupplyConfig::DirectSMPS => {
300 pwr_reg.modify(|w| {
301 w.set_sdexthp(false);
302 w.set_sden(true);
303 w.set_ldoen(false);
304 w.set_bypass(false);
305 });
306 }
307 SupplyConfig::SMPSLDO(sdlevel)
308 | SupplyConfig::SMPSExternalLDO(sdlevel)
309 | SupplyConfig::SMPSExternalLDOBypass(sdlevel) => {
310 let sdlevel = match sdlevel {
311 SMPSSupplyVoltage::V1_8 => Sdlevel::V1_8,
312 #[cfg(not(pwr_h7rs))]
313 SMPSSupplyVoltage::V2_5 => Sdlevel::V2_5,
314 };
315 pwr_reg.modify(|w| {
316 w.set_sdlevel(sdlevel);
317 w.set_sdexthp(matches!(
318 config.supply_config,
319 SupplyConfig::SMPSExternalLDO(_) | SupplyConfig::SMPSExternalLDOBypass(_)
320 ));
321 w.set_sden(true);
322 w.set_ldoen(matches!(
323 config.supply_config,
324 SupplyConfig::SMPSLDO(_) | SupplyConfig::SMPSExternalLDO(_)
325 ));
326 w.set_bypass(matches!(config.supply_config, SupplyConfig::SMPSExternalLDOBypass(_)));
327 });
328 }
329 SupplyConfig::SMPSDisabledLDOBypass => {
330 pwr_reg.modify(|w| {
331 w.set_sden(false);
332 w.set_ldoen(false);
333 w.set_bypass(true);
334 });
335 }
336 }
337 }
338
339 #[cfg(any(stm32h7))]
345 while !PWR.csr1().read().actvosrdy() {}
346 #[cfg(any(stm32h7rs))]
347 while !PWR.sr1().read().actvosrdy() {}
348
349 #[cfg(any(pwr_h5, pwr_h50))]
351 {
352 PWR.voscr().modify(|w| {
353 w.set_vos(match config.voltage_scale {
354 VoltageScale::Scale0 => crate::pac::pwr::vals::Vos::SCALE0,
355 VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1,
356 VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2,
357 VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3,
358 })
359 });
360 while !PWR.vossr().read().vosrdy() {}
361 }
362 #[cfg(syscfg_h7)]
363 {
364 PWR.d3cr().modify(|w| {
366 w.set_vos(match config.voltage_scale {
367 VoltageScale::Scale0 => crate::pac::pwr::vals::Vos::SCALE0,
368 VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1,
369 VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2,
370 VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3,
371 })
372 });
373 while !PWR.d3cr().read().vosrdy() {}
374 }
375 #[cfg(pwr_h7rs)]
376 {
377 PWR.csr4().modify(|w| w.set_vos(config.voltage_scale));
378 while !PWR.csr4().read().vosrdy() {}
379 }
380
381 #[cfg(syscfg_h7od)]
382 {
383 match config.voltage_scale {
384 VoltageScale::Scale0 => {
385 PWR.d3cr().modify(|w| w.set_vos(crate::pac::pwr::vals::Vos::SCALE1));
387 while !PWR.d3cr().read().vosrdy() {}
388
389 critical_section::with(|_| pac::SYSCFG.pwrcr().modify(|w| w.set_oden(1)));
391 while !PWR.d3cr().read().vosrdy() {}
392 }
393 _ => {
394 PWR.d3cr().modify(|w| {
396 w.set_vos(match config.voltage_scale {
397 VoltageScale::Scale0 => unreachable!(),
398 VoltageScale::Scale1 => crate::pac::pwr::vals::Vos::SCALE1,
399 VoltageScale::Scale2 => crate::pac::pwr::vals::Vos::SCALE2,
400 VoltageScale::Scale3 => crate::pac::pwr::vals::Vos::SCALE3,
401 })
402 });
403 while !PWR.d3cr().read().vosrdy() {}
404 }
405 }
406 }
407
408 match config.hsi {
410 None => RCC.cr().modify(|w| w.set_hsion(true)),
411 Some(hsidiv) => RCC.cr().modify(|w| {
412 w.set_hsidiv(hsidiv);
413 w.set_hsion(true);
414 }),
415 }
416 while !RCC.cr().read().hsirdy() {}
417
418 RCC.cfgr().modify(|w| w.set_sw(Sysclk::HSI));
420 while RCC.cfgr().read().sws() != Sysclk::HSI {}
421
422 let hsi = match config.hsi {
424 None => None,
425 Some(hsidiv) => Some(HSI_FREQ / hsidiv),
426 };
427
428 let hse = match config.hse {
430 None => {
431 RCC.cr().modify(|w| w.set_hseon(false));
432 None
433 }
434 Some(hse) => {
435 RCC.cr().modify(|w| {
436 w.set_hsebyp(hse.mode != HseMode::Oscillator);
437 #[cfg(any(rcc_h5, rcc_h50, rcc_h7rs))]
438 w.set_hseext(match hse.mode {
439 HseMode::Oscillator | HseMode::Bypass => pac::rcc::vals::Hseext::ANALOG,
440 HseMode::BypassDigital => pac::rcc::vals::Hseext::DIGITAL,
441 });
442 });
443 RCC.cr().modify(|w| w.set_hseon(true));
444 while !RCC.cr().read().hserdy() {}
445 Some(hse.freq)
446 }
447 };
448
449 let hsi48 = config.hsi48.map(super::init_hsi48);
451
452 RCC.cr().modify(|w| w.set_csion(config.csi));
454 let csi = match config.csi {
455 false => None,
456 true => {
457 while !RCC.cr().read().csirdy() {}
458 Some(CSI_FREQ)
459 }
460 };
461
462 #[cfg(any(stm32h7, stm32h7rs))]
464 {
465 let plls = [&config.pll1, &config.pll2, &config.pll3];
466 if !super::util::all_equal(plls.into_iter().flatten().map(|p| p.source)) {
467 panic!("Source must be equal across all enabled PLLs.")
468 };
469 }
470
471 let pll_input = PllInput { csi, hse, hsi };
473 let pll1 = init_pll(0, config.pll1, &pll_input);
474 let pll2 = init_pll(1, config.pll2, &pll_input);
475 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
476 let pll3 = init_pll(2, config.pll3, &pll_input);
477
478 let sys = match config.sys {
480 Sysclk::HSI => unwrap!(hsi),
481 Sysclk::HSE => unwrap!(hse),
482 Sysclk::CSI => unwrap!(csi),
483 Sysclk::PLL1_P => unwrap!(pll1.p),
484 _ => unreachable!(),
485 };
486
487 #[cfg(stm32h5)]
489 let (hclk_max, pclk_max) = match config.voltage_scale {
490 VoltageScale::Scale0 => (Hertz(250_000_000), Hertz(250_000_000)),
491 VoltageScale::Scale1 => (Hertz(200_000_000), Hertz(200_000_000)),
492 VoltageScale::Scale2 => (Hertz(150_000_000), Hertz(150_000_000)),
493 VoltageScale::Scale3 => (Hertz(100_000_000), Hertz(100_000_000)),
494 };
495 #[cfg(pwr_h7rm0455)]
496 let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale {
497 VoltageScale::Scale0 => (Hertz(280_000_000), Hertz(280_000_000), Hertz(140_000_000)),
498 VoltageScale::Scale1 => (Hertz(225_000_000), Hertz(225_000_000), Hertz(112_500_000)),
499 VoltageScale::Scale2 => (Hertz(160_000_000), Hertz(160_000_000), Hertz(80_000_000)),
500 VoltageScale::Scale3 => (Hertz(88_000_000), Hertz(88_000_000), Hertz(44_000_000)),
501 };
502 #[cfg(pwr_h7rm0468)]
503 let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale {
504 VoltageScale::Scale0 => {
505 let d1cpre_clk_max = if pac::SYSCFG.ur18().read().cpu_freq_boost() {
506 550_000_000
507 } else {
508 520_000_000
509 };
510 (Hertz(d1cpre_clk_max), Hertz(275_000_000), Hertz(137_500_000))
511 }
512 VoltageScale::Scale1 => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)),
513 VoltageScale::Scale2 => (Hertz(300_000_000), Hertz(150_000_000), Hertz(75_000_000)),
514 VoltageScale::Scale3 => (Hertz(170_000_000), Hertz(85_000_000), Hertz(42_500_000)),
515 };
516 #[cfg(all(stm32h7, not(any(pwr_h7rm0455, pwr_h7rm0468))))]
517 let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale {
518 VoltageScale::Scale0 => (Hertz(480_000_000), Hertz(240_000_000), Hertz(120_000_000)),
519 VoltageScale::Scale1 => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)),
520 VoltageScale::Scale2 => (Hertz(300_000_000), Hertz(150_000_000), Hertz(75_000_000)),
521 VoltageScale::Scale3 => (Hertz(200_000_000), Hertz(100_000_000), Hertz(50_000_000)),
522 };
523 #[cfg(stm32h7rs)]
524 let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale {
525 VoltageScale::HIGH => (Hertz(600_000_000), Hertz(300_000_000), Hertz(150_000_000)),
526 VoltageScale::LOW => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)),
527 };
528
529 #[cfg(any(stm32h7, stm32h7rs))]
530 let hclk = {
531 let d1cpre_clk = sys / config.d1c_pre;
532 assert!(d1cpre_clk <= d1cpre_clk_max);
533 sys / config.ahb_pre
534 };
535 #[cfg(stm32h5)]
536 let hclk = sys / config.ahb_pre;
537 assert!(hclk <= hclk_max);
538
539 let apb1 = hclk / config.apb1_pre;
540 let apb1_tim = apb_div_tim(&config.apb1_pre, hclk, config.timer_prescaler);
541 assert!(apb1 <= pclk_max);
542 let apb2 = hclk / config.apb2_pre;
543 let apb2_tim = apb_div_tim(&config.apb2_pre, hclk, config.timer_prescaler);
544 assert!(apb2 <= pclk_max);
545 #[cfg(not(stm32h7rs))]
546 let apb3 = hclk / config.apb3_pre;
547 #[cfg(not(stm32h7rs))]
548 assert!(apb3 <= pclk_max);
549 #[cfg(any(stm32h7, stm32h7rs))]
550 let apb4 = hclk / config.apb4_pre;
551 #[cfg(any(stm32h7, stm32h7rs))]
552 assert!(apb4 <= pclk_max);
553 #[cfg(stm32h7rs)]
554 let apb5 = hclk / config.apb5_pre;
555 #[cfg(stm32h7rs)]
556 assert!(apb5 <= pclk_max);
557
558 flash_setup(hclk, config.voltage_scale);
559
560 let rtc = config.ls.init();
561
562 #[cfg(all(stm32h7rs, peri_usb_otg_hs))]
563 let usb_refck = match config.mux.usbphycsel {
564 Usbphycsel::HSE => hse,
565 Usbphycsel::HSE_DIV_2 => hse.map(|hse_val| hse_val / 2u8),
566 Usbphycsel::PLL3_Q => pll3.q,
567 _ => None,
568 };
569 #[cfg(all(stm32h7rs, peri_usb_otg_hs))]
570 let usb_refck_sel = match usb_refck {
571 Some(clk_val) => match clk_val {
572 Hertz(16_000_000) => Usbrefcksel::MHZ16,
573 Hertz(19_200_000) => Usbrefcksel::MHZ19_2,
574 Hertz(20_000_000) => Usbrefcksel::MHZ20,
575 Hertz(24_000_000) => Usbrefcksel::MHZ24,
576 Hertz(26_000_000) => Usbrefcksel::MHZ26,
577 Hertz(32_000_000) => Usbrefcksel::MHZ32,
578 _ => panic!("cannot select USBPHYC reference clock with source frequency of {} Hz, must be one of 16, 19.2, 20, 24, 26, 32 MHz", clk_val),
579 },
580 None => Usbrefcksel::MHZ24,
581 };
582
583 #[cfg(stm32h7)]
584 {
585 RCC.d1cfgr().modify(|w| {
586 w.set_d1cpre(config.d1c_pre);
587 w.set_d1ppre(config.apb3_pre);
588 w.set_hpre(config.ahb_pre);
589 });
590 while RCC.d1cfgr().read().d1cpre() != config.d1c_pre {}
592
593 RCC.d2cfgr().modify(|w| {
594 w.set_d2ppre1(config.apb1_pre);
595 w.set_d2ppre2(config.apb2_pre);
596 });
597 RCC.d3cfgr().modify(|w| {
598 w.set_d3ppre(config.apb4_pre);
599 });
600 }
601 #[cfg(stm32h7rs)]
602 {
603 RCC.cdcfgr().write(|w| {
604 w.set_cpre(config.d1c_pre);
605 });
606 while RCC.cdcfgr().read().cpre() != config.d1c_pre {}
607
608 RCC.bmcfgr().write(|w| {
609 w.set_bmpre(config.ahb_pre);
610 });
611 while RCC.bmcfgr().read().bmpre() != config.ahb_pre {}
612
613 RCC.apbcfgr().modify(|w| {
614 w.set_ppre1(config.apb1_pre);
615 w.set_ppre2(config.apb2_pre);
616 w.set_ppre4(config.apb4_pre);
617 w.set_ppre5(config.apb5_pre);
618 });
619
620 #[cfg(peri_usb_otg_hs)]
621 RCC.ahbperckselr().modify(|w| {
622 w.set_usbrefcksel(usb_refck_sel);
623 });
624 }
625 #[cfg(stm32h5)]
626 {
627 RCC.cfgr2().modify(|w| w.set_hpre(config.ahb_pre));
629 while RCC.cfgr2().read().hpre() != config.ahb_pre {}
630
631 RCC.cfgr2().modify(|w| {
633 w.set_ppre1(config.apb1_pre);
634 w.set_ppre2(config.apb2_pre);
635 w.set_ppre3(config.apb3_pre);
636 });
637 }
638
639 RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into()));
640
641 RCC.cfgr().modify(|w| w.set_sw(config.sys));
642 while RCC.cfgr().read().sws() != config.sys {}
643
644 if config.hsi.is_none() {
646 RCC.cr().modify(|w| w.set_hsion(false));
647 }
648
649 #[cfg(any(stm32h7))] if csi.is_some() {
652 critical_section::with(|_| {
655 pac::SYSCFG.cccsr().modify(|w| {
656 w.set_en(true);
657 w.set_cs(false);
658 w.set_hslv(false);
659 })
660 });
661 while !pac::SYSCFG.cccsr().read().rdy() {}
662 }
663
664 config.mux.init();
665
666 set_clocks!(
667 sys: Some(sys),
668 hclk1: Some(hclk),
669 hclk2: Some(hclk),
670 hclk3: Some(hclk),
671 hclk4: Some(hclk),
672 #[cfg(stm32h7rs)]
673 hclk5: Some(hclk),
674 pclk1: Some(apb1),
675 pclk2: Some(apb2),
676 #[cfg(not(stm32h7rs))]
677 pclk3: Some(apb3),
678 #[cfg(any(stm32h7, stm32h7rs))]
679 pclk4: Some(apb4),
680 #[cfg(stm32h7rs)]
681 pclk5: Some(apb5),
682
683 pclk1_tim: Some(apb1_tim),
684 pclk2_tim: Some(apb2_tim),
685 rtc: rtc,
686
687 hsi: hsi,
688 hsi48: hsi48,
689 csi: csi,
690 csi_div_122: csi.map(|c| c / 122u32),
691 hse: hse,
692
693 lse: None,
694 lsi: None,
695
696 pll1_q: pll1.q,
697 pll2_p: pll2.p,
698 pll2_q: pll2.q,
699 pll2_r: pll2.r,
700 #[cfg(stm32h7rs)]
701 pll2_s: None, #[cfg(stm32h7rs)]
703 pll2_t: None, #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
705 pll3_p: pll3.p,
706 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
707 pll3_q: pll3.q,
708 #[cfg(any(rcc_h5, stm32h7, stm32h7rs))]
709 pll3_r: pll3.r,
710
711 #[cfg(rcc_h50)]
712 pll3_p: None,
713 #[cfg(rcc_h50)]
714 pll3_q: None,
715 #[cfg(rcc_h50)]
716 pll3_r: None,
717
718 #[cfg(dsihost)]
719 dsi_phy: None, #[cfg(stm32h5)]
722 audioclk: None,
723 i2s_ckin: None,
724 #[cfg(stm32h7rs)]
725 spdifrx_symb: None, #[cfg(stm32h7rs)]
727 clk48mohci: None, #[cfg(stm32h7rs)]
729 hse_div_2: hse.map(|clk| clk / 2u32),
730 #[cfg(stm32h7rs)]
731 usb: Some(Hertz(48_000_000)),
732 );
733}
734
735struct PllInput {
736 hsi: Option<Hertz>,
737 hse: Option<Hertz>,
738 csi: Option<Hertz>,
739}
740
741struct PllOutput {
742 p: Option<Hertz>,
743 #[allow(dead_code)]
744 q: Option<Hertz>,
745 #[allow(dead_code)]
746 r: Option<Hertz>,
747}
748
749fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
750 let Some(config) = config else {
751 RCC.cr().modify(|w| w.set_pllon(num, false));
753 while RCC.cr().read().pllrdy(num) {}
754
755 #[cfg(any(stm32h7, stm32h7rs))]
757 RCC.pllckselr().write(|w| w.set_divm(num, PllPreDiv::from_bits(0)));
758 #[cfg(stm32h5)]
759 RCC.pllcfgr(num).write(|w| w.set_divm(PllPreDiv::from_bits(0)));
760
761 return PllOutput {
762 p: None,
763 q: None,
764 r: None,
765 };
766 };
767
768 let in_clk = match config.source {
769 PllSource::DISABLE => panic!("must not set PllSource::Disable"),
770 PllSource::HSI => unwrap!(input.hsi),
771 PllSource::HSE => unwrap!(input.hse),
772 PllSource::CSI => unwrap!(input.csi),
773 };
774
775 let ref_clk = in_clk / config.prediv as u32;
776
777 let ref_range = match ref_clk.0 {
778 ..=1_999_999 => Pllrge::RANGE1,
779 ..=3_999_999 => Pllrge::RANGE2,
780 ..=7_999_999 => Pllrge::RANGE4,
781 ..=16_000_000 => Pllrge::RANGE8,
782 x => panic!("pll ref_clk out of range: {} hz", x),
783 };
784
785 let wide_allowed = ref_range != Pllrge::RANGE1;
788
789 let vco_clk = ref_clk * config.mul;
790 let vco_range = if VCO_RANGE.contains(&vco_clk) {
791 Pllvcosel::MEDIUM_VCO
792 } else if wide_allowed && VCO_WIDE_RANGE.contains(&vco_clk) {
793 Pllvcosel::WIDE_VCO
794 } else {
795 panic!("pll vco_clk out of range: {} hz", vco_clk.0)
796 };
797
798 let p = config.divp.map(|div| {
799 if num == 0 {
800 #[cfg(not(any(pwr_h7rm0468, stm32h7rs)))]
803 assert!(div.to_bits() % 2 == 1);
804 #[cfg(pwr_h7rm0468)]
805 assert!(div.to_bits() % 2 == 1 || div.to_bits() == 0);
806 }
807
808 vco_clk / div
809 });
810 let q = config.divq.map(|div| vco_clk / div);
811 let r = config.divr.map(|div| vco_clk / div);
812
813 #[cfg(stm32h5)]
814 RCC.pllcfgr(num).write(|w| {
815 w.set_pllsrc(config.source);
816 w.set_divm(config.prediv);
817 w.set_pllvcosel(vco_range);
818 w.set_pllrge(ref_range);
819 w.set_pllfracen(false);
820 w.set_pllpen(p.is_some());
821 w.set_pllqen(q.is_some());
822 w.set_pllren(r.is_some());
823 });
824
825 #[cfg(any(stm32h7, stm32h7rs))]
826 {
827 RCC.pllckselr().modify(|w| {
828 w.set_divm(num, config.prediv);
829 w.set_pllsrc(config.source);
830 });
831 RCC.pllcfgr().modify(|w| {
832 w.set_pllvcosel(num, vco_range);
833 w.set_pllrge(num, ref_range);
834 w.set_pllfracen(num, false);
835 w.set_divpen(num, p.is_some());
836 w.set_divqen(num, q.is_some());
837 w.set_divren(num, r.is_some());
838 });
839 }
840
841 RCC.plldivr(num).write(|w| {
842 w.set_plln(config.mul);
843 w.set_pllp(config.divp.unwrap_or(PllDiv::DIV2));
844 w.set_pllq(config.divq.unwrap_or(PllDiv::DIV2));
845 w.set_pllr(config.divr.unwrap_or(PllDiv::DIV2));
846 });
847
848 RCC.cr().modify(|w| w.set_pllon(num, true));
849 while !RCC.cr().read().pllrdy(num) {}
850
851 PllOutput { p, q, r }
852}
853
854fn flash_setup(clk: Hertz, vos: VoltageScale) {
855 #[cfg(stm32h5)]
864 let (latency, wrhighfreq) = match (vos, clk.0) {
865 (VoltageScale::Scale0, ..=42_000_000) => (0, 0),
866 (VoltageScale::Scale0, ..=84_000_000) => (1, 0),
867 (VoltageScale::Scale0, ..=126_000_000) => (2, 1),
868 (VoltageScale::Scale0, ..=168_000_000) => (3, 1),
869 (VoltageScale::Scale0, ..=210_000_000) => (4, 2),
870 (VoltageScale::Scale0, ..=250_000_000) => (5, 2),
871
872 (VoltageScale::Scale1, ..=34_000_000) => (0, 0),
873 (VoltageScale::Scale1, ..=68_000_000) => (1, 0),
874 (VoltageScale::Scale1, ..=102_000_000) => (2, 1),
875 (VoltageScale::Scale1, ..=136_000_000) => (3, 1),
876 (VoltageScale::Scale1, ..=170_000_000) => (4, 2),
877 (VoltageScale::Scale1, ..=200_000_000) => (5, 2),
878
879 (VoltageScale::Scale2, ..=30_000_000) => (0, 0),
880 (VoltageScale::Scale2, ..=60_000_000) => (1, 0),
881 (VoltageScale::Scale2, ..=90_000_000) => (2, 1),
882 (VoltageScale::Scale2, ..=120_000_000) => (3, 1),
883 (VoltageScale::Scale2, ..=150_000_000) => (4, 2),
884
885 (VoltageScale::Scale3, ..=20_000_000) => (0, 0),
886 (VoltageScale::Scale3, ..=40_000_000) => (1, 0),
887 (VoltageScale::Scale3, ..=60_000_000) => (2, 1),
888 (VoltageScale::Scale3, ..=80_000_000) => (3, 1),
889 (VoltageScale::Scale3, ..=100_000_000) => (4, 2),
890
891 _ => unreachable!(),
892 };
893
894 #[cfg(all(flash_h7, not(pwr_h7rm0468)))]
895 let (latency, wrhighfreq) = match (vos, clk.0) {
896 (VoltageScale::Scale0, ..=70_000_000) => (0, 0),
898 (VoltageScale::Scale0, ..=140_000_000) => (1, 1),
899 (VoltageScale::Scale0, ..=185_000_000) => (2, 1),
900 (VoltageScale::Scale0, ..=210_000_000) => (2, 2),
901 (VoltageScale::Scale0, ..=225_000_000) => (3, 2),
902 (VoltageScale::Scale0, ..=240_000_000) => (4, 2),
903 (VoltageScale::Scale1, ..=70_000_000) => (0, 0),
905 (VoltageScale::Scale1, ..=140_000_000) => (1, 1),
906 (VoltageScale::Scale1, ..=185_000_000) => (2, 1),
907 (VoltageScale::Scale1, ..=210_000_000) => (2, 2),
908 (VoltageScale::Scale1, ..=225_000_000) => (3, 2),
909 (VoltageScale::Scale2, ..=55_000_000) => (0, 0),
911 (VoltageScale::Scale2, ..=110_000_000) => (1, 1),
912 (VoltageScale::Scale2, ..=165_000_000) => (2, 1),
913 (VoltageScale::Scale2, ..=224_000_000) => (3, 2),
914 (VoltageScale::Scale3, ..=45_000_000) => (0, 0),
916 (VoltageScale::Scale3, ..=90_000_000) => (1, 1),
917 (VoltageScale::Scale3, ..=135_000_000) => (2, 1),
918 (VoltageScale::Scale3, ..=180_000_000) => (3, 2),
919 (VoltageScale::Scale3, ..=224_000_000) => (4, 2),
920 _ => unreachable!(),
921 };
922
923 #[cfg(all(flash_h7, pwr_h7rm0468))]
926 let (latency, wrhighfreq) = match (vos, clk.0) {
927 (VoltageScale::Scale0, ..=70_000_000) => (0, 0),
929 (VoltageScale::Scale0, ..=140_000_000) => (1, 1),
930 (VoltageScale::Scale0, ..=210_000_000) => (2, 2),
931 (VoltageScale::Scale0, ..=275_000_000) => (3, 3),
932 (VoltageScale::Scale1, ..=67_000_000) => (0, 0),
934 (VoltageScale::Scale1, ..=133_000_000) => (1, 1),
935 (VoltageScale::Scale1, ..=200_000_000) => (2, 2),
936 (VoltageScale::Scale2, ..=50_000_000) => (0, 0),
938 (VoltageScale::Scale2, ..=100_000_000) => (1, 1),
939 (VoltageScale::Scale2, ..=150_000_000) => (2, 2),
940 (VoltageScale::Scale3, ..=35_000_000) => (0, 0),
942 (VoltageScale::Scale3, ..=70_000_000) => (1, 1),
943 (VoltageScale::Scale3, ..=85_000_000) => (2, 2),
944 _ => unreachable!(),
945 };
946
947 #[cfg(flash_h7ab)]
950 let (latency, wrhighfreq) = match (vos, clk.0) {
951 (VoltageScale::Scale0, ..=42_000_000) => (0, 0),
953 (VoltageScale::Scale0, ..=84_000_000) => (1, 0),
954 (VoltageScale::Scale0, ..=126_000_000) => (2, 1),
955 (VoltageScale::Scale0, ..=168_000_000) => (3, 1),
956 (VoltageScale::Scale0, ..=210_000_000) => (4, 2),
957 (VoltageScale::Scale0, ..=252_000_000) => (5, 2),
958 (VoltageScale::Scale0, ..=280_000_000) => (6, 3),
959 (VoltageScale::Scale1, ..=38_000_000) => (0, 0),
961 (VoltageScale::Scale1, ..=76_000_000) => (1, 0),
962 (VoltageScale::Scale1, ..=114_000_000) => (2, 1),
963 (VoltageScale::Scale1, ..=152_000_000) => (3, 1),
964 (VoltageScale::Scale1, ..=190_000_000) => (4, 2),
965 (VoltageScale::Scale1, ..=225_000_000) => (5, 2),
966 (VoltageScale::Scale2, ..=34) => (0, 0),
968 (VoltageScale::Scale2, ..=68) => (1, 0),
969 (VoltageScale::Scale2, ..=102) => (2, 1),
970 (VoltageScale::Scale2, ..=136) => (3, 1),
971 (VoltageScale::Scale2, ..=160) => (4, 2),
972 (VoltageScale::Scale3, ..=22) => (0, 0),
974 (VoltageScale::Scale3, ..=44) => (1, 0),
975 (VoltageScale::Scale3, ..=66) => (2, 1),
976 (VoltageScale::Scale3, ..=88) => (3, 1),
977 _ => unreachable!(),
978 };
979 #[cfg(flash_h7rs)]
980 let (latency, wrhighfreq) = match (vos, clk.0) {
981 (VoltageScale::HIGH, ..=40_000_000) => (0, 0),
983 (VoltageScale::HIGH, ..=80_000_000) => (1, 0),
984 (VoltageScale::HIGH, ..=120_000_000) => (2, 1),
985 (VoltageScale::HIGH, ..=160_000_000) => (3, 1),
986 (VoltageScale::HIGH, ..=200_000_000) => (4, 2),
987 (VoltageScale::HIGH, ..=240_000_000) => (5, 2),
988 (VoltageScale::HIGH, ..=280_000_000) => (6, 3),
989 (VoltageScale::HIGH, ..=320_000_000) => (7, 3),
990 (VoltageScale::LOW, ..=36_000_000) => (0, 0),
992 (VoltageScale::LOW, ..=72_000_000) => (1, 0),
993 (VoltageScale::LOW, ..=108_000_000) => (2, 1),
994 (VoltageScale::LOW, ..=144_000_000) => (3, 1),
995 (VoltageScale::LOW, ..=180_000_000) => (4, 2),
996 (VoltageScale::LOW, ..=216_000_000) => (5, 2),
997 _ => unreachable!(),
998 };
999
1000 debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq);
1001
1002 FLASH.acr().write(|w| {
1003 w.set_wrhighfreq(wrhighfreq);
1004 w.set_latency(latency);
1005 });
1006 while FLASH.acr().read().latency() != latency {}
1007}