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