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