1use core::cmp::min;
4
5mod enable;
6
7#[cfg_attr(test, allow(unused_imports))]
8use micromath::F32Ext;
9
10use crate::pac::{rcc, FLASH, PWR, RCC};
11use fugit::{HertzU32 as Hertz, RateExtU32};
12
13const HSI_FREQUENCY: Hertz = Hertz::from_raw(16_000_000);
15
16pub trait RccExt {
18 fn constrain(self) -> Rcc;
20}
21
22impl RccExt for RCC {
23 fn constrain(self) -> Rcc {
24 Rcc {
25 ahb1: AHB1::new(),
26 ahb2: AHB2::new(),
27 ahb3: AHB3::new(),
28 apb1: APB1::new(),
29 apb2: APB2::new(),
30 bdcr: BDCR::new(),
31 cfgr: CFGR {
32 hse: None,
33 hclk: None,
34 sysclk: None,
35 pclk1: None,
36 pclk2: None,
37 lse: None,
38 lsi: None,
39 use_pll: false,
40 pll48clk: None,
41 pllm: 2,
42 plln: 50,
43 pllp: PLLP::Div2,
44 pllq: 2,
45 use_pllsai: false,
46 pllsain: 192,
47 pllsaip: PLLSAIP::Div2,
48 pllsaiq: 2,
49 use_plli2s: false,
50 plli2sr: 2,
51 plli2sq: 2,
52 plli2sn: 192,
53 mco1: MCO1::Hsi,
54 mco1pre: MCOPRE::Div1_no_div,
55 mco2: MCO2::Sysclk,
56 mco2pre: MCOPRE::Div1_no_div,
57 },
58 }
59 }
60}
61
62pub struct Rcc {
64 pub ahb1: AHB1,
66 pub ahb2: AHB2,
68 pub ahb3: AHB3,
70
71 pub apb1: APB1,
73 pub apb2: APB2,
75 pub bdcr: BDCR,
77 pub cfgr: CFGR,
78}
79
80macro_rules! bus_struct {
81 ($($busX:ident => ($EN:ident, $en:ident, $LPEN:ident, $lpen:ident, $RST:ident, $rst:ident, $doc:literal),)+) => {
82 $(
83 #[doc = $doc]
84 pub struct $busX {
85 _0: (),
86 }
87
88 impl $busX {
89 pub(crate) fn new() -> Self {
90 Self { _0: () }
91 }
92
93 pub(crate) fn enr(&self) -> &rcc::$EN {
94 unsafe { &(*RCC::ptr()).$en }
96 }
97
98 pub(crate) fn lpenr(&self) -> &rcc::$LPEN {
99 unsafe { &(*RCC::ptr()).$lpen }
101 }
102
103 pub(crate) fn rstr(&self) -> &rcc::$RST {
104 unsafe { &(*RCC::ptr()).$rst }
106 }
107 }
108 )+
109 };
110}
111
112bus_struct! {
113 APB1 => (APB1ENR, apb1enr, APB1LPENR, apb1lpenr, APB1RSTR, apb1rstr, "Advanced Peripheral Bus 1 (APB1) registers"),
114 APB2 => (APB2ENR, apb2enr, APB2LPENR, apb2lpenr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
115 AHB1 => (AHB1ENR, ahb1enr, AHB1LPENR, ahb1lpenr, AHB1RSTR, ahb1rstr, "Advanced High-performance Bus 1 (AHB1) registers"),
116 AHB2 => (AHB2ENR, ahb2enr, AHB2LPENR, ahb2lpenr, AHB2RSTR, ahb2rstr, "Advanced High-performance Bus 2 (AHB2) registers"),
117 AHB3 => (AHB3ENR, ahb3enr, AHB3LPENR, ahb3lpenr, AHB3RSTR, ahb3rstr, "Advanced High-performance Bus 3 (AHB3) registers"),
118}
119
120pub struct BDCR {
122 _0: (),
123}
124
125impl BDCR {
126 pub(crate) fn new() -> Self {
127 Self { _0: () }
128 }
129}
130
131#[derive(Clone, Copy, Debug, PartialEq, Eq)]
133pub enum HSEClockMode {
134 Oscillator,
136 Bypass,
138}
139
140#[derive(Clone, Copy, Debug, PartialEq, Eq)]
142pub struct HSEClock {
143 pub(crate) freq: Hertz,
145 mode: HSEClockMode,
147}
148
149impl HSEClock {
150 pub fn new(freq: Hertz, mode: HSEClockMode) -> Self {
157 let valid_range = match mode {
158 HSEClockMode::Oscillator => Hertz::MHz(4)..=Hertz::MHz(26),
160 HSEClockMode::Bypass => Hertz::MHz(1)..=Hertz::MHz(50),
162 };
163 assert!(valid_range.contains(&freq));
164
165 HSEClock { freq, mode }
166 }
167}
168
169#[derive(Clone, Copy, Debug, PartialEq, Eq)]
171pub enum LSEClockMode {
172 Oscillator,
174 Bypass,
177}
178
179#[derive(Clone, Copy, Debug, PartialEq, Eq)]
181pub struct LSEClock {
182 freq: Hertz,
184 mode: LSEClockMode,
186}
187
188impl LSEClock {
189 pub fn new(mode: LSEClockMode) -> Self {
191 LSEClock {
193 freq: 32_768.Hz(),
194 mode,
195 }
196 }
197}
198
199#[derive(Clone, Copy, Debug, PartialEq, Eq)]
201pub enum PLLP {
202 Div2 = 0b00,
203 Div4 = 0b01,
204 Div6 = 0b10,
205 Div8 = 0b11,
206}
207
208#[derive(Clone, Copy, Debug, PartialEq, Eq)]
212pub enum MCOPRE {
213 Div1_no_div,
215 Div2,
217 Div3,
219 Div4,
221 Div5,
223}
224
225#[derive(Clone, Copy, Debug, PartialEq, Eq)]
227pub enum PLL48CLK {
228 Pllq,
230 Pllsai,
232}
233
234#[derive(Clone, Copy, Debug, PartialEq, Eq)]
236pub enum PLLSAIP {
237 Div2 = 0b00,
238 Div4 = 0b01,
239 Div6 = 0b10,
240 Div8 = 0b11,
241}
242
243#[derive(Clone, Copy, Debug, PartialEq, Eq)]
247pub enum MCO1 {
248 Hsi,
250 Lse,
252 Hse,
254 Pll,
256}
257
258#[derive(Clone, Copy, Debug, PartialEq, Eq)]
262pub enum MCO2 {
263 Sysclk,
265 Plli2s,
267 Hse,
269 Pll,
271}
272
273#[derive(Clone, Copy, Debug, PartialEq, Eq)]
274enum VOSscale {
275 PwrScale1,
276 PwrScale2,
277 PwrScale3,
278}
279
280impl Default for VOSscale {
281 fn default() -> Self {
282 VOSscale::PwrScale3
283 }
284}
285
286#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
287struct InternalRCCConfig {
288 hpre: u8,
289 ppre1: u8,
290 ppre2: u8,
291 flash_waitstates: u8,
292 overdrive: bool,
293 vos_scale: VOSscale,
294}
295
296#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
297struct FreqRequest {
298 p: Option<(u32, u32)>,
299 q: Option<(u32, u32)>,
300}
301
302#[derive(Debug, PartialEq, Eq)]
304pub struct CFGR {
305 hse: Option<HSEClock>,
306 hclk: Option<u32>,
307 sysclk: Option<u32>,
308 pclk1: Option<u32>,
309 pclk2: Option<u32>,
310 lse: Option<LSEClock>,
311 lsi: Option<Hertz>,
312 use_pll: bool,
313 pll48clk: Option<PLL48CLK>,
314 pllm: u8,
315 plln: u16,
316 pllp: PLLP,
317 pllq: u8,
318 use_pllsai: bool,
319 pllsain: u16,
320 pllsaip: PLLSAIP,
321 pllsaiq: u8,
322 use_plli2s: bool,
323 plli2sr: u8,
324 plli2sq: u8,
325 plli2sn: u16,
326 mco1: MCO1,
327 mco1pre: MCOPRE,
328 mco2: MCO2,
329 mco2pre: MCOPRE,
330}
331
332impl CFGR {
333 pub fn hse(mut self, hse: HSEClock) -> Self {
335 self.hse = Some(hse);
336 self
337 }
338
339 pub fn hclk(mut self, freq: Hertz) -> Self {
347 assert!(freq.raw() <= 216_000_000);
348
349 self.hclk = Some(freq.raw());
350 self
351 }
352
353 pub fn sysclk(mut self, sysclk: Hertz) -> Self {
364 assert!((12_500_000..=216_000_000).contains(&sysclk.raw()));
365
366 self.sysclk = Some(sysclk.raw());
367 self
368 }
369
370 pub fn pclk1(mut self, freq: Hertz) -> Self {
378 assert!((12_500_000..=54_000_000).contains(&freq.raw()));
379
380 self.pclk1 = Some(freq.raw());
381 self
382 }
383
384 pub fn pclk2(mut self, freq: Hertz) -> Self {
392 assert!((12_500_000..=108_000_000).contains(&freq.raw()));
393
394 self.pclk2 = Some(freq.raw());
395 self
396 }
397
398 pub fn lse(mut self, lse: LSEClock) -> Self {
400 self.lse = Some(lse);
401 self
402 }
403
404 pub fn lsi(mut self) -> Self {
408 self.lsi = Some(32.kHz());
409 self
410 }
411
412 pub fn use_pll(mut self) -> Self {
416 self.use_pll = true;
417 self
418 }
419
420 pub fn use_pll48clk(mut self, pll48clk: PLL48CLK) -> Self {
422 self.pll48clk = Some(pll48clk);
423 self
424 }
425
426 pub fn pllm(mut self, pllm: u8) -> Self {
432 assert!((2..=63).contains(&pllm));
433 self.pllm = pllm;
434 self
435 }
436
437 pub fn plln(mut self, plln: u16) -> Self {
443 assert!((50..=432).contains(&plln));
444 self.plln = plln;
445 self
446 }
447
448 pub fn pllp(mut self, pllp: PLLP) -> Self {
450 self.pllp = pllp;
451 self
452 }
453
454 pub fn pllq(mut self, pllq: u8) -> Self {
459 assert!((2..=15).contains(&pllq));
460 self.pllq = pllq;
461 self
462 }
463
464 pub fn use_pllsai(mut self) -> Self {
466 self.use_pllsai = true;
467 self
468 }
469
470 pub fn pllsain(mut self, pllsain: u16) -> Self {
476 assert!((50..=432).contains(&pllsain));
477 self.pllsain = pllsain;
478 self
479 }
480
481 pub fn pllsaip(mut self, pllsaip: PLLSAIP) -> Self {
483 self.pllsaip = pllsaip;
484 self
485 }
486
487 pub fn pllsaiq(mut self, pllsaiq: u8) -> Self {
493 assert!((2..=15).contains(&pllsaiq));
494 self.pllsaiq = pllsaiq;
495 self
496 }
497
498 pub fn use_plli2s(mut self) -> Self {
500 self.use_plli2s = true;
501 self
502 }
503
504 pub fn plli2sn(mut self, plli2sn: u16) -> Self {
510 assert!((50..=432).contains(&plli2sn));
511 self.plli2sn = plli2sn;
512 self
513 }
514
515 pub fn plli2sq(mut self, plli2sq: u8) -> Self {
521 assert!((2..=15).contains(&plli2sq));
522 self.plli2sq = plli2sq;
523 self
524 }
525
526 pub fn plli2sr(mut self, plli2sr: u8) -> Self {
532 assert!((2..=7).contains(&plli2sr));
533 self.plli2sr = plli2sr;
534 self
535 }
536
537 pub fn mco1(mut self, mco1: MCO1) -> Self {
539 self.mco1 = mco1;
540 self
541 }
542
543 pub fn mco1pre(mut self, mco1pre: MCOPRE) -> Self {
545 self.mco1pre = mco1pre;
546 self
547 }
548
549 pub fn mco2(mut self, mco2: MCO2) -> Self {
551 self.mco2 = mco2;
552 self
553 }
554
555 pub fn mco2pre(mut self, mco2pre: MCOPRE) -> Self {
557 self.mco2pre = mco2pre;
558 self
559 }
560
561 const FIXED_POINT_LSHIFT: u32 = 31;
590 const FIXED_POINT_RSHIFT: u32 = 30;
591
592 const BASE_CLK_SHIFT: u32 = 4;
597
598 fn calculate_clocks(&self) -> (Clocks, InternalRCCConfig) {
600 let mut config = InternalRCCConfig::default();
601
602 let base_clk = u64::from(
603 match self.hse.as_ref() {
604 Some(hse) => hse.freq,
605 None => HSI_FREQUENCY,
606 }
607 .raw(),
608 ) >> Self::BASE_CLK_SHIFT;
609
610 let mut sysclk = base_clk << Self::BASE_CLK_SHIFT;
611
612 let mut pll48clk_valid = false;
613
614 if self.use_pll {
615 let one_over_m = ((1 << Self::FIXED_POINT_LSHIFT) / (self.pllm as u32) + 1) >> 1;
620 let one_over_p = ((1 << Self::FIXED_POINT_LSHIFT)
621 / match self.pllp {
622 PLLP::Div2 => 2u32,
623 PLLP::Div4 => 4u32,
624 PLLP::Div6 => 6u32,
625 PLLP::Div8 => 8u32,
626 }
627 + 1)
628 >> 1;
629 sysclk = (((base_clk as u64 * self.plln as u64 * one_over_m as u64)
630 >> Self::FIXED_POINT_RSHIFT)
631 * one_over_p as u64)
632 >> Self::FIXED_POINT_RSHIFT
633 << Self::BASE_CLK_SHIFT;
634 }
635
636 if let Some(pll48clk) = self.pll48clk {
638 match pll48clk {
639 PLL48CLK::Pllq => {
640 pll48clk_valid = {
641 let one_over_m =
642 ((1 << Self::FIXED_POINT_LSHIFT) / (self.pllm as u32) + 1) >> 1;
643 let one_over_q =
644 ((1 << Self::FIXED_POINT_LSHIFT) / (self.pllq as u32) + 1) >> 1;
645 let pll48clk = (((base_clk as u64 * self.plln as u64 * one_over_m as u64)
646 >> Self::FIXED_POINT_RSHIFT)
647 * one_over_q as u64)
648 >> Self::FIXED_POINT_RSHIFT
649 << Self::BASE_CLK_SHIFT;
650 (48_000_000 - 120_000..=48_000_000 + 120_000).contains(&pll48clk)
651 }
652 }
653 PLL48CLK::Pllsai => {
654 pll48clk_valid = {
655 if self.use_pllsai {
656 let one_over_m =
658 ((1 << Self::FIXED_POINT_LSHIFT) / (self.pllm as u32) + 1) >> 1;
659 let one_over_p = ((1 << Self::FIXED_POINT_LSHIFT)
660 / match self.pllsaip {
661 PLLSAIP::Div2 => 2u32,
662 PLLSAIP::Div4 => 4u32,
663 PLLSAIP::Div6 => 6u32,
664 PLLSAIP::Div8 => 8u32,
665 }
666 + 1)
667 >> 1;
668 let pll48clk =
669 (((base_clk as u64 * self.pllsain as u64 * one_over_m as u64)
670 >> Self::FIXED_POINT_RSHIFT)
671 * one_over_p as u64)
672 >> Self::FIXED_POINT_RSHIFT
673 << Self::BASE_CLK_SHIFT;
674 (48_000_000 - 120_000..=48_000_000 + 120_000).contains(&pll48clk)
675 } else {
676 false
677 }
678 }
679 }
680 }
681 }
682
683 assert!(sysclk <= 216_000_000);
685 let sysclk = sysclk as u32;
686
687 let mut hclk: u32 = min(sysclk, self.hclk.unwrap_or(sysclk));
692
693 let hpre_val: f32 = (sysclk as f32 / hclk as f32).ceil();
695
696 let (hpre_val, hpre): (f32, u8) = match hpre_val as u32 {
699 0 => unreachable!(),
700 1 => (1.0, 0b000),
701 2 => (2.0, 0b1000),
702 3..=5 => (4.0, 0b1001),
703 6..=11 => (8.0, 0b1010),
704 12..=39 => (16.0, 0b1011),
705 40..=95 => (64.0, 0b1100),
706 96..=191 => (128.0, 0b1101),
707 192..=383 => (256.0, 0b1110),
708 _ => (512.0, 0b1111),
709 };
710 config.hpre = hpre;
711 hclk = (sysclk as f32 / hpre_val).floor() as u32;
713
714 let max_pclk1 = if sysclk <= 180_000_000 {
718 45_000_000
719 } else {
720 54_000_000
721 };
722 let mut pclk1: u32 = min(max_pclk1, self.pclk1.unwrap_or(hclk));
723 let max_pclk2 = if sysclk <= 180_000_000 {
727 90_000_000
728 } else {
729 108_000_000
730 };
731 let mut pclk2: u32 = min(max_pclk2, self.pclk2.unwrap_or(hclk));
732
733 let mut ppre1_val: u32 = (hclk as f32 / pclk1 as f32).ceil() as u32;
735 config.ppre1 = match ppre1_val {
736 0 => unreachable!(),
737 1 => {
738 ppre1_val = 1;
739 0b000
740 }
741 2 => {
742 ppre1_val = 2;
743 0b100
744 }
745 3..=6 => {
746 ppre1_val = 4;
747 0b101
748 }
749 7..=12 => {
750 ppre1_val = 8;
751 0b110
752 }
753 _ => {
754 ppre1_val = 16;
755 0b111
756 }
757 };
758 pclk1 = hclk / ppre1_val;
760
761 let mut ppre2_val: u32 = (hclk as f32 / pclk2 as f32).ceil() as u32;
763 config.ppre2 = match ppre2_val {
764 0 => unreachable!(),
765 1 => {
766 ppre2_val = 1;
767 0b000
768 }
769 2 => {
770 ppre2_val = 2;
771 0b100
772 }
773 3..=6 => {
774 ppre2_val = 4;
775 0b101
776 }
777 7..=12 => {
778 ppre2_val = 8;
779 0b110
780 }
781 _ => {
782 ppre2_val = 16;
783 0b111
784 }
785 };
786 pclk2 = hclk / ppre2_val;
788
789 let timclk1 = if ppre1_val == 1 { pclk1 } else { 2 * pclk1 };
791 let timclk2 = if ppre2_val == 1 { pclk2 } else { 2 * pclk2 };
792
793 config.flash_waitstates = if sysclk <= 30_000_000 {
795 0b0000
796 } else if sysclk <= 60_000_000 {
797 0b0001
798 } else if sysclk <= 90_000_000 {
799 0b0010
800 } else if sysclk <= 120_000_000 {
801 0b0011
802 } else if sysclk <= 150_000_000 {
803 0b0100
804 } else if sysclk <= 180_000_000 {
805 0b0101
806 } else if sysclk <= 210_000_000 {
807 0b0110
808 } else {
809 0b0111
810 };
811 config.vos_scale = if sysclk <= 144_000_000 {
815 VOSscale::PwrScale3
816 } else if sysclk <= 168_000_000 {
817 VOSscale::PwrScale2
818 } else {
819 VOSscale::PwrScale1
820 };
821 config.overdrive = sysclk > 180_000_000;
824
825 let clocks = Clocks {
826 hclk: hclk.Hz(),
827 pclk1: pclk1.Hz(),
828 pclk2: pclk2.Hz(),
829 sysclk: sysclk.Hz(),
830 timclk1: timclk1.Hz(),
831 timclk2: timclk2.Hz(),
832 pll48clk_valid,
833 hse: self.hse.map(|hse| hse.freq),
834 lse: self.lse.map(|lse| lse.freq),
835 lsi: self.lsi,
836 };
837
838 (clocks, config)
839 }
840
841 fn calculate_mnpq(
843 f_pll_clock_input: u32,
844 freq_req: FreqRequest,
845 ) -> Option<(u32, u32, Option<u32>, Option<u32>)> {
846 let mut m = 2;
847 let mut n = 432;
848 let mut p = None;
849 let mut q = None;
850
851 if freq_req.p.is_none() && freq_req.q.is_none() {
852 return None;
853 }
854
855 loop {
856 if m > 63 {
857 return None;
858 }
859 let f_vco_input = f_pll_clock_input / m;
860 if f_vco_input < 1_000_000 {
861 return None;
862 }
863 if f_vco_input > 2_000_000 || n < 50 {
864 m += 1;
865 n = 432;
866 continue;
867 }
868 let one_over_m = ((1 << Self::FIXED_POINT_LSHIFT) / (m as u32) + 1) >> 1;
870 let f_vco_clock = (((f_pll_clock_input as u64 >> Self::BASE_CLK_SHIFT)
871 * n as u64
872 * one_over_m as u64)
873 >> Self::FIXED_POINT_RSHIFT
874 << Self::BASE_CLK_SHIFT) as u32;
875 if f_vco_clock < 50_000_000 {
876 m += 1;
877 n = 432;
878 continue;
879 }
880 if f_vco_clock > 432_000_000 {
881 n -= 1;
882 continue;
883 }
884
885 if let Some((p_freq_min, p_freq_max)) = freq_req.p {
886 let mut div = None;
887 for div_p in &[2, 4, 6, 8] {
888 let f_pll_clock_output = f_vco_clock / div_p;
889 if f_pll_clock_output >= p_freq_min && f_pll_clock_output <= p_freq_max {
890 div = Some(*div_p)
891 }
892 }
893 if div.is_some() {
894 p = div;
895 if freq_req.q.is_none() {
896 break;
897 }
898 } else {
899 n -= 1;
900 continue;
901 }
902 }
903
904 if let Some((q_freq_min, q_freq_max)) = freq_req.q {
905 let mut div = None;
906 for div_q in 2..=15 {
907 let f_usb_clock_output = f_vco_clock / div_q;
908 if f_usb_clock_output >= q_freq_min && f_usb_clock_output <= q_freq_max {
909 div = Some(div_q)
910 }
911 }
912 if div.is_some() {
913 q = div;
914 break;
915 } else {
916 n -= 1;
917 continue;
918 }
919 }
920 }
921
922 Some((m, n, p, q))
923 }
924
925 fn pll_configure(&mut self) {
926 let base_clk = match self.hse.as_ref() {
927 Some(hse) => hse.freq,
928 None => HSI_FREQUENCY,
929 }
930 .raw()
931 >> Self::BASE_CLK_SHIFT;
932
933 let sysclk = if let Some(clk) = self.sysclk {
934 clk
935 } else {
936 base_clk << Self::BASE_CLK_SHIFT
937 };
938
939 let p = if base_clk << Self::BASE_CLK_SHIFT == sysclk {
940 None
941 } else {
942 Some((sysclk - 1, sysclk + 1))
943 };
944
945 let q = if let Some(PLL48CLK::Pllq) = self.pll48clk {
946 Some((48_000_000 - 120_000, 48_000_000 + 120_000))
947 } else {
948 None
949 };
950
951 if p.is_none() && q.is_none() {
952 self.use_pll = false;
954 return;
955 }
956
957 let one_over_m = ((1 << Self::FIXED_POINT_LSHIFT) / (self.pllm as u32) + 1) >> 1;
960 let one_over_p = ((1 << Self::FIXED_POINT_LSHIFT)
961 / match self.pllp {
962 PLLP::Div2 => 2u32,
963 PLLP::Div4 => 4u32,
964 PLLP::Div6 => 6u32,
965 PLLP::Div8 => 8u32,
966 }
967 + 1)
968 >> 1;
969 let p_ok = (sysclk as u64)
970 == (((base_clk as u64 * self.plln as u64 * one_over_m as u64)
971 >> Self::FIXED_POINT_RSHIFT)
972 * one_over_p as u64)
973 >> Self::FIXED_POINT_RSHIFT
974 << Self::BASE_CLK_SHIFT;
975 if p_ok && q.is_none() {
976 return;
977 }
978
979 if let Some((m, n, p, q)) =
980 CFGR::calculate_mnpq(base_clk << Self::BASE_CLK_SHIFT, FreqRequest { p, q })
981 {
982 self.pllm = m as u8;
983 self.plln = n as u16;
984 if let Some(p) = p {
985 self.use_pll = true;
986 self.pllp = match p {
987 2 => PLLP::Div2,
988 4 => PLLP::Div4,
989 6 => PLLP::Div6,
990 8 => PLLP::Div8,
991 _ => unreachable!(),
992 };
993 }
994 if let Some(q) = q {
995 self.pllq = q as u8;
996 }
997 } else {
998 panic!("couldn't calculate {} from {}", sysclk, base_clk);
999 }
1000 }
1001
1002 pub fn set_defaults(self) -> Self {
1006 self.sysclk(216.MHz())
1007 }
1008
1009 pub fn freeze(mut self) -> Clocks {
1019 let flash = unsafe { &(*FLASH::ptr()) };
1020 let rcc = unsafe { &(*RCC::ptr()) };
1021 let pwr = unsafe { &(*PWR::ptr()) };
1022
1023 self.pll_configure();
1024
1025 let (clocks, config) = self.calculate_clocks();
1026
1027 rcc.cr.modify(|_, w| w.hsion().set_bit());
1031 while rcc.cr.read().hsirdy().bit_is_clear() {}
1032 rcc.cfgr.modify(|_, w| w.sw().hsi());
1034
1035 if self.hse.is_some() {
1037 match self.hse.as_ref().unwrap().mode {
1039 HSEClockMode::Bypass => rcc.cr.modify(|_, w| w.hsebyp().bypassed()),
1040 HSEClockMode::Oscillator => rcc.cr.modify(|_, w| w.hsebyp().not_bypassed()),
1041 }
1042 rcc.cr.modify(|_, w| w.hseon().on());
1044 while rcc.cr.read().hserdy().is_not_ready() {}
1045 }
1046
1047 if self.use_pll || self.pll48clk.is_some() {
1049 rcc.cr.modify(|_, w| w.pllon().off());
1054
1055 rcc.pllcfgr.modify(|_, w| unsafe {
1056 w.pllm().bits(self.pllm);
1057 w.plln().bits(self.plln);
1058 w.pllp().bits(self.pllp as u8);
1059 w.pllq().bits(self.pllq);
1060 w.pllsrc().bit(self.hse.is_some())
1061 });
1062
1063 rcc.apb1enr.modify(|_, w| w.pwren().set_bit());
1065
1066 pwr.cr1.modify(|_, w| match config.vos_scale {
1067 VOSscale::PwrScale3 => w.vos().scale3(),
1068 VOSscale::PwrScale2 => w.vos().scale2(),
1069 VOSscale::PwrScale1 => w.vos().scale1(),
1070 });
1071
1072 rcc.cr.modify(|_, w| w.pllon().on());
1074
1075 while rcc.cr.read().pllrdy().is_not_ready() {}
1077
1078 if config.overdrive {
1080 pwr.cr1.modify(|_, w| w.oden().set_bit());
1083
1084 while !pwr.csr1.read().odrdy().bit_is_set() {}
1086
1087 pwr.cr1.modify(|_, w| w.odswen().set_bit());
1089
1090 while !pwr.csr1.read().odswrdy().bit_is_set() {}
1092 }
1093 }
1094
1095 if self.lse.is_some() {
1097 match self.lse.as_ref().unwrap().mode {
1099 LSEClockMode::Bypass => rcc.bdcr.modify(|_, w| w.lsebyp().bypassed()),
1100 LSEClockMode::Oscillator => rcc.bdcr.modify(|_, w| w.lsebyp().not_bypassed()),
1101 }
1102 rcc.bdcr.modify(|_, w| w.lseon().on());
1104 while rcc.bdcr.read().lserdy().is_not_ready() {}
1105 }
1106
1107 if self.lsi.is_some() {
1108 rcc.csr.modify(|_, w| w.lsion().on());
1109 while rcc.csr.read().lsirdy().is_not_ready() {}
1110 }
1111
1112 if self.use_pllsai {
1113 let pllsain_freq = match self.hse.as_ref() {
1114 Some(hse) => hse.freq.raw() as u64 / self.pllm as u64 * self.pllsain as u64,
1115 None => 16_000_000 / self.pllm as u64 * self.pllsain as u64,
1116 };
1117 let pllsaip_freq = pllsain_freq
1118 / match self.pllsaip {
1119 PLLSAIP::Div2 => 2,
1120 PLLSAIP::Div4 => 4,
1121 PLLSAIP::Div6 => 6,
1122 PLLSAIP::Div8 => 8,
1123 };
1124 assert!((192_000_000..=432_000_000).contains(&pllsain_freq));
1130 assert!(pllsaip_freq <= 48_000_000);
1131
1132 rcc.pllsaicfgr.modify(|_, w| unsafe {
1133 w.pllsain().bits(self.pllsain);
1134 w.pllsaip().bits(self.pllsaip as u8);
1135 w.pllsaiq().bits(self.pllsaiq)
1136 });
1137 rcc.cr.modify(|_, w| w.pllsaion().on());
1138 }
1139
1140 if let Some(pll48clk) = self.pll48clk {
1141 match pll48clk {
1142 PLL48CLK::Pllq => rcc.dckcfgr2.modify(|_, w| w.ck48msel().bit(false)),
1143 PLL48CLK::Pllsai => rcc.dckcfgr2.modify(|_, w| w.ck48msel().bit(true)),
1144 }
1145 }
1146
1147 if self.use_plli2s {
1148 let plli2sn_freq = match self.hse.as_ref() {
1149 Some(hse) => hse.freq.raw() as u64 / self.pllm as u64 * self.plli2sn as u64,
1150 None => 16_000_000 / self.pllm as u64 * self.plli2sn as u64,
1151 };
1152 let plli2sr_freq = plli2sn_freq / self.plli2sr as u64;
1153 let plli2sq_freq = plli2sn_freq / self.plli2sq as u64;
1154
1155 assert!((192_000_000..=432_000_000).contains(&plli2sn_freq));
1156 assert!(plli2sr_freq <= 216_000_000);
1157 assert!(plli2sq_freq <= 216_000_000);
1158
1159 rcc.plli2scfgr.modify(|_, w| unsafe {
1160 w.plli2sn().bits(self.plli2sn);
1161 w.plli2sr().bits(self.plli2sr);
1162 w.plli2sq().bits(self.plli2sq)
1163 });
1164 rcc.cr.modify(|_, w| w.plli2son().on());
1165 }
1166
1167 rcc.cfgr.modify(|_, w| {
1168 w.mco1()
1169 .variant(self.mco1.into())
1170 .mco1pre()
1171 .variant(self.mco1pre.into());
1172 w.mco2()
1173 .variant(self.mco2.into())
1174 .mco2pre()
1175 .variant(self.mco2pre.into())
1176 });
1177
1178 flash
1179 .acr
1180 .write(|w| w.latency().bits(config.flash_waitstates));
1181
1182 rcc.cfgr.modify(|_, w| unsafe {
1184 w.ppre1()
1185 .bits(config.ppre1)
1186 .ppre2()
1187 .bits(config.ppre2)
1188 .hpre()
1189 .bits(config.hpre)
1190 });
1191
1192 if self.use_pll {
1194 rcc.cfgr.modify(|_, w| w.sw().pll());
1195 while !rcc.cfgr.read().sws().is_pll() {}
1196 } else if self.hse.is_some() {
1197 rcc.cfgr.modify(|_, w| w.sw().hse());
1198 while !rcc.cfgr.read().sws().is_hse() {}
1199 } else {
1200 rcc.cfgr.modify(|_, w| w.sw().hsi());
1201 while !rcc.cfgr.read().sws().is_hsi() {}
1202 }
1203
1204 cortex_m::asm::delay(16);
1207
1208 clocks
1209 }
1210}
1211
1212#[derive(Clone, Copy, Debug)]
1216pub struct Clocks {
1217 hclk: Hertz,
1218 pclk1: Hertz,
1219 pclk2: Hertz,
1220 sysclk: Hertz,
1221 timclk1: Hertz,
1222 timclk2: Hertz,
1223 pll48clk_valid: bool,
1224 hse: Option<Hertz>,
1225 lse: Option<Hertz>,
1226 lsi: Option<Hertz>,
1227}
1228
1229impl Clocks {
1230 pub fn hclk(&self) -> Hertz {
1232 self.hclk
1233 }
1234
1235 pub fn pclk1(&self) -> Hertz {
1237 self.pclk1
1238 }
1239
1240 pub fn pclk2(&self) -> Hertz {
1242 self.pclk2
1243 }
1244
1245 pub fn sysclk(&self) -> Hertz {
1247 self.sysclk
1248 }
1249
1250 pub fn timclk1(&self) -> Hertz {
1252 self.timclk1
1253 }
1254
1255 pub fn timclk2(&self) -> Hertz {
1257 self.timclk2
1258 }
1259
1260 pub fn is_pll48clk_valid(&self) -> bool {
1263 self.pll48clk_valid
1265 }
1266
1267 pub fn hse(&self) -> Option<Hertz> {
1269 self.hse
1270 }
1271
1272 pub fn lse(&self) -> Option<Hertz> {
1274 self.lse
1275 }
1276
1277 pub fn lsi(&self) -> Option<Hertz> {
1279 self.lsi
1280 }
1281}
1282
1283pub trait BusClock {
1285 fn clock(clocks: &Clocks) -> Hertz;
1287}
1288
1289pub trait BusTimerClock {
1291 fn timer_clock(clocks: &Clocks) -> Hertz;
1293}
1294
1295impl<T> BusClock for T
1296where
1297 T: RccBus,
1298 T::Bus: BusClock,
1299{
1300 fn clock(clocks: &Clocks) -> Hertz {
1301 T::Bus::clock(clocks)
1302 }
1303}
1304
1305impl<T> BusTimerClock for T
1306where
1307 T: RccBus,
1308 T::Bus: BusTimerClock,
1309{
1310 fn timer_clock(clocks: &Clocks) -> Hertz {
1311 T::Bus::timer_clock(clocks)
1312 }
1313}
1314
1315impl BusClock for AHB1 {
1316 fn clock(clocks: &Clocks) -> Hertz {
1317 clocks.hclk
1318 }
1319}
1320
1321impl BusClock for AHB2 {
1322 fn clock(clocks: &Clocks) -> Hertz {
1323 clocks.hclk
1324 }
1325}
1326
1327impl BusClock for AHB3 {
1328 fn clock(clocks: &Clocks) -> Hertz {
1329 clocks.hclk
1330 }
1331}
1332
1333impl BusClock for APB1 {
1334 fn clock(clocks: &Clocks) -> Hertz {
1335 clocks.pclk1
1336 }
1337}
1338
1339impl BusClock for APB2 {
1340 fn clock(clocks: &Clocks) -> Hertz {
1341 clocks.pclk2
1342 }
1343}
1344
1345impl BusTimerClock for APB1 {
1346 fn timer_clock(clocks: &Clocks) -> Hertz {
1347 clocks.timclk1
1348 }
1349}
1350
1351impl BusTimerClock for APB2 {
1352 fn timer_clock(clocks: &Clocks) -> Hertz {
1353 clocks.timclk2
1354 }
1355}
1356
1357impl From<MCO1> for crate::pac::rcc::cfgr::MCO1_A {
1358 fn from(input: MCO1) -> Self {
1359 match input {
1360 MCO1::Hsi => Self::Hsi,
1361 MCO1::Lse => Self::Lse,
1362 MCO1::Hse => Self::Hse,
1363 MCO1::Pll => Self::Pll,
1364 }
1365 }
1366}
1367
1368impl From<MCO2> for crate::pac::rcc::cfgr::MCO2_A {
1369 fn from(input: MCO2) -> Self {
1370 match input {
1371 MCO2::Sysclk => Self::Sysclk,
1372 MCO2::Plli2s => Self::Plli2s,
1373 MCO2::Hse => Self::Hse,
1374 MCO2::Pll => Self::Pll,
1375 }
1376 }
1377}
1378
1379impl From<MCOPRE> for crate::pac::rcc::cfgr::MCO2PRE_A {
1380 fn from(input: MCOPRE) -> Self {
1381 match input {
1382 MCOPRE::Div1_no_div => Self::Div1,
1383 MCOPRE::Div2 => Self::Div2,
1384 MCOPRE::Div3 => Self::Div3,
1385 MCOPRE::Div4 => Self::Div4,
1386 MCOPRE::Div5 => Self::Div5,
1387 }
1388 }
1389}
1390
1391pub trait RccBus: crate::Sealed {
1393 type Bus;
1395}
1396
1397pub trait Enable: RccBus {
1399 fn enable(bus: &mut Self::Bus);
1401
1402 fn disable(bus: &mut Self::Bus);
1404
1405 fn is_enabled() -> bool;
1407
1408 fn is_disabled() -> bool;
1410
1411 unsafe fn enable_unchecked();
1415
1416 unsafe fn disable_unchecked();
1420}
1421
1422pub trait LPEnable: RccBus {
1424 fn low_power_enable(bus: &mut Self::Bus);
1426
1427 fn low_power_disable(bus: &mut Self::Bus);
1429
1430 fn is_low_power_enabled() -> bool;
1432
1433 fn is_low_power_disabled() -> bool;
1435
1436 unsafe fn low_power_enable_unchecked();
1440
1441 unsafe fn low_power_disable_unchecked();
1445}
1446
1447pub trait Reset: RccBus {
1449 fn reset(bus: &mut Self::Bus);
1451
1452 unsafe fn reset_unchecked();
1456}
1457
1458#[cfg(test)]
1459mod tests {
1460 use fugit::{HertzU32 as Hertz, RateExtU32};
1461
1462 use super::{FreqRequest, CFGR};
1463
1464 fn build_request(sysclk: u32, use_pll48clk: bool) -> FreqRequest {
1465 let p = Some((sysclk - 1, sysclk + 1));
1466 let q = if use_pll48clk {
1467 Some((48_000_000 - 120_000, 48_000_000 + 120_000))
1468 } else {
1469 None
1470 };
1471 FreqRequest { p, q }
1472 }
1473
1474 fn check(hse: u32, sysclk: u32, use_pll48clk: bool) {
1475 let request = build_request(sysclk, use_pll48clk);
1476 let (m, n, p, q) =
1477 CFGR::calculate_mnpq(hse, request).expect("Can't calculate PLL parameters");
1478
1479 let pll_in = hse;
1480
1481 if m < 2 || m > 63 {
1482 panic!("Invalid PLL M value: {}", m);
1483 }
1484
1485 let vco_in = pll_in / m;
1486 if vco_in < 1_000_000 || vco_in > 2_000_000 {
1487 panic!("Invalid VCO input frequency: {}", vco_in);
1488 }
1489
1490 if n < 50 || n > 432 {
1491 panic!("Invalid PLL N value: {}", n);
1492 }
1493
1494 let vco = ((pll_in as u64) * (n as u64) / (m as u64)) as u32;
1495 if vco < 100_000_000 || vco > 432_000_000 {
1496 panic!("Invalid VCO frequency: {}", vco);
1497 }
1498
1499 let p = p.expect("PLL P value should be defined!");
1500 if [2, 4, 6, 8].iter().find(|v| **v == p).is_none() {
1501 panic!("Invalid PLL P value: {}", p);
1502 }
1503
1504 let p_freq = vco / p;
1505 if p_freq > 216_000_000 {
1506 panic!("Invalid PLL P frequency: {}", p_freq);
1507 }
1508 if p_freq < (sysclk - 1) || p_freq > (sysclk + 1) {
1509 panic!(
1510 "Invalid PLL P frequency: {} (requested sysclk {})",
1511 p_freq, sysclk
1512 );
1513 }
1514
1515 if use_pll48clk && q.is_none() {
1516 panic!("PLL Q value should be defined!");
1517 }
1518 if let Some(q) = q {
1519 if q < 2 || q > 15 {
1520 panic!("Invalid PLL Q value: {}", q);
1521 }
1522 if use_pll48clk {
1523 let q_freq = vco / q;
1524 if q_freq < (48_000_000 - 120_000) || q_freq > (48_000_000 + 120_000) {
1525 panic!("Invalid PLL Q frequency: {}", q_freq);
1526 }
1527 }
1528 }
1529 }
1530
1531 #[test]
1532 fn test_pll_calc1() {
1533 check(25_000_000, 48_000_000, false);
1534 }
1535
1536 #[test]
1537 fn test_pll_calc1_usb() {
1538 check(25_000_000, 48_000_000, true);
1539 }
1540
1541 #[test]
1542 fn test_pll_calc2() {
1543 check(12_000_000, 48_000_000, false);
1544 }
1545
1546 #[test]
1547 fn test_pll_calc2_usb() {
1548 check(12_000_000, 48_000_000, true);
1549 }
1550
1551 #[test]
1552 fn test_pll_calc3() {
1553 check(12_000_000, 216_000_000, false);
1554 }
1555
1556 #[test]
1557 fn test_pll_calc3_usb() {
1558 check(12_000_000, 216_000_000, true);
1559 }
1560
1561 #[test]
1562 fn test_rcc_calc1() {
1563 use super::{HSEClock, HSEClockMode, MCO1, MCO2, MCOPRE, PLL48CLK, PLLP, PLLSAIP};
1564
1565 let cfgr = CFGR {
1566 hse: None,
1567 hclk: None,
1568 sysclk: None,
1569 pclk1: None,
1570 pclk2: None,
1571 lse: None,
1572 lsi: None,
1573 use_pll: false,
1574 pll48clk: None,
1575 pllm: 2,
1576 plln: 50,
1577 pllp: PLLP::Div2,
1578 pllq: 2,
1579 use_pllsai: false,
1580 pllsain: 192,
1581 pllsaip: PLLSAIP::Div2,
1582 pllsaiq: 2,
1583 use_plli2s: false,
1584 plli2sr: 2,
1585 plli2sq: 2,
1586 plli2sn: 192,
1587 mco1: MCO1::Hsi,
1588 mco1pre: MCOPRE::Div1_no_div,
1589 mco2: MCO2::Sysclk,
1590 mco2pre: MCOPRE::Div1_no_div,
1591 };
1592
1593 let mut cfgr = cfgr
1594 .hse(HSEClock::new(25.MHz(), HSEClockMode::Bypass))
1595 .use_pll()
1596 .use_pll48clk(PLL48CLK::Pllq)
1597 .sysclk(216.MHz());
1598 cfgr.pll_configure();
1599
1600 assert_eq!(cfgr.hse.unwrap().freq, Hertz::MHz(25));
1601
1602 let (clocks, _config) = cfgr.calculate_clocks();
1603 assert_eq!(clocks.sysclk().raw(), 216_000_000);
1604 assert!(clocks.is_pll48clk_valid());
1605 }
1606
1607 #[test]
1608 fn test_rcc_calc2() {
1609 use super::{HSEClock, HSEClockMode, MCO1, MCO2, MCOPRE, PLL48CLK, PLLP, PLLSAIP};
1610
1611 let cfgr = CFGR {
1612 hse: None,
1613 hclk: None,
1614 sysclk: None,
1615 pclk1: None,
1616 pclk2: None,
1617 lse: None,
1618 lsi: None,
1619 use_pll: false,
1620 pll48clk: None,
1621 pllm: 2,
1622 plln: 50,
1623 pllp: PLLP::Div2,
1624 pllq: 2,
1625 use_pllsai: false,
1626 pllsain: 192,
1627 pllsaip: PLLSAIP::Div2,
1628 pllsaiq: 2,
1629 use_plli2s: false,
1630 plli2sr: 2,
1631 plli2sq: 2,
1632 plli2sn: 192,
1633 mco1: MCO1::Hsi,
1634 mco1pre: MCOPRE::Div1_no_div,
1635 mco2: MCO2::Sysclk,
1636 mco2pre: MCOPRE::Div1_no_div,
1637 };
1638
1639 let mut cfgr = cfgr
1640 .hse(HSEClock::new(25.MHz(), HSEClockMode::Bypass))
1641 .use_pll48clk(PLL48CLK::Pllq)
1642 .sysclk(216.MHz());
1643 cfgr.pll_configure();
1644
1645 assert_eq!(cfgr.hse.unwrap().freq, Hertz::MHz(25));
1646
1647 let (clocks, _config) = cfgr.calculate_clocks();
1648 assert_eq!(clocks.sysclk().raw(), 216_000_000);
1649 assert!(clocks.is_pll48clk_valid());
1650 }
1651
1652 #[test]
1653 fn test_rcc_calc3() {
1654 use super::{HSEClock, HSEClockMode, MCO1, MCO2, MCOPRE, PLL48CLK, PLLP, PLLSAIP};
1655
1656 let cfgr = CFGR {
1657 hse: None,
1658 hclk: None,
1659 sysclk: None,
1660 pclk1: None,
1661 pclk2: None,
1662 lse: None,
1663 lsi: None,
1664 use_pll: false,
1665 pll48clk: None,
1666 pllm: 2,
1667 plln: 50,
1668 pllp: PLLP::Div2,
1669 pllq: 2,
1670 use_pllsai: false,
1671 pllsain: 192,
1672 pllsaip: PLLSAIP::Div2,
1673 pllsaiq: 2,
1674 use_plli2s: false,
1675 plli2sr: 2,
1676 plli2sq: 2,
1677 plli2sn: 192,
1678 mco1: MCO1::Hsi,
1679 mco1pre: MCOPRE::Div1_no_div,
1680 mco2: MCO2::Sysclk,
1681 mco2pre: MCOPRE::Div1_no_div,
1682 };
1683
1684 let mut cfgr = cfgr
1685 .hse(HSEClock::new(25.MHz(), HSEClockMode::Bypass))
1686 .use_pll48clk(PLL48CLK::Pllq)
1687 .set_defaults();
1688 cfgr.pll_configure();
1689
1690 assert_eq!(cfgr.hse.unwrap().freq, Hertz::MHz(25));
1691
1692 let (clocks, _config) = cfgr.calculate_clocks();
1693 assert_eq!(clocks.sysclk().raw(), 216_000_000);
1694 assert!(clocks.is_pll48clk_valid());
1695 }
1696
1697 #[test]
1698 fn test_rcc_default() {
1699 use super::{MCO1, MCO2, MCOPRE, PLLP, PLLSAIP};
1700
1701 let mut cfgr = CFGR {
1702 hse: None,
1703 hclk: None,
1704 sysclk: None,
1705 pclk1: None,
1706 pclk2: None,
1707 lse: None,
1708 lsi: None,
1709 use_pll: false,
1710 pll48clk: None,
1711 pllm: 2,
1712 plln: 50,
1713 pllp: PLLP::Div2,
1714 pllq: 2,
1715 use_pllsai: false,
1716 pllsain: 192,
1717 pllsaip: PLLSAIP::Div2,
1718 pllsaiq: 2,
1719 use_plli2s: false,
1720 plli2sr: 2,
1721 plli2sq: 2,
1722 plli2sn: 192,
1723 mco1: MCO1::Hsi,
1724 mco1pre: MCOPRE::Div1_no_div,
1725 mco2: MCO2::Sysclk,
1726 mco2pre: MCOPRE::Div1_no_div,
1727 };
1728
1729 cfgr.pll_configure();
1730 assert!(!cfgr.use_pll);
1731 let (clocks, _config) = cfgr.calculate_clocks();
1732 assert_eq!(clocks.sysclk().raw(), 16_000_000);
1733 }
1734}