1use core::ops::{Deref, DerefMut};
4
5use crate::pac::{
6 BKP, PWR, RCC,
7 rcc::{self, RegisterBlock as RccRB},
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
25impl RccExt for RCC {
26 fn constrain(self) -> Rcc {
27 Rcc {
28 rb: self,
29 clocks: Clocks::default(),
30 }
31 }
32}
33
34pub struct Rcc {
44 pub clocks: Clocks,
45 pub(crate) rb: RCC,
46}
47
48impl Rcc {
49 #[allow(unused_variables)]
62 #[inline(always)]
63 pub fn freeze(self, cfg: impl Into<RawConfig>, acr: &mut ACR) -> Self {
64 let cfg = cfg.into();
65 let clocks = cfg.get_clocks();
66 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
68 unsafe {
69 acr.acr().write(|w| {
70 w.latency().bits(if clocks.sysclk <= MHz(24) {
71 0b000
72 } else if clocks.sysclk <= MHz(48) {
73 0b001
74 } else {
75 0b010
76 })
77 });
78 }
79
80 let rcc = unsafe { &*RCC::ptr() };
81
82 if cfg.hse.is_some() {
83 rcc.cr().modify(|_, w| {
86 if cfg.hse_bypass {
87 w.hsebyp().bypassed();
88 }
89 w.hseon().set_bit()
90 });
91
92 while rcc.cr().read().hserdy().bit_is_clear() {}
93 }
94
95 if let Some(pllmul_bits) = cfg.pllmul {
96 #[allow(unused_unsafe)]
99 rcc.cfgr().modify(|_, w| unsafe {
100 w.pllmul().bits(pllmul_bits).pllsrc().bit(cfg.hse.is_some())
101 });
102
103 rcc.cr().modify(|_, w| w.pllon().set_bit());
104
105 while rcc.cr().read().pllrdy().bit_is_clear() {}
106 }
107
108 #[cfg(feature = "connectivity")]
110 rcc.cfgr().modify(|_, w| unsafe {
111 w.adcpre().variant(cfg.adcpre);
112 w.ppre2().bits(cfg.ppre2 as u8);
113 w.ppre1().bits(cfg.ppre1 as u8);
114 w.hpre().bits(cfg.hpre as u8);
115 w.otgfspre().variant(cfg.usbpre);
116 w.sw().bits(if cfg.pllmul.is_some() {
117 0b10
119 } else if cfg.hse.is_some() {
120 0b1
122 } else {
123 0b0
125 })
126 });
127
128 #[cfg(feature = "stm32f103")]
129 rcc.cfgr().modify(|_, w| unsafe {
130 w.adcpre().variant(cfg.adcpre);
131 w.ppre2().bits(cfg.ppre2 as u8);
132 w.ppre1().bits(cfg.ppre1 as u8);
133 w.hpre().bits(cfg.hpre as u8);
134 w.usbpre().variant(cfg.usbpre);
135 w.sw().bits(if cfg.pllmul.is_some() {
136 0b10
138 } else {
139 u8::from(cfg.hse.is_some())
141 })
142 });
143
144 #[cfg(any(feature = "stm32f100", feature = "stm32f101"))]
145 rcc.cfgr().modify(|_, w| unsafe {
146 w.adcpre().variant(cfg.adcpre);
147 w.ppre2().bits(cfg.ppre2 as u8);
148 w.ppre1().bits(cfg.ppre1 as u8);
149 w.hpre().bits(cfg.hpre as u8);
150 w.sw().bits(if cfg.pllmul.is_some() {
151 0b10
153 } else if cfg.hse.is_some() {
154 0b1
156 } else {
157 0b0
159 })
160 });
161
162 Self {
163 rb: self.rb,
164 clocks,
165 }
166 }
167
168 pub fn enable<T: Enable>(&mut self, _periph: &T) {
169 T::enable(self);
170 }
171
172 pub fn reset<T: Reset>(&mut self, _periph: &T) {
173 T::reset(self);
174 }
175
176 pub fn get_clock<T: BusClock>(&self, _periph: &T) -> Hertz {
177 T::clock(&self.clocks)
178 }
179
180 pub fn get_timer_clock<T: BusTimerClock>(&self, _periph: &T) -> Hertz {
181 T::timer_clock(&self.clocks)
182 }
183}
184
185impl Deref for Rcc {
186 type Target = RCC;
187 fn deref(&self) -> &Self::Target {
188 &self.rb
189 }
190}
191
192impl DerefMut for Rcc {
193 fn deref_mut(&mut self) -> &mut Self::Target {
194 &mut self.rb
195 }
196}
197
198macro_rules! bus_struct {
199 ($($busX:ident => ($EN:ident, $en:ident, $($RST:ident, $rst:ident,)? $doc:literal),)+) => {
200 $(
201 #[doc = $doc]
202 #[non_exhaustive]
203 pub struct $busX;
204
205 impl $busX {
206 pub(crate) fn enr(rcc: &RccRB) -> &rcc::$EN {
207 rcc.$en()
208 }
209 $(
210 pub(crate) fn rstr(rcc: &RccRB) -> &rcc::$RST {
211 rcc.$rst()
212 }
213 )?
214 }
215 )+
216 };
217}
218use bus_struct;
219
220bus_struct! {
221 APB1 => (APB1ENR, apb1enr, APB1RSTR, apb1rstr, "Advanced Peripheral Bus 1 (APB1) registers"),
222 APB2 => (APB2ENR, apb2enr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
223 AHB => (AHBENR, ahbenr, "Advanced High-performance Bus (AHB) registers"),
224}
225
226const HSI: u32 = 8_000_000; #[derive(Debug, Default, PartialEq, Eq)]
238pub struct Config {
239 hse: Option<u32>,
240 hse_bypass: bool,
241 hclk: Option<u32>,
242 pclk1: Option<u32>,
243 pclk2: Option<u32>,
244 sysclk: Option<u32>,
245 adcclk: Option<u32>,
246}
247
248impl Config {
249 pub const DEFAULT: Self = Self {
250 hse: None,
251 hse_bypass: false,
252 hclk: None,
253 pclk1: None,
254 pclk2: None,
255 sysclk: None,
256 adcclk: None,
257 };
258
259 pub fn hsi() -> Self {
260 Self::DEFAULT
261 }
262
263 pub fn hse(freq: Hertz) -> Self {
264 Self::DEFAULT.use_hse(freq)
265 }
266
267 #[inline(always)]
271 pub fn use_hse(mut self, freq: Hertz) -> Self {
272 self.hse = Some(freq.raw());
273 self
274 }
275
276 pub fn bypass_hse_oscillator(self) -> Self {
284 Self {
285 hse_bypass: true,
286 ..self
287 }
288 }
289
290 #[inline(always)]
292 pub fn hclk(mut self, freq: Hertz) -> Self {
293 self.hclk = Some(freq.raw());
294 self
295 }
296
297 #[inline(always)]
299 pub fn pclk1(mut self, freq: Hertz) -> Self {
300 self.pclk1 = Some(freq.raw());
301 self
302 }
303
304 #[inline(always)]
306 pub fn pclk2(mut self, freq: Hertz) -> Self {
307 self.pclk2 = Some(freq.raw());
308 self
309 }
310
311 #[inline(always)]
313 pub fn sysclk(mut self, freq: Hertz) -> Self {
314 self.sysclk = Some(freq.raw());
315 self
316 }
317
318 #[inline(always)]
320 pub fn adcclk(mut self, freq: Hertz) -> Self {
321 self.adcclk = Some(freq.raw());
322 self
323 }
324}
325
326pub trait BkpExt {
327 fn constrain(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain;
329}
330
331impl BkpExt for BKP {
332 fn constrain(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain {
333 BKP::enable(rcc);
335 PWR::enable(rcc);
336
337 pwr.cr().modify(|_r, w| w.dbp().set_bit());
339
340 BackupDomain { _regs: self }
341 }
342}
343
344#[derive(Clone, Copy, Debug, PartialEq, Eq)]
359pub struct Clocks {
360 hclk: Hertz,
361 pclk1: Hertz,
362 pclk2: Hertz,
363 ppre1: u8,
364 ppre2: u8,
365 sysclk: Hertz,
366 adcclk: Hertz,
367 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
368 usbclk_valid: bool,
369}
370
371impl Default for Clocks {
372 fn default() -> Clocks {
373 let freq = HSI.Hz();
374 Clocks {
375 hclk: freq,
376 pclk1: freq,
377 pclk2: freq,
378 ppre1: 1,
379 ppre2: 1,
380 sysclk: freq,
381 adcclk: freq / 2,
382 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
383 usbclk_valid: false,
384 }
385 }
386}
387
388impl Clocks {
389 pub const fn hclk(&self) -> Hertz {
391 self.hclk
392 }
393
394 pub const fn pclk1(&self) -> Hertz {
396 self.pclk1
397 }
398
399 pub const fn pclk2(&self) -> Hertz {
401 self.pclk2
402 }
403
404 pub const fn pclk1_tim(&self) -> Hertz {
406 Hertz::from_raw(self.pclk1.raw() * if self.ppre1() == 1 { 1 } else { 2 })
407 }
408
409 pub const fn pclk2_tim(&self) -> Hertz {
411 Hertz::from_raw(self.pclk2.raw() * if self.ppre2() == 1 { 1 } else { 2 })
412 }
413
414 pub(crate) const fn ppre1(&self) -> u8 {
415 self.ppre1
416 }
417
418 #[allow(dead_code)]
420 pub(crate) const fn ppre2(&self) -> u8 {
421 self.ppre2
422 }
423
424 pub const fn sysclk(&self) -> Hertz {
426 self.sysclk
427 }
428
429 pub const fn adcclk(&self) -> Hertz {
431 self.adcclk
432 }
433
434 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
436 pub const fn usbclk_valid(&self) -> bool {
437 self.usbclk_valid
438 }
439}
440
441pub trait BusClock {
443 fn clock(clocks: &Clocks) -> Hertz;
445}
446
447pub trait BusTimerClock {
449 fn timer_clock(clocks: &Clocks) -> Hertz;
451}
452
453impl<T> BusClock for T
454where
455 T: RccBus,
456 T::Bus: BusClock,
457{
458 fn clock(clocks: &Clocks) -> Hertz {
459 T::Bus::clock(clocks)
460 }
461}
462
463impl<T> BusTimerClock for T
464where
465 T: RccBus,
466 T::Bus: BusTimerClock,
467{
468 fn timer_clock(clocks: &Clocks) -> Hertz {
469 T::Bus::timer_clock(clocks)
470 }
471}
472
473impl BusClock for AHB {
474 fn clock(clocks: &Clocks) -> Hertz {
475 clocks.hclk
476 }
477}
478
479impl BusClock for APB1 {
480 fn clock(clocks: &Clocks) -> Hertz {
481 clocks.pclk1
482 }
483}
484
485impl BusClock for APB2 {
486 fn clock(clocks: &Clocks) -> Hertz {
487 clocks.pclk2
488 }
489}
490
491impl BusTimerClock for APB1 {
492 fn timer_clock(clocks: &Clocks) -> Hertz {
493 clocks.pclk1_tim()
494 }
495}
496
497impl BusTimerClock for APB2 {
498 fn timer_clock(clocks: &Clocks) -> Hertz {
499 clocks.pclk2_tim()
500 }
501}
502
503pub trait RccBus {
505 type Bus;
507}
508
509pub trait Enable: RccBus {
511 fn enable(rcc: &mut RCC);
513
514 fn disable(rcc: &mut RCC);
516
517 fn is_enabled() -> bool;
519
520 #[inline]
522 fn is_disabled() -> bool {
523 !Self::is_enabled()
524 }
525
526 unsafe fn enable_unchecked() {
530 let mut rcc = unsafe { RCC::steal() };
531 Self::enable(&mut rcc);
532 }
533
534 unsafe fn disable_unchecked() {
538 let mut rcc = unsafe { RCC::steal() };
539 Self::disable(&mut rcc);
540 }
541}
542
543pub trait Reset: RccBus {
545 fn reset(rcc: &mut RCC);
547
548 unsafe fn reset_unchecked() {
552 let mut rcc = unsafe { RCC::steal() };
553 Self::reset(&mut rcc);
554 }
555}
556
557#[derive(Clone, Copy, Debug, PartialEq)]
558pub struct RawConfig {
559 pub hse: Option<u32>,
560 pub hse_bypass: bool,
561 pub pllmul: Option<u8>,
562 pub hpre: HPre,
563 pub ppre1: PPre,
564 pub ppre2: PPre,
565 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
566 pub usbpre: UsbPre,
567 pub adcpre: AdcPre,
568 pub allow_overclock: bool,
569}
570
571impl Default for RawConfig {
572 fn default() -> Self {
573 Self {
574 hse: None,
575 hse_bypass: false,
576 pllmul: None,
577 hpre: HPre::Div1,
578 ppre1: PPre::Div1,
579 ppre2: PPre::Div1,
580 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
581 usbpre: UsbPre::Div1_5,
582 adcpre: AdcPre::Div2,
583 allow_overclock: false,
584 }
585 }
586}
587
588#[repr(u8)]
589#[derive(Clone, Copy, Debug, PartialEq, Eq)]
590pub enum HPre {
591 Div1 = 7,
593 Div2 = 8,
595 Div4 = 9,
597 Div8 = 10,
599 Div16 = 11,
601 Div64 = 12,
603 Div128 = 13,
605 Div256 = 14,
607 Div512 = 15,
609}
610
611#[derive(Clone, Copy, Debug, PartialEq, Eq)]
612#[repr(u8)]
613pub enum PPre {
614 Div1 = 3,
616 Div2 = 4,
618 Div4 = 5,
620 Div8 = 6,
622 Div16 = 7,
624}
625
626#[cfg(feature = "stm32f103")]
627pub type UsbPre = rcc::cfgr::USBPRE;
628#[cfg(feature = "connectivity")]
629pub type UsbPre = rcc::cfgr::OTGFSPRE;
630pub type AdcPre = rcc::cfgr::ADCPRE;
631
632impl From<Config> for RawConfig {
633 #[inline(always)]
634 fn from(cfgr: Config) -> Self {
635 Self::from_cfgr(cfgr)
636 }
637}
638
639impl RawConfig {
640 pub const fn from_cfgr(cfgr: Config) -> Self {
641 let hse = cfgr.hse;
642 let hse_bypass = cfgr.hse_bypass;
643 let pllsrcclk = if let Some(hse) = hse { hse } else { HSI / 2 };
644
645 let pllmul = if let Some(sysclk) = cfgr.sysclk {
646 sysclk / pllsrcclk
647 } else {
648 1
649 };
650
651 let (pllmul_bits, sysclk) = if pllmul == 1 {
652 (None, if let Some(hse) = hse { hse } else { HSI })
653 } else {
654 #[cfg(not(feature = "connectivity"))]
655 let pllmul = match pllmul {
656 1..=16 => pllmul,
657 0 => 1,
658 _ => 16,
659 };
660
661 #[cfg(feature = "connectivity")]
662 let pllmul = match pllmul {
663 4..=9 => pllmul,
664 0..=3 => 4,
665 _ => 9,
666 };
667
668 (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
669 };
670
671 let hpre_bits = if let Some(hclk) = cfgr.hclk {
672 match sysclk / hclk {
673 0..=1 => HPre::Div1,
674 2 => HPre::Div2,
675 3..=5 => HPre::Div4,
676 6..=11 => HPre::Div8,
677 12..=39 => HPre::Div16,
678 40..=95 => HPre::Div64,
679 96..=191 => HPre::Div128,
680 192..=383 => HPre::Div256,
681 _ => HPre::Div512,
682 }
683 } else {
684 HPre::Div1
685 };
686
687 let hclk = if hpre_bits as u8 >= 0b1100 {
688 sysclk / (1 << (hpre_bits as u8 - 0b0110))
689 } else {
690 sysclk / (1 << (hpre_bits as u8 - 0b0111))
691 };
692
693 let pclk1 = if let Some(pclk1) = cfgr.pclk1 {
694 pclk1
695 } else if hclk < 36_000_000 {
696 hclk
697 } else {
698 36_000_000
699 };
700 let ppre1_bits = match hclk.div_ceil(pclk1) {
701 0 | 1 => PPre::Div1,
702 2 => PPre::Div2,
703 3..=5 => PPre::Div4,
704 6..=11 => PPre::Div8,
705 _ => PPre::Div16,
706 };
707
708 let ppre2_bits = if let Some(pclk2) = cfgr.pclk2 {
709 match hclk / pclk2 {
710 0..=1 => PPre::Div1,
711 2 => PPre::Div2,
712 3..=5 => PPre::Div4,
713 6..=11 => PPre::Div8,
714 _ => PPre::Div16,
715 }
716 } else {
717 PPre::Div1
718 };
719
720 let ppre2 = 1 << (ppre2_bits as u8 - 0b011);
721 let pclk2 = hclk / (ppre2 as u32);
722
723 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
725 let usbpre = match (hse, pllmul_bits, sysclk) {
726 (Some(_), Some(_), 72_000_000) => UsbPre::Div1_5,
727 _ => UsbPre::Div1,
728 };
729
730 let apre_bits = if let Some(adcclk) = cfgr.adcclk {
731 match pclk2 / adcclk {
732 0..=2 => AdcPre::Div2,
733 3..=4 => AdcPre::Div4,
734 5..=7 => AdcPre::Div6,
735 _ => AdcPre::Div8,
736 }
737 } else {
738 AdcPre::Div8
739 };
740
741 Self {
742 hse,
743 hse_bypass,
744 pllmul: pllmul_bits,
745 hpre: hpre_bits,
746 ppre1: ppre1_bits,
747 ppre2: ppre2_bits,
748 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
749 usbpre,
750 adcpre: apre_bits,
751 allow_overclock: false,
752 }
753 }
754
755 fn get_clocks(&self) -> Clocks {
758 let sysclk = if let Some(pllmul_bits) = self.pllmul {
759 let pllsrcclk = if let Some(hse) = self.hse {
760 hse
761 } else {
762 HSI / 2
763 };
764 pllsrcclk * (pllmul_bits as u32 + 2)
765 } else if let Some(hse) = self.hse {
766 hse
767 } else {
768 HSI
769 };
770
771 let hclk = if self.hpre as u8 >= 0b1100 {
772 sysclk / (1 << (self.hpre as u8 - 0b0110))
773 } else {
774 sysclk / (1 << (self.hpre as u8 - 0b0111))
775 };
776
777 let ppre1 = 1 << (self.ppre1 as u8 - 0b011);
778 let pclk1 = hclk / (ppre1 as u32);
779
780 let ppre2 = 1 << (self.ppre2 as u8 - 0b011);
781 let pclk2 = hclk / (ppre2 as u32);
782
783 let apre = (self.adcpre as u8 + 1) << 1;
784 let adcclk = pclk2 / (apre as u32);
785
786 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
789 let usbclk_valid = matches!(
790 (self.hse, self.pllmul, sysclk),
791 (Some(_), Some(_), 72_000_000) | (Some(_), Some(_), 48_000_000)
792 );
793
794 assert!(
795 self.allow_overclock
796 || (sysclk <= 72_000_000
797 && hclk <= 72_000_000
798 && pclk1 <= 36_000_000
799 && pclk2 <= 72_000_000
800 && adcclk <= 14_000_000)
801 );
802
803 Clocks {
804 hclk: hclk.Hz(),
805 pclk1: pclk1.Hz(),
806 pclk2: pclk2.Hz(),
807 ppre1,
808 ppre2,
809 sysclk: sysclk.Hz(),
810 adcclk: adcclk.Hz(),
811 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
812 usbclk_valid,
813 }
814 }
815}
816
817#[test]
818fn rcc_config_usb() {
819 let cfgr = Config::default()
820 .use_hse(8.MHz())
821 .sysclk(48.MHz())
822 .pclk1(24.MHz());
823
824 let config = RawConfig::from_cfgr(cfgr);
825 let config_expected = RawConfig {
826 hse: Some(8_000_000),
827 hse_bypass: false,
828 pllmul: Some(4),
829 hpre: HPre::Div1,
830 ppre1: PPre::Div2,
831 ppre2: PPre::Div1,
832 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
833 usbpre: UsbPre::Div1,
834 adcpre: AdcPre::Div8,
835 allow_overclock: false,
836 };
837 assert_eq!(config, config_expected);
838
839 let clocks = config.get_clocks();
840 let clocks_expected = Clocks {
841 hclk: 48.MHz(),
842 pclk1: 24.MHz(),
843 pclk2: 48.MHz(),
844 ppre1: 2,
845 ppre2: 1,
846 sysclk: 48.MHz(),
847 adcclk: 6.MHz(),
848 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
849 usbclk_valid: true,
850 };
851 assert_eq!(clocks, clocks_expected);
852}