1use crate::pac::{rcc, PWR, RCC};
4
5use crate::flash::ACR;
6#[cfg(any(feature = "stm32f103", feature = "connectivity"))]
7use crate::time::MHz;
8use fugit::{HertzU32 as Hertz, RateExtU32};
9
10use crate::backup_domain::BackupDomain;
11
12mod enable;
13
14pub trait RccExt {
16 fn constrain(self) -> Rcc;
18}
19
20impl RccExt for RCC {
21 fn constrain(self) -> Rcc {
22 Rcc {
23 cfgr: CFGR {
24 hse: None,
25 hclk: None,
26 pclk1: None,
27 pclk2: None,
28 sysclk: None,
29 adcclk: None,
30 },
31 bkp: BKP { _0: () },
32 }
33 }
34}
35
36pub struct Rcc {
46 pub cfgr: CFGR,
47 pub bkp: BKP,
48}
49
50pub struct AHB {
52 _0: (),
53}
54
55impl AHB {
56 fn enr(rcc: &rcc::RegisterBlock) -> &rcc::AHBENR {
57 &rcc.ahbenr
58 }
59}
60
61pub struct APB1 {
63 _0: (),
64}
65
66impl APB1 {
67 fn enr(rcc: &rcc::RegisterBlock) -> &rcc::APB1ENR {
68 &rcc.apb1enr
69 }
70
71 fn rstr(rcc: &rcc::RegisterBlock) -> &rcc::APB1RSTR {
72 &rcc.apb1rstr
73 }
74}
75
76impl APB1 {
77 pub fn set_pwren() {
79 let rcc = unsafe { &*RCC::ptr() };
80 PWR::enable(rcc);
81 }
82}
83
84pub struct APB2 {
86 _0: (),
87}
88
89impl APB2 {
90 fn enr(rcc: &rcc::RegisterBlock) -> &rcc::APB2ENR {
91 &rcc.apb2enr
92 }
93
94 fn rstr(rcc: &rcc::RegisterBlock) -> &rcc::APB2RSTR {
95 &rcc.apb2rstr
96 }
97}
98
99const HSI: u32 = 8_000_000; #[derive(Debug, Default, PartialEq, Eq)]
111pub struct CFGR {
112 hse: Option<u32>,
113 hclk: Option<u32>,
114 pclk1: Option<u32>,
115 pclk2: Option<u32>,
116 sysclk: Option<u32>,
117 adcclk: Option<u32>,
118}
119
120impl CFGR {
121 #[inline(always)]
125 pub fn use_hse(mut self, freq: Hertz) -> Self {
126 self.hse = Some(freq.raw());
127 self
128 }
129
130 #[inline(always)]
132 pub fn hclk(mut self, freq: Hertz) -> Self {
133 self.hclk = Some(freq.raw());
134 self
135 }
136
137 #[inline(always)]
139 pub fn pclk1(mut self, freq: Hertz) -> Self {
140 self.pclk1 = Some(freq.raw());
141 self
142 }
143
144 #[inline(always)]
146 pub fn pclk2(mut self, freq: Hertz) -> Self {
147 self.pclk2 = Some(freq.raw());
148 self
149 }
150
151 #[inline(always)]
153 pub fn sysclk(mut self, freq: Hertz) -> Self {
154 self.sysclk = Some(freq.raw());
155 self
156 }
157
158 #[inline(always)]
160 pub fn adcclk(mut self, freq: Hertz) -> Self {
161 self.adcclk = Some(freq.raw());
162 self
163 }
164
165 #[inline(always)]
179 pub fn freeze(self, acr: &mut ACR) -> Clocks {
180 let cfg = Config::from_cfgr(self);
181 Self::_freeze_with_config(cfg, acr)
182 }
183
184 #[inline(always)]
185 pub fn freeze_with_config(self, cfg: Config, acr: &mut ACR) -> Clocks {
186 Self::_freeze_with_config(cfg, acr)
187 }
188
189 #[allow(unused_variables)]
190 fn _freeze_with_config(cfg: Config, acr: &mut ACR) -> Clocks {
191 let clocks = cfg.get_clocks();
192 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
194 unsafe {
195 acr.acr().write(|w| {
196 w.latency().bits(if clocks.sysclk <= MHz(24) {
197 0b000
198 } else if clocks.sysclk <= MHz(48) {
199 0b001
200 } else {
201 0b010
202 })
203 })
204 }
205
206 let rcc = unsafe { &*RCC::ptr() };
207
208 if cfg.hse.is_some() {
209 rcc.cr.modify(|_, w| w.hseon().set_bit());
212
213 while rcc.cr.read().hserdy().bit_is_clear() {}
214 }
215
216 if let Some(pllmul_bits) = cfg.pllmul {
217 #[allow(unused_unsafe)]
220 rcc.cfgr.modify(|_, w| unsafe {
221 w.pllmul().bits(pllmul_bits).pllsrc().bit(cfg.hse.is_some())
222 });
223
224 rcc.cr.modify(|_, w| w.pllon().set_bit());
225
226 while rcc.cr.read().pllrdy().bit_is_clear() {}
227 }
228
229 #[cfg(feature = "connectivity")]
231 rcc.cfgr.modify(|_, w| unsafe {
232 w.adcpre().variant(cfg.adcpre);
233 w.ppre2()
234 .bits(cfg.ppre2 as u8)
235 .ppre1()
236 .bits(cfg.ppre1 as u8)
237 .hpre()
238 .bits(cfg.hpre as u8)
239 .otgfspre()
240 .variant(cfg.usbpre)
241 .sw()
242 .bits(if cfg.pllmul.is_some() {
243 0b10
245 } else if cfg.hse.is_some() {
246 0b1
248 } else {
249 0b0
251 })
252 });
253
254 #[cfg(feature = "stm32f103")]
255 rcc.cfgr.modify(|_, w| unsafe {
256 w.adcpre().variant(cfg.adcpre);
257 w.ppre2()
258 .bits(cfg.ppre2 as u8)
259 .ppre1()
260 .bits(cfg.ppre1 as u8)
261 .hpre()
262 .bits(cfg.hpre as u8)
263 .usbpre()
264 .variant(cfg.usbpre)
265 .sw()
266 .bits(if cfg.pllmul.is_some() {
267 0b10
269 } else {
270 u8::from(cfg.hse.is_some())
272 })
273 });
274
275 #[cfg(any(feature = "stm32f100", feature = "stm32f101"))]
276 rcc.cfgr.modify(|_, w| unsafe {
277 w.adcpre().variant(cfg.adcpre);
278 w.ppre2()
279 .bits(cfg.ppre2 as u8)
280 .ppre1()
281 .bits(cfg.ppre1 as u8)
282 .hpre()
283 .bits(cfg.hpre as u8)
284 .sw()
285 .bits(if cfg.pllmul.is_some() {
286 0b10
288 } else if cfg.hse.is_some() {
289 0b1
291 } else {
292 0b0
294 })
295 });
296
297 clocks
298 }
299}
300
301pub struct BKP {
302 _0: (),
303}
304
305impl BKP {
306 pub fn constrain(self, bkp: crate::pac::BKP, pwr: &mut PWR) -> BackupDomain {
308 let rcc = unsafe { &(*RCC::ptr()) };
310 crate::pac::BKP::enable(rcc);
311 crate::pac::PWR::enable(rcc);
312
313 pwr.cr.modify(|_r, w| w.dbp().set_bit());
315
316 BackupDomain { _regs: bkp }
317 }
318}
319
320#[derive(Clone, Copy, Debug, PartialEq, Eq)]
335pub struct Clocks {
336 hclk: Hertz,
337 pclk1: Hertz,
338 pclk2: Hertz,
339 ppre1: u8,
340 ppre2: u8,
341 sysclk: Hertz,
342 adcclk: Hertz,
343 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
344 usbclk_valid: bool,
345}
346
347impl Clocks {
348 pub const fn hclk(&self) -> Hertz {
350 self.hclk
351 }
352
353 pub const fn pclk1(&self) -> Hertz {
355 self.pclk1
356 }
357
358 pub const fn pclk2(&self) -> Hertz {
360 self.pclk2
361 }
362
363 pub const fn pclk1_tim(&self) -> Hertz {
365 Hertz::from_raw(self.pclk1.raw() * if self.ppre1() == 1 { 1 } else { 2 })
366 }
367
368 pub const fn pclk2_tim(&self) -> Hertz {
370 Hertz::from_raw(self.pclk2.raw() * if self.ppre2() == 1 { 1 } else { 2 })
371 }
372
373 pub(crate) const fn ppre1(&self) -> u8 {
374 self.ppre1
375 }
376
377 #[allow(dead_code)]
379 pub(crate) const fn ppre2(&self) -> u8 {
380 self.ppre2
381 }
382
383 pub const fn sysclk(&self) -> Hertz {
385 self.sysclk
386 }
387
388 pub const fn adcclk(&self) -> Hertz {
390 self.adcclk
391 }
392
393 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
395 pub const fn usbclk_valid(&self) -> bool {
396 self.usbclk_valid
397 }
398}
399
400pub trait BusClock {
402 fn clock(clocks: &Clocks) -> Hertz;
404}
405
406pub trait BusTimerClock {
408 fn timer_clock(clocks: &Clocks) -> Hertz;
410}
411
412impl<T> BusClock for T
413where
414 T: RccBus,
415 T::Bus: BusClock,
416{
417 fn clock(clocks: &Clocks) -> Hertz {
418 T::Bus::clock(clocks)
419 }
420}
421
422impl<T> BusTimerClock for T
423where
424 T: RccBus,
425 T::Bus: BusTimerClock,
426{
427 fn timer_clock(clocks: &Clocks) -> Hertz {
428 T::Bus::timer_clock(clocks)
429 }
430}
431
432impl BusClock for AHB {
433 fn clock(clocks: &Clocks) -> Hertz {
434 clocks.hclk
435 }
436}
437
438impl BusClock for APB1 {
439 fn clock(clocks: &Clocks) -> Hertz {
440 clocks.pclk1
441 }
442}
443
444impl BusClock for APB2 {
445 fn clock(clocks: &Clocks) -> Hertz {
446 clocks.pclk2
447 }
448}
449
450impl BusTimerClock for APB1 {
451 fn timer_clock(clocks: &Clocks) -> Hertz {
452 clocks.pclk1_tim()
453 }
454}
455
456impl BusTimerClock for APB2 {
457 fn timer_clock(clocks: &Clocks) -> Hertz {
458 clocks.pclk2_tim()
459 }
460}
461
462pub trait RccBus: crate::Sealed {
464 type Bus;
466}
467
468pub trait Enable: RccBus {
470 fn enable(rcc: &rcc::RegisterBlock);
471 fn disable(rcc: &rcc::RegisterBlock);
472}
473pub trait Reset: RccBus {
475 fn reset(rcc: &rcc::RegisterBlock);
476}
477
478#[derive(Clone, Copy, Debug, PartialEq)]
479pub struct Config {
480 pub hse: Option<u32>,
481 pub pllmul: Option<u8>,
482 pub hpre: HPre,
483 pub ppre1: PPre,
484 pub ppre2: PPre,
485 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
486 pub usbpre: UsbPre,
487 pub adcpre: AdcPre,
488}
489
490impl Default for Config {
491 fn default() -> Self {
492 Self {
493 hse: None,
494 pllmul: None,
495 hpre: HPre::Div1,
496 ppre1: PPre::Div1,
497 ppre2: PPre::Div1,
498 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
499 usbpre: UsbPre::Div15,
500 adcpre: AdcPre::Div2,
501 }
502 }
503}
504
505#[repr(u8)]
506#[derive(Clone, Copy, Debug, PartialEq, Eq)]
507pub enum HPre {
508 Div1 = 7,
510 Div2 = 8,
512 Div4 = 9,
514 Div8 = 10,
516 Div16 = 11,
518 Div64 = 12,
520 Div128 = 13,
522 Div256 = 14,
524 Div512 = 15,
526}
527
528#[derive(Clone, Copy, Debug, PartialEq, Eq)]
529#[repr(u8)]
530pub enum PPre {
531 Div1 = 3,
533 Div2 = 4,
535 Div4 = 5,
537 Div8 = 6,
539 Div16 = 7,
541}
542
543#[cfg(feature = "stm32f103")]
544pub type UsbPre = rcc::cfgr::USBPRE_A;
545#[cfg(feature = "connectivity")]
546pub type UsbPre = rcc::cfgr::OTGFSPRE_A;
547pub type AdcPre = rcc::cfgr::ADCPRE_A;
548
549impl Config {
550 pub const fn from_cfgr(cfgr: CFGR) -> Self {
551 let hse = cfgr.hse;
552 let pllsrcclk = if let Some(hse) = hse { hse } else { HSI / 2 };
553
554 let pllmul = if let Some(sysclk) = cfgr.sysclk {
555 sysclk / pllsrcclk
556 } else {
557 1
558 };
559
560 let (pllmul_bits, sysclk) = if pllmul == 1 {
561 (None, if let Some(hse) = hse { hse } else { HSI })
562 } else {
563 #[cfg(not(feature = "connectivity"))]
564 let pllmul = match pllmul {
565 1..=16 => pllmul,
566 0 => 1,
567 _ => 16,
568 };
569
570 #[cfg(feature = "connectivity")]
571 let pllmul = match pllmul {
572 4..=9 => pllmul,
573 0..=3 => 4,
574 _ => 9,
575 };
576
577 (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
578 };
579
580 let hpre_bits = if let Some(hclk) = cfgr.hclk {
581 match sysclk / hclk {
582 0..=1 => HPre::Div1,
583 2 => HPre::Div2,
584 3..=5 => HPre::Div4,
585 6..=11 => HPre::Div8,
586 12..=39 => HPre::Div16,
587 40..=95 => HPre::Div64,
588 96..=191 => HPre::Div128,
589 192..=383 => HPre::Div256,
590 _ => HPre::Div512,
591 }
592 } else {
593 HPre::Div1
594 };
595
596 let hclk = if hpre_bits as u8 >= 0b1100 {
597 sysclk / (1 << (hpre_bits as u8 - 0b0110))
598 } else {
599 sysclk / (1 << (hpre_bits as u8 - 0b0111))
600 };
601
602 let pclk1 = if let Some(pclk1) = cfgr.pclk1 {
603 pclk1
604 } else if hclk < 36_000_000 {
605 hclk
606 } else {
607 36_000_000
608 };
609 let ppre1_bits = match (hclk + pclk1 - 1) / pclk1 {
610 0 | 1 => PPre::Div1,
611 2 => PPre::Div2,
612 3..=5 => PPre::Div4,
613 6..=11 => PPre::Div8,
614 _ => PPre::Div16,
615 };
616
617 let ppre2_bits = if let Some(pclk2) = cfgr.pclk2 {
618 match hclk / pclk2 {
619 0..=1 => PPre::Div1,
620 2 => PPre::Div2,
621 3..=5 => PPre::Div4,
622 6..=11 => PPre::Div8,
623 _ => PPre::Div16,
624 }
625 } else {
626 PPre::Div1
627 };
628
629 let ppre2 = 1 << (ppre2_bits as u8 - 0b011);
630 let pclk2 = hclk / (ppre2 as u32);
631
632 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
634 let usbpre = match (hse, pllmul_bits, sysclk) {
635 (Some(_), Some(_), 72_000_000) => UsbPre::Div15,
636 _ => UsbPre::Div1,
637 };
638
639 let apre_bits = if let Some(adcclk) = cfgr.adcclk {
640 match pclk2 / adcclk {
641 0..=2 => AdcPre::Div2,
642 3..=4 => AdcPre::Div4,
643 5..=7 => AdcPre::Div6,
644 _ => AdcPre::Div8,
645 }
646 } else {
647 AdcPre::Div8
648 };
649
650 Self {
651 hse,
652 pllmul: pllmul_bits,
653 hpre: hpre_bits,
654 ppre1: ppre1_bits,
655 ppre2: ppre2_bits,
656 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
657 usbpre,
658 adcpre: apre_bits,
659 }
660 }
661
662 fn get_clocks(&self) -> Clocks {
665 let sysclk = if let Some(pllmul_bits) = self.pllmul {
666 let pllsrcclk = if let Some(hse) = self.hse {
667 hse
668 } else {
669 HSI / 2
670 };
671 pllsrcclk * (pllmul_bits as u32 + 2)
672 } else if let Some(hse) = self.hse {
673 hse
674 } else {
675 HSI
676 };
677
678 let hclk = if self.hpre as u8 >= 0b1100 {
679 sysclk / (1 << (self.hpre as u8 - 0b0110))
680 } else {
681 sysclk / (1 << (self.hpre as u8 - 0b0111))
682 };
683
684 let ppre1 = 1 << (self.ppre1 as u8 - 0b011);
685 let pclk1 = hclk / (ppre1 as u32);
686
687 let ppre2 = 1 << (self.ppre2 as u8 - 0b011);
688 let pclk2 = hclk / (ppre2 as u32);
689
690 let apre = (self.adcpre as u8 + 1) << 1;
691 let adcclk = pclk2 / (apre as u32);
692
693 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
696 let usbclk_valid = matches!(
697 (self.hse, self.pllmul, sysclk),
698 (Some(_), Some(_), 72_000_000) | (Some(_), Some(_), 48_000_000)
699 );
700
701 assert!(
702 sysclk <= 72_000_000
703 && hclk <= 72_000_000
704 && pclk1 <= 36_000_000
705 && pclk2 <= 72_000_000
706 && adcclk <= 14_000_000
707 );
708
709 Clocks {
710 hclk: hclk.Hz(),
711 pclk1: pclk1.Hz(),
712 pclk2: pclk2.Hz(),
713 ppre1,
714 ppre2,
715 sysclk: sysclk.Hz(),
716 adcclk: adcclk.Hz(),
717 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
718 usbclk_valid,
719 }
720 }
721}
722
723#[test]
724fn rcc_config_usb() {
725 let cfgr = CFGR::default()
726 .use_hse(8.MHz())
727 .sysclk(48.MHz())
728 .pclk1(24.MHz());
729
730 let config = Config::from_cfgr(cfgr);
731 let config_expected = Config {
732 hse: Some(8_000_000),
733 pllmul: Some(4),
734 hpre: HPre::Div1,
735 ppre1: PPre::Div2,
736 ppre2: PPre::Div1,
737 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
738 usbpre: UsbPre::Div1,
739 adcpre: AdcPre::Div8,
740 };
741 assert_eq!(config, config_expected);
742
743 let clocks = config.get_clocks();
744 let clocks_expected = Clocks {
745 hclk: 48.MHz(),
746 pclk1: 24.MHz(),
747 pclk2: 48.MHz(),
748 ppre1: 2,
749 ppre2: 1,
750 sysclk: 48.MHz(),
751 adcclk: 6.MHz(),
752 #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
753 usbclk_valid: true,
754 };
755 assert_eq!(clocks, clocks_expected);
756}