1use crate::stm32::{rcc, RCC};
4use cast::u32;
5
6use crate::flash::ACR;
7use crate::pwr::Pwr;
8use crate::time::Hertz;
9use fugit::RateExtU32;
10
11mod enable;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum MsiFreq {
15 #[doc = "range 0 around 100 kHz"]
16 RANGE100K = 0,
17 #[doc = "range 1 around 200 kHz"]
18 RANGE200K = 1,
19 #[doc = "range 2 around 400 kHz"]
20 RANGE400K = 2,
21 #[doc = "range 3 around 800 kHz"]
22 RANGE800K = 3,
23 #[doc = "range 4 around 1 MHz"]
24 RANGE1M = 4,
25 #[doc = "range 5 around 2 MHz"]
26 RANGE2M = 5,
27 #[doc = "range 6 around 4 MHz"]
28 RANGE4M = 6,
29 #[doc = "range 7 around 8 MHz"]
30 RANGE8M = 7,
31 #[doc = "range 8 around 16 MHz"]
32 RANGE16M = 8,
33 #[doc = "range 9 around 24 MHz"]
34 RANGE24M = 9,
35 #[doc = "range 10 around 32 MHz"]
36 RANGE32M = 10,
37 #[doc = "range 11 around 48 MHz"]
38 RANGE48M = 11,
39}
40
41impl MsiFreq {
42 fn to_hertz(self) -> Hertz {
43 (match self {
44 Self::RANGE100K => 100_000,
45 Self::RANGE200K => 200_000,
46 Self::RANGE400K => 400_000,
47 Self::RANGE800K => 800_000,
48 Self::RANGE1M => 1_000_000,
49 Self::RANGE2M => 2_000_000,
50 Self::RANGE4M => 4_000_000,
51 Self::RANGE8M => 8_000_000,
52 Self::RANGE16M => 16_000_000,
53 Self::RANGE24M => 24_000_000,
54 Self::RANGE32M => 32_000_000,
55 Self::RANGE48M => 48_000_000,
56 })
57 .Hz()
58 }
59}
60
61pub trait RccExt {
63 fn constrain(self) -> Rcc;
65}
66
67impl RccExt for RCC {
68 fn constrain(self) -> Rcc {
69 Rcc {
70 ahb1: AHB1::new(),
71 ahb2: AHB2::new(),
72 ahb3: AHB3::new(),
73 apb1r1: APB1R1::new(),
74 apb1r2: APB1R2::new(),
75 apb2: APB2::new(),
76 bdcr: BDCR { _0: () },
77 csr: CSR { _0: () },
78 crrcr: CRRCR { _0: () },
79 ccipr: CCIPR { _0: () },
80 cfgr: CFGR {
81 hse: None,
82 lse: None,
83 msi: None,
84 hsi48: false,
85 lsi: false,
86 hclk: None,
87 pclk1: None,
88 pclk2: None,
89 sysclk: None,
90 pll_source: None,
91 pll_config: None,
92 },
93 }
94 }
95}
96
97pub struct Rcc {
99 pub ahb1: AHB1,
101 pub ahb2: AHB2,
103 pub ahb3: AHB3,
105 pub apb1r1: APB1R1,
107 pub apb1r2: APB1R2,
109 pub apb2: APB2,
111 pub cfgr: CFGR,
113 pub bdcr: BDCR,
115 pub csr: CSR,
117 pub crrcr: CRRCR,
119 pub ccipr: CCIPR,
121}
122
123pub struct CSR {
125 _0: (),
126}
127
128impl CSR {
129 #[allow(dead_code)]
131 pub(crate) fn csr(&mut self) -> &rcc::CSR {
132 unsafe { &(*RCC::ptr()).csr }
134 }
135}
136
137pub struct CRRCR {
139 _0: (),
140}
141
142impl CRRCR {
143 #[allow(dead_code)]
145 pub(crate) fn crrcr(&mut self) -> &rcc::CRRCR {
146 unsafe { &(*RCC::ptr()).crrcr }
148 }
149
150 pub fn is_hsi48_on(&mut self) -> bool {
152 self.crrcr().read().hsi48on().bit()
153 }
154
155 pub fn is_hsi48_ready(&mut self) -> bool {
157 self.crrcr().read().hsi48rdy().bit()
158 }
159}
160
161pub struct CCIPR {
163 _0: (),
164}
165
166impl CCIPR {
167 #[allow(dead_code)]
168 pub(crate) fn ccipr(&mut self) -> &rcc::CCIPR {
169 unsafe { &(*RCC::ptr()).ccipr }
171 }
172}
173
174pub struct BDCR {
176 _0: (),
177}
178
179impl BDCR {
180 #[allow(dead_code)]
182 pub(crate) fn enr(&mut self) -> &rcc::BDCR {
183 unsafe { &(*RCC::ptr()).bdcr }
185 }
186}
187
188macro_rules! bus_struct {
189 ($($busX:ident => ($EN:ident, $en:ident, $SMEN:ident, $smen:ident, $RST:ident, $rst:ident, $doc:literal),)+) => {
190 $(
191 #[doc = $doc]
192 pub struct $busX {
193 _0: (),
194 }
195
196 impl $busX {
197 pub(crate) fn new() -> Self {
198 Self { _0: () }
199 }
200
201 #[allow(unused)]
202 pub(crate) fn enr(&self) -> &rcc::$EN {
203 unsafe { &(*RCC::ptr()).$en }
205 }
206
207 #[allow(unused)]
208 pub(crate) fn smenr(&self) -> &rcc::$SMEN {
209 unsafe { &(*RCC::ptr()).$smen }
211 }
212
213 #[allow(unused)]
214 pub(crate) fn rstr(&self) -> &rcc::$RST {
215 unsafe { &(*RCC::ptr()).$rst }
217 }
218 }
219 )+
220 };
221}
222
223bus_struct! {
224 AHB1 => (AHB1ENR, ahb1enr, AHB1SMENR, ahb1smenr, AHB1RSTR, ahb1rstr, "Advanced High-performance Bus 1 (AHB1) registers"),
225 AHB2 => (AHB2ENR, ahb2enr, AHB2SMENR, ahb2smenr, AHB2RSTR, ahb2rstr, "Advanced High-performance Bus 2 (AHB2) registers"),
226 AHB3 => (AHB3ENR, ahb3enr, AHB3SMENR, ahb3smenr, AHB3RSTR, ahb3rstr, "Advanced High-performance Bus 3 (AHB3) registers"),
227 APB1R1 => (APB1ENR1, apb1enr1, APB1SMENR1, apb1smenr1, APB1RSTR1, apb1rstr1, "Advanced Peripheral Bus 1 (APB1) registers"),
228 APB1R2 => (APB1ENR2, apb1enr2, APB1SMENR2, apb1smenr2, APB1RSTR2, apb1rstr2, "Advanced Peripheral Bus 1 (APB1) registers"),
229 APB2 => (APB2ENR, apb2enr, APB2SMENR, apb2smenr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
230}
231
232pub trait RccBus: crate::Sealed {
234 type Bus;
236}
237
238pub trait Enable: RccBus {
240 fn enable(bus: &mut Self::Bus);
242
243 fn disable(bus: &mut Self::Bus);
245
246 fn is_enabled() -> bool;
248
249 fn is_disabled() -> bool;
251
252 unsafe fn enable_unchecked();
256
257 unsafe fn disable_unchecked();
261}
262
263pub trait SMEnable: RccBus {
265 fn enable_in_sleep_mode(bus: &mut Self::Bus);
267
268 fn disable_in_sleep_mode(bus: &mut Self::Bus);
270
271 fn is_enabled_in_sleep_mode() -> bool;
273
274 fn is_disabled_in_sleep_mode() -> bool;
276
277 unsafe fn enable_in_sleep_mode_unchecked();
281
282 unsafe fn disable_in_sleep_mode_unchecked();
286}
287
288pub trait Reset: RccBus {
290 fn reset(bus: &mut Self::Bus);
292
293 unsafe fn reset_unchecked();
297}
298
299#[derive(Debug, PartialEq)]
300struct HseConfig {
302 speed: u32,
304 bypass: CrystalBypass,
307 css: ClockSecuritySystem,
309}
310
311#[derive(Debug, PartialEq)]
312struct LseConfig {
314 bypass: CrystalBypass,
317 css: ClockSecuritySystem,
319}
320
321#[derive(Clone, Copy, Debug, PartialEq)]
323pub enum CrystalBypass {
324 Enable,
326 Disable,
328}
329
330#[derive(Clone, Copy, Debug, PartialEq)]
336pub enum ClockSecuritySystem {
337 Enable,
339 Disable,
341}
342
343const HSI: u32 = 16_000_000; pub struct CFGR {
347 hse: Option<HseConfig>,
348 lse: Option<LseConfig>,
349 msi: Option<MsiFreq>,
350 hsi48: bool,
351 lsi: bool,
352 hclk: Option<u32>,
353 pclk1: Option<u32>,
354 pclk2: Option<u32>,
355 sysclk: Option<u32>,
356 pll_source: Option<PllSource>,
357 pll_config: Option<PllConfig>,
358}
359
360impl CFGR {
361 pub fn hse(mut self, freq: Hertz, bypass: CrystalBypass, css: ClockSecuritySystem) -> Self {
363 self.hse = Some(HseConfig {
364 speed: freq.raw(),
365 bypass,
366 css,
367 });
368
369 self
370 }
371
372 pub fn lse(mut self, bypass: CrystalBypass, css: ClockSecuritySystem) -> Self {
374 self.lse = Some(LseConfig { bypass, css });
375
376 self
377 }
378
379 pub fn hclk(mut self, freq: Hertz) -> Self {
381 self.hclk = Some(freq.raw());
382 self
383 }
384
385 pub fn hsi48(mut self, on: bool) -> Self {
387 self.hsi48 = on;
388 self
389 }
390
391 pub fn msi(mut self, range: MsiFreq) -> Self {
393 self.msi = Some(range);
394 self
395 }
396
397 pub fn lsi(mut self, on: bool) -> Self {
399 self.lsi = on;
400 self
401 }
402
403 pub fn pclk1(mut self, freq: Hertz) -> Self {
405 self.pclk1 = Some(freq.raw());
406 self
407 }
408
409 pub fn pclk2(mut self, freq: Hertz) -> Self {
411 self.pclk2 = Some(freq.raw());
412 self
413 }
414
415 pub fn sysclk(mut self, freq: Hertz) -> Self {
417 self.sysclk = Some(freq.raw());
418 self
419 }
420
421 pub fn sysclk_with_pll(mut self, freq: Hertz, cfg: PllConfig) -> Self {
423 self.pll_config = Some(cfg);
424 self.sysclk = Some(freq.raw());
425 self
426 }
427
428 pub fn pll_source(mut self, source: PllSource) -> Self {
430 self.pll_source = Some(source);
431 self
432 }
433
434 pub fn freeze(&self, acr: &mut ACR, pwr: &mut Pwr) -> Clocks {
436 let rcc = unsafe { &*RCC::ptr() };
437
438 if rcc.cr.read().msion().bit_is_clear() {
440 rcc.cr.modify(|_, w| {
442 w.msirgsel().set_bit(); w.msirange().range4m();
444 w.msipllen().clear_bit();
445 w.msion().set_bit()
446 });
447
448 while rcc.cr.read().msirdy().bit_is_clear() {}
450 }
451 if rcc.cfgr.read().sws().bits() != 0 {
452 rcc.cfgr.reset();
454 while rcc.cfgr.read().sws().bits() != 0 {}
456 }
457
458 let lsi_used = match (self.lsi, &self.lse) {
464 (true, _)
465 | (
466 _,
467 &Some(LseConfig {
468 bypass: _,
469 css: ClockSecuritySystem::Enable,
470 }),
471 ) => {
472 rcc.csr.modify(|_, w| w.lsion().set_bit());
473
474 while rcc.csr.read().lsirdy().bit_is_clear() {}
476
477 true
478 }
479 _ => false,
480 };
481
482 if let Some(lse_cfg) = &self.lse {
483 pwr.cr1.reg().modify(|_, w| w.dbp().set_bit());
485
486 rcc.bdcr.modify(|_, w| {
488 w.lseon().set_bit(); if lse_cfg.bypass == CrystalBypass::Enable {
491 w.lsebyp().set_bit();
492 } else {
493 unsafe {
494 w.lsedrv().bits(0b11);
495 } }
497
498 w
499 });
500
501 while rcc.bdcr.read().lserdy().bit_is_clear() {}
503
504 if lse_cfg.css == ClockSecuritySystem::Enable {
506 rcc.bdcr.modify(|_, w| w.lsecsson().set_bit());
508 rcc.cier.modify(|_, w| w.lsecssie().set_bit());
509 }
510 }
511
512 if let Some(hse_cfg) = &self.hse {
514 rcc.cr.write(|w| {
515 w.hseon().set_bit();
516
517 if hse_cfg.bypass == CrystalBypass::Enable {
518 w.hsebyp().set_bit();
519 }
520
521 w
522 });
523
524 while rcc.cr.read().hserdy().bit_is_clear() {}
525
526 if hse_cfg.css == ClockSecuritySystem::Enable {
528 rcc.cr.modify(|_, w| w.csson().set_bit());
530 }
531 }
532
533 if let Some(msi) = self.msi {
534 unsafe {
535 rcc.cr.modify(|_, w| {
536 w.msirange()
537 .bits(msi as u8)
538 .msirgsel()
539 .set_bit()
540 .msion()
541 .set_bit();
542
543 if self.lse.is_some() {
545 w.msipllen().set_bit();
546 }
547
548 w
549 })
550 };
551
552 while rcc.cr.read().msirdy().bit_is_clear() {}
554 }
555
556 if self.hsi48 {
558 rcc.crrcr.modify(|_, w| w.hsi48on().set_bit());
560
561 while rcc.crrcr.read().hsi48rdy().bit_is_clear() {}
563 }
564
565 if let Some(MsiFreq::RANGE48M) = self.msi {
567 unsafe { rcc.ccipr.modify(|_, w| w.clk48sel().bits(0b11)) };
568 }
569
570 let (clock_speed, pll_source) = if let Some(source) = self.pll_source {
576 match source {
577 PllSource::HSE => {
578 if let Some(hse) = &self.hse {
579 (hse.speed, source)
580 } else {
581 panic!("HSE selected as PLL source, but not enabled");
582 }
583 }
584 PllSource::HSI16 => (HSI, source),
585 PllSource::MSI => {
586 if let Some(msi) = self.msi {
587 (msi.to_hertz().raw(), source)
588 } else {
589 panic!("MSI selected as PLL source, but not enabled");
590 }
591 }
592 }
593 } else {
594 if let Some(hse) = &self.hse {
598 (hse.speed, PllSource::HSE)
599 }
600 else if let Some(msi) = self.msi {
602 (msi.to_hertz().raw(), PllSource::MSI)
603 }
604 else {
606 (HSI, PllSource::HSI16)
607 }
608 };
609
610 if pll_source == PllSource::HSI16 || (self.msi.is_none() && self.hse.is_none()) {
612 rcc.cr.write(|w| w.hsion().set_bit());
613 while rcc.cr.read().hsirdy().bit_is_clear() {}
614 }
615
616 let pllconf = if self.pll_config.is_none() {
617 if let Some(sysclk) = self.sysclk {
618 let plln = (2 * sysclk) / clock_speed;
620
621 Some(PllConfig::new(1, plln as u8, PllDivider::Div2))
622 } else {
623 None
624 }
625 } else {
626 self.pll_config
627 };
628
629 let sysclk = match (self.sysclk, self.msi) {
630 (Some(sysclk), _) => sysclk,
631 (None, Some(msi)) => msi.to_hertz().raw(),
632 (None, None) => MsiFreq::RANGE4M.to_hertz().raw(),
633 };
634
635 assert!(sysclk <= 80_000_000);
636
637 let (hpre_bits, hpre_div) = self
638 .hclk
639 .map(|hclk| match sysclk / hclk {
640 0 => unreachable!(),
642 1 => (0b0000, 1),
643 2 => (0b1000, 2),
644 3..=5 => (0b1001, 4),
645 6..=11 => (0b1010, 8),
646 12..=39 => (0b1011, 16),
647 40..=95 => (0b1100, 64),
648 96..=191 => (0b1101, 128),
649 192..=383 => (0b1110, 256),
650 _ => (0b1111, 512),
651 })
652 .unwrap_or((0b0000, 1));
653
654 let hclk = sysclk / hpre_div;
655
656 assert!(hclk <= sysclk);
657
658 let (ppre1_bits, ppre1) = self
659 .pclk1
660 .map(|pclk1| match hclk / pclk1 {
661 0 => unreachable!(),
663 1 => (0b000, 1),
664 2 => (0b100, 2),
665 3..=5 => (0b101, 4),
666 6..=11 => (0b110, 8),
667 _ => (0b111, 16),
668 })
669 .unwrap_or((0b000, 1));
670
671 let pclk1: u32 = hclk / u32(ppre1);
672
673 assert!(pclk1 <= sysclk);
674
675 let (ppre2_bits, ppre2) = self
676 .pclk2
677 .map(|pclk2| match hclk / pclk2 {
678 0 => unreachable!(),
680 1 => (0b000, 1),
681 2 => (0b100, 2),
682 3..=5 => (0b101, 4),
683 6..=11 => (0b110, 8),
684 _ => (0b111, 16),
685 })
686 .unwrap_or((0b000, 1));
687
688 let pclk2: u32 = hclk / u32(ppre2);
689
690 assert!(pclk2 <= sysclk);
691
692 unsafe {
694 acr.acr().write(|w| {
695 w.latency().bits(if hclk <= 16_000_000 {
696 0b000
697 } else if hclk <= 32_000_000 {
698 0b001
699 } else if hclk <= 48_000_000 {
700 0b010
701 } else if hclk <= 64_000_000 {
702 0b011
703 } else {
704 0b100
705 })
706 })
707 }
708
709 let sysclk_src_bits;
710 let mut msi = self.msi;
711 if let Some(pllconf) = pllconf {
712 let r = pllconf.r.to_division_factor();
714 let clock_speed = clock_speed / (pllconf.m as u32 + 1);
715 let vco = clock_speed * pllconf.n as u32;
716 let output_clock = vco / r;
717
718 assert!(r <= 8); assert!(pllconf.n >= 8); assert!(pllconf.n <= 86); assert!(clock_speed >= 4_000_000); assert!(clock_speed <= 16_000_000); assert!(vco >= 64_000_000); assert!(vco <= 334_000_000); assert!(output_clock <= 80_000_000); sysclk_src_bits = 0b11;
729 rcc.cr.modify(|_, w| w.pllon().clear_bit());
730 while rcc.cr.read().pllrdy().bit_is_set() {}
731
732 let pllsrc_bits = pll_source.to_pllsrc();
733
734 rcc.pllcfgr.modify(|_, w| unsafe {
735 w.pllsrc()
736 .bits(pllsrc_bits)
737 .pllm()
738 .bits(pllconf.m)
739 .pllr()
740 .bits(pllconf.r.to_bits())
741 .plln()
742 .bits(pllconf.n)
743 });
744
745 rcc.cr.modify(|_, w| w.pllon().set_bit());
746
747 while rcc.cr.read().pllrdy().bit_is_clear() {}
748
749 rcc.pllcfgr.modify(|_, w| w.pllren().set_bit());
750
751 rcc.cfgr.modify(|_, w| unsafe {
753 w.ppre2()
754 .bits(ppre2_bits)
755 .ppre1()
756 .bits(ppre1_bits)
757 .hpre()
758 .bits(hpre_bits)
759 .sw()
760 .bits(sysclk_src_bits)
761 });
762 } else {
763 sysclk_src_bits = 0b00;
765 if msi.is_none() {
766 msi = Some(MsiFreq::RANGE4M);
767 }
768
769 rcc.cfgr.write(|w| unsafe {
771 w.ppre2()
772 .bits(ppre2_bits)
773 .ppre1()
774 .bits(ppre1_bits)
775 .hpre()
776 .bits(hpre_bits)
777 .sw()
778 .bits(sysclk_src_bits)
779 });
780 }
781
782 while rcc.cfgr.read().sws().bits() != sysclk_src_bits {}
783
784 if msi.is_none() {
790 rcc.cr
791 .modify(|_, w| w.msion().clear_bit().msipllen().clear_bit())
792 }
793
794 Clocks {
799 hclk: hclk.Hz(),
800 lsi: lsi_used,
801 lse: self.lse.is_some(),
802 msi,
803 hsi48: self.hsi48,
804 pclk1: pclk1.Hz(),
805 pclk2: pclk2.Hz(),
806 ppre1,
807 ppre2,
808 sysclk: sysclk.Hz(),
809 pll_source: pllconf.map(|_| pll_source),
810 }
811 }
812}
813
814#[derive(Clone, Copy, Debug)]
815pub enum PllDivider {
817 Div2 = 0b00,
819 Div4 = 0b01,
821 Div6 = 0b10,
823 Div8 = 0b11,
825}
826
827impl PllDivider {
828 #[inline(always)]
829 fn to_bits(self) -> u8 {
830 self as u8
831 }
832
833 #[inline(always)]
834 fn to_division_factor(self) -> u32 {
835 match self {
836 Self::Div2 => 2,
837 Self::Div4 => 4,
838 Self::Div6 => 6,
839 Self::Div8 => 8,
840 }
841 }
842}
843
844#[derive(Clone, Copy, Debug)]
845pub struct PllConfig {
847 m: u8,
849 n: u8,
851 r: PllDivider,
853}
854
855impl PllConfig {
856 pub fn new(input_divider: u8, multiplier: u8, output_divider: PllDivider) -> Self {
860 assert!(input_divider > 0);
861
862 PllConfig {
863 m: input_divider - 1,
864 n: multiplier,
865 r: output_divider,
866 }
867 }
868}
869
870#[derive(Clone, Copy, Debug, PartialEq)]
871pub enum PllSource {
873 MSI,
875 HSI16,
877 HSE,
879}
880
881impl PllSource {
882 fn to_pllsrc(self) -> u8 {
883 match self {
884 Self::MSI => 0b01,
885 Self::HSI16 => 0b10,
886 Self::HSE => 0b11,
887 }
888 }
889}
890
891#[derive(Clone, Copy, Debug)]
895pub struct Clocks {
896 hclk: Hertz,
897 hsi48: bool,
898 msi: Option<MsiFreq>,
899 lsi: bool,
900 lse: bool,
901 pclk1: Hertz,
902 pclk2: Hertz,
903 ppre1: u8,
904 ppre2: u8,
905 sysclk: Hertz,
906 pll_source: Option<PllSource>,
907}
908
909impl Clocks {
910 pub fn hclk(&self) -> Hertz {
912 self.hclk
913 }
914
915 pub fn hsi48(&self) -> bool {
917 self.hsi48
918 }
919
920 pub fn msi(&self) -> Option<MsiFreq> {
922 self.msi
923 }
924
925 pub fn lsi(&self) -> bool {
927 self.lsi
928 }
929
930 pub fn lse(&self) -> bool {
932 self.lse
933 }
934
935 pub fn pclk1(&self) -> Hertz {
937 self.pclk1
938 }
939
940 pub fn pclk2(&self) -> Hertz {
942 self.pclk2
943 }
944
945 pub fn pll_source(&self) -> Option<PllSource> {
947 self.pll_source
948 }
949
950 #[allow(dead_code)]
952 pub(crate) fn ppre1(&self) -> u8 {
953 self.ppre1
954 }
955 #[allow(dead_code)]
957 pub(crate) fn ppre2(&self) -> u8 {
958 self.ppre2
959 }
960
961 pub fn sysclk(&self) -> Hertz {
963 self.sysclk
964 }
965}