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