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 Deref for Rcc {
49 type Target = RCC;
50 fn deref(&self) -> &Self::Target {
51 &self.rb
52 }
53}
54
55impl DerefMut for Rcc {
56 fn deref_mut(&mut self) -> &mut Self::Target {
57 &mut self.rb
58 }
59}
60
61macro_rules! bus_struct {
62 ($($busX:ident => ($EN:ident, $en:ident, $($RST:ident, $rst:ident,)? $doc:literal),)+) => {
63 $(
64 #[doc = $doc]
65 #[non_exhaustive]
66 pub struct $busX;
67
68 impl $busX {
69 pub(crate) fn enr(rcc: &RccRB) -> &rcc::$EN {
70 rcc.$en()
71 }
72 $(
73 pub(crate) fn rstr(rcc: &RccRB) -> &rcc::$RST {
74 rcc.$rst()
75 }
76 )?
77 }
78 )+
79 };
80}
81use bus_struct;
82
83bus_struct! {
84 APB1 => (APB1ENR, apb1enr, APB1RSTR, apb1rstr, "Advanced Peripheral Bus 1 (APB1) registers"),
85 APB2 => (APB2ENR, apb2enr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
86 AHB => (AHBENR, ahbenr, "Advanced High-performance Bus (AHB) registers"),
87}
88
89const HSI: u32 = 8_000_000; #[derive(Debug, Default, PartialEq, Eq)]
101pub struct Config {
102 hse: Option<u32>,
103 hse_bypass: bool,
104 hclk: Option<u32>,
105 pclk1: Option<u32>,
106 pclk2: Option<u32>,
107 sysclk: Option<u32>,
108 adcclk: Option<u32>,
109}
110
111impl Config {
112 pub const DEFAULT: Self = Self {
113 hse: None,
114 hse_bypass: false,
115 hclk: None,
116 pclk1: None,
117 pclk2: None,
118 sysclk: None,
119 adcclk: None,
120 };
121
122 pub fn hsi() -> Self {
123 Self::DEFAULT
124 }
125
126 pub fn hse(freq: Hertz) -> Self {
127 Self::DEFAULT.use_hse(freq)
128 }
129
130 #[inline(always)]
134 pub fn use_hse(mut self, freq: Hertz) -> Self {
135 self.hse = Some(freq.raw());
136 self
137 }
138
139 pub fn bypass_hse_oscillator(self) -> Self {
147 Self {
148 hse_bypass: true,
149 ..self
150 }
151 }
152
153 #[inline(always)]
155 pub fn hclk(mut self, freq: Hertz) -> Self {
156 self.hclk = Some(freq.raw());
157 self
158 }
159
160 #[inline(always)]
162 pub fn pclk1(mut self, freq: Hertz) -> Self {
163 self.pclk1 = Some(freq.raw());
164 self
165 }
166
167 #[inline(always)]
169 pub fn pclk2(mut self, freq: Hertz) -> Self {
170 self.pclk2 = Some(freq.raw());
171 self
172 }
173
174 #[inline(always)]
176 pub fn sysclk(mut self, freq: Hertz) -> Self {
177 self.sysclk = Some(freq.raw());
178 self
179 }
180
181 #[inline(always)]
183 pub fn adcclk(mut self, freq: Hertz) -> Self {
184 self.adcclk = Some(freq.raw());
185 self
186 }
187}
188
189impl Rcc {
190 #[inline(always)]
203 pub fn freeze(self, cfg: impl Into<RawConfig>, acr: &mut ACR) -> Self {
204 let cfg = cfg.into();
205 let clocks = cfg.get_clocks();
206 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
208 unsafe {
209 acr.acr().write(|w| {
210 w.latency().bits(if clocks.sysclk <= MHz(24) {
211 0b000
212 } else if clocks.sysclk <= MHz(48) {
213 0b001
214 } else {
215 0b010
216 })
217 });
218 }
219
220 let rcc = unsafe { &*RCC::ptr() };
221
222 if cfg.hse.is_some() {
223 rcc.cr().modify(|_, w| {
226 if cfg.hse_bypass {
227 w.hsebyp().bypassed();
228 }
229 w.hseon().set_bit()
230 });
231
232 while rcc.cr().read().hserdy().bit_is_clear() {}
233 }
234
235 if let Some(pllmul_bits) = cfg.pllmul {
236 #[allow(unused_unsafe)]
239 rcc.cfgr().modify(|_, w| unsafe {
240 w.pllmul().bits(pllmul_bits).pllsrc().bit(cfg.hse.is_some())
241 });
242
243 rcc.cr().modify(|_, w| w.pllon().set_bit());
244
245 while rcc.cr().read().pllrdy().bit_is_clear() {}
246 }
247
248 #[cfg(feature = "connectivity")]
250 rcc.cfgr().modify(|_, w| unsafe {
251 w.adcpre().variant(cfg.adcpre);
252 w.ppre2().bits(cfg.ppre2 as u8);
253 w.ppre1().bits(cfg.ppre1 as u8);
254 w.hpre().bits(cfg.hpre as u8);
255 w.otgfspre().variant(cfg.usbpre);
256 w.sw().bits(if cfg.pllmul.is_some() {
257 0b10
259 } else if cfg.hse.is_some() {
260 0b1
262 } else {
263 0b0
265 })
266 });
267
268 #[cfg(feature = "stm32f103")]
269 rcc.cfgr().modify(|_, w| unsafe {
270 w.adcpre().variant(cfg.adcpre);
271 w.ppre2().bits(cfg.ppre2 as u8);
272 w.ppre1().bits(cfg.ppre1 as u8);
273 w.hpre().bits(cfg.hpre as u8);
274 w.usbpre().variant(cfg.usbpre);
275 w.sw().bits(if cfg.pllmul.is_some() {
276 0b10
278 } else {
279 u8::from(cfg.hse.is_some())
281 })
282 });
283
284 #[cfg(any(feature = "stm32f100", feature = "stm32f101"))]
285 rcc.cfgr().modify(|_, w| unsafe {
286 w.adcpre().variant(cfg.adcpre);
287 w.ppre2().bits(cfg.ppre2 as u8);
288 w.ppre1().bits(cfg.ppre1 as u8);
289 w.hpre().bits(cfg.hpre as u8);
290 w.sw().bits(if cfg.pllmul.is_some() {
291 0b10
293 } else if cfg.hse.is_some() {
294 0b1
296 } else {
297 0b0
299 })
300 });
301
302 Self {
303 rb: self.rb,
304 clocks,
305 }
306 }
307}
308
309pub trait BkpExt {
310 fn constrain(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain;
312}
313
314impl BkpExt for BKP {
315 fn constrain(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain {
316 BKP::enable(rcc);
318 PWR::enable(rcc);
319
320 pwr.cr().modify(|_r, w| w.dbp().set_bit());
322
323 BackupDomain { _regs: self }
324 }
325}
326
327#[derive(Clone, Copy, Debug, PartialEq, Eq)]
342pub struct Clocks {
343 hclk: Hertz,
344 pclk1: Hertz,
345 pclk2: Hertz,
346 ppre1: u8,
347 ppre2: u8,
348 sysclk: Hertz,
349 adcclk: Hertz,
350 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
351 usbclk_valid: bool,
352}
353
354impl Default for Clocks {
355 fn default() -> Clocks {
356 let freq = HSI.Hz();
357 Clocks {
358 hclk: freq,
359 pclk1: freq,
360 pclk2: freq,
361 ppre1: 1,
362 ppre2: 1,
363 sysclk: freq,
364 adcclk: freq / 2,
365 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
366 usbclk_valid: false,
367 }
368 }
369}
370
371impl Clocks {
372 pub const fn hclk(&self) -> Hertz {
374 self.hclk
375 }
376
377 pub const fn pclk1(&self) -> Hertz {
379 self.pclk1
380 }
381
382 pub const fn pclk2(&self) -> Hertz {
384 self.pclk2
385 }
386
387 pub const fn pclk1_tim(&self) -> Hertz {
389 Hertz::from_raw(self.pclk1.raw() * if self.ppre1() == 1 { 1 } else { 2 })
390 }
391
392 pub const fn pclk2_tim(&self) -> Hertz {
394 Hertz::from_raw(self.pclk2.raw() * if self.ppre2() == 1 { 1 } else { 2 })
395 }
396
397 pub(crate) const fn ppre1(&self) -> u8 {
398 self.ppre1
399 }
400
401 #[allow(dead_code)]
403 pub(crate) const fn ppre2(&self) -> u8 {
404 self.ppre2
405 }
406
407 pub const fn sysclk(&self) -> Hertz {
409 self.sysclk
410 }
411
412 pub const fn adcclk(&self) -> Hertz {
414 self.adcclk
415 }
416
417 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
419 pub const fn usbclk_valid(&self) -> bool {
420 self.usbclk_valid
421 }
422}
423
424pub trait BusClock {
426 fn clock(clocks: &Clocks) -> Hertz;
428}
429
430pub trait BusTimerClock {
432 fn timer_clock(clocks: &Clocks) -> Hertz;
434}
435
436impl<T> BusClock for T
437where
438 T: RccBus,
439 T::Bus: BusClock,
440{
441 fn clock(clocks: &Clocks) -> Hertz {
442 T::Bus::clock(clocks)
443 }
444}
445
446impl<T> BusTimerClock for T
447where
448 T: RccBus,
449 T::Bus: BusTimerClock,
450{
451 fn timer_clock(clocks: &Clocks) -> Hertz {
452 T::Bus::timer_clock(clocks)
453 }
454}
455
456impl BusClock for AHB {
457 fn clock(clocks: &Clocks) -> Hertz {
458 clocks.hclk
459 }
460}
461
462impl BusClock for APB1 {
463 fn clock(clocks: &Clocks) -> Hertz {
464 clocks.pclk1
465 }
466}
467
468impl BusClock for APB2 {
469 fn clock(clocks: &Clocks) -> Hertz {
470 clocks.pclk2
471 }
472}
473
474impl BusTimerClock for APB1 {
475 fn timer_clock(clocks: &Clocks) -> Hertz {
476 clocks.pclk1_tim()
477 }
478}
479
480impl BusTimerClock for APB2 {
481 fn timer_clock(clocks: &Clocks) -> Hertz {
482 clocks.pclk2_tim()
483 }
484}
485
486pub trait RccBus {
488 type Bus;
490}
491
492pub trait Enable: RccBus {
494 fn enable(rcc: &mut RCC);
496
497 fn disable(rcc: &mut RCC);
499
500 fn is_enabled() -> bool;
502
503 #[inline]
505 fn is_disabled() -> bool {
506 !Self::is_enabled()
507 }
508
509 unsafe fn enable_unchecked() {
513 let mut rcc = unsafe { RCC::steal() };
514 Self::enable(&mut rcc);
515 }
516
517 unsafe fn disable_unchecked() {
521 let mut rcc = unsafe { RCC::steal() };
522 Self::disable(&mut rcc);
523 }
524}
525
526pub trait Reset: RccBus {
528 fn reset(rcc: &mut RCC);
530
531 unsafe fn reset_unchecked() {
535 let mut rcc = unsafe { RCC::steal() };
536 Self::reset(&mut rcc);
537 }
538}
539
540#[derive(Clone, Copy, Debug, PartialEq)]
541pub struct RawConfig {
542 pub hse: Option<u32>,
543 pub hse_bypass: bool,
544 pub pllmul: Option<u8>,
545 pub hpre: HPre,
546 pub ppre1: PPre,
547 pub ppre2: PPre,
548 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
549 pub usbpre: UsbPre,
550 pub adcpre: AdcPre,
551 pub allow_overclock: bool,
552}
553
554impl Default for RawConfig {
555 fn default() -> Self {
556 Self {
557 hse: None,
558 hse_bypass: false,
559 pllmul: None,
560 hpre: HPre::Div1,
561 ppre1: PPre::Div1,
562 ppre2: PPre::Div1,
563 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
564 usbpre: UsbPre::Div1_5,
565 adcpre: AdcPre::Div2,
566 allow_overclock: false,
567 }
568 }
569}
570
571#[repr(u8)]
572#[derive(Clone, Copy, Debug, PartialEq, Eq)]
573pub enum HPre {
574 Div1 = 7,
576 Div2 = 8,
578 Div4 = 9,
580 Div8 = 10,
582 Div16 = 11,
584 Div64 = 12,
586 Div128 = 13,
588 Div256 = 14,
590 Div512 = 15,
592}
593
594#[derive(Clone, Copy, Debug, PartialEq, Eq)]
595#[repr(u8)]
596pub enum PPre {
597 Div1 = 3,
599 Div2 = 4,
601 Div4 = 5,
603 Div8 = 6,
605 Div16 = 7,
607}
608
609#[cfg(feature = "stm32f103")]
610pub type UsbPre = rcc::cfgr::USBPRE;
611#[cfg(feature = "connectivity")]
612pub type UsbPre = rcc::cfgr::OTGFSPRE;
613pub type AdcPre = rcc::cfgr::ADCPRE;
614
615impl From<Config> for RawConfig {
616 #[inline(always)]
617 fn from(cfgr: Config) -> Self {
618 Self::from_cfgr(cfgr)
619 }
620}
621
622impl RawConfig {
623 pub const fn from_cfgr(cfgr: Config) -> Self {
624 let hse = cfgr.hse;
625 let hse_bypass = cfgr.hse_bypass;
626 let pllsrcclk = if let Some(hse) = hse { hse } else { HSI / 2 };
627
628 let pllmul = if let Some(sysclk) = cfgr.sysclk {
629 sysclk / pllsrcclk
630 } else {
631 1
632 };
633
634 let (pllmul_bits, sysclk) = if pllmul == 1 {
635 (None, if let Some(hse) = hse { hse } else { HSI })
636 } else {
637 #[cfg(not(feature = "connectivity"))]
638 let pllmul = match pllmul {
639 1..=16 => pllmul,
640 0 => 1,
641 _ => 16,
642 };
643
644 #[cfg(feature = "connectivity")]
645 let pllmul = match pllmul {
646 4..=9 => pllmul,
647 0..=3 => 4,
648 _ => 9,
649 };
650
651 (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
652 };
653
654 let hpre_bits = if let Some(hclk) = cfgr.hclk {
655 match sysclk / hclk {
656 0..=1 => HPre::Div1,
657 2 => HPre::Div2,
658 3..=5 => HPre::Div4,
659 6..=11 => HPre::Div8,
660 12..=39 => HPre::Div16,
661 40..=95 => HPre::Div64,
662 96..=191 => HPre::Div128,
663 192..=383 => HPre::Div256,
664 _ => HPre::Div512,
665 }
666 } else {
667 HPre::Div1
668 };
669
670 let hclk = if hpre_bits as u8 >= 0b1100 {
671 sysclk / (1 << (hpre_bits as u8 - 0b0110))
672 } else {
673 sysclk / (1 << (hpre_bits as u8 - 0b0111))
674 };
675
676 let pclk1 = if let Some(pclk1) = cfgr.pclk1 {
677 pclk1
678 } else if hclk < 36_000_000 {
679 hclk
680 } else {
681 36_000_000
682 };
683 let ppre1_bits = match (hclk + pclk1 - 1) / pclk1 {
684 0 | 1 => PPre::Div1,
685 2 => PPre::Div2,
686 3..=5 => PPre::Div4,
687 6..=11 => PPre::Div8,
688 _ => PPre::Div16,
689 };
690
691 let ppre2_bits = if let Some(pclk2) = cfgr.pclk2 {
692 match hclk / pclk2 {
693 0..=1 => PPre::Div1,
694 2 => PPre::Div2,
695 3..=5 => PPre::Div4,
696 6..=11 => PPre::Div8,
697 _ => PPre::Div16,
698 }
699 } else {
700 PPre::Div1
701 };
702
703 let ppre2 = 1 << (ppre2_bits as u8 - 0b011);
704 let pclk2 = hclk / (ppre2 as u32);
705
706 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
708 let usbpre = match (hse, pllmul_bits, sysclk) {
709 (Some(_), Some(_), 72_000_000) => UsbPre::Div1_5,
710 _ => UsbPre::Div1,
711 };
712
713 let apre_bits = if let Some(adcclk) = cfgr.adcclk {
714 match pclk2 / adcclk {
715 0..=2 => AdcPre::Div2,
716 3..=4 => AdcPre::Div4,
717 5..=7 => AdcPre::Div6,
718 _ => AdcPre::Div8,
719 }
720 } else {
721 AdcPre::Div8
722 };
723
724 Self {
725 hse,
726 hse_bypass,
727 pllmul: pllmul_bits,
728 hpre: hpre_bits,
729 ppre1: ppre1_bits,
730 ppre2: ppre2_bits,
731 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
732 usbpre,
733 adcpre: apre_bits,
734 allow_overclock: false,
735 }
736 }
737
738 fn get_clocks(&self) -> Clocks {
741 let sysclk = if let Some(pllmul_bits) = self.pllmul {
742 let pllsrcclk = if let Some(hse) = self.hse {
743 hse
744 } else {
745 HSI / 2
746 };
747 pllsrcclk * (pllmul_bits as u32 + 2)
748 } else if let Some(hse) = self.hse {
749 hse
750 } else {
751 HSI
752 };
753
754 let hclk = if self.hpre as u8 >= 0b1100 {
755 sysclk / (1 << (self.hpre as u8 - 0b0110))
756 } else {
757 sysclk / (1 << (self.hpre as u8 - 0b0111))
758 };
759
760 let ppre1 = 1 << (self.ppre1 as u8 - 0b011);
761 let pclk1 = hclk / (ppre1 as u32);
762
763 let ppre2 = 1 << (self.ppre2 as u8 - 0b011);
764 let pclk2 = hclk / (ppre2 as u32);
765
766 let apre = (self.adcpre as u8 + 1) << 1;
767 let adcclk = pclk2 / (apre as u32);
768
769 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
772 let usbclk_valid = matches!(
773 (self.hse, self.pllmul, sysclk),
774 (Some(_), Some(_), 72_000_000) | (Some(_), Some(_), 48_000_000)
775 );
776
777 assert!(
778 self.allow_overclock
779 || (sysclk <= 72_000_000
780 && hclk <= 72_000_000
781 && pclk1 <= 36_000_000
782 && pclk2 <= 72_000_000
783 && adcclk <= 14_000_000)
784 );
785
786 Clocks {
787 hclk: hclk.Hz(),
788 pclk1: pclk1.Hz(),
789 pclk2: pclk2.Hz(),
790 ppre1,
791 ppre2,
792 sysclk: sysclk.Hz(),
793 adcclk: adcclk.Hz(),
794 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
795 usbclk_valid,
796 }
797 }
798}
799
800#[test]
801fn rcc_config_usb() {
802 let cfgr = Config::default()
803 .use_hse(8.MHz())
804 .sysclk(48.MHz())
805 .pclk1(24.MHz());
806
807 let config = RawConfig::from_cfgr(cfgr);
808 let config_expected = RawConfig {
809 hse: Some(8_000_000),
810 hse_bypass: false,
811 pllmul: Some(4),
812 hpre: HPre::Div1,
813 ppre1: PPre::Div2,
814 ppre2: PPre::Div1,
815 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
816 usbpre: UsbPre::Div1,
817 adcpre: AdcPre::Div8,
818 allow_overclock: false,
819 };
820 assert_eq!(config, config_expected);
821
822 let clocks = config.get_clocks();
823 let clocks_expected = Clocks {
824 hclk: 48.MHz(),
825 pclk1: 24.MHz(),
826 pclk2: 48.MHz(),
827 ppre1: 2,
828 ppre2: 1,
829 sysclk: 48.MHz(),
830 adcclk: 6.MHz(),
831 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
832 usbclk_valid: true,
833 };
834 assert_eq!(clocks, clocks_expected);
835}