1use core::ops::{Deref, DerefMut};
4
5use crate::pac::{
6 rcc::{self, RegisterBlock as RccRB},
7 BKP, PWR, RCC,
8};
9
10use crate::flash::ACR;
11#[cfg(any(feature = "stm32f103", feature = "connectivity"))]
12use crate::time::MHz;
13use fugit::{HertzU32 as Hertz, RateExtU32};
14
15use crate::backup_domain::BackupDomain;
16
17mod enable;
18
19pub trait RccExt {
21 fn constrain(self) -> Rcc;
23
24 fn freeze(self, rcc_cfg: impl Into<RawConfig>, acr: &mut ACR) -> Rcc;
26}
27
28impl RccExt for RCC {
29 fn constrain(self) -> Rcc {
30 Rcc {
31 rb: self,
32 clocks: Clocks::default(),
33 }
34 }
35
36 fn freeze(self, rcc_cfg: impl Into<RawConfig>, acr: &mut ACR) -> Rcc {
37 self.constrain().freeze(rcc_cfg, acr)
38 }
39}
40
41pub struct Rcc {
51 pub clocks: Clocks,
52 pub(crate) rb: RCC,
53}
54
55impl Deref for Rcc {
56 type Target = RCC;
57 fn deref(&self) -> &Self::Target {
58 &self.rb
59 }
60}
61
62impl DerefMut for Rcc {
63 fn deref_mut(&mut self) -> &mut Self::Target {
64 &mut self.rb
65 }
66}
67
68macro_rules! bus_struct {
69 ($($busX:ident => ($EN:ident, $en:ident, $($RST:ident, $rst:ident,)? $doc:literal),)+) => {
70 $(
71 #[doc = $doc]
72 #[non_exhaustive]
73 pub struct $busX;
74
75 impl $busX {
76 pub(crate) fn enr(rcc: &RccRB) -> &rcc::$EN {
77 rcc.$en()
78 }
79 $(
80 pub(crate) fn rstr(rcc: &RccRB) -> &rcc::$RST {
81 rcc.$rst()
82 }
83 )?
84 }
85 )+
86 };
87}
88use bus_struct;
89
90bus_struct! {
91 APB1 => (APB1ENR, apb1enr, APB1RSTR, apb1rstr, "Advanced Peripheral Bus 1 (APB1) registers"),
92 APB2 => (APB2ENR, apb2enr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
93 AHB => (AHBENR, ahbenr, "Advanced High-performance Bus (AHB) registers"),
94}
95
96const HSI: u32 = 8_000_000; #[derive(Debug, Default, PartialEq, Eq)]
108pub struct Config {
109 hse: Option<u32>,
110 hse_bypass: bool,
111 hclk: Option<u32>,
112 pclk1: Option<u32>,
113 pclk2: Option<u32>,
114 sysclk: Option<u32>,
115 adcclk: Option<u32>,
116}
117
118impl Config {
119 pub const DEFAULT: Self = Self {
120 hse: None,
121 hse_bypass: false,
122 hclk: None,
123 pclk1: None,
124 pclk2: None,
125 sysclk: None,
126 adcclk: None,
127 };
128
129 pub fn hsi() -> Self {
130 Self::DEFAULT
131 }
132
133 pub fn hse(freq: Hertz) -> Self {
134 Self::DEFAULT.use_hse(freq)
135 }
136
137 #[inline(always)]
141 pub fn use_hse(mut self, freq: Hertz) -> Self {
142 self.hse = Some(freq.raw());
143 self
144 }
145
146 pub fn bypass_hse_oscillator(self) -> Self {
154 Self {
155 hse_bypass: true,
156 ..self
157 }
158 }
159
160 #[inline(always)]
162 pub fn hclk(mut self, freq: Hertz) -> Self {
163 self.hclk = Some(freq.raw());
164 self
165 }
166
167 #[inline(always)]
169 pub fn pclk1(mut self, freq: Hertz) -> Self {
170 self.pclk1 = Some(freq.raw());
171 self
172 }
173
174 #[inline(always)]
176 pub fn pclk2(mut self, freq: Hertz) -> Self {
177 self.pclk2 = Some(freq.raw());
178 self
179 }
180
181 #[inline(always)]
183 pub fn sysclk(mut self, freq: Hertz) -> Self {
184 self.sysclk = Some(freq.raw());
185 self
186 }
187
188 #[inline(always)]
190 pub fn adcclk(mut self, freq: Hertz) -> Self {
191 self.adcclk = Some(freq.raw());
192 self
193 }
194}
195
196impl Rcc {
197 #[inline(always)]
210 pub fn freeze(self, cfg: impl Into<RawConfig>, acr: &mut ACR) -> Self {
211 let cfg = cfg.into();
212 let clocks = cfg.get_clocks();
213 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
215 unsafe {
216 acr.acr().write(|w| {
217 w.latency().bits(if clocks.sysclk <= MHz(24) {
218 0b000
219 } else if clocks.sysclk <= MHz(48) {
220 0b001
221 } else {
222 0b010
223 })
224 });
225 }
226
227 let rcc = unsafe { &*RCC::ptr() };
228
229 if cfg.hse.is_some() {
230 rcc.cr().modify(|_, w| {
233 if cfg.hse_bypass {
234 w.hsebyp().bypassed();
235 }
236 w.hseon().set_bit()
237 });
238
239 while rcc.cr().read().hserdy().bit_is_clear() {}
240 }
241
242 if let Some(pllmul_bits) = cfg.pllmul {
243 #[allow(unused_unsafe)]
246 rcc.cfgr().modify(|_, w| unsafe {
247 w.pllmul().bits(pllmul_bits).pllsrc().bit(cfg.hse.is_some())
248 });
249
250 rcc.cr().modify(|_, w| w.pllon().set_bit());
251
252 while rcc.cr().read().pllrdy().bit_is_clear() {}
253 }
254
255 #[cfg(feature = "connectivity")]
257 rcc.cfgr().modify(|_, w| unsafe {
258 w.adcpre().variant(cfg.adcpre);
259 w.ppre2().bits(cfg.ppre2 as u8);
260 w.ppre1().bits(cfg.ppre1 as u8);
261 w.hpre().bits(cfg.hpre as u8);
262 w.otgfspre().variant(cfg.usbpre);
263 w.sw().bits(if cfg.pllmul.is_some() {
264 0b10
266 } else if cfg.hse.is_some() {
267 0b1
269 } else {
270 0b0
272 })
273 });
274
275 #[cfg(feature = "stm32f103")]
276 rcc.cfgr().modify(|_, w| unsafe {
277 w.adcpre().variant(cfg.adcpre);
278 w.ppre2().bits(cfg.ppre2 as u8);
279 w.ppre1().bits(cfg.ppre1 as u8);
280 w.hpre().bits(cfg.hpre as u8);
281 w.usbpre().variant(cfg.usbpre);
282 w.sw().bits(if cfg.pllmul.is_some() {
283 0b10
285 } else {
286 u8::from(cfg.hse.is_some())
288 })
289 });
290
291 #[cfg(any(feature = "stm32f100", feature = "stm32f101"))]
292 rcc.cfgr().modify(|_, w| unsafe {
293 w.adcpre().variant(cfg.adcpre);
294 w.ppre2().bits(cfg.ppre2 as u8);
295 w.ppre1().bits(cfg.ppre1 as u8);
296 w.hpre().bits(cfg.hpre as u8);
297 w.sw().bits(if cfg.pllmul.is_some() {
298 0b10
300 } else if cfg.hse.is_some() {
301 0b1
303 } else {
304 0b0
306 })
307 });
308
309 Self {
310 rb: self.rb,
311 clocks,
312 }
313 }
314}
315
316pub trait BkpExt {
317 fn constrain(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain;
319}
320
321impl BkpExt for BKP {
322 fn constrain(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain {
323 BKP::enable(rcc);
325 PWR::enable(rcc);
326
327 pwr.cr().modify(|_r, w| w.dbp().set_bit());
329
330 BackupDomain { _regs: self }
331 }
332}
333
334#[derive(Clone, Copy, Debug, PartialEq, Eq)]
349pub struct Clocks {
350 hclk: Hertz,
351 pclk1: Hertz,
352 pclk2: Hertz,
353 ppre1: u8,
354 ppre2: u8,
355 sysclk: Hertz,
356 adcclk: Hertz,
357 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
358 usbclk_valid: bool,
359}
360
361impl Default for Clocks {
362 fn default() -> Clocks {
363 let freq = HSI.Hz();
364 Clocks {
365 hclk: freq,
366 pclk1: freq,
367 pclk2: freq,
368 ppre1: 1,
369 ppre2: 1,
370 sysclk: freq,
371 adcclk: freq / 2,
372 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
373 usbclk_valid: false,
374 }
375 }
376}
377
378impl Clocks {
379 pub const fn hclk(&self) -> Hertz {
381 self.hclk
382 }
383
384 pub const fn pclk1(&self) -> Hertz {
386 self.pclk1
387 }
388
389 pub const fn pclk2(&self) -> Hertz {
391 self.pclk2
392 }
393
394 pub const fn pclk1_tim(&self) -> Hertz {
396 Hertz::from_raw(self.pclk1.raw() * if self.ppre1() == 1 { 1 } else { 2 })
397 }
398
399 pub const fn pclk2_tim(&self) -> Hertz {
401 Hertz::from_raw(self.pclk2.raw() * if self.ppre2() == 1 { 1 } else { 2 })
402 }
403
404 pub(crate) const fn ppre1(&self) -> u8 {
405 self.ppre1
406 }
407
408 #[allow(dead_code)]
410 pub(crate) const fn ppre2(&self) -> u8 {
411 self.ppre2
412 }
413
414 pub const fn sysclk(&self) -> Hertz {
416 self.sysclk
417 }
418
419 pub const fn adcclk(&self) -> Hertz {
421 self.adcclk
422 }
423
424 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
426 pub const fn usbclk_valid(&self) -> bool {
427 self.usbclk_valid
428 }
429}
430
431pub trait BusClock {
433 fn clock(clocks: &Clocks) -> Hertz;
435}
436
437pub trait BusTimerClock {
439 fn timer_clock(clocks: &Clocks) -> Hertz;
441}
442
443impl<T> BusClock for T
444where
445 T: RccBus,
446 T::Bus: BusClock,
447{
448 fn clock(clocks: &Clocks) -> Hertz {
449 T::Bus::clock(clocks)
450 }
451}
452
453impl<T> BusTimerClock for T
454where
455 T: RccBus,
456 T::Bus: BusTimerClock,
457{
458 fn timer_clock(clocks: &Clocks) -> Hertz {
459 T::Bus::timer_clock(clocks)
460 }
461}
462
463impl BusClock for AHB {
464 fn clock(clocks: &Clocks) -> Hertz {
465 clocks.hclk
466 }
467}
468
469impl BusClock for APB1 {
470 fn clock(clocks: &Clocks) -> Hertz {
471 clocks.pclk1
472 }
473}
474
475impl BusClock for APB2 {
476 fn clock(clocks: &Clocks) -> Hertz {
477 clocks.pclk2
478 }
479}
480
481impl BusTimerClock for APB1 {
482 fn timer_clock(clocks: &Clocks) -> Hertz {
483 clocks.pclk1_tim()
484 }
485}
486
487impl BusTimerClock for APB2 {
488 fn timer_clock(clocks: &Clocks) -> Hertz {
489 clocks.pclk2_tim()
490 }
491}
492
493pub trait RccBus: crate::Sealed {
495 type Bus;
497}
498
499pub trait Enable: RccBus {
501 fn enable(rcc: &mut RCC);
503
504 fn disable(rcc: &mut RCC);
506
507 fn is_enabled() -> bool;
509
510 #[inline]
512 fn is_disabled() -> bool {
513 !Self::is_enabled()
514 }
515
516 unsafe fn enable_unchecked() {
520 let mut rcc = RCC::steal();
521 Self::enable(&mut rcc);
522 }
523
524 unsafe fn disable_unchecked() {
528 let mut rcc = RCC::steal();
529 Self::disable(&mut rcc);
530 }
531}
532
533pub trait Reset: RccBus {
535 fn reset(rcc: &mut RCC);
537
538 unsafe fn reset_unchecked() {
542 let mut rcc = RCC::steal();
543 Self::reset(&mut rcc);
544 }
545}
546
547#[derive(Clone, Copy, Debug, PartialEq)]
548pub struct RawConfig {
549 pub hse: Option<u32>,
550 pub hse_bypass: bool,
551 pub pllmul: Option<u8>,
552 pub hpre: HPre,
553 pub ppre1: PPre,
554 pub ppre2: PPre,
555 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
556 pub usbpre: UsbPre,
557 pub adcpre: AdcPre,
558 pub allow_overclock: bool,
559}
560
561impl Default for RawConfig {
562 fn default() -> Self {
563 Self {
564 hse: None,
565 hse_bypass: false,
566 pllmul: None,
567 hpre: HPre::Div1,
568 ppre1: PPre::Div1,
569 ppre2: PPre::Div1,
570 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
571 usbpre: UsbPre::Div1_5,
572 adcpre: AdcPre::Div2,
573 allow_overclock: false,
574 }
575 }
576}
577
578#[repr(u8)]
579#[derive(Clone, Copy, Debug, PartialEq, Eq)]
580pub enum HPre {
581 Div1 = 7,
583 Div2 = 8,
585 Div4 = 9,
587 Div8 = 10,
589 Div16 = 11,
591 Div64 = 12,
593 Div128 = 13,
595 Div256 = 14,
597 Div512 = 15,
599}
600
601#[derive(Clone, Copy, Debug, PartialEq, Eq)]
602#[repr(u8)]
603pub enum PPre {
604 Div1 = 3,
606 Div2 = 4,
608 Div4 = 5,
610 Div8 = 6,
612 Div16 = 7,
614}
615
616#[cfg(feature = "stm32f103")]
617pub type UsbPre = rcc::cfgr::USBPRE;
618#[cfg(feature = "connectivity")]
619pub type UsbPre = rcc::cfgr::OTGFSPRE;
620pub type AdcPre = rcc::cfgr::ADCPRE;
621
622impl From<Config> for RawConfig {
623 #[inline(always)]
624 fn from(cfgr: Config) -> Self {
625 Self::from_cfgr(cfgr)
626 }
627}
628
629impl RawConfig {
630 pub const fn from_cfgr(cfgr: Config) -> Self {
631 let hse = cfgr.hse;
632 let hse_bypass = cfgr.hse_bypass;
633 let pllsrcclk = if let Some(hse) = hse { hse } else { HSI / 2 };
634
635 let pllmul = if let Some(sysclk) = cfgr.sysclk {
636 sysclk / pllsrcclk
637 } else {
638 1
639 };
640
641 let (pllmul_bits, sysclk) = if pllmul == 1 {
642 (None, if let Some(hse) = hse { hse } else { HSI })
643 } else {
644 #[cfg(not(feature = "connectivity"))]
645 let pllmul = match pllmul {
646 1..=16 => pllmul,
647 0 => 1,
648 _ => 16,
649 };
650
651 #[cfg(feature = "connectivity")]
652 let pllmul = match pllmul {
653 4..=9 => pllmul,
654 0..=3 => 4,
655 _ => 9,
656 };
657
658 (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
659 };
660
661 let hpre_bits = if let Some(hclk) = cfgr.hclk {
662 match sysclk / hclk {
663 0..=1 => HPre::Div1,
664 2 => HPre::Div2,
665 3..=5 => HPre::Div4,
666 6..=11 => HPre::Div8,
667 12..=39 => HPre::Div16,
668 40..=95 => HPre::Div64,
669 96..=191 => HPre::Div128,
670 192..=383 => HPre::Div256,
671 _ => HPre::Div512,
672 }
673 } else {
674 HPre::Div1
675 };
676
677 let hclk = if hpre_bits as u8 >= 0b1100 {
678 sysclk / (1 << (hpre_bits as u8 - 0b0110))
679 } else {
680 sysclk / (1 << (hpre_bits as u8 - 0b0111))
681 };
682
683 let pclk1 = if let Some(pclk1) = cfgr.pclk1 {
684 pclk1
685 } else if hclk < 36_000_000 {
686 hclk
687 } else {
688 36_000_000
689 };
690 let ppre1_bits = match (hclk + pclk1 - 1) / pclk1 {
691 0 | 1 => PPre::Div1,
692 2 => PPre::Div2,
693 3..=5 => PPre::Div4,
694 6..=11 => PPre::Div8,
695 _ => PPre::Div16,
696 };
697
698 let ppre2_bits = if let Some(pclk2) = cfgr.pclk2 {
699 match hclk / pclk2 {
700 0..=1 => PPre::Div1,
701 2 => PPre::Div2,
702 3..=5 => PPre::Div4,
703 6..=11 => PPre::Div8,
704 _ => PPre::Div16,
705 }
706 } else {
707 PPre::Div1
708 };
709
710 let ppre2 = 1 << (ppre2_bits as u8 - 0b011);
711 let pclk2 = hclk / (ppre2 as u32);
712
713 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
715 let usbpre = match (hse, pllmul_bits, sysclk) {
716 (Some(_), Some(_), 72_000_000) => UsbPre::Div1_5,
717 _ => UsbPre::Div1,
718 };
719
720 let apre_bits = if let Some(adcclk) = cfgr.adcclk {
721 match pclk2 / adcclk {
722 0..=2 => AdcPre::Div2,
723 3..=4 => AdcPre::Div4,
724 5..=7 => AdcPre::Div6,
725 _ => AdcPre::Div8,
726 }
727 } else {
728 AdcPre::Div8
729 };
730
731 Self {
732 hse,
733 hse_bypass,
734 pllmul: pllmul_bits,
735 hpre: hpre_bits,
736 ppre1: ppre1_bits,
737 ppre2: ppre2_bits,
738 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
739 usbpre,
740 adcpre: apre_bits,
741 allow_overclock: false,
742 }
743 }
744
745 fn get_clocks(&self) -> Clocks {
748 let sysclk = if let Some(pllmul_bits) = self.pllmul {
749 let pllsrcclk = if let Some(hse) = self.hse {
750 hse
751 } else {
752 HSI / 2
753 };
754 pllsrcclk * (pllmul_bits as u32 + 2)
755 } else if let Some(hse) = self.hse {
756 hse
757 } else {
758 HSI
759 };
760
761 let hclk = if self.hpre as u8 >= 0b1100 {
762 sysclk / (1 << (self.hpre as u8 - 0b0110))
763 } else {
764 sysclk / (1 << (self.hpre as u8 - 0b0111))
765 };
766
767 let ppre1 = 1 << (self.ppre1 as u8 - 0b011);
768 let pclk1 = hclk / (ppre1 as u32);
769
770 let ppre2 = 1 << (self.ppre2 as u8 - 0b011);
771 let pclk2 = hclk / (ppre2 as u32);
772
773 let apre = (self.adcpre as u8 + 1) << 1;
774 let adcclk = pclk2 / (apre as u32);
775
776 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
779 let usbclk_valid = matches!(
780 (self.hse, self.pllmul, sysclk),
781 (Some(_), Some(_), 72_000_000) | (Some(_), Some(_), 48_000_000)
782 );
783
784 assert!(
785 self.allow_overclock
786 || (sysclk <= 72_000_000
787 && hclk <= 72_000_000
788 && pclk1 <= 36_000_000
789 && pclk2 <= 72_000_000
790 && adcclk <= 14_000_000)
791 );
792
793 Clocks {
794 hclk: hclk.Hz(),
795 pclk1: pclk1.Hz(),
796 pclk2: pclk2.Hz(),
797 ppre1,
798 ppre2,
799 sysclk: sysclk.Hz(),
800 adcclk: adcclk.Hz(),
801 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
802 usbclk_valid,
803 }
804 }
805}
806
807#[test]
808fn rcc_config_usb() {
809 let cfgr = Config::default()
810 .use_hse(8.MHz())
811 .sysclk(48.MHz())
812 .pclk1(24.MHz());
813
814 let config = RawConfig::from_cfgr(cfgr);
815 let config_expected = RawConfig {
816 hse: Some(8_000_000),
817 hse_bypass: false,
818 pllmul: Some(4),
819 hpre: HPre::Div1,
820 ppre1: PPre::Div2,
821 ppre2: PPre::Div1,
822 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
823 usbpre: UsbPre::Div1,
824 adcpre: AdcPre::Div8,
825 allow_overclock: false,
826 };
827 assert_eq!(config, config_expected);
828
829 let clocks = config.get_clocks();
830 let clocks_expected = Clocks {
831 hclk: 48.MHz(),
832 pclk1: 24.MHz(),
833 pclk2: 48.MHz(),
834 ppre1: 2,
835 ppre2: 1,
836 sysclk: 48.MHz(),
837 adcclk: 6.MHz(),
838 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
839 usbclk_valid: true,
840 };
841 assert_eq!(clocks, clocks_expected);
842}