1use cfg_if::cfg_if;
8
9#[cfg(any(feature = "l4", feature = "l5", feature = "wb", feature = "g4"))]
10use crate::pac::CRS;
11#[cfg(not(any(feature = "wb", feature = "wl")))]
12use crate::util::rcc_en_reset;
13use crate::{
14 clocks::RccError,
15 error::{Error, Result},
16 pac::{self, FLASH, RCC},
17 util::bounded_loop,
18};
19
20#[cfg(not(any(feature = "g0", feature = "wl", feature = "c0")))]
23#[derive(Clone, Copy, PartialEq)]
24#[repr(u8)]
25pub enum Clk48Src {
26 Hsi48 = 0b00, #[cfg(not(feature = "g4"))]
30 PllSai1 = 0b01, Pllq = 0b10,
32 #[cfg(msi)]
33 Msi = 0b11,
34}
35
36#[cfg(feature = "c071")]
37#[derive(Clone, Copy, PartialEq)]
38#[repr(u8)]
39pub enum Clk48Src {
41 HsiUsb48 = 0,
42 Hse = 1,
43}
44
45#[cfg(any(feature = "l4", feature = "l5", feature = "wb", feature = "g4"))]
46#[derive(Clone, Copy)]
47#[repr(u8)]
48pub enum CrsSyncSrc {
50 Gpio = 0b00,
51 Lse = 0b01,
52 Usb = 0b10,
53}
54
55#[cfg(not(any(feature = "g0", feature = "g4", feature = "c0")))]
56#[derive(Clone, Copy, PartialEq)]
57pub enum PllSrc {
58 None,
59 Msi(MsiRange),
60 Hsi,
61 Hse(u32),
62}
63
64#[cfg(any(feature = "g0", feature = "g4", feature = "c0"))]
65#[derive(Clone, Copy, PartialEq)]
66pub enum PllSrc {
67 None,
68 Hsi,
69 Hse(u32),
70}
71
72impl PllSrc {
73 pub fn bits(&self) -> u8 {
77 #[cfg(not(any(feature = "g0", feature = "g4", feature = "c0")))]
79 match self {
80 Self::None => 0b00,
81 Self::Msi(_) => 0b01,
82 Self::Hsi => 0b10,
83 Self::Hse(_) => 0b11,
84 }
85 #[cfg(any(feature = "g0", feature = "g4", feature = "c0"))]
86 match self {
87 Self::None => 0b00,
88 Self::Hsi => 0b10,
89 Self::Hse(_) => 0b11,
90 }
91 }
92}
93
94#[cfg(any(feature = "l4", feature = "l5", feature = "wb", feature = "wl"))]
95#[derive(Clone, Copy, PartialEq)]
96#[repr(u8)]
97pub enum StopWuck {
99 Msi = 0,
100 Hsi = 1,
101}
102
103cfg_if! {
104 if #[cfg(feature = "c0")] {
105 #[derive(Clone, Copy, PartialEq)]
106 pub enum InputSrc {
108 Hsi,
110 Hse(u32), #[cfg(feature = "c071")]
112 HsiUsb48,
113 Lsi,
114 Lse,
115 }
116
117 impl InputSrc {
118 pub fn bits(&self) -> u8 {
121 match self {
122 Self::Hsi => 0b000,
123 Self::Hse(_) => 0b001,
124 #[cfg(feature = "c071")]
125 Self::HsiUsb48 => 0b010,
126 Self::Lsi => 0b011,
127 Self::Lse => 0b100,
128 }
129 }
130 }
131 } else if #[cfg(feature = "g0")] {
132 #[derive(Clone, Copy, PartialEq)]
133 pub enum InputSrc {
135 Hsi,
136 Hse(u32), Pll(PllSrc),
138 Lsi,
139 Lse,
140 }
141
142 impl InputSrc {
143 pub fn bits(&self) -> u8 {
146 match self {
147 Self::Hsi => 0b000,
148 Self::Hse(_) => 0b001,
149 Self::Pll(_) => 0b010,
150 Self::Lsi => 0b011,
151 Self::Lse => 0b100,
152 }
153 }
154 }
155 } else if #[cfg(feature = "g4")] {
156 #[derive(Clone, Copy, PartialEq)]
157 pub enum InputSrc {
158 Hsi,
159 Hse(u32), Pll(PllSrc),
161 }
162
163 impl InputSrc {
164 pub fn bits(&self) -> u8 {
167 match self {
168 Self::Hsi => 0b01,
169 Self::Hse(_) => 0b10,
170 Self::Pll(_) => 0b11,
171 }
172 }
173 }
174 } else { #[derive(Clone, Copy, PartialEq)]
176 pub enum InputSrc {
177 Msi(MsiRange),
178 Hsi,
179 Hse(u32), Pll(PllSrc),
181 }
182
183 impl InputSrc {
184 pub fn bits(&self) -> u8 {
187 match self {
188 Self::Msi(_) => 0b00,
189 Self::Hsi => 0b01,
190 Self::Hse(_) => 0b10,
191 Self::Pll(_) => 0b11,
192 }
193 }
194 }
195 }
196}
197
198#[cfg(feature = "wb")]
199#[derive(Clone, Copy, PartialEq)]
200#[repr(u8)]
201pub enum RfWakeupSrc {
203 NoClock = 0b00,
204 Lse = 0b01,
206 Hse = 0b11,
208}
209
210#[derive(Clone, Copy)]
213#[repr(u8)]
214enum WaitState {
216 W0 = 0,
217 W1 = 1,
218 #[cfg(not(feature = "c0"))]
219 W2 = 2,
220 #[cfg(not(any(feature = "wl", feature = "c0")))]
221 W3 = 3,
222 #[cfg(not(any(feature = "wb", feature = "wl", feature = "c0")))]
223 W4 = 4,
224 #[cfg(feature = "l5")]
225 W5 = 5,
226}
227
228#[cfg(not(any(feature = "g0", feature = "g4", feature = "c0")))]
229#[derive(Clone, Copy, PartialEq)]
230#[repr(u8)]
231pub enum MsiRange {
233 R100k = 0b0000,
234 R200k = 0b0001,
235 R400k = 0b0010,
236 R800k = 0b0011,
237 R1M = 0b0100,
238 R2M = 0b0101,
239 R4M = 0b0110, R8M = 0b0111,
241 R16M = 0b1000,
242 R24M = 0b1001,
243 R32M = 0b1010,
244 R48M = 0b1011,
245}
246
247#[cfg(not(any(feature = "g0", feature = "g4", feature = "c0")))]
248impl MsiRange {
249 const fn value(&self) -> u32 {
251 match self {
252 Self::R100k => 100_000,
253 Self::R200k => 200_000,
254 Self::R400k => 400_000,
255 Self::R800k => 800_000,
256 Self::R1M => 1_000_000,
257 Self::R2M => 2_000_000,
258 Self::R4M => 4_000_000,
259 Self::R8M => 8_000_000,
260 Self::R16M => 16_000_000,
261 Self::R24M => 24_000_000,
262 Self::R32M => 32_000_000,
263 Self::R48M => 48_000_000,
264 }
265 }
266}
267
268#[cfg(feature = "c0")]
269#[derive(Clone, Copy, PartialEq)]
270#[repr(u8)]
271pub enum HsiDiv {
273 Div1 = 0b000,
274 Div2 = 0b001,
275 Div4 = 0b010,
276 Div8 = 0b011,
277 Div16 = 0b100,
278 Div32 = 0b101,
279 Div64 = 0b110,
280 Div128 = 0b111,
281}
282
283#[cfg(feature = "c0")]
284impl HsiDiv {
285 pub const fn value(&self) -> u32 {
286 match self {
287 HsiDiv::Div1 => 1,
288 HsiDiv::Div2 => 2,
289 HsiDiv::Div4 => 4,
290 HsiDiv::Div8 => 8,
291 HsiDiv::Div16 => 16,
292 HsiDiv::Div32 => 32,
293 HsiDiv::Div64 => 64,
294 HsiDiv::Div128 => 128,
295 }
296 }
297}
298
299#[cfg(feature = "c071")]
300#[derive(Clone, Copy, PartialEq)]
301#[repr(u8)]
302pub enum SysDiv {
304 Div1 = 0b000,
305 Div2 = 0b001,
306 Div3 = 0b010,
307 Div4 = 0b011,
308 Div5 = 0b100,
309 Div6 = 0b101,
310 Div7 = 0b110,
311 Div8 = 0b111,
312}
313
314#[cfg(feature = "c071")]
315impl SysDiv {
316 pub const fn value(&self) -> u32 {
317 match self {
318 SysDiv::Div1 => 1,
319 SysDiv::Div2 => 2,
320 SysDiv::Div3 => 3,
321 SysDiv::Div4 => 4,
322 SysDiv::Div5 => 5,
323 SysDiv::Div6 => 6,
324 SysDiv::Div7 => 7,
325 SysDiv::Div8 => 8,
326 }
327 }
328}
329
330pub struct PllCfg {
333 pub enabled: bool,
335 pub pllr_en: bool,
336 pub pllq_en: bool,
337 pub pllp_en: bool,
338 pub divm: Pllm,
340 pub divn: u8,
341 pub divr: Pllr,
342 pub divq: Pllr,
343 pub divp: Pllp,
344 pub pdiv: u8,
347}
348
349impl Default for PllCfg {
350 fn default() -> Self {
351 Self {
353 enabled: true,
354 pllr_en: true,
355 pllq_en: false,
356 pllp_en: false,
357 divm: Pllm::Div4,
358 #[cfg(feature = "l4")]
359 divn: 40,
360 #[cfg(feature = "l5")]
361 divn: 55,
362 #[cfg(feature = "g0")]
363 divn: 32,
364 #[cfg(feature = "g4")]
365 divn: 85,
366 #[cfg(feature = "wb")]
367 divn: 64,
368 #[cfg(feature = "wl")]
369 divn: 24,
370 #[cfg(feature = "c0")]
371 divn: 24, #[cfg(not(feature = "wb"))]
373 divr: Pllr::Div2,
374 #[cfg(feature = "wb")]
375 divr: Pllr::Div4,
376 divq: Pllr::Div4,
377 divp: Pllp::Div7,
378 pdiv: 0,
379 }
380 }
381}
382
383impl PllCfg {
384 pub fn disabled() -> Self {
385 Self {
386 enabled: false,
387 pllp_en: false,
388 pllr_en: false,
389 pllq_en: false,
390 ..Default::default()
391 }
392 }
393
394 pub const fn pvalue(&self) -> u8 {
395 match self.pdiv {
396 0 => self.divp.value(),
397 pdiv => pdiv,
398 }
399 }
400}
401
402#[cfg(not(any(feature = "l5", feature = "g4")))]
403#[derive(Clone, Copy)]
404#[repr(u8)]
405pub enum Pllm {
406 Div1 = 0b000,
407 Div2 = 0b001,
408 Div3 = 0b010,
409 Div4 = 0b011,
410 Div5 = 0b100,
411 Div6 = 0b101,
412 Div7 = 0b110,
413 Div8 = 0b111,
414}
415
416#[cfg(any(feature = "l5", feature = "g4"))]
417#[derive(Clone, Copy)]
418#[repr(u8)]
419pub enum Pllm {
420 Div1 = 0b0000,
421 Div2 = 0b0001,
422 Div3 = 0b0010,
423 Div4 = 0b0011,
424 Div5 = 0b0100,
425 Div6 = 0b0101,
426 Div7 = 0b0110,
427 Div8 = 0b0111,
428 Div9 = 0b1000,
429 Div10 = 0b1001,
430 Div11 = 0b1010,
431 Div12 = 0b1011,
432 Div13 = 0b1100,
433 Div14 = 0b1101,
434 Div15 = 0b1110,
435 Div16 = 0b1111,
436}
437
438impl Pllm {
439 pub const fn value(&self) -> u8 {
440 #[cfg(not(any(feature = "l5", feature = "g4")))]
441 match self {
442 Self::Div1 => 1,
443 Self::Div2 => 2,
444 Self::Div3 => 3,
445 Self::Div4 => 4,
446 Self::Div5 => 5,
447 Self::Div6 => 6,
448 Self::Div7 => 7,
449 Self::Div8 => 8,
450 }
451
452 #[cfg(any(feature = "l5", feature = "g4"))]
453 match self {
454 Self::Div1 => 1,
455 Self::Div2 => 2,
456 Self::Div3 => 3,
457 Self::Div4 => 4,
458 Self::Div5 => 5,
459 Self::Div6 => 6,
460 Self::Div7 => 7,
461 Self::Div8 => 8,
462 Self::Div9 => 9,
463 Self::Div10 => 10,
464 Self::Div11 => 11,
465 Self::Div12 => 12,
466 Self::Div13 => 13,
467 Self::Div14 => 14,
468 Self::Div15 => 15,
469 Self::Div16 => 16,
470 }
471 }
472}
473
474#[cfg(any(feature = "g0", feature = "wb"))]
475#[derive(Clone, Copy)]
476#[repr(u8)]
477pub enum Pllr {
480 Div2 = 0b001,
481 Div3 = 0b010,
482 Div4 = 0b011,
483 Div5 = 0b100,
484 Div6 = 0b101,
485 Div7 = 0b110,
486 Div8 = 0b111,
487}
488
489#[cfg(any(feature = "g0", feature = "wb"))]
490impl Pllr {
491 pub const fn value(&self) -> u8 {
492 match self {
493 Self::Div2 => 2,
494 Self::Div3 => 3,
495 Self::Div4 => 4,
496 Self::Div5 => 5,
497 Self::Div6 => 6,
498 Self::Div7 => 7,
499 Self::Div8 => 8,
500 }
501 }
502}
503
504#[cfg(not(any(feature = "g0", feature = "wb")))]
505#[derive(Clone, Copy)]
506#[repr(u8)]
507pub enum Pllr {
509 Div2 = 0b00,
510 Div4 = 0b01,
511 Div6 = 0b10,
512 Div8 = 0b11,
513}
514
515#[cfg(not(any(feature = "g0", feature = "wb")))]
516impl Pllr {
517 pub const fn value(&self) -> u8 {
518 match self {
519 Self::Div2 => 2,
520 Self::Div4 => 4,
521 Self::Div6 => 6,
522 Self::Div8 => 8,
523 }
524 }
525}
526
527#[derive(Clone, Copy)]
528#[repr(u8)]
529pub enum Pllp {
531 Div7 = 0,
532 Div17 = 1,
533}
534
535impl Pllp {
536 pub const fn value(&self) -> u8 {
537 match self {
538 Self::Div7 => 7,
539 Self::Div17 => 17,
540 }
541 }
542}
543
544#[derive(Clone, Copy)]
545#[repr(u8)]
546pub enum HclkPrescaler {
549 Div1 = 0b0000,
550 #[cfg(feature = "wb")]
551 Div3 = 0b0001,
552 #[cfg(feature = "wb")]
553 Div5 = 0b0010,
554 #[cfg(feature = "wb")]
555 Div6 = 0b0101,
556 #[cfg(feature = "wb")]
557 Div10 = 0b0110,
558 #[cfg(feature = "wb")]
559 Div32 = 0b0111,
560 Div2 = 0b1000,
561 Div4 = 0b1001,
562 Div8 = 0b1010,
563 Div16 = 0b1011,
564 Div64 = 0b1100,
565 Div128 = 0b1101,
566 Div256 = 0b1110,
567 Div512 = 0b1111,
568}
569
570impl HclkPrescaler {
571 pub const fn value(&self) -> u16 {
572 match self {
573 Self::Div1 => 1,
574 #[cfg(feature = "wb")]
575 Self::Div3 => 3,
576 #[cfg(feature = "wb")]
577 Self::Div5 => 5,
578 #[cfg(feature = "wb")]
579 Self::Div6 => 6,
580 #[cfg(feature = "wb")]
581 Self::Div10 => 10,
582 #[cfg(feature = "wb")]
583 Self::Div32 => 32,
584 Self::Div2 => 2,
585 Self::Div4 => 4,
586 Self::Div8 => 8,
587 Self::Div16 => 16,
588 Self::Div64 => 64,
589 Self::Div128 => 128,
590 Self::Div256 => 256,
591 Self::Div512 => 512,
592 }
593 }
594}
595
596#[derive(Clone, Copy)]
597#[repr(u8)]
598pub enum ApbPrescaler {
600 Div1 = 0b000,
601 Div2 = 0b100,
602 Div4 = 0b101,
603 Div8 = 0b110,
604 Div16 = 0b111,
605}
606
607impl ApbPrescaler {
608 pub const fn value(&self) -> u8 {
609 match self {
610 Self::Div1 => 1,
611 Self::Div2 => 2,
612 Self::Div4 => 4,
613 Self::Div8 => 8,
614 Self::Div16 => 16,
615 }
616 }
617}
618
619#[derive(Clone, Copy, PartialEq)]
620#[repr(u8)]
621pub enum SaiSrc {
623 PllSai1P = 0b00,
625 Pllp = 0b01,
627 Hsi = 0b10,
629 ExtClk = 0b11,
631}
632
633#[cfg(any(feature = "g0", feature = "g4"))]
634#[derive(Clone, Copy, PartialEq)]
635#[repr(u8)]
636pub enum CanSrc {
638 Hse = 0b00,
640 PllQ = 0b01,
642 Pclk = 0b10,
644}
645
646#[cfg(not(any(feature = "f", feature = "l", feature = "g0")))]
648#[derive(Clone, Copy, PartialEq)]
649#[repr(u8)]
650pub enum LpUartSrc {
652 Pclk = 0b00,
653 Sysclk = 0b01,
654 Hsi16 = 0b10,
655 Lse = 0b11,
656}
657
658pub struct Clocks {
662 pub input_src: InputSrc,
664 #[cfg(not(feature = "c0"))]
666 pub pll: PllCfg,
667 #[cfg(not(any(feature = "g0", feature = "g4", feature = "wl", feature = "c0")))]
669 pub pllsai1: PllCfg,
670 #[cfg(any(feature = "l4x5", feature = "l4x6"))]
671 pub pllsai2: PllCfg,
672 pub hclk_prescaler: HclkPrescaler,
674 #[cfg(feature = "wb")]
675 pub hclk2_prescaler: HclkPrescaler,
677 #[cfg(feature = "wl")]
678 pub hclk3_prescaler: HclkPrescaler,
680 #[cfg(feature = "wb")]
681 pub hclk4_prescaler: HclkPrescaler,
683 pub apb1_prescaler: ApbPrescaler,
685 #[cfg(not(any(feature = "g0", feature = "c0")))]
686 pub apb2_prescaler: ApbPrescaler,
688 #[cfg(not(any(feature = "g0", feature = "wl", feature = "c011", feature = "c031")))]
691 pub clk48_src: Clk48Src,
693 #[cfg(not(any(feature = "f", feature = "l", feature = "g0", feature = "c0")))]
694 pub lpuart_src: LpUartSrc,
695 pub hse_bypass: bool,
698 pub security_system: bool,
699 #[cfg(not(any(feature = "g0", feature = "wl", feature = "c011", feature = "c031")))]
700 pub hsi48_on: bool,
702 #[cfg(any(feature = "l4", feature = "l5", feature = "wb", feature = "wl"))]
703 pub stop_wuck: StopWuck,
705 #[cfg(feature = "wb")]
706 pub rf_wakeup_src: RfWakeupSrc,
708 #[cfg(not(any(feature = "g0", feature = "g4", feature = "wl", feature = "c0")))]
709 pub sai1_src: SaiSrc,
711 #[cfg(feature = "g4")]
712 pub boost_mode: bool,
715 #[cfg(any(feature = "g0", feature = "g4"))]
716 pub can_src: CanSrc,
718 #[cfg(feature = "c0")]
719 pub hsi_div: HsiDiv,
720 #[cfg(feature = "c071")]
721 pub sys_div: SysDiv,
722}
723
724impl Clocks {
727 pub fn setup(&self) -> Result<()> {
732 if let Err(e) = self.validate_speeds() {
733 return Err(e);
734 }
735
736 let rcc = unsafe { &(*RCC::ptr()) };
737 let flash = unsafe { &(*FLASH::ptr()) };
738 #[cfg(feature = "l5")]
739 let icache = unsafe { &(*pac::ICACHE::ptr()) };
740
741 #[cfg(not(any(feature = "wb", feature = "wl")))]
744 rcc_en_reset!(apb2, syscfg, rcc);
745
746 let sysclk = self.sysclk();
749
750 cfg_if! {
751 if #[cfg(feature = "wb")] {
752 let hclk = sysclk / self.hclk4_prescaler.value() as u32;
753 } else if #[cfg(feature = "wl")] {
754 let hclk = sysclk / self.hclk3_prescaler.value() as u32;
755 } else {
756 let hclk = sysclk / self.hclk_prescaler.value() as u32;
757 }
758 }
759
760 cfg_if! {
761 if #[cfg(feature = "g4")] {
762 if self.boost_mode {
763 rcc.cfgr().modify(|_, w| unsafe { w.hpre().bits(HclkPrescaler::Div2 as u8) });
767 let pwr = unsafe { &(*pac::PWR::ptr()) };
769 pwr.cr5().modify(|_, w| w.r1mode().clear_bit());
770 }
771
772 }
779 }
780
781 cfg_if! {
782 if #[cfg(feature = "l4")] { let wait_state = if hclk <= 16_000_000 {
784 WaitState::W0
785 } else if hclk <= 32_000_000 {
786 WaitState::W1
787 } else if hclk <= 48_000_000 {
788 WaitState::W2
789 } else if hclk <= 64_000_000 {
790 WaitState::W3
791 } else {
792 WaitState::W4
793 };
794 } else if #[cfg(feature = "l5")] { let wait_state = if hclk <= 20_000_000 {
796 WaitState::W0
797 } else if hclk <= 40_000_000 {
798 WaitState::W1
799 } else if hclk <= 60_000_000 {
800 WaitState::W2
801 } else if hclk <= 80_000_000 {
802 WaitState::W3
803 } else if hclk <= 100_000_000 {
804 WaitState::W4
805 } else {
806 WaitState::W5
807 };
808 } else if #[cfg(feature = "g0")] { let wait_state = if hclk <= 24_000_000 {
810 WaitState::W0
811 } else if hclk <= 48_000_000 {
812 WaitState::W1
813 } else {
814 WaitState::W2
815 };
816 } else if #[cfg(feature = "c0")] { let wait_state = if hclk <= 24_000_000 {
818 WaitState::W0
819 } else {
820 WaitState::W1
821 };
822 } else if #[cfg(feature = "wb")] { let wait_state = if hclk <= 18_000_000 {
825 WaitState::W0
826 } else if hclk <= 36_000_000 {
827 WaitState::W1
828 } else if hclk <= 54_000_000 {
829 WaitState::W2
830 } else {
831 WaitState::W3
832 };
833 } else if #[cfg(any(feature = "wb", feature = "wl"))] { let wait_state = if hclk <= 18_000_000 {
836 WaitState::W0
837 } else if hclk <= 36_000_000 {
838 WaitState::W1
839 } else {
840 WaitState::W2
841 };
842 } else { let wait_state = if self.boost_mode {
844 if hclk <= 34_000_000 {
846 WaitState::W0
847 } else if hclk <= 68_000_000 {
848 WaitState::W1
849 } else if hclk <= 102_000_000 {
850 WaitState::W2
851 } else if hclk <= 136_000_000 {
852 WaitState::W3
853 } else {
854 WaitState::W4
855 }
856 } else {
857 if hclk <= 30_000_000 {
859 WaitState::W0
860 } else if hclk <= 60_000_000 {
861 WaitState::W1
862 } else if hclk <= 90_000_000 {
863 WaitState::W2
864 } else if hclk <= 120_000_000 {
865 WaitState::W3
866 } else {
867 WaitState::W4
868 }
869 };
870 }
871 }
872
873 #[cfg(not(feature = "l5"))]
878 flash.acr().modify(|_, w| unsafe {
879 #[cfg(not(any(feature = "g0", feature = "c0")))]
880 w.dcrst().bit(true);
881 w.icrst().bit(true)
882 });
883
884 #[cfg(not(feature = "l5"))]
886 flash.acr().modify(|_, w| unsafe {
887 w.latency().bits(wait_state as u8);
889 #[cfg(not(any(feature = "g0", feature = "c0")))]
890 w.dcen().bit(true);
891 w.icen().bit(true);
892 w.prften().bit(true)
898 });
899
900 #[cfg(feature = "l5")]
901 flash
902 .acr()
903 .modify(|_, w| unsafe { w.latency().bits(wait_state as u8) });
904
905 match self.input_src {
928 #[cfg(msi)]
929 InputSrc::Msi(range) => {
930 rcc.cr().modify(|_, w| w.msion().clear_bit());
933
934 bounded_loop!(
935 rcc.cr().read().msirdy().bit_is_set(),
936 Error::RegisterUnchanged
937 );
938
939 rcc.cr().modify(|_, w| unsafe {
940 w.msirange().bits(range as u8);
941 #[cfg(not(any(feature = "wb", feature = "wl")))]
942 w.msirgsel().bit(true);
943 w.msion().bit(true)
944 });
945 bounded_loop!(
947 rcc.cr().read().msirdy().bit_is_clear(),
948 Error::RegisterUnchanged
949 );
950 }
952 InputSrc::Hse(_) => {
953 rcc.cr().modify(|_, w| w.hseon().bit(true));
954 bounded_loop!(
956 rcc.cr().read().hserdy().bit_is_clear(),
957 Error::RegisterUnchanged
958 );
959 }
960 InputSrc::Hsi => {
961 rcc.cr().modify(|_, w| w.hsion().bit(true));
962
963 bounded_loop!(
964 rcc.cr().read().hsirdy().bit_is_clear(),
965 Error::RegisterUnchanged
966 );
967 }
968 #[cfg(not(feature = "c0"))]
969 InputSrc::Pll(pll_src) => {
970 match pll_src {
972 #[cfg(msi)]
973 PllSrc::Msi(range) => {
974 rcc.cr().modify(|_, w| unsafe {
975 w.msirange().bits(range as u8);
976 #[cfg(not(any(feature = "wb", feature = "wl")))]
977 w.msirgsel().bit(true);
978 w.msion().bit(true)
979 });
980
981 bounded_loop!(
982 rcc.cr().read().msirdy().bit_is_clear(),
983 Error::RegisterUnchanged
984 );
985 }
986 PllSrc::Hse(_) => {
987 rcc.cr().modify(|_, w| w.hseon().bit(true));
988
989 bounded_loop!(
990 rcc.cr().read().hserdy().bit_is_clear(),
991 Error::RegisterUnchanged
992 );
993 }
994 PllSrc::Hsi => {
995 rcc.cr().modify(|_, w| w.hsion().bit(true));
996
997 bounded_loop!(
998 rcc.cr().read().hsirdy().bit_is_clear(),
999 Error::RegisterUnchanged
1000 );
1001 }
1002 PllSrc::None => {}
1003 }
1004 }
1005 #[cfg(feature = "g0")]
1006 InputSrc::Lsi => {
1007 rcc.csr().modify(|_, w| w.lsion().bit(true));
1008
1009 bounded_loop!(
1010 rcc.csr().read().lsirdy().bit_is_clear(),
1011 Error::RegisterUnchanged
1012 );
1013 }
1014 #[cfg(feature = "g0")]
1015 InputSrc::Lse => {
1016 rcc.bdcr().modify(|_, w| w.lseon().bit(true));
1017
1018 bounded_loop!(
1019 rcc.bdcr().read().lserdy().bit_is_clear(),
1020 Error::RegisterUnchanged
1021 );
1022 }
1023 #[cfg(feature = "c0")]
1024 InputSrc::Lsi => {
1025 rcc.csr2().modify(|_, w| w.lsion().bit(true));
1026
1027 bounded_loop!(
1028 rcc.csr2().read().lsirdy().bit_is_clear(),
1029 Error::RegisterUnchanged
1030 );
1031 }
1032 #[cfg(feature = "c0")]
1033 InputSrc::Lse => {
1034 rcc.csr1().modify(|_, w| w.lseon().bit(true));
1035
1036 bounded_loop!(
1037 rcc.csr1().read().lserdy().bit_is_clear(),
1038 Error::RegisterUnchanged
1039 );
1040 }
1041 #[cfg(feature = "c071")]
1042 InputSrc::HsiUsb48 => {
1043 }
1045 }
1046
1047 rcc.cr().modify(|_, w| unsafe {
1048 #[cfg(feature = "c0")]
1049 w.hsidiv().bits(self.hsi_div as u8);
1050 #[cfg(feature = "c071")]
1051 w.sysdiv().bits(self.sys_div as u8);
1052 #[cfg(feature = "wl")]
1053 return w.hsebyppwr().bit(self.hse_bypass);
1054 #[cfg(not(feature = "wl"))]
1055 w.hsebyp().bit(self.hse_bypass)
1056 });
1057
1058 rcc.cfgr().modify(|_, w| unsafe {
1059 w.sw().bits(self.input_src.bits());
1060 w.hpre().bits(self.hclk_prescaler as u8);
1061 #[cfg(not(any(feature = "g0", feature = "c0")))]
1062 w.ppre2().bits(self.apb2_prescaler as u8); #[cfg(any(feature = "l4", feature = "l5"))]
1064 w.stopwuck().bit(self.stop_wuck as u8 != 0);
1065 #[cfg(not(any(feature = "g0", feature = "c0")))]
1066 return w.ppre1().bits(self.apb1_prescaler as u8); #[cfg(any(feature = "g0", feature = "c0"))]
1068 return w.ppre().bits(self.apb1_prescaler as u8);
1069 });
1070
1071 #[cfg(feature = "wb")]
1073 rcc.extcfgr().modify(|_, w| unsafe {
1074 w.c2hpre().bits(self.hclk2_prescaler as u8);
1075 w.shdhpre().bits(self.hclk4_prescaler as u8)
1076 });
1077
1078 #[cfg(feature = "wl")]
1079 rcc.extcfgr()
1080 .modify(|_, w| unsafe { w.shdhpre().bits(self.hclk3_prescaler as u8) });
1081
1082 rcc.cr().modify(|_, w| w.csson().bit(self.security_system));
1083
1084 #[cfg(not(feature = "c0"))]
1087 if let InputSrc::Pll(pll_src) = self.input_src {
1088 rcc.cr().modify(|_, w| w.pllon().clear_bit());
1090 bounded_loop!(
1093 rcc.cr().read().pllrdy().bit_is_set(),
1094 Error::RegisterUnchanged
1095 );
1096
1097 rcc.pllcfgr().modify(|_, w| unsafe {
1098 w.pllsrc().bits(pll_src.bits());
1099 w.pllren().bit(true);
1100 w.pllqen().bit(self.pll.pllq_en);
1101 w.pllpen().bit(self.pll.pllp_en);
1102 w.plln().bits(self.pll.divn);
1103 w.pllm().bits(self.pll.divm as u8);
1104 w.pllr().bits(self.pll.divr as u8);
1105 #[cfg(not(any(
1106 feature = "wb",
1107 feature = "wl",
1108 feature = "l4x5",
1109 feature = "l4x3",
1110 feature = "g0"
1111 )))]
1112 w.pllpdiv().bits(self.pll.pdiv);
1113 #[cfg(not(any(feature = "wb", feature = "wl", feature = "g0")))]
1114 w.pllp().bit(self.pll.divp as u8 != 0);
1115 #[cfg(any(feature = "wb", feature = "wl", feature = "g0"))]
1116 w.pllp().bits(self.pll.divp as u8);
1117 w.pllq().bits(self.pll.divq as u8)
1118 });
1119
1120 rcc.pllcfgr().modify(|_, w| {
1121 w.pllpen().bit(true);
1122 w.pllqen().bit(true);
1123 w.pllren().bit(true)
1124 });
1125
1126 cfg_if! {
1127 if #[cfg(all(any(feature = "l4", feature = "l5"), not(feature = "l412")))] {
1129 rcc.pllsai1cfgr().modify(|_, w| unsafe {
1130 w.pllsai1ren().bit(self.pllsai1.pllr_en);
1131 w.pllsai1qen().bit(self.pllsai1.pllq_en);
1132 w.pllsai1pen().bit(self.pllsai1.pllp_en);
1133 w.pllsai1n().bits(self.pllsai1.divn);
1134 #[cfg(not(any(feature = "l4x5", feature = "l4x3")))]
1135 w.pllsai1pdiv().bits(self.pllsai1.pdiv);
1136 w.pllsai1r().bits(self.pllsai1.divr as u8);
1137 w.pllsai1q().bits(self.pllsai1.divq as u8);
1138 w.pllsai1p().bit(self.pllsai1.divp as u8 != 0)
1139 });
1140
1141 #[cfg(any(feature = "l4x5", feature = "l4x6"))]
1142 rcc.pllsai2cfgr().modify(|_, w| unsafe {
1143 w.pllsai2ren().bit(self.pllsai1.pllr_en);
1144 w.pllsai2pen().bit(self.pllsai1.pllp_en);
1146 w.pllsai2n().bits(self.pllsai1.divn);
1147 #[cfg(not(feature = "l4x5"))]
1148 w.pllsai2pdiv().bits(self.pllsai1.pdiv);
1149 w.pllsai2r().bits(self.pllsai1.divr as u8);
1150 w.pllsai2p().bit(self.pllsai1.divp as u8 != 0)
1152 });
1153
1154 } else if #[cfg(feature = "wb")] {
1155 rcc.pllsai1cfgr().modify(|_, w| unsafe {
1156 w.pllren().bit(self.pllsai1.pllr_en);
1157 w.pllqen().bit(self.pllsai1.pllq_en);
1158 w.pllpen().bit(self.pllsai1.pllp_en);
1159 w.plln().bits(self.pllsai1.divn);
1160 w.pllr().bits(self.pllsai1.divr as u8);
1161 w.pllq().bits(self.pllsai1.divq as u8);
1162 w.pllp().bits(self.pllsai1.divp as u8)
1163 });
1164 }
1165 }
1166
1167 rcc.cr().modify(|_, w| w.pllon().bit(true));
1168 bounded_loop!(
1169 rcc.cr().read().pllrdy().bit_is_clear(),
1170 Error::RegisterUnchanged
1171 );
1172
1173 cfg_if! {
1174 if #[cfg(not(any(feature = "g0", feature = "g4", feature = "wl", feature = "l412")))] {
1175 if self.pllsai1.enabled {
1176 rcc.cr().modify(|_, w| w.pllsai1on().bit(true));
1177 bounded_loop!(
1178 rcc.cr().read().pllsai1rdy().bit_is_clear(),
1179 Error::RegisterUnchanged
1180 );
1181 }
1182 #[cfg(any(feature = "l4x5", feature = "l4x6",))]
1183 if self.pllsai2.enabled {
1184 rcc.cr().modify(|_, w| w.pllsai2on().bit(true));
1185 bounded_loop!(
1186 rcc.cr().read().pllsai2rdy().bit_is_clear(),
1187 Error::RegisterUnchanged
1188 );
1189 }
1190 }
1191 }
1192 }
1193
1194 #[cfg(not(any(feature = "g0", feature = "wl", feature = "c0")))]
1197 if self.hsi48_on {
1198 rcc.crrcr().modify(|_, w| w.hsi48on().bit(true));
1199 bounded_loop!(
1200 rcc.crrcr().read().hsi48rdy().bit_is_clear(),
1201 Error::RegisterUnchanged
1202 );
1203 }
1204
1205 #[cfg(feature = "c071")]
1206 if self.hsi48_on {
1207 rcc.cr().modify(|_, w| w.hsiusb48on().bit(true));
1208 bounded_loop!(
1209 rcc.cr().read().hsiusb48rdy().bit_is_clear(),
1210 Error::RegisterUnchanged
1211 );
1212 }
1213
1214 #[cfg(not(any(
1217 feature = "g0",
1218 feature = "g4",
1219 feature = "wl",
1220 feature = "l5",
1221 feature = "l412",
1222 feature = "c0",
1223 )))]
1224 rcc.ccipr()
1225 .modify(|_, w| unsafe { w.sai1sel().bits(self.sai1_src as u8) });
1226
1227 #[cfg(feature = "g4")]
1228 rcc.ccipr()
1229 .modify(|_, w| unsafe { w.fdcansel().bits(self.can_src as u8) });
1230
1231 #[cfg(feature = "g0c1")]
1232 rcc.ccipr2()
1233 .modify(|_, w| unsafe { w.fdcansel().bits(self.can_src as u8) });
1234
1235 #[cfg(feature = "l5")]
1236 rcc.ccipr2()
1237 .modify(|_, w| unsafe { w.sai1sel().bits(self.sai1_src as u8) });
1238
1239 #[cfg(any(feature = "l4", feature = "g4"))]
1240 rcc.ccipr()
1241 .modify(|_, w| unsafe { w.clk48sel().bits(self.clk48_src as u8) });
1242
1243 #[cfg(feature = "l5")]
1244 rcc.ccipr1()
1245 .modify(|_, w| unsafe { w.clk48msel().bits(self.clk48_src as u8) });
1246
1247 #[cfg(feature = "c071")]
1248 rcc.ccipr2()
1251 .modify(|_, w| unsafe { w.usbsel().bit(self.clk48_src as u8 != 0) });
1252
1253 #[cfg(not(any(feature = "f", feature = "l", feature = "g0", feature = "c0")))]
1254 rcc.ccipr()
1255 .modify(|_, w| unsafe { w.lpuart1sel().bits(self.lpuart_src as u8) });
1257
1258 cfg_if! {
1260 if #[cfg(any(feature = "l4", feature = "l5"))] {
1261 match self.input_src {
1262 InputSrc::Msi(_) => (),
1263 InputSrc::Pll(pll_src) => {
1264 match pll_src {
1265 PllSrc::Msi(_) => (),
1266 _ => {
1267 rcc.cr().modify(|_, w| w.msion().clear_bit());
1268 }
1269 }
1270 }
1271 _ => {
1272 rcc.cr().modify(|_, w| w.msion().clear_bit());
1273 }
1274 }
1275
1276 } else {
1277 match self.input_src {
1278 InputSrc::Hsi => (),
1279 #[cfg(not(feature = "c0"))]
1280 InputSrc::Pll(pll_src) => {
1281 match pll_src {
1282 PllSrc::Hsi => (),
1283 _ => {
1284 rcc.cr().modify(|_, w| w.hsion().clear_bit());
1285 }
1286 }
1287 }
1288 _ => {
1289 rcc.cr().modify(|_, w| w.hsion().clear_bit());
1290 }
1291 }
1292 }
1293 }
1294
1295 #[cfg(feature = "wb")]
1296 rcc.csr()
1297 .modify(|_, w| unsafe { w.rfwkpsel().bits(self.rf_wakeup_src as u8) });
1298
1299 Ok(())
1300 }
1301
1302 pub fn reselect_input(&self) -> Result<()> {
1305 let rcc = unsafe { &(*RCC::ptr()) };
1306
1307 match self.input_src {
1312 InputSrc::Hse(_) => {
1313 rcc.cr().modify(|_, w| w.hseon().bit(true));
1314 bounded_loop!(
1315 rcc.cr().read().hserdy().bit_is_clear(),
1316 Error::RegisterUnchanged
1317 );
1318
1319 rcc.cfgr()
1320 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1321 }
1322 #[cfg(not(feature = "c0"))]
1323 InputSrc::Pll(pll_src) => {
1324 match pll_src {
1326 PllSrc::Hse(_) => {
1327 rcc.cr().modify(|_, w| w.hseon().bit(true));
1328 bounded_loop!(
1329 rcc.cr().read().hserdy().bit_is_clear(),
1330 Error::RegisterUnchanged
1331 );
1332 }
1333 PllSrc::Hsi => {
1334 #[cfg(any(feature = "l4", feature = "l5"))]
1335 if let StopWuck::Msi = self.stop_wuck {
1337 rcc.cr().modify(|_, w| w.hsion().bit(true));
1338 bounded_loop!(
1339 rcc.cr().read().hsirdy().bit_is_clear(),
1340 Error::RegisterUnchanged
1341 );
1342 }
1343 }
1345 #[cfg(msi)]
1346 PllSrc::Msi(range) => {
1347 #[cfg(not(feature = "wb"))]
1349 rcc.cr().modify(|_, w| unsafe {
1350 w.msirange().bits(range as u8);
1351 w.msirgsel().bit(true)
1352 });
1353 #[cfg(feature = "wb")]
1354 rcc.cr()
1355 .modify(|_, w| unsafe { w.msirange().bits(range as u8) });
1356
1357 if let StopWuck::Hsi = self.stop_wuck {
1358 rcc.cr().modify(|_, w| w.msion().bit(true));
1359 bounded_loop!(
1360 rcc.cr().read().msirdy().bit_is_clear(),
1361 Error::RegisterUnchanged
1362 );
1363 }
1364 }
1365 PllSrc::None => (),
1366 }
1367
1368 rcc.cr().modify(|_, w| w.pllon().clear_bit());
1369 bounded_loop!(
1370 rcc.cr().read().pllrdy().bit_is_set(),
1371 Error::RegisterUnchanged
1372 );
1373
1374 rcc.cfgr()
1375 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1376
1377 rcc.cr().modify(|_, w| w.pllon().bit(true));
1378 bounded_loop!(
1379 rcc.cr().read().pllrdy().bit_is_clear(),
1380 Error::RegisterUnchanged
1381 );
1382 }
1383 InputSrc::Hsi => {
1384 {
1385 #[cfg(msi)]
1395 if let StopWuck::Msi = self.stop_wuck {
1396 rcc.cr().modify(|_, w| w.hsion().bit(true));
1397 bounded_loop!(
1398 rcc.cr().read().hsirdy().bit_is_clear(),
1399 Error::RegisterUnchanged
1400 );
1401
1402 rcc.cfgr()
1403 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1404 }
1405 }
1406 }
1407 #[cfg(msi)]
1408 InputSrc::Msi(range) => {
1409 #[cfg(not(feature = "wb"))]
1411 rcc.cr().modify(|_, w| unsafe {
1412 w.msirange().bits(range as u8);
1413 w.msirgsel().bit(true)
1414 });
1415 #[cfg(feature = "wb")]
1416 rcc.cr()
1417 .modify(|_, w| unsafe { w.msirange().bits(range as u8) });
1418
1419 if let StopWuck::Hsi = self.stop_wuck {
1420 rcc.cr().modify(|_, w| w.msion().bit(true));
1421 bounded_loop!(
1422 rcc.cr().read().msirdy().bit_is_clear(),
1423 Error::RegisterUnchanged
1424 );
1425
1426 rcc.cfgr()
1427 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1428 }
1429 }
1430 #[cfg(feature = "g0")]
1431 InputSrc::Lsi => {
1432 rcc.csr().modify(|_, w| w.lsion().bit(true));
1433 bounded_loop!(
1434 rcc.csr().read().lsirdy().bit_is_clear(),
1435 Error::RegisterUnchanged
1436 );
1437 rcc.cfgr()
1438 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1439 }
1440 #[cfg(feature = "c0")]
1441 InputSrc::Lsi => {
1442 rcc.csr2().modify(|_, w| w.lsion().bit(true));
1443 bounded_loop!(
1444 rcc.csr2().read().lsirdy().bit_is_clear(),
1445 Error::RegisterUnchanged
1446 );
1447 rcc.cfgr()
1448 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1449 }
1450 #[cfg(feature = "g0")]
1451 InputSrc::Lse => {
1452 rcc.bdcr().modify(|_, w| w.lseon().bit(true));
1453 bounded_loop!(
1454 rcc.bdcr().read().lserdy().bit_is_clear(),
1455 Error::RegisterUnchanged
1456 );
1457 rcc.cfgr()
1458 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1459 }
1460 #[cfg(feature = "c0")]
1461 InputSrc::Lse => {
1462 rcc.csr1().modify(|_, w| w.lseon().bit(true));
1463 bounded_loop!(
1464 rcc.csr1().read().lserdy().bit_is_clear(),
1465 Error::RegisterUnchanged
1466 );
1467 rcc.cfgr()
1468 .modify(|_, w| unsafe { w.sw().bits(self.input_src.bits()) });
1469 }
1470 #[cfg(feature = "c071")]
1471 InputSrc::HsiUsb48 => {
1472 }
1474 }
1475
1476 Ok(())
1477 }
1478
1479 #[cfg(any(feature = "l4", feature = "l5"))]
1480 pub fn change_msi_speed(&mut self, range: MsiRange) -> Result<()> {
1483 let rcc = unsafe { &(*RCC::ptr()) };
1486
1487 match self.input_src {
1488 InputSrc::Msi(_) => (),
1489 _ => panic!("Only change MSI speed using this function if MSI is the input source."),
1490 }
1491
1492 bounded_loop!(
1496 rcc.cr().read().msirdy().bit_is_clear(),
1497 Error::RegisterUnchanged
1498 );
1499
1500 rcc.cr()
1501 .modify(|_, w| unsafe { w.msirange().bits(range as u8).msirgsel().bit(true) });
1502
1503 self.input_src = InputSrc::Msi(range);
1505
1506 Ok(())
1507 }
1508
1509 #[cfg(msi)]
1510 pub fn enable_msi_48(&self) -> Result<()> {
1516 let rcc = unsafe { &(*RCC::ptr()) };
1517
1518 if let InputSrc::Msi(_) = self.input_src {
1519 panic!(
1520 "Only use this function to set up MSI as 48MHz oscillator\
1521 if not using it as the input source."
1522 );
1523 }
1524 if let InputSrc::Pll(pll_src) = self.input_src {
1525 if let PllSrc::Msi(_) = pll_src {
1526 panic!(
1527 "Only use this function to set up MSI as 48MHz oscillator \
1528 if not using it as the input source."
1529 );
1530 }
1531 }
1532
1533 rcc.cr().modify(|_, w| w.msion().clear_bit());
1534 bounded_loop!(
1535 rcc.cr().read().msirdy().bit_is_set(),
1536 Error::RegisterUnchanged
1537 );
1538
1539 #[cfg(not(feature = "wb"))]
1546 rcc.cr().modify(|_, w| unsafe {
1547 w.msirange()
1548 .bits(MsiRange::R48M as u8)
1549 .msirgsel()
1550 .bit(true)
1551 .msipllen()
1552 .bit(true)
1553 .msion()
1554 .bit(true)
1555 });
1556
1557 bounded_loop!(
1558 rcc.cr().read().msirdy().bit_is_clear(),
1559 Error::RegisterUnchanged
1560 );
1561
1562 Ok(())
1563 }
1564
1565 pub const fn sysclk(&self) -> u32 {
1567 let clk = match self.input_src {
1568 #[cfg(not(feature = "c0"))]
1569 InputSrc::Pll(pll_src) => {
1570 let input_freq = match pll_src {
1571 #[cfg(not(any(feature = "g0", feature = "g4")))]
1572 PllSrc::Msi(range) => range.value() as u32,
1573 PllSrc::Hsi => 16_000_000,
1574 PllSrc::Hse(freq) => freq,
1575 PllSrc::None => unimplemented!(),
1576 };
1577 input_freq / self.pll.divm.value() as u32 * self.pll.divn as u32
1578 / self.pll.divr.value() as u32
1579 }
1580
1581 #[cfg(msi)]
1582 InputSrc::Msi(range) => range.value() as u32,
1583 #[cfg(not(feature = "c0"))]
1584 InputSrc::Hsi => 16_000_000,
1585 #[cfg(feature = "c0")]
1586 InputSrc::Hsi => 48_000_000 / self.hsi_div.value(),
1587 InputSrc::Hse(freq) => freq,
1588 #[cfg(any(feature = "g0", feature = "c0"))]
1589 InputSrc::Lsi => 32_000,
1590 #[cfg(any(feature = "g0", feature = "c0"))]
1591 InputSrc::Lse => 32_768,
1592 #[cfg(feature = "c071")]
1593 InputSrc::HsiUsb48 => 48_000_000,
1594 };
1595 #[cfg(feature = "c071")]
1596 return clk / self.sys_div.value();
1597 #[cfg(not(feature = "c071"))]
1598 return clk;
1599 }
1600
1601 #[cfg(not(feature = "c0"))]
1609 pub fn pll_is_enabled(&self) -> bool {
1610 let rcc = unsafe { &(*RCC::ptr()) };
1611 rcc.cr().read().pllon().bit_is_set()
1612 }
1613
1614 pub const fn hclk(&self) -> u32 {
1616 self.sysclk() / self.hclk_prescaler.value() as u32
1617 }
1618
1619 pub const fn systick(&self) -> u32 {
1624 self.hclk()
1625 }
1626
1627 cfg_if! {
1628 if #[cfg(any(feature = "g0", feature = "wl"))] {
1629 pub const fn usb(&self) -> u32 {
1630 unimplemented!();
1632 }
1633 } else if #[cfg(any(feature = "g4", feature = "c071"))] {
1634 pub const fn usb(&self) -> u32 {
1635 48_000_000 }
1637 } else if #[cfg(feature = "c071")] {
1639 match self.clk48_src {
1640 Clk48Src::HsiUsb48 => 48_000_000,
1641 Clk48Src::Hse => unimplemented!(),
1642 }
1643 } else { #[cfg(not(feature = "c0"))]
1645 pub const fn usb(&self) -> u32 {
1646 match self.clk48_src {
1647 Clk48Src::Hsi48 => 48_000_000,
1648 Clk48Src::PllSai1 => unimplemented!(),
1649 Clk48Src::Pllq => unimplemented!(),
1650 Clk48Src::Msi => unimplemented!(),
1651 }
1652 }
1653 }
1654 }
1655
1656 pub const fn apb1(&self) -> u32 {
1658 self.hclk() / self.apb1_prescaler.value() as u32
1659 }
1660
1661 pub const fn apb1_timer(&self) -> u32 {
1663 if let ApbPrescaler::Div1 = self.apb1_prescaler {
1668 self.apb1()
1669 } else {
1670 self.apb1() * 2
1671 }
1672 }
1673
1674 cfg_if! {
1675 if #[cfg(feature = "g0")] {
1676 pub const fn apb2(&self) -> u32 {
1678 self.hclk() / self.apb1_prescaler.value() as u32
1679 }
1680
1681 pub const fn apb2_timer(&self) -> u32 {
1682 if let ApbPrescaler::Div1 = self.apb1_prescaler {
1683 self.apb2()
1684 } else {
1685 self.apb2() * 2
1686 }
1687 }
1688 } else if #[cfg(not(feature = "c0"))] {
1689 pub const fn apb2(&self) -> u32 {
1691 self.hclk() / self.apb2_prescaler.value() as u32
1692 }
1693
1694 pub const fn apb2_timer(&self) -> u32 {
1695 if let ApbPrescaler::Div1 = self.apb2_prescaler {
1696 self.apb2()
1697 } else {
1698 self.apb2() * 2
1699 }
1700 }
1701 }
1702 }
1703
1704 #[cfg(not(any(feature = "g0", feature = "g4", feature = "wl", feature = "c0")))]
1706 pub const fn sai1_speed(&self) -> u32 {
1707 let pll_src = match self.input_src {
1708 InputSrc::Msi(msi_rng) => PllSrc::Msi(msi_rng),
1709 InputSrc::Hsi => PllSrc::Hsi,
1710 InputSrc::Hse(freq) => PllSrc::Hse(freq),
1711 InputSrc::Pll(pll_src) => pll_src,
1712 };
1713
1714 let input_freq = match pll_src {
1716 PllSrc::Msi(range) => range.value() as u32,
1717 PllSrc::Hsi => 16_000_000,
1718 PllSrc::Hse(freq) => freq,
1719 PllSrc::None => unimplemented!(),
1720 };
1721
1722 match self.sai1_src {
1723 SaiSrc::PllSai1P => {
1724 input_freq / self.pll.divm.value() as u32 * self.pllsai1.divn as u32
1725 / self.pllsai1.pvalue() as u32
1726 }
1727 SaiSrc::Pllp => {
1728 input_freq / self.pll.divm.value() as u32 * self.pll.divn as u32
1729 / self.pll.pvalue() as u32
1730 }
1731 SaiSrc::Hsi => 16_000_000,
1732 SaiSrc::ExtClk => unimplemented!(),
1733 }
1734 }
1735
1736 #[cfg(feature = "c0")] pub fn validate_speeds(&self) -> Result<()> {
1738 Ok(()) }
1740
1741 #[cfg(not(feature = "c0"))] pub fn validate_speeds(&self) -> Result<()> {
1743 #[cfg(feature = "l4")]
1744 let max_clock = 80_000_000;
1745
1746 #[cfg(feature = "l5")]
1747 let max_clock = 110_000_000;
1748
1749 #[cfg(feature = "g0")]
1750 let max_clock = 64_000_000;
1751
1752 #[cfg(feature = "g4")]
1753 let max_clock = 170_000_000;
1754
1755 #[cfg(feature = "wb")]
1756 let max_clock = 64_000_000;
1757
1758 #[cfg(feature = "wl")]
1759 let max_clock = 48_000_000;
1760
1761 #[cfg(feature = "c0")]
1762 let max_clock = 48_000_000;
1763
1764 #[cfg(any(feature = "l4", feature = "l5", feature = "wb"))]
1770 if self.pll.divn < 7
1771 || self.pll.divn > 86
1772 || self.pllsai1.divn < 7
1773 || self.pllsai1.divn > 86
1774 {
1775 return Err(Error::RccError(RccError::Speed));
1776 }
1777
1778 if self.pll.pdiv == 1 {
1779 return Err(Error::RccError(RccError::Speed));
1780 }
1781
1782 #[cfg(not(any(feature = "g0", feature = "g4", feature = "wl", feature = "c0")))]
1783 if self.pllsai1.pdiv == 1 {
1784 return Err(Error::RccError(RccError::Speed));
1785 }
1786
1787 #[cfg(any(feature = "l4x5", feature = "l4x6"))]
1788 if self.pllsai2.pdiv == 1 {
1789 return Err(Error::RccError(RccError::Speed));
1790 }
1791
1792 #[cfg(feature = "g0")]
1793 if self.pll.divn < 9 || self.pll.divn > 86 {
1794 return Err(Error::RccError(RccError::Speed));
1795 }
1796
1797 #[cfg(feature = "g4")]
1798 if self.pll.divn < 8 || self.pll.divn > 127 {
1799 return Err(Error::RccError(RccError::Speed));
1800 }
1801
1802 if self.sysclk() > max_clock {
1810 return Err(Error::RccError(RccError::Speed));
1811 }
1812
1813 if self.hclk() > max_clock {
1816 return Err(Error::RccError(RccError::Speed));
1817 }
1818
1819 if self.apb1() > max_clock {
1820 return Err(Error::RccError(RccError::Speed));
1821 }
1822
1823 #[cfg(not(feature = "g0"))]
1824 if self.apb2() > max_clock {
1825 return Err(Error::RccError(RccError::Speed));
1826 }
1827
1828 Ok(())
1829 }
1830}
1831
1832impl Default for Clocks {
1833 fn default() -> Self {
1836 Self {
1837 #[cfg(not(feature = "c0"))]
1838 input_src: InputSrc::Pll(PllSrc::Hsi),
1839 #[cfg(feature = "c0")]
1840 input_src: InputSrc::Hsi,
1841 #[cfg(not(feature = "c0"))]
1842 pll: PllCfg::default(),
1843 #[cfg(not(any(feature = "g0", feature = "g4", feature = "wl", feature = "c0")))]
1844 pllsai1: PllCfg::disabled(),
1845 #[cfg(any(feature = "l4x5", feature = "l4x6"))]
1846 pllsai2: PllCfg::disabled(),
1847 hclk_prescaler: HclkPrescaler::Div1,
1848 #[cfg(feature = "wb")]
1849 hclk2_prescaler: HclkPrescaler::Div2,
1850 #[cfg(feature = "wl")]
1851 hclk3_prescaler: HclkPrescaler::Div1,
1852 #[cfg(feature = "wb")]
1853 hclk4_prescaler: HclkPrescaler::Div1,
1854 apb1_prescaler: ApbPrescaler::Div1,
1855 #[cfg(not(any(feature = "g0", feature = "c0")))]
1856 apb2_prescaler: ApbPrescaler::Div1,
1857 #[cfg(not(any(feature = "g0", feature = "wl", feature = "c0")))]
1858 clk48_src: Clk48Src::Hsi48,
1859 #[cfg(feature = "c071")]
1860 clk48_src: Clk48Src::HsiUsb48,
1861 #[cfg(not(any(feature = "f", feature = "l", feature = "g0", feature = "c0")))]
1862 lpuart_src: LpUartSrc::Pclk,
1863 hse_bypass: false,
1864 security_system: false,
1865 #[cfg(not(any(feature = "g0", feature = "wl", feature = "c011", feature = "c031")))]
1866 hsi48_on: false,
1867 #[cfg(any(feature = "l4", feature = "l5", feature = "wb", feature = "wl"))]
1868 stop_wuck: StopWuck::Msi,
1869 #[cfg(feature = "wb")]
1870 rf_wakeup_src: RfWakeupSrc::Lse,
1871 #[cfg(not(any(feature = "g0", feature = "g4", feature = "wl", feature = "c0")))]
1872 sai1_src: SaiSrc::Pllp,
1873 #[cfg(feature = "g4")]
1874 boost_mode: true,
1875 #[cfg(any(feature = "g0", feature = "g4"))]
1876 can_src: CanSrc::Pclk,
1877 #[cfg(feature = "c0")]
1878 hsi_div: HsiDiv::Div4, #[cfg(feature = "c071")]
1880 sys_div: SysDiv::Div1, }
1882 }
1883}
1884
1885#[cfg(any(feature = "l4", feature = "l5", feature = "g4", feature = "wb"))]
1886pub fn enable_crs(sync_src: CrsSyncSrc) {
1895 let crs = unsafe { &(*CRS::ptr()) };
1896 let rcc = unsafe { &(*RCC::ptr()) };
1897
1898 cfg_if! {
1900 if #[cfg(feature = "l4x5")] {
1901 let val = rcc.apb1enr1().read().bits();
1902 rcc.apb1enr1().write(|w| unsafe { w.bits(val | (1 << 24)) });
1903 } else {
1904 rcc.apb1enr1().modify(|_, w| w.crsen().bit(true));
1905 }
1906 }
1907
1908 crs.cfgr()
1909 .modify(|_, w| unsafe { w.syncsrc().bits(sync_src as u8) });
1910
1911 crs.cr().modify(|_, w| {
1912 w.autotrimen().bit(true);
1914 w.cen().bit(true)
1916 });
1917
1918 }