1mod enable;
4
5#[cfg(any(feature = "stm32f103", feature = "connectivity"))]
6use crate::time::MHz;
7use crate::{
8 backup_domain::BackupDomain,
9 flash::ACR,
10 fugit::{HertzU32, RateExtU32},
11 pac::{
12 BKP, PWR, RCC,
13 rcc::{self, RegisterBlock as RccRB},
14 },
15};
16use core::ops::{Deref, DerefMut};
17
18pub trait RccInit {
19 fn init(self) -> Rcc;
20}
21
22impl RccInit for RCC {
23 fn init(self) -> Rcc {
24 Rcc {
25 rb: self,
26 clocks: Clocks::default(),
27 }
28 }
29}
30
31pub struct Rcc {
41 pub clocks: Clocks,
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 = "stm32f103", 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 = "stm32f103")]
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 = "stm32f100", feature = "stm32f101"))]
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 Self {
160 rb: self.rb,
161 clocks,
162 }
163 }
164
165 pub fn enable<T: Enable>(&mut self, _periph: &T) {
166 T::enable(self);
167 }
168
169 pub fn reset<T: Reset>(&mut self, _periph: &T) {
170 T::reset(self);
171 }
172}
173
174impl Deref for Rcc {
175 type Target = RCC;
176 fn deref(&self) -> &Self::Target {
177 &self.rb
178 }
179}
180
181impl DerefMut for Rcc {
182 fn deref_mut(&mut self) -> &mut Self::Target {
183 &mut self.rb
184 }
185}
186
187macro_rules! bus_struct {
188 ($($busX:ident => ($EN:ident, $en:ident, $($RST:ident, $rst:ident,)? $doc:literal),)+) => {
189 $(
190 #[doc = $doc]
191 #[non_exhaustive]
192 pub struct $busX;
193
194 impl $busX {
195 pub(crate) fn enr(rcc: &RccRB) -> &rcc::$EN {
196 rcc.$en()
197 }
198 $(
199 pub(crate) fn rstr(rcc: &RccRB) -> &rcc::$RST {
200 rcc.$rst()
201 }
202 )?
203 }
204 )+
205 };
206}
207
208bus_struct! {
209 APB1 => (APB1ENR, apb1enr, APB1RSTR, apb1rstr, "Advanced Peripheral Bus 1 (APB1) registers"),
210 APB2 => (APB2ENR, apb2enr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
211 AHB => (AHBENR, ahbenr, "Advanced High-performance Bus (AHB) registers"),
212}
213
214const HSI: u32 = 8_000_000; #[derive(Debug, Default, PartialEq, Eq)]
226pub struct Config {
227 hse: Option<u32>,
228 hse_bypass: bool,
229 hclk: Option<u32>,
230 pclk1: Option<u32>,
231 pclk2: Option<u32>,
232 sysclk: Option<u32>,
233 adcclk: Option<u32>,
234}
235
236impl Config {
237 pub const DEFAULT: Self = Self {
238 hse: None,
239 hse_bypass: false,
240 hclk: None,
241 pclk1: None,
242 pclk2: None,
243 sysclk: None,
244 adcclk: None,
245 };
246
247 pub fn hsi() -> Self {
248 Self::DEFAULT
249 }
250
251 pub fn hse(freq: HertzU32) -> Self {
252 Self::DEFAULT.use_hse(freq)
253 }
254
255 #[inline(always)]
259 pub fn use_hse(mut self, freq: HertzU32) -> Self {
260 self.hse = Some(freq.raw());
261 self
262 }
263
264 pub fn bypass_hse_oscillator(self) -> Self {
272 Self {
273 hse_bypass: true,
274 ..self
275 }
276 }
277
278 #[inline(always)]
280 pub fn hclk(mut self, freq: HertzU32) -> Self {
281 self.hclk = Some(freq.raw());
282 self
283 }
284
285 #[inline(always)]
287 pub fn pclk1(mut self, freq: HertzU32) -> Self {
288 self.pclk1 = Some(freq.raw());
289 self
290 }
291
292 #[inline(always)]
294 pub fn pclk2(mut self, freq: HertzU32) -> Self {
295 self.pclk2 = Some(freq.raw());
296 self
297 }
298
299 #[inline(always)]
301 pub fn sysclk(mut self, freq: HertzU32) -> Self {
302 self.sysclk = Some(freq.raw());
303 self
304 }
305
306 #[inline(always)]
308 pub fn adcclk(mut self, freq: HertzU32) -> Self {
309 self.adcclk = Some(freq.raw());
310 self
311 }
312}
313
314pub trait BkpInit {
315 fn init(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain;
317}
318
319impl BkpInit for BKP {
320 fn init(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain {
321 BKP::enable(rcc);
323 PWR::enable(rcc);
324
325 pwr.cr().modify(|_r, w| w.dbp().set_bit());
327
328 BackupDomain { _regs: self }
329 }
330}
331
332#[derive(Clone, Copy, Debug, PartialEq, Eq)]
347pub struct Clocks {
348 hclk: HertzU32,
349 pclk1: HertzU32,
350 pclk2: HertzU32,
351 ppre1: u8,
352 ppre2: u8,
353 sysclk: HertzU32,
354 adcclk: HertzU32,
355 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
356 usbclk_valid: bool,
357}
358
359impl Default for Clocks {
360 fn default() -> Clocks {
361 let freq = HSI.Hz();
362 Clocks {
363 hclk: freq,
364 pclk1: freq,
365 pclk2: freq,
366 ppre1: 1,
367 ppre2: 1,
368 sysclk: freq,
369 adcclk: freq / 2,
370 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
371 usbclk_valid: false,
372 }
373 }
374}
375
376impl Clocks {
377 pub const fn hclk(&self) -> HertzU32 {
379 self.hclk
380 }
381
382 pub const fn pclk1(&self) -> HertzU32 {
384 self.pclk1
385 }
386
387 pub const fn pclk2(&self) -> HertzU32 {
389 self.pclk2
390 }
391
392 pub const fn pclk1_tim(&self) -> HertzU32 {
394 HertzU32::from_raw(self.pclk1.raw() * if self.ppre1() == 1 { 1 } else { 2 })
395 }
396
397 pub const fn pclk2_tim(&self) -> HertzU32 {
399 HertzU32::from_raw(self.pclk2.raw() * if self.ppre2() == 1 { 1 } else { 2 })
400 }
401
402 pub(crate) const fn ppre1(&self) -> u8 {
403 self.ppre1
404 }
405
406 #[allow(dead_code)]
408 pub(crate) const fn ppre2(&self) -> u8 {
409 self.ppre2
410 }
411
412 pub const fn sysclk(&self) -> HertzU32 {
414 self.sysclk
415 }
416
417 pub const fn adcclk(&self) -> HertzU32 {
419 self.adcclk
420 }
421
422 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
424 pub const fn usbclk_valid(&self) -> bool {
425 self.usbclk_valid
426 }
427}
428
429pub trait BusClock {
431 fn clock(clocks: &Clocks) -> HertzU32;
433}
434
435impl BusClock for AHB {
436 fn clock(clocks: &Clocks) -> HertzU32 {
437 clocks.hclk
438 }
439}
440
441impl BusClock for APB1 {
442 fn clock(clocks: &Clocks) -> HertzU32 {
443 clocks.pclk1
444 }
445}
446
447impl BusClock for APB2 {
448 fn clock(clocks: &Clocks) -> HertzU32 {
449 clocks.pclk2
450 }
451}
452
453pub trait GetClock: RccBus {
454 fn get_clock(&self, rcc: &Rcc) -> HertzU32;
455}
456
457impl<T> GetClock for T
458where
459 T: RccBus,
460 T::Bus: BusClock,
461{
462 fn get_clock(&self, rcc: &Rcc) -> HertzU32 {
463 T::Bus::clock(&rcc.clocks)
464 }
465}
466
467pub trait BusTimerClock {
469 fn timer_clock(clocks: &Clocks) -> HertzU32;
471}
472
473impl BusTimerClock for APB1 {
474 fn timer_clock(clocks: &Clocks) -> HertzU32 {
475 clocks.pclk1_tim()
476 }
477}
478
479impl BusTimerClock for APB2 {
480 fn timer_clock(clocks: &Clocks) -> HertzU32 {
481 clocks.pclk2_tim()
482 }
483}
484
485pub trait GetTimerClock: RccBus {
486 fn get_timer_clock(&self, rcc: &Rcc) -> HertzU32;
487}
488
489impl<T> GetTimerClock for T
490where
491 T: RccBus,
492 T::Bus: BusTimerClock,
493{
494 fn get_timer_clock(&self, rcc: &Rcc) -> HertzU32 {
495 T::Bus::timer_clock(&rcc.clocks)
496 }
497}
498
499pub trait RccBus {
501 type Bus;
503}
504
505pub trait Enable: RccBus {
507 fn enable(rcc: &mut RCC);
509
510 fn disable(rcc: &mut RCC);
512
513 fn is_enabled() -> bool;
515
516 #[inline]
518 fn is_disabled() -> bool {
519 !Self::is_enabled()
520 }
521
522 unsafe fn enable_unchecked() {
526 let mut rcc = unsafe { RCC::steal() };
527 Self::enable(&mut rcc);
528 }
529
530 unsafe fn disable_unchecked() {
534 let mut rcc = unsafe { RCC::steal() };
535 Self::disable(&mut rcc);
536 }
537}
538
539pub trait Reset: RccBus {
541 fn reset(rcc: &mut RCC);
543
544 unsafe fn reset_unchecked() {
548 let mut rcc = unsafe { RCC::steal() };
549 Self::reset(&mut rcc);
550 }
551}
552
553#[derive(Clone, Copy, Debug, PartialEq)]
554pub struct RawConfig {
555 pub hse: Option<u32>,
556 pub hse_bypass: bool,
557 pub pllmul: Option<u8>,
558 pub hpre: HPre,
559 pub ppre1: PPre,
560 pub ppre2: PPre,
561 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
562 pub usbpre: UsbPre,
563 pub adcpre: AdcPre,
564 pub allow_overclock: bool,
565}
566
567impl Default for RawConfig {
568 fn default() -> Self {
569 Self {
570 hse: None,
571 hse_bypass: false,
572 pllmul: None,
573 hpre: HPre::Div1,
574 ppre1: PPre::Div1,
575 ppre2: PPre::Div1,
576 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
577 usbpre: UsbPre::Div1_5,
578 adcpre: AdcPre::Div2,
579 allow_overclock: false,
580 }
581 }
582}
583
584#[repr(u8)]
585#[derive(Clone, Copy, Debug, PartialEq, Eq)]
586pub enum HPre {
587 Div1 = 7,
589 Div2 = 8,
591 Div4 = 9,
593 Div8 = 10,
595 Div16 = 11,
597 Div64 = 12,
599 Div128 = 13,
601 Div256 = 14,
603 Div512 = 15,
605}
606
607#[derive(Clone, Copy, Debug, PartialEq, Eq)]
608#[repr(u8)]
609pub enum PPre {
610 Div1 = 3,
612 Div2 = 4,
614 Div4 = 5,
616 Div8 = 6,
618 Div16 = 7,
620}
621
622#[cfg(feature = "stm32f103")]
623pub type UsbPre = rcc::cfgr::USBPRE;
624#[cfg(feature = "connectivity")]
625pub type UsbPre = rcc::cfgr::OTGFSPRE;
626pub type AdcPre = rcc::cfgr::ADCPRE;
627
628impl From<Config> for RawConfig {
629 #[inline(always)]
630 fn from(cfgr: Config) -> Self {
631 Self::from_cfgr(cfgr)
632 }
633}
634
635impl RawConfig {
636 pub const fn from_cfgr(cfgr: Config) -> Self {
637 let hse = cfgr.hse;
638 let hse_bypass = cfgr.hse_bypass;
639 let pllsrcclk = if let Some(hse) = hse { hse } else { HSI / 2 };
640
641 let pllmul = if let Some(sysclk) = cfgr.sysclk {
642 sysclk / pllsrcclk
643 } else {
644 1
645 };
646
647 let (pllmul_bits, sysclk) = if pllmul == 1 {
648 (None, if let Some(hse) = hse { hse } else { HSI })
649 } else {
650 #[cfg(not(feature = "connectivity"))]
651 let pllmul = match pllmul {
652 1..=16 => pllmul,
653 0 => 1,
654 _ => 16,
655 };
656
657 #[cfg(feature = "connectivity")]
658 let pllmul = match pllmul {
659 4..=9 => pllmul,
660 0..=3 => 4,
661 _ => 9,
662 };
663
664 (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
665 };
666
667 let hpre_bits = if let Some(hclk) = cfgr.hclk {
668 match sysclk / hclk {
669 0..=1 => HPre::Div1,
670 2 => HPre::Div2,
671 3..=5 => HPre::Div4,
672 6..=11 => HPre::Div8,
673 12..=39 => HPre::Div16,
674 40..=95 => HPre::Div64,
675 96..=191 => HPre::Div128,
676 192..=383 => HPre::Div256,
677 _ => HPre::Div512,
678 }
679 } else {
680 HPre::Div1
681 };
682
683 let hclk = if hpre_bits as u8 >= 0b1100 {
684 sysclk / (1 << (hpre_bits as u8 - 0b0110))
685 } else {
686 sysclk / (1 << (hpre_bits as u8 - 0b0111))
687 };
688
689 let pclk1 = if let Some(pclk1) = cfgr.pclk1 {
690 pclk1
691 } else if hclk < 36_000_000 {
692 hclk
693 } else {
694 36_000_000
695 };
696 let ppre1_bits = match hclk.div_ceil(pclk1) {
697 0 | 1 => PPre::Div1,
698 2 => PPre::Div2,
699 3..=5 => PPre::Div4,
700 6..=11 => PPre::Div8,
701 _ => PPre::Div16,
702 };
703
704 let ppre2_bits = if let Some(pclk2) = cfgr.pclk2 {
705 match hclk / pclk2 {
706 0..=1 => PPre::Div1,
707 2 => PPre::Div2,
708 3..=5 => PPre::Div4,
709 6..=11 => PPre::Div8,
710 _ => PPre::Div16,
711 }
712 } else {
713 PPre::Div1
714 };
715
716 let ppre2 = 1 << (ppre2_bits as u8 - 0b011);
717 let pclk2 = hclk / (ppre2 as u32);
718
719 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
721 let usbpre = match (hse, pllmul_bits, sysclk) {
722 (Some(_), Some(_), 72_000_000) => UsbPre::Div1_5,
723 _ => UsbPre::Div1,
724 };
725
726 let apre_bits = if let Some(adcclk) = cfgr.adcclk {
727 match pclk2 / adcclk {
728 0..=2 => AdcPre::Div2,
729 3..=4 => AdcPre::Div4,
730 5..=7 => AdcPre::Div6,
731 _ => AdcPre::Div8,
732 }
733 } else {
734 AdcPre::Div8
735 };
736
737 Self {
738 hse,
739 hse_bypass,
740 pllmul: pllmul_bits,
741 hpre: hpre_bits,
742 ppre1: ppre1_bits,
743 ppre2: ppre2_bits,
744 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
745 usbpre,
746 adcpre: apre_bits,
747 allow_overclock: false,
748 }
749 }
750
751 fn get_clocks(&self) -> Clocks {
754 let sysclk = if let Some(pllmul_bits) = self.pllmul {
755 let pllsrcclk = if let Some(hse) = self.hse {
756 hse
757 } else {
758 HSI / 2
759 };
760 pllsrcclk * (pllmul_bits as u32 + 2)
761 } else if let Some(hse) = self.hse {
762 hse
763 } else {
764 HSI
765 };
766
767 let hclk = if self.hpre as u8 >= 0b1100 {
768 sysclk / (1 << (self.hpre as u8 - 0b0110))
769 } else {
770 sysclk / (1 << (self.hpre as u8 - 0b0111))
771 };
772
773 let ppre1 = 1 << (self.ppre1 as u8 - 0b011);
774 let pclk1 = hclk / (ppre1 as u32);
775
776 let ppre2 = 1 << (self.ppre2 as u8 - 0b011);
777 let pclk2 = hclk / (ppre2 as u32);
778
779 let apre = (self.adcpre as u8 + 1) << 1;
780 let adcclk = pclk2 / (apre as u32);
781
782 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
785 let usbclk_valid = matches!(
786 (self.hse, self.pllmul, sysclk),
787 (Some(_), Some(_), 72_000_000) | (Some(_), Some(_), 48_000_000)
788 );
789
790 assert!(
791 self.allow_overclock
792 || (sysclk <= 72_000_000
793 && hclk <= 72_000_000
794 && pclk1 <= 36_000_000
795 && pclk2 <= 72_000_000
796 && adcclk <= 14_000_000)
797 );
798
799 Clocks {
800 hclk: hclk.Hz(),
801 pclk1: pclk1.Hz(),
802 pclk2: pclk2.Hz(),
803 ppre1,
804 ppre2,
805 sysclk: sysclk.Hz(),
806 adcclk: adcclk.Hz(),
807 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
808 usbclk_valid,
809 }
810 }
811}
812
813#[test]
814fn rcc_config_usb() {
815 let cfgr = Config::default()
816 .use_hse(8.MHz())
817 .sysclk(48.MHz())
818 .pclk1(24.MHz());
819
820 let config = RawConfig::from_cfgr(cfgr);
821 let config_expected = RawConfig {
822 hse: Some(8_000_000),
823 hse_bypass: false,
824 pllmul: Some(4),
825 hpre: HPre::Div1,
826 ppre1: PPre::Div2,
827 ppre2: PPre::Div1,
828 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
829 usbpre: UsbPre::Div1,
830 adcpre: AdcPre::Div8,
831 allow_overclock: false,
832 };
833 assert_eq!(config, config_expected);
834
835 let clocks = config.get_clocks();
836 let clocks_expected = Clocks {
837 hclk: 48.MHz(),
838 pclk1: 24.MHz(),
839 pclk2: 48.MHz(),
840 ppre1: 2,
841 ppre2: 1,
842 sysclk: 48.MHz(),
843 adcclk: 6.MHz(),
844 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
845 usbclk_valid: true,
846 };
847 assert_eq!(clocks, clocks_expected);
848}