stm32f3xx_hal/
rcc.rs

1//! # Reset and Clock Control
2//!
3//! The most important function this module
4//! delivers is the clock configuration.
5//!
6//! To configure the clock, we first have to obtain the
7//! device peripherals.
8//!
9//! ```
10//! # use cortex_m_rt::entry;
11//! # use stm32f3xx-hal::{prelude::*, time::rate::*};
12//!
13//! # #[entry]
14//! # fn main() -> ! {
15//! // Get our peripherals
16//! let dp = pac::Peripherals::take().unwrap();
17//!
18//! let mut flash = dp.FLASH.constrain();
19//! let mut rcc = dp.RCC.constrain();
20//! # }
21//! ```
22//!
23//! After that we can configure the clock
24//!
25//! ```
26//! # use cortex_m_rt::entry;
27//! # use stm32f3xx-hal::{prelude::*, time::rate::*};
28//! #
29//! # #[entry]
30//! # fn main() -> ! {
31//! # let dp = pac::Peripherals::take().unwrap();
32//!
33//! # let mut flash = dp.FLASH.constrain();
34//! # let mut rcc = dp.RCC.constrain();
35//! let clocks = rcc.cfgr
36//!     // Using the external oscillator
37//!     // Set the frequency to that of the external oscillator
38//!     .use_hse(8.MHz())
39//!     // Set the frequency for the AHB bus,
40//!     // which the root of every following clock peripheral
41//!     .hclk(48.MHz())
42//!     // The sysclk is equivalent to the core clock
43//!     .sysclk(48.MHz())
44//!     // The following are peripheral clocks, which are both
45//!     // needed to configure specific peripherals.
46//!     // Looking at the peripheral function parameters
47//!     // should give more insight, which peripheral clock is needed.
48//!     .pclk1(12.MHz())
49//!     .pclk2(12.MHz())
50//!     // Freeze / apply the configuration and setup all clocks
51//!     .freeze(&mut flash.acr);
52//! # }
53//! ```
54//!
55//! All fields can be omitted and will internally be set to a calculated default.
56//! For more details read the documentation of the [`CFGR`] methods to
57//! find out how to setup the clock.
58
59use crate::pac::{
60    rcc::{self, cfgr, cfgr2},
61    RCC,
62};
63
64use crate::flash::ACR;
65use crate::time::{
66    fixed_point::FixedPoint,
67    rate::{Hertz, Megahertz},
68};
69
70impl crate::private::Sealed for RCC {}
71
72/// Extension trait that constrains the []`RCC`] peripheral
73#[allow(clippy::module_name_repetitions)]
74pub trait RccExt: crate::private::Sealed {
75    /// Constrains the [`RCC`] peripheral.
76    ///
77    /// Consumes the [`pac::RCC`] peripheral and converts it to a [`HAL`] internal type
78    /// constraining it's public access surface to fit the design of the `HAL`.
79    ///
80    /// [`pac::RCC`]: `crate::pac::RCC`
81    /// [`HAL`]: `crate`
82    fn constrain(self) -> Rcc;
83}
84
85mod enable;
86
87impl RccExt for RCC {
88    fn constrain(self) -> Rcc {
89        Rcc {
90            ahb: AHB { _0: () },
91            apb1: APB1 { _0: () },
92            apb2: APB2 { _0: () },
93            bdcr: BDCR { _0: () },
94            cfgr: CFGR::default(),
95        }
96    }
97}
98
99/// Constrained RCC peripheral
100///
101/// An instance of this struct is acquired by calling the [`constrain`](RccExt::constrain) function
102/// on the [`RCC`](crate::pac::RCC) struct.
103///
104/// ```
105/// let dp = pac::Peripherals::take().unwrap();
106/// let rcc = dp.RCC.constrain();
107/// ```
108pub struct Rcc {
109    /// AMBA High-performance Bus (AHB) registers
110    pub ahb: AHB,
111    /// Advanced Peripheral Bus 1 (APB1) registers
112    pub apb1: APB1,
113    /// Advanced Peripheral Bus 2 (APB2) registers
114    pub apb2: APB2,
115    /// RCC Backup Domain
116    pub bdcr: BDCR,
117    /// Clock configuration
118    pub cfgr: CFGR,
119}
120
121/// AMBA High-performance Bus (AHB) registers
122///
123/// An instance of this struct is acquired from the [`RCC`](crate::pac::RCC) struct.
124///
125/// ```
126/// let dp = pac::Peripherals::take().unwrap();
127/// let rcc = dp.RCC.constrain();
128/// use_ahb(&mut rcc.ahb)
129/// ```
130pub struct AHB {
131    _0: (),
132}
133
134/// Advanced Peripheral Bus 1 (APB1) registers
135///
136/// An instance of this struct is acquired from the [`RCC`](crate::pac::RCC) struct.
137///
138/// ```
139/// let dp = pac::Peripherals::take().unwrap();
140/// let rcc = dp.RCC.constrain();
141/// use_apb1(&mut rcc.apb1)
142/// ```
143pub struct APB1 {
144    _0: (),
145}
146
147/// Advanced Peripheral Bus 2 (APB2) registers
148///
149/// An instance of this struct is acquired from the [`RCC`](crate::pac::RCC) struct.
150///
151/// ```
152/// let dp = pac::Peripherals::take().unwrap();
153/// let rcc = dp.RCC.constrain();
154/// use_apb2(&mut rcc.apb2)
155/// ```
156pub struct APB2 {
157    _0: (),
158}
159
160macro_rules! bus_struct {
161    ($($busX:ident => ($EN:ident, $en:ident, $RST:ident, $rst:ident),)+) => {
162        $(
163            impl $busX {
164                fn new() -> Self {
165                    Self { _0: () }
166                }
167
168                #[allow(unused)]
169                fn enr(&self) -> &rcc::$EN {
170                    // FIXME: this should still be shared carefully
171                    // SAFETY: this proxy grants exclusive access to this register
172                    unsafe { &(*RCC::ptr()).$en }
173                }
174
175                #[allow(unused)]
176                fn rstr(&self) -> &rcc::$RST {
177                    // FIXME: this should still be shared carefully
178                    // SAFETY: this proxy grants exclusive access to this register
179                    unsafe { &(*RCC::ptr()).$rst }
180                }
181            }
182        )+
183    };
184}
185
186bus_struct! {
187    AHB => (AHBENR, ahbenr, AHBRSTR, ahbrstr),
188    APB1 => (APB1ENR, apb1enr, APB1RSTR, apb1rstr),
189    APB2 => (APB2ENR, apb2enr, APB2RSTR, apb2rstr),
190}
191
192/// Bus associated to peripheral
193#[allow(clippy::module_name_repetitions)]
194pub trait RccBus: crate::Sealed {
195    /// The underlying bus peripheral
196    type Bus;
197}
198
199/// Enable/disable peripheral
200pub trait Enable: RccBus {
201    /// Enables peripheral
202    fn enable(bus: &mut Self::Bus);
203
204    /// Disables peripheral
205    fn disable(bus: &mut Self::Bus);
206
207    /// Check if peripheral enabled
208    fn is_enabled() -> bool;
209
210    /// Check if peripheral disabled
211    fn is_disabled() -> bool;
212
213    /// Enables peripheral
214    ///
215    /// # Safety
216    ///
217    /// Takes access to RCC internally, so you have to make sure
218    /// you don't have race condition accessing RCC registers
219    unsafe fn enable_unchecked();
220
221    /// Disables peripheral
222    ///
223    /// # Safety
224    ///
225    /// Takes access to RCC internally, so you have to make sure
226    /// you don't have race condition accessing RCC registers
227    unsafe fn disable_unchecked();
228}
229
230/// Reset peripheral
231pub trait Reset: RccBus {
232    /// Resets peripheral
233    fn reset(bus: &mut Self::Bus);
234
235    /// # Safety
236    ///
237    /// Resets peripheral. Takes access to RCC internally
238    unsafe fn reset_unchecked();
239}
240
241/// Frequency on bus that peripheral is connected in
242pub trait BusClock {
243    /// Calculates frequency depending on `Clock` state
244    fn clock(clocks: &Clocks) -> Hertz;
245}
246
247impl<T> BusClock for T
248where
249    T: RccBus,
250    T::Bus: BusClock,
251{
252    fn clock(clocks: &Clocks) -> Hertz {
253        T::Bus::clock(clocks)
254    }
255}
256
257impl BusClock for AHB {
258    fn clock(clocks: &Clocks) -> Hertz {
259        clocks.hclk
260    }
261}
262impl BusClock for APB1 {
263    fn clock(clocks: &Clocks) -> Hertz {
264        clocks.pclk1
265    }
266}
267impl BusClock for APB2 {
268    fn clock(clocks: &Clocks) -> Hertz {
269        clocks.pclk2
270    }
271}
272
273/// Frequency on bus that timer is connected in
274pub trait BusTimerClock {
275    /// Calculates base frequency of timer depending on `Clock` state
276    fn timer_clock(clocks: &Clocks) -> Hertz;
277}
278
279impl<T> BusTimerClock for T
280where
281    T: RccBus,
282    T::Bus: BusTimerClock,
283{
284    fn timer_clock(clocks: &Clocks) -> Hertz {
285        T::Bus::timer_clock(clocks)
286    }
287}
288
289impl BusTimerClock for APB1 {
290    fn timer_clock(clocks: &Clocks) -> Hertz {
291        let pclk_mul = if clocks.ppre1 > 1 { 2 } else { 1 };
292        Hertz(clocks.pclk1.0 * pclk_mul)
293    }
294}
295impl BusTimerClock for APB2 {
296    fn timer_clock(clocks: &Clocks) -> Hertz {
297        let pclk_mul = if clocks.ppre2 > 1 { 2 } else { 1 };
298        Hertz(clocks.pclk2.0 * pclk_mul)
299    }
300}
301
302/// Frequency of interal hardware RC oscillator (HSI OSC)
303pub const HSI: Hertz = Hertz(8_000_000);
304/// Frequency of external 32.768 kHz oscillator (LSE OSC)
305pub const LSE: Hertz = Hertz(32_768);
306
307// some microcontrollers do not have USB
308#[cfg(any(feature = "stm32f301", feature = "stm32f318", feature = "stm32f334",))]
309mod usb_clocking {
310    use crate::rcc::PllConfig;
311
312    pub(crate) fn is_valid(
313        _sysclk: u32,
314        _hse: Option<u32>,
315        _pclk1: u32,
316        _pll_config: &Option<PllConfig>,
317    ) -> (bool, bool) {
318        (false, false)
319    }
320
321    pub(crate) fn set_usbpre<W>(w: &mut W, _: bool) -> &mut W {
322        w
323    }
324}
325
326#[cfg(not(any(feature = "stm32f301", feature = "stm32f318", feature = "stm32f334",)))]
327mod usb_clocking {
328    use crate::pac::rcc::cfgr;
329    use crate::rcc::PllConfig;
330
331    /// Check for all clock options to be
332    pub(crate) fn is_valid(
333        sysclk: u32,
334        hse: Option<u32>,
335        pclk1: u32,
336        pll_config: &Option<PllConfig>,
337    ) -> (cfgr::USBPRE_A, bool) {
338        // the USB clock is only valid if an external crystal is used, the PLL is enabled, and the
339        // PLL output frequency is a supported one.
340        // usbpre == false: divide clock by 1.5, otherwise no division
341        let usb_ok = hse.is_some() && pll_config.is_some();
342        // The APB1 clock must have a minimum frequency of 10 MHz to avoid data overrun/underrun
343        // problems. [RM0316 32.5.2]
344        if pclk1 >= 10_000_000 {
345            match (usb_ok, sysclk) {
346                (true, 72_000_000) => (cfgr::USBPRE_A::Div15, true),
347                (true, 48_000_000) => (cfgr::USBPRE_A::Div1, true),
348                _ => (cfgr::USBPRE_A::Div1, false),
349            }
350        } else {
351            (cfgr::USBPRE_A::Div1, false)
352        }
353    }
354
355    pub(crate) fn set_usbpre(w: &mut cfgr::W, usb_prescale: cfgr::USBPRE_A) -> &mut cfgr::W {
356        w.usbpre().variant(usb_prescale)
357    }
358}
359
360/// Backup Domain Control register (`RCC_BDCR`)
361pub struct BDCR {
362    _0: (),
363}
364
365impl BDCR {
366    #[allow(unused)]
367    #[allow(clippy::unused_self)]
368    #[must_use]
369    pub(crate) fn bdcr(&mut self) -> &rcc::BDCR {
370        // SAFETY: this proxy grants exclusive access to this register
371        unsafe { &(*RCC::ptr()).bdcr }
372    }
373}
374
375/// Clock configuration
376///
377/// An instance of this struct is acquired from the [`RCC`](crate::pac::RCC) struct.
378///
379/// ```
380/// let dp = pac::Peripherals::take().unwrap();
381/// let rcc = dp.RCC.constrain();
382/// use_cfgr(&mut rcc.cfgr)
383/// ```
384pub struct CFGR {
385    hse: Option<u32>,
386    hse_bypass: bool,
387    pll_bypass: bool,
388    css: bool,
389    hclk: Option<u32>,
390    pclk1: Option<u32>,
391    pclk2: Option<u32>,
392    sysclk: Option<u32>,
393}
394
395impl Default for CFGR {
396    fn default() -> Self {
397        Self {
398            hse: None,
399            hse_bypass: false,
400            pll_bypass: true,
401            css: false,
402            hclk: None,
403            pclk1: None,
404            pclk2: None,
405            sysclk: None,
406        }
407    }
408}
409
410pub(crate) struct PllConfig {
411    src: cfgr::PLLSRC_A,
412    mul: cfgr::PLLMUL_A,
413    div: Option<cfgr2::PREDIV_A>,
414}
415
416/// Determine the [greatest common divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor)
417///
418/// This function is based on the [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm).
419// TODO(Sh3Rm4n): As num-traits is a indirecty dependecy of this crate through embedded-time,
420// use its implementation instead.
421fn gcd(mut a: u32, mut b: u32) -> u32 {
422    while b != 0 {
423        let r = a % b;
424        a = b;
425        b = r;
426    }
427    a
428}
429
430/// Convert pll multiplier into equivalent register field type
431fn into_pll_mul(mul: u8) -> cfgr::PLLMUL_A {
432    match mul {
433        2 => cfgr::PLLMUL_A::Mul2,
434        3 => cfgr::PLLMUL_A::Mul3,
435        4 => cfgr::PLLMUL_A::Mul4,
436        5 => cfgr::PLLMUL_A::Mul5,
437        6 => cfgr::PLLMUL_A::Mul6,
438        7 => cfgr::PLLMUL_A::Mul7,
439        8 => cfgr::PLLMUL_A::Mul8,
440        9 => cfgr::PLLMUL_A::Mul9,
441        10 => cfgr::PLLMUL_A::Mul10,
442        11 => cfgr::PLLMUL_A::Mul11,
443        12 => cfgr::PLLMUL_A::Mul12,
444        13 => cfgr::PLLMUL_A::Mul13,
445        14 => cfgr::PLLMUL_A::Mul14,
446        15 => cfgr::PLLMUL_A::Mul15,
447        16 => cfgr::PLLMUL_A::Mul16,
448        _ => crate::unreachable!(),
449    }
450}
451
452/// Convert pll divisor into equivalent register field type
453fn into_pre_div(div: u8) -> cfgr2::PREDIV_A {
454    match div {
455        1 => cfgr2::PREDIV_A::Div1,
456        2 => cfgr2::PREDIV_A::Div2,
457        3 => cfgr2::PREDIV_A::Div3,
458        4 => cfgr2::PREDIV_A::Div4,
459        5 => cfgr2::PREDIV_A::Div5,
460        6 => cfgr2::PREDIV_A::Div6,
461        7 => cfgr2::PREDIV_A::Div7,
462        8 => cfgr2::PREDIV_A::Div8,
463        9 => cfgr2::PREDIV_A::Div9,
464        10 => cfgr2::PREDIV_A::Div10,
465        11 => cfgr2::PREDIV_A::Div11,
466        12 => cfgr2::PREDIV_A::Div12,
467        13 => cfgr2::PREDIV_A::Div13,
468        14 => cfgr2::PREDIV_A::Div14,
469        15 => cfgr2::PREDIV_A::Div15,
470        16 => cfgr2::PREDIV_A::Div16,
471        _ => crate::unreachable!(),
472    }
473}
474
475impl CFGR {
476    /// Uses `HSE` (external oscillator) instead of `HSI` (internal RC oscillator) as the clock source.
477    ///
478    /// Will result in a hang if an external oscillator is not connected or it fails to start,
479    /// unless [css](CFGR::enable_css) is enabled.
480    ///
481    /// # Panics
482    ///
483    /// Panics if conversion from `Megahertz` to `Hertz` produces a value greater then `u32::MAX`.
484    #[must_use]
485    pub fn use_hse(mut self, freq: Megahertz) -> Self {
486        let freq: Hertz = crate::expect!(freq.try_into(), "ConversionError");
487        self.hse = Some(freq.integer());
488        self
489    }
490
491    /// Set this to disallow bypass the PLLCLK for the systemclock generation.
492    #[must_use]
493    pub fn use_pll(mut self) -> Self {
494        self.pll_bypass = false;
495        self
496    }
497
498    /// Enable `HSE` bypass.
499    ///
500    /// Uses user provided clock signal instead of an external oscillator.
501    /// `OSC_OUT` pin is free and can be used as GPIO.
502    ///
503    /// No effect if `HSE` is not enabled.
504    #[must_use]
505    pub fn bypass_hse(mut self) -> Self {
506        self.hse_bypass = true;
507        self
508    }
509
510    /// Enable `CSS` (Clock Security System).
511    ///
512    /// System clock is automatically switched to `HSI` and an interrupt (`CSSI`) is generated
513    /// when `HSE` clock failure is detected.
514    ///
515    /// No effect if `HSE` is not enabled.
516    #[must_use]
517    pub fn enable_css(mut self) -> Self {
518        self.css = true;
519        self
520    }
521
522    /// Sets a frequency for the AHB bus.
523    ///
524    /// # Panics
525    ///
526    /// Panics if conversion from `Megahertz` to `Hertz` produces a value greater then `u32::MAX`.
527    #[must_use]
528    pub fn hclk(mut self, freq: Megahertz) -> Self {
529        let freq: Hertz = crate::expect!(freq.try_into(), "ConversionError");
530        self.hclk = Some(freq.integer());
531        self
532    }
533
534    /// Sets a frequency for the `APB1` bus
535    ///
536    /// - Maximal supported frequency: 36 Mhz
537    ///
538    /// If not manually set, it will be set to [`CFGR::sysclk`] frequency
539    /// or [`CFGR::sysclk`] frequency / 2, if [`CFGR::sysclk`] > 36 Mhz
540    ///
541    /// # Panics
542    ///
543    /// Panics if conversion from `Megahertz` to `Hertz` produces a value greater then `u32::MAX`.
544    #[must_use]
545    pub fn pclk1(mut self, freq: Megahertz) -> Self {
546        let freq: Hertz = crate::expect!(freq.try_into(), "ConversionError");
547        self.pclk1 = Some(freq.integer());
548        self
549    }
550
551    /// Sets a frequency for the `APB2` bus
552    ///
553    /// # Resolution and Limits
554    ///
555    /// - Maximal supported frequency with HSE: 72 Mhz
556    /// - Maximal supported frequency without HSE: 64 Mhz
557    ///
558    /// This is true for devices **except** the following devices,
559    /// as these allow finer resolutions
560    /// even when using the internal oscillator:
561    ///
562    ///     [stm32f302xd,stm32f302xe,stm32f303xd,stm32f303xe,stm32f398]
563    ///
564    /// # Panics
565    ///
566    /// Panics if conversion from `Megahertz` to `Hertz` produces a value greater then `u32::MAX`.
567    #[must_use]
568    pub fn pclk2(mut self, freq: Megahertz) -> Self {
569        let freq: Hertz = crate::expect!(freq.try_into(), "ConversionError");
570        self.pclk2 = Some(freq.integer());
571        self
572    }
573
574    /// Sets the system (core) frequency
575    ///
576    /// # Resolution and Limits
577    ///
578    /// - Maximal supported frequency with `HSE`: 72 Mhz
579    /// - Maximal supported frequency without `HSE`: 64 Mhz
580    ///
581    /// If [`CFGR::use_hse`] is not set, `HSI / 2` will be used.
582    /// Only multiples of (HSI / 2) (4 Mhz) are allowed.
583    ///
584    /// This is true for devices **except** the following devices,
585    /// as these allow finer resolutions
586    /// even when using the internal oscillator:
587    ///
588    ///     [stm32f302xd,stm32f302xe,stm32f303xd,stm32f303xe,stm32f398]
589    ///
590    /// # Panics
591    ///
592    /// Panics if conversion from `Megahertz` to `Hertz` produces a value greater then `u32::MAX`.
593    #[must_use]
594    pub fn sysclk(mut self, freq: Megahertz) -> Self {
595        let freq: Hertz = crate::expect!(freq.try_into(), "ConversionError");
596        self.sysclk = Some(freq.integer());
597        self
598    }
599
600    /// Calculate the values for the pll multiplier (`PLLMUL`) and the pll divisior (`PLLDIV`).
601    ///
602    /// These values are chosen depending on the chosen system clock (SYSCLK) and the frequency of the
603    /// oscillator clock (`HSE` / `HSI`).
604    ///
605    /// For these devices, `PLL_SRC` can selected between the internal oscillator (`HSI`) and
606    /// the external oscillator (`HSE`).
607    ///
608    /// HSI is divided by 2 before its transferred to `PLL_SRC`.
609    /// HSE can be divided between `1..16`, before it is transferred to `PLL_SRC`.
610    /// After this system clock frequency (`SYSCLK`) can be changed via multiplier.
611    /// The value can be multiplied with `2..16`.
612    ///
613    /// To determine the optimal values, if `HSE` is chosen as `PLL_SRC`, the greatest common divisor
614    /// is calculated and the limitations of the possible values are taken into consideration.
615    ///
616    /// `HSI` is simpler to calculate, but the possible system clocks are less than `HSE`, because the
617    /// division is not configurable.
618    #[cfg(not(feature = "gpio-f303e"))]
619    fn calc_pll(&self, sysclk: u32) -> (u32, PllConfig) {
620        let pllsrcclk = self.hse.unwrap_or(HSI.integer() / 2);
621        // Get the optimal value for the pll divisor (PLL_DIV) and multiplier (PLL_MUL)
622        // Only for HSE PLL_DIV can be changed
623        let (pll_mul, pll_div): (u32, Option<u32>) = if self.hse.is_some() {
624            // Get the optimal value for the pll divisor (PLL_DIV) and multiplier (PLL_MUL)
625            // with the greatest common divisor calculation.
626            let common_divisor = gcd(sysclk, pllsrcclk);
627            let mut multiplier = sysclk / common_divisor;
628            let mut divisor = pllsrcclk / common_divisor;
629
630            // Check if the multiplier can be represented by PLL_MUL
631            if multiplier == 1 {
632                // PLL_MUL minimal value is 2
633                multiplier *= 2;
634                divisor *= 2;
635            }
636
637            // PLL_MUL maximal value is 16
638            crate::assert!(multiplier <= 16);
639
640            // PRE_DIV maximal value is 16
641            crate::assert!(divisor <= 16);
642
643            (multiplier, Some(divisor))
644        }
645        // HSI division is always divided by 2 and has no adjustable division
646        else {
647            let pll_mul = sysclk / pllsrcclk;
648            crate::assert!(pll_mul <= 16);
649            (pll_mul, None)
650        };
651
652        let sysclk = (pllsrcclk / pll_div.unwrap_or(1)) * pll_mul;
653        crate::assert!(sysclk <= 72_000_000);
654
655        let pll_src = if self.hse.is_some() {
656            cfgr::PLLSRC_A::HseDivPrediv
657        } else {
658            cfgr::PLLSRC_A::HsiDiv2
659        };
660
661        // Convert into register bit field types
662        #[allow(clippy::cast_possible_truncation)]
663        let pll_mul_bits = into_pll_mul(pll_mul as u8);
664        #[allow(clippy::cast_possible_truncation)]
665        let pll_div_bits = pll_div.map(|pll_div| into_pre_div(pll_div as u8));
666
667        (
668            sysclk,
669            PllConfig {
670                src: pll_src,
671                mul: pll_mul_bits,
672                div: pll_div_bits,
673            },
674        )
675    }
676
677    /// Calculate the values for the pll multiplier (`PLLMUL`) and the pll divisor (`PLLDIV`).
678    ///
679    /// These values are chosen depending on the chosen system clock (`SYSCLK`) and the frequency of the oscillator
680    /// clk (`HSI` / `HSE`).
681    ///
682    /// For these devices, `PLL_SRC` can be set to choose between the internal oscillator (HSI) and
683    /// the external oscillator (`HSE`).
684    /// After this the system clock frequency (`SYSCLK`) can be changed via a division and a
685    /// multiplication block.
686    /// It can be divided from with values `1..16`  and multiplied from `2..16`.
687    ///
688    /// To determine the optimal values, the greatest common divisor is calculated and the
689    /// limitations of the possible values are taken into considiration.
690    #[cfg(feature = "gpio-f303e")]
691    fn calc_pll(&self, sysclk: u32) -> (u32, PllConfig) {
692        let pllsrcclk = self.hse.unwrap_or(HSI.integer());
693
694        let (pll_mul, pll_div) = {
695            // Get the optimal value for the pll divisor (PLL_DIV) and multiplcator (PLL_MUL)
696            // with the greatest common divisor calculation.
697            let common_divisor = gcd(sysclk, pllsrcclk);
698            let mut multiplier = sysclk / common_divisor;
699            let mut divisor = pllsrcclk / common_divisor;
700
701            // Check if the multiplier can be represented by PLL_MUL
702            if multiplier == 1 {
703                // PLL_MUL minimal value is 2
704                multiplier *= 2;
705                divisor *= 2;
706            }
707
708            // PLL_MUL maximal value is 16
709            crate::assert!(multiplier <= 16);
710
711            // PRE_DIV maximal value is 16
712            crate::assert!(divisor <= 16);
713
714            (multiplier, divisor)
715        };
716
717        let sysclk = (pllsrcclk / pll_div) * pll_mul;
718        crate::assert!(sysclk <= 72_000_000);
719
720        // Select hardware clock source of the PLL
721        // TODO Check whether HSI_DIV2 could be useful
722        let pll_src = if self.hse.is_some() {
723            cfgr::PLLSRC_A::HseDivPrediv
724        } else {
725            cfgr::PLLSRC_A::HseDivPrediv
726        };
727
728        // Convert into register bit field types
729        #[allow(clippy::cast_possible_truncation)]
730        let pll_mul_bits = into_pll_mul(pll_mul as u8);
731        #[allow(clippy::cast_possible_truncation)]
732        let pll_div_bits = into_pre_div(pll_div as u8);
733
734        (
735            sysclk,
736            PllConfig {
737                src: pll_src,
738                mul: pll_mul_bits,
739                div: Some(pll_div_bits),
740            },
741        )
742    }
743
744    /// Get the system clock, the system clock source and the `pll_options`, if needed.
745    ///
746    /// The system clock source is determined by the chosen system clock and the provided hardware
747    /// clock.
748    /// This function does only chose the PLL if needed, otherwise it will use the oscillator clock as system clock.
749    ///
750    /// Calls [`CFGR::calc_pll`] internally.
751    fn get_sysclk(&self) -> (u32, cfgr::SW_A, Option<PllConfig>) {
752        // If a sysclk is given, check if the PLL has to be used,
753        // else select the system clock source, which is either HSI or HSE.
754        match (self.sysclk, self.hse) {
755            // No need to use the PLL
756            // PLL is needed for USB, but we can make this assumption, to not use PLL here,
757            // because the two valid USB clocks, 72 Mhz and 48 Mhz, can't be generated
758            // directly from neither the internal rc (8 Mhz)  nor the external
759            // Oscillator (max 32 Mhz), without using the PLL.
760            (Some(sysclk), Some(hse)) if sysclk == hse && self.pll_bypass => {
761                (hse, cfgr::SW_A::Hse, None)
762            }
763            // No need to use the PLL
764            (Some(sysclk), None) if sysclk == HSI.integer() && self.pll_bypass => {
765                (HSI.integer(), cfgr::SW_A::Hsi, None)
766            }
767            (Some(sysclk), _) => {
768                let (sysclk, pll_config) = self.calc_pll(sysclk);
769                (sysclk, cfgr::SW_A::Pll, Some(pll_config))
770            }
771            // Use HSE as system clock
772            (None, Some(hse)) => (hse, cfgr::SW_A::Hse, None),
773            // Use HSI as system clock
774            (None, None) => (HSI.integer(), cfgr::SW_A::Hsi, None),
775        }
776    }
777
778    /// Freezes the clock configuration, making it effective
779    ///
780    /// This function internally calculates the specific.
781    /// divisors for the different clock peripheries.
782    ///
783    /// # Panics
784    ///
785    /// If any of the set frequencies via [`sysclk`](CFGR::sysclk), [`hclk`](CFGR::hclk), [`pclk1`](CFGR::pclk1) or [`pclk2`](CFGR::pclk2)
786    /// are invalid or can not be reached because of e.g. to low frequencies
787    /// of the former, as [`sysclk`](CFGR::sysclk) depends on the configuration of [`hclk`](CFGR::hclk)
788    /// this function will panic.
789    pub fn freeze(self, acr: &mut ACR) -> Clocks {
790        let (sysclk, sysclk_source, pll_config) = self.get_sysclk();
791
792        let (hpre_bits, hpre) =
793            self.hclk
794                .map_or((cfgr::HPRE_A::Div1, 1), |hclk| match sysclk / hclk {
795                    0 => crate::unreachable!(),
796                    1 => (cfgr::HPRE_A::Div1, 1),
797                    2 => (cfgr::HPRE_A::Div2, 2),
798                    3..=5 => (cfgr::HPRE_A::Div4, 4),
799                    6..=11 => (cfgr::HPRE_A::Div8, 8),
800                    12..=39 => (cfgr::HPRE_A::Div16, 16),
801                    40..=95 => (cfgr::HPRE_A::Div64, 64),
802                    96..=191 => (cfgr::HPRE_A::Div128, 128),
803                    192..=383 => (cfgr::HPRE_A::Div256, 256),
804                    _ => (cfgr::HPRE_A::Div512, 512),
805                });
806
807        let hclk: u32 = sysclk / hpre;
808
809        crate::assert!(hclk <= 72_000_000);
810
811        let (mut ppre1_bits, mut ppre1) =
812            self.pclk1
813                .map_or((cfgr::PPRE1_A::Div1, 1), |pclk1| match hclk / pclk1 {
814                    0 => crate::unreachable!(),
815                    1 => (cfgr::PPRE1_A::Div1, 1),
816                    2 => (cfgr::PPRE1_A::Div2, 2),
817                    3..=5 => (cfgr::PPRE1_A::Div4, 4),
818                    6..=11 => (cfgr::PPRE1_A::Div8, 8),
819                    _ => (cfgr::PPRE1_A::Div16, 16),
820                });
821
822        let mut pclk1 = hclk / u32::from(ppre1);
823
824        // This ensures, that no panic happens, when
825        // pclk1 is not manually set.
826        // As hclk highest value is 72.MHz()
827        // dividing by 2 should always be sufficient
828        if self.pclk1.is_none() && pclk1 > 36_000_000 {
829            ppre1_bits = cfgr::PPRE1_A::Div2;
830            ppre1 = 2;
831            pclk1 = hclk / u32::from(ppre1);
832        }
833
834        crate::assert!(pclk1 <= 36_000_000);
835
836        let (ppre2_bits, ppre2) =
837            self.pclk2
838                .map_or((cfgr::PPRE2_A::Div1, 1), |pclk2| match hclk / pclk2 {
839                    0 => crate::unreachable!(),
840                    1 => (cfgr::PPRE2_A::Div1, 1),
841                    2 => (cfgr::PPRE2_A::Div2, 2),
842                    3..=5 => (cfgr::PPRE2_A::Div4, 4),
843                    6..=11 => (cfgr::PPRE2_A::Div8, 8),
844                    _ => (cfgr::PPRE2_A::Div16, 16),
845                });
846
847        let pclk2 = hclk / u32::from(ppre2);
848
849        crate::assert!(pclk2 <= 72_000_000);
850
851        // Adjust flash wait states according to the
852        // HCLK frequency (cpu core clock)
853        acr.acr().modify(|_, w| {
854            if hclk <= 24_000_000 {
855                w.latency().ws0()
856            } else if hclk <= 48_000_000 {
857                w.latency().ws1()
858            } else {
859                w.latency().ws2()
860            }
861        });
862
863        let (usbpre, usbclk_valid) = usb_clocking::is_valid(sysclk, self.hse, pclk1, &pll_config);
864
865        // SAFETY: RCC ptr is guaranteed to be valid. This funciton is the first, which uses the
866        // RCC peripheral: RCC.constrain() -> Rcc -> CFGR
867        let rcc = unsafe { &*RCC::ptr() };
868
869        // enable HSE and wait for it to be ready
870        if self.hse.is_some() {
871            rcc.cr.modify(|_, w| {
872                w.hsebyp().bit(self.hse_bypass);
873                w.csson().bit(self.css);
874                w.hseon().on()
875            });
876
877            while rcc.cr.read().hserdy().is_not_ready() {}
878        }
879
880        // enable PLL and wait for it to be ready
881        if let Some(pll_config) = pll_config {
882            rcc.cfgr.modify(|_, w| {
883                w.pllmul()
884                    .variant(pll_config.mul)
885                    .pllsrc()
886                    .variant(pll_config.src)
887            });
888
889            if let Some(pll_div) = pll_config.div {
890                rcc.cfgr2.modify(|_, w| w.prediv().variant(pll_div));
891            };
892
893            rcc.cr.modify(|_, w| w.pllon().on());
894
895            while rcc.cr.read().pllrdy().is_not_ready() {}
896        };
897
898        // set prescalers and clock source
899        rcc.cfgr.modify(|_, w| {
900            usb_clocking::set_usbpre(w, usbpre);
901
902            w.ppre2()
903                .variant(ppre2_bits)
904                .ppre1()
905                .variant(ppre1_bits)
906                .hpre()
907                .variant(hpre_bits)
908                .sw()
909                .variant(sysclk_source)
910        });
911
912        Clocks {
913            hclk: Hertz(hclk),
914            pclk1: Hertz(pclk1),
915            pclk2: Hertz(pclk2),
916            ppre1,
917            ppre2,
918            sysclk: Hertz(sysclk),
919            usbclk_valid,
920            pll_bypass: self.pll_bypass,
921        }
922    }
923}
924
925/// Frozen clock frequencies
926///
927/// The existence of this value indicates that the clock configuration can no longer be changed.
928/// This struct can be obtained via the [freeze](CFGR::freeze) method of the [CFGR](CFGR) struct.
929#[derive(Debug, Clone, Copy)]
930pub struct Clocks {
931    hclk: Hertz,
932    pclk1: Hertz,
933    pclk2: Hertz,
934    ppre1: u8,
935    ppre2: u8,
936    sysclk: Hertz,
937    usbclk_valid: bool,
938    pll_bypass: bool,
939}
940
941// TODO(Sh3Rm4n) Add defmt support for embedded-time!
942#[cfg(feature = "defmt")]
943impl defmt::Format for Clocks {
944    fn format(&self, f: defmt::Formatter) {
945        // Format as hexadecimal.
946        defmt::write!(
947            f,
948            "Clocks {{ hclk: {} Hz, pclk1: {} Hz, pclk2: {} Hz, ppre1: {:b}, ppre2: {:b}, sysclk: {} Hz, usbclk_valid: {}, pll_bypass: {} }}",
949            self.hclk.integer(),
950            self.pclk1.integer(),
951            self.pclk2.integer(),
952            self.ppre1,
953            self.ppre2,
954            self.sysclk.integer(),
955            self.usbclk_valid,
956            self.pll_bypass,
957        );
958    }
959}
960
961// TODO(Sh3Rm4n): Think of some way to generlize APB1 and APB2 as types to then implement a method,
962// with which the ppre or pclk can be obtained by passing in the type of APB.
963// With that in place, some places of macro magic are not needed anymore.
964impl Clocks {
965    /// Returns the frequency of the AHB
966    #[must_use]
967    pub fn hclk(&self) -> Hertz {
968        self.hclk
969    }
970
971    /// Returns the frequency of the APB1
972    #[must_use]
973    pub fn pclk1(&self) -> Hertz {
974        self.pclk1
975    }
976
977    /// Returns the frequency of the APB2
978    #[must_use]
979    pub fn pclk2(&self) -> Hertz {
980        self.pclk2
981    }
982
983    /// Returns the prescaler of the APB1
984    #[must_use]
985    pub fn ppre1(&self) -> u8 {
986        self.ppre1
987    }
988
989    /// Returns the prescaler of the APB2
990    #[must_use]
991    pub fn ppre2(&self) -> u8 {
992        self.ppre2
993    }
994
995    /// Returns the system (core) frequency
996    #[must_use]
997    pub fn sysclk(&self) -> Hertz {
998        self.sysclk
999    }
1000
1001    /// Returns the PLL clock if configured, else it returns `None`.
1002    ///
1003    /// The PLL clock is a source of the system clock, but it is not necessarily configured to be one.
1004    #[must_use]
1005    pub fn pllclk(&self) -> Option<Hertz> {
1006        if self.pll_bypass {
1007            None
1008        } else {
1009            // The PLLCLK is the same as the sysclk, beccause
1010            // the sysclk is using it as a source.
1011            Some(self.sysclk())
1012        }
1013    }
1014
1015    /// Returns whether the USBCLK clock frequency is valid for the USB peripheral
1016    ///
1017    /// If the microcontroller does support USB, 48 Mhz or 72 Mhz have to be used
1018    /// and the [`CFGR::use_hse`] must be set.
1019    ///
1020    /// The APB1 / [`CFGR::pclk1`] clock must have a minimum frequency of 10 MHz to avoid data
1021    /// overrun/underrun problems. [RM0316 32.5.2][RM0316]
1022    ///
1023    /// [RM0316]: https://www.st.com/resource/en/reference_manual/dm00043574.pdf
1024    #[must_use]
1025    pub fn usbclk_valid(&self) -> bool {
1026        self.usbclk_valid
1027    }
1028}