From b06e705a737a7b1d040ab415b4e7ecc71cd79094 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 4 Jan 2022 19:25:50 +0100 Subject: [PATCH] stm32/rcc: change family-specific code from dirs to single files. Consistent with how other peripherals handle their versions. --- embassy-stm32/src/rcc/{f0/mod.rs => f0.rs} | 2 +- embassy-stm32/src/rcc/{f1/mod.rs => f1.rs} | 2 +- embassy-stm32/src/rcc/{f3/mod.rs => f3.rs} | 2 +- embassy-stm32/src/rcc/{f4/mod.rs => f4.rs} | 37 +++- embassy-stm32/src/rcc/f4/max.rs | 21 --- embassy-stm32/src/rcc/{f7/mod.rs => f7.rs} | 26 ++- embassy-stm32/src/rcc/f7/max.rs | 19 --- embassy-stm32/src/rcc/{g0/mod.rs => g0.rs} | 2 +- embassy-stm32/src/rcc/{g4/mod.rs => g4.rs} | 2 +- embassy-stm32/src/rcc/{h7/mod.rs => h7.rs} | 158 +++++++++++++++++- embassy-stm32/src/rcc/h7/pll.rs | 145 ---------------- embassy-stm32/src/rcc/{l0/mod.rs => l0.rs} | 2 +- embassy-stm32/src/rcc/{l1/mod.rs => l1.rs} | 2 +- embassy-stm32/src/rcc/{l4/mod.rs => l4.rs} | 2 +- embassy-stm32/src/rcc/mod.rs | 67 +++----- embassy-stm32/src/rcc/{u5/mod.rs => u5.rs} | 2 +- embassy-stm32/src/rcc/{wb/mod.rs => wb.rs} | 2 +- embassy-stm32/src/rcc/{wl5x/mod.rs => wl5.rs} | 2 +- 18 files changed, 234 insertions(+), 261 deletions(-) rename embassy-stm32/src/rcc/{f0/mod.rs => f0.rs} (99%) rename embassy-stm32/src/rcc/{f1/mod.rs => f1.rs} (99%) rename embassy-stm32/src/rcc/{f3/mod.rs => f3.rs} (99%) rename embassy-stm32/src/rcc/{f4/mod.rs => f4.rs} (89%) delete mode 100644 embassy-stm32/src/rcc/f4/max.rs rename embassy-stm32/src/rcc/{f7/mod.rs => f7.rs} (92%) delete mode 100644 embassy-stm32/src/rcc/f7/max.rs rename embassy-stm32/src/rcc/{g0/mod.rs => g0.rs} (99%) rename embassy-stm32/src/rcc/{g4/mod.rs => g4.rs} (99%) rename embassy-stm32/src/rcc/{h7/mod.rs => h7.rs} (81%) delete mode 100644 embassy-stm32/src/rcc/h7/pll.rs rename embassy-stm32/src/rcc/{l0/mod.rs => l0.rs} (99%) rename embassy-stm32/src/rcc/{l1/mod.rs => l1.rs} (99%) rename embassy-stm32/src/rcc/{l4/mod.rs => l4.rs} (99%) rename embassy-stm32/src/rcc/{u5/mod.rs => u5.rs} (99%) rename embassy-stm32/src/rcc/{wb/mod.rs => wb.rs} (99%) rename embassy-stm32/src/rcc/{wl5x/mod.rs => wl5.rs} (99%) diff --git a/embassy-stm32/src/rcc/f0/mod.rs b/embassy-stm32/src/rcc/f0.rs similarity index 99% rename from embassy-stm32/src/rcc/f0/mod.rs rename to embassy-stm32/src/rcc/f0.rs index 916ed39f..07a28cc3 100644 --- a/embassy-stm32/src/rcc/f0/mod.rs +++ b/embassy-stm32/src/rcc/f0.rs @@ -201,7 +201,7 @@ impl<'d> Rcc<'d> { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let rcc = Rcc::new(::steal(), config); let clocks = rcc.freeze(); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/f1/mod.rs b/embassy-stm32/src/rcc/f1.rs similarity index 99% rename from embassy-stm32/src/rcc/f1/mod.rs rename to embassy-stm32/src/rcc/f1.rs index d613f5a2..c9d09ee3 100644 --- a/embassy-stm32/src/rcc/f1/mod.rs +++ b/embassy-stm32/src/rcc/f1.rs @@ -207,7 +207,7 @@ impl<'d> Rcc<'d> { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let rcc = Rcc::new(::steal(), config); let clocks = rcc.freeze(); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/f3/mod.rs b/embassy-stm32/src/rcc/f3.rs similarity index 99% rename from embassy-stm32/src/rcc/f3/mod.rs rename to embassy-stm32/src/rcc/f3.rs index ab1bd760..7b5e0cce 100644 --- a/embassy-stm32/src/rcc/f3/mod.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -54,7 +54,7 @@ struct PllConfig { } /// Initialize and Set the clock frequencies -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = Rcc::new(r, config).freeze(); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/f4/mod.rs b/embassy-stm32/src/rcc/f4.rs similarity index 89% rename from embassy-stm32/src/rcc/f4/mod.rs rename to embassy-stm32/src/rcc/f4.rs index 04083dfa..08a9bc9b 100644 --- a/embassy-stm32/src/rcc/f4/mod.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -5,9 +5,6 @@ use crate::time::Hertz; use core::marker::PhantomData; use embassy::util::Unborrow; -mod max; -use max::{PCLK1_MAX, PCLK2_MAX}; - const HSI: u32 = 16_000_000; /// Clocks configutation @@ -88,7 +85,7 @@ impl<'d> Rcc<'d> { .config .pclk1 .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(PCLK1_MAX, hclk)); + .unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk)); let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 { 0 => unreachable!(), 1 => (0b000, 1), @@ -101,13 +98,13 @@ impl<'d> Rcc<'d> { // Calculate real APB1 clock let pclk1 = hclk / ppre1; - assert!(pclk1 <= PCLK1_MAX); + assert!(pclk1 <= max::PCLK1_MAX); let pclk2 = self .config .pclk2 .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(PCLK2_MAX, hclk)); + .unwrap_or_else(|| core::cmp::min(max::PCLK2_MAX, hclk)); let (ppre2_bits, ppre2) = match (hclk + pclk2 - 1) / pclk2 { 0 => unreachable!(), 1 => (0b000, 1), @@ -120,7 +117,7 @@ impl<'d> Rcc<'d> { // Calculate real APB2 clock let pclk2 = hclk / ppre2; - assert!(pclk2 <= PCLK2_MAX); + assert!(pclk2 <= max::PCLK2_MAX); Self::flash_setup(sysclk); @@ -298,7 +295,7 @@ impl<'d> Rcc<'d> { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = Rcc::new(r, config).freeze(); set_freqs(clocks); @@ -309,3 +306,27 @@ struct PllResults { pllsysclk: Option, pll48clk: Option, } + +mod max { + #[cfg(stm32f401)] + pub(crate) const SYSCLK_MAX: u32 = 84_000_000; + + #[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))] + pub(crate) const SYSCLK_MAX: u32 = 168_000_000; + + #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] + pub(crate) const SYSCLK_MAX: u32 = 100_000_000; + + #[cfg(any( + stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479, + ))] + pub(crate) const SYSCLK_MAX: u32 = 180_000_000; + + #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] + pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX; + + #[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))] + pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; + + pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2; +} diff --git a/embassy-stm32/src/rcc/f4/max.rs b/embassy-stm32/src/rcc/f4/max.rs deleted file mode 100644 index dd8de3da..00000000 --- a/embassy-stm32/src/rcc/f4/max.rs +++ /dev/null @@ -1,21 +0,0 @@ -#[cfg(stm32f401)] -pub(crate) const SYSCLK_MAX: u32 = 84_000_000; - -#[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))] -pub(crate) const SYSCLK_MAX: u32 = 168_000_000; - -#[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] -pub(crate) const SYSCLK_MAX: u32 = 100_000_000; - -#[cfg(any( - stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479, -))] -pub(crate) const SYSCLK_MAX: u32 = 180_000_000; - -#[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] -pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX; - -#[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))] -pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; - -pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2; diff --git a/embassy-stm32/src/rcc/f7/mod.rs b/embassy-stm32/src/rcc/f7.rs similarity index 92% rename from embassy-stm32/src/rcc/f7/mod.rs rename to embassy-stm32/src/rcc/f7.rs index c13e2016..25f78c70 100644 --- a/embassy-stm32/src/rcc/f7/mod.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -1,5 +1,3 @@ -mod max; - use crate::pac::{FLASH, PWR, RCC}; use crate::peripherals; use crate::rcc::{get_freqs, set_freqs, Clocks}; @@ -334,7 +332,7 @@ impl<'d> Rcc<'d> { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = Rcc::new(r, config).freeze(); set_freqs(clocks); @@ -345,3 +343,25 @@ struct PllResults { pllsysclk: Option, pll48clk: Option, } + +mod max { + pub(crate) const HSE_OSC_MIN: u32 = 4_000_000; + pub(crate) const HSE_OSC_MAX: u32 = 26_000_000; + pub(crate) const HSE_BYPASS_MIN: u32 = 1_000_000; + pub(crate) const HSE_BYPASS_MAX: u32 = 50_000_000; + + pub(crate) const HCLK_MAX: u32 = 216_000_000; + pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 180_000_000; + + pub(crate) const SYSCLK_MIN: u32 = 12_500_000; + pub(crate) const SYSCLK_MAX: u32 = 216_000_000; + + pub(crate) const PCLK1_MIN: u32 = SYSCLK_MIN; + pub(crate) const PCLK1_MAX: u32 = SYSCLK_MAX / 4; + + pub(crate) const PCLK2_MIN: u32 = SYSCLK_MIN; + pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; + + pub(crate) const PLL_48_CLK: u32 = 48_000_000; + pub(crate) const PLL_48_TOLERANCE: u32 = 120_000; +} diff --git a/embassy-stm32/src/rcc/f7/max.rs b/embassy-stm32/src/rcc/f7/max.rs deleted file mode 100644 index db00fdf3..00000000 --- a/embassy-stm32/src/rcc/f7/max.rs +++ /dev/null @@ -1,19 +0,0 @@ -pub(crate) const HSE_OSC_MIN: u32 = 4_000_000; -pub(crate) const HSE_OSC_MAX: u32 = 26_000_000; -pub(crate) const HSE_BYPASS_MIN: u32 = 1_000_000; -pub(crate) const HSE_BYPASS_MAX: u32 = 50_000_000; - -pub(crate) const HCLK_MAX: u32 = 216_000_000; -pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 180_000_000; - -pub(crate) const SYSCLK_MIN: u32 = 12_500_000; -pub(crate) const SYSCLK_MAX: u32 = 216_000_000; - -pub(crate) const PCLK1_MIN: u32 = SYSCLK_MIN; -pub(crate) const PCLK1_MAX: u32 = SYSCLK_MAX / 4; - -pub(crate) const PCLK2_MIN: u32 = SYSCLK_MIN; -pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; - -pub(crate) const PLL_48_CLK: u32 = 48_000_000; -pub(crate) const PLL_48_TOLERANCE: u32 = 120_000; diff --git a/embassy-stm32/src/rcc/g0/mod.rs b/embassy-stm32/src/rcc/g0.rs similarity index 99% rename from embassy-stm32/src/rcc/g0/mod.rs rename to embassy-stm32/src/rcc/g0.rs index 7f7af2fc..df11ff36 100644 --- a/embassy-stm32/src/rcc/g0/mod.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -227,7 +227,7 @@ impl RccExt for RCC { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/g4/mod.rs b/embassy-stm32/src/rcc/g4.rs similarity index 99% rename from embassy-stm32/src/rcc/g4/mod.rs rename to embassy-stm32/src/rcc/g4.rs index 8a75b2e0..ee49e2ec 100644 --- a/embassy-stm32/src/rcc/g4/mod.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -203,7 +203,7 @@ impl RccExt for RCC { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/h7/mod.rs b/embassy-stm32/src/rcc/h7.rs similarity index 81% rename from embassy-stm32/src/rcc/h7/mod.rs rename to embassy-stm32/src/rcc/h7.rs index cd493a80..ac4d033b 100644 --- a/embassy-stm32/src/rcc/h7/mod.rs +++ b/embassy-stm32/src/rcc/h7.rs @@ -13,8 +13,6 @@ use crate::pwr::{Power, VoltageScale}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; -mod pll; -use pll::pll_setup; pub use pll::PllConfig; const HSI: Hertz = Hertz(64_000_000); @@ -116,11 +114,11 @@ impl<'d> Rcc<'d> { // NOTE(unsafe) We have exclusive access to the RCC let (pll1_p_ck, pll1_q_ck, pll1_r_ck) = - unsafe { pll_setup(srcclk.0, &self.config.pll1, 0) }; + unsafe { pll::pll_setup(srcclk.0, &self.config.pll1, 0) }; let (pll2_p_ck, pll2_q_ck, pll2_r_ck) = - unsafe { pll_setup(srcclk.0, &self.config.pll2, 1) }; + unsafe { pll::pll_setup(srcclk.0, &self.config.pll2, 1) }; let (pll3_p_ck, pll3_q_ck, pll3_r_ck) = - unsafe { pll_setup(srcclk.0, &self.config.pll3, 2) }; + unsafe { pll::pll_setup(srcclk.0, &self.config.pll3, 2) }; let sys_ck = if sys_use_pll1_p { Hertz(unwrap!(pll1_p_ck)) // Must have been set by sys_ck_setup @@ -683,7 +681,7 @@ impl<'d, T: McoInstance> Mco<'d, T> { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let mut power = Power::new(::steal(), false); let rcc = Rcc::new(::steal(), config); let core_clocks = rcc.freeze(&mut power); @@ -700,3 +698,151 @@ pub unsafe fn init(config: Config) { apb2_tim: core_clocks.timy_ker_ck.unwrap_or(core_clocks.pclk2), }); } + +mod pll { + use super::{Hertz, RCC}; + + const VCO_MIN: u32 = 150_000_000; + const VCO_MAX: u32 = 420_000_000; + + #[derive(Default)] + pub struct PllConfig { + pub p_ck: Option, + pub q_ck: Option, + pub r_ck: Option, + } + + pub(super) struct PllConfigResults { + pub ref_x_ck: u32, + pub pll_x_m: u32, + pub pll_x_p: u32, + pub vco_ck_target: u32, + } + + fn vco_output_divider_setup(output: u32, plln: usize) -> (u32, u32) { + let pll_x_p = if plln == 0 { + if output > VCO_MAX / 2 { + 1 + } else { + ((VCO_MAX / output) | 1) - 1 // Must be even or unity + } + } else { + // Specific to PLL2/3, will subtract 1 later + if output > VCO_MAX / 2 { + 1 + } else { + VCO_MAX / output + } + }; + + let vco_ck = output + pll_x_p; + + assert!(pll_x_p < 128); + assert!(vco_ck >= VCO_MIN); + assert!(vco_ck <= VCO_MAX); + + (vco_ck, pll_x_p) + } + + /// # Safety + /// + /// Must have exclusive access to the RCC register block + unsafe fn vco_setup(pll_src: u32, requested_output: u32, plln: usize) -> PllConfigResults { + use crate::pac::rcc::vals::{Pllrge, Pllvcosel}; + + let (vco_ck_target, pll_x_p) = vco_output_divider_setup(requested_output, plln); + + // Input divisor, resulting in a reference clock in the range + // 1 to 2 MHz. Choose the highest reference clock (lowest m) + let pll_x_m = (pll_src + 1_999_999) / 2_000_000; + assert!(pll_x_m < 64); + + // Calculate resulting reference clock + let ref_x_ck = pll_src / pll_x_m; + assert!((1_000_000..=2_000_000).contains(&ref_x_ck)); + + RCC.pllcfgr().modify(|w| { + w.set_pllvcosel(plln, Pllvcosel::MEDIUMVCO); + w.set_pllrge(plln, Pllrge::RANGE1); + }); + PllConfigResults { + ref_x_ck, + pll_x_m, + pll_x_p, + vco_ck_target, + } + } + + /// # Safety + /// + /// Must have exclusive access to the RCC register block + pub(super) unsafe fn pll_setup( + pll_src: u32, + config: &PllConfig, + plln: usize, + ) -> (Option, Option, Option) { + use crate::pac::rcc::vals::Divp; + + match config.p_ck { + Some(requested_output) => { + let config_results = vco_setup(pll_src, requested_output.0, plln); + let PllConfigResults { + ref_x_ck, + pll_x_m, + pll_x_p, + vco_ck_target, + } = config_results; + + RCC.pllckselr().modify(|w| w.set_divm(plln, pll_x_m as u8)); + + // Feedback divider. Integer only + let pll_x_n = vco_ck_target / ref_x_ck; + assert!(pll_x_n >= 4); + assert!(pll_x_n <= 512); + RCC.plldivr(plln) + .modify(|w| w.set_divn1((pll_x_n - 1) as u16)); + + // No FRACN + RCC.pllcfgr().modify(|w| w.set_pllfracen(plln, false)); + let vco_ck = ref_x_ck * pll_x_n; + + RCC.plldivr(plln) + .modify(|w| w.set_divp1(Divp((pll_x_p - 1) as u8))); + RCC.pllcfgr().modify(|w| w.set_divpen(plln, true)); + + // Calulate additional output dividers + let q_ck = match config.q_ck { + Some(Hertz(ck)) if ck > 0 => { + let div = (vco_ck + ck - 1) / ck; + RCC.plldivr(plln).modify(|w| w.set_divq1((div - 1) as u8)); + RCC.pllcfgr().modify(|w| w.set_divqen(plln, true)); + Some(vco_ck / div) + } + _ => None, + }; + let r_ck = match config.r_ck { + Some(Hertz(ck)) if ck > 0 => { + let div = (vco_ck + ck - 1) / ck; + RCC.plldivr(plln).modify(|w| w.set_divr1((div - 1) as u8)); + RCC.pllcfgr().modify(|w| w.set_divren(plln, true)); + Some(vco_ck / div) + } + _ => None, + }; + + (Some(vco_ck / pll_x_p), q_ck, r_ck) + } + None => { + assert!( + config.q_ck.is_none(), + "Must set PLL P clock for Q clock to take effect!" + ); + assert!( + config.r_ck.is_none(), + "Must set PLL P clock for R clock to take effect!" + ); + (None, None, None) + } + } + } +} diff --git a/embassy-stm32/src/rcc/h7/pll.rs b/embassy-stm32/src/rcc/h7/pll.rs deleted file mode 100644 index d3709378..00000000 --- a/embassy-stm32/src/rcc/h7/pll.rs +++ /dev/null @@ -1,145 +0,0 @@ -use super::{Hertz, RCC}; - -const VCO_MIN: u32 = 150_000_000; -const VCO_MAX: u32 = 420_000_000; - -#[derive(Default)] -pub struct PllConfig { - pub p_ck: Option, - pub q_ck: Option, - pub r_ck: Option, -} - -pub(super) struct PllConfigResults { - pub ref_x_ck: u32, - pub pll_x_m: u32, - pub pll_x_p: u32, - pub vco_ck_target: u32, -} - -fn vco_output_divider_setup(output: u32, plln: usize) -> (u32, u32) { - let pll_x_p = if plln == 0 { - if output > VCO_MAX / 2 { - 1 - } else { - ((VCO_MAX / output) | 1) - 1 // Must be even or unity - } - } else { - // Specific to PLL2/3, will subtract 1 later - if output > VCO_MAX / 2 { - 1 - } else { - VCO_MAX / output - } - }; - - let vco_ck = output + pll_x_p; - - assert!(pll_x_p < 128); - assert!(vco_ck >= VCO_MIN); - assert!(vco_ck <= VCO_MAX); - - (vco_ck, pll_x_p) -} - -/// # Safety -/// -/// Must have exclusive access to the RCC register block -unsafe fn vco_setup(pll_src: u32, requested_output: u32, plln: usize) -> PllConfigResults { - use crate::pac::rcc::vals::{Pllrge, Pllvcosel}; - - let (vco_ck_target, pll_x_p) = vco_output_divider_setup(requested_output, plln); - - // Input divisor, resulting in a reference clock in the range - // 1 to 2 MHz. Choose the highest reference clock (lowest m) - let pll_x_m = (pll_src + 1_999_999) / 2_000_000; - assert!(pll_x_m < 64); - - // Calculate resulting reference clock - let ref_x_ck = pll_src / pll_x_m; - assert!((1_000_000..=2_000_000).contains(&ref_x_ck)); - - RCC.pllcfgr().modify(|w| { - w.set_pllvcosel(plln, Pllvcosel::MEDIUMVCO); - w.set_pllrge(plln, Pllrge::RANGE1); - }); - PllConfigResults { - ref_x_ck, - pll_x_m, - pll_x_p, - vco_ck_target, - } -} - -/// # Safety -/// -/// Must have exclusive access to the RCC register block -pub(super) unsafe fn pll_setup( - pll_src: u32, - config: &PllConfig, - plln: usize, -) -> (Option, Option, Option) { - use crate::pac::rcc::vals::Divp; - - match config.p_ck { - Some(requested_output) => { - let config_results = vco_setup(pll_src, requested_output.0, plln); - let PllConfigResults { - ref_x_ck, - pll_x_m, - pll_x_p, - vco_ck_target, - } = config_results; - - RCC.pllckselr().modify(|w| w.set_divm(plln, pll_x_m as u8)); - - // Feedback divider. Integer only - let pll_x_n = vco_ck_target / ref_x_ck; - assert!(pll_x_n >= 4); - assert!(pll_x_n <= 512); - RCC.plldivr(plln) - .modify(|w| w.set_divn1((pll_x_n - 1) as u16)); - - // No FRACN - RCC.pllcfgr().modify(|w| w.set_pllfracen(plln, false)); - let vco_ck = ref_x_ck * pll_x_n; - - RCC.plldivr(plln) - .modify(|w| w.set_divp1(Divp((pll_x_p - 1) as u8))); - RCC.pllcfgr().modify(|w| w.set_divpen(plln, true)); - - // Calulate additional output dividers - let q_ck = match config.q_ck { - Some(Hertz(ck)) if ck > 0 => { - let div = (vco_ck + ck - 1) / ck; - RCC.plldivr(plln).modify(|w| w.set_divq1((div - 1) as u8)); - RCC.pllcfgr().modify(|w| w.set_divqen(plln, true)); - Some(vco_ck / div) - } - _ => None, - }; - let r_ck = match config.r_ck { - Some(Hertz(ck)) if ck > 0 => { - let div = (vco_ck + ck - 1) / ck; - RCC.plldivr(plln).modify(|w| w.set_divr1((div - 1) as u8)); - RCC.pllcfgr().modify(|w| w.set_divren(plln, true)); - Some(vco_ck / div) - } - _ => None, - }; - - (Some(vco_ck / pll_x_p), q_ck, r_ck) - } - None => { - assert!( - config.q_ck.is_none(), - "Must set PLL P clock for Q clock to take effect!" - ); - assert!( - config.r_ck.is_none(), - "Must set PLL P clock for R clock to take effect!" - ); - (None, None, None) - } - } -} diff --git a/embassy-stm32/src/rcc/l0/mod.rs b/embassy-stm32/src/rcc/l0.rs similarity index 99% rename from embassy-stm32/src/rcc/l0/mod.rs rename to embassy-stm32/src/rcc/l0.rs index fd84f09c..fc70ef0a 100644 --- a/embassy-stm32/src/rcc/l0/mod.rs +++ b/embassy-stm32/src/rcc/l0.rs @@ -430,7 +430,7 @@ impl RccExt for RCC { #[derive(Clone, Copy)] pub struct HSI48(()); -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/l1/mod.rs b/embassy-stm32/src/rcc/l1.rs similarity index 99% rename from embassy-stm32/src/rcc/l1/mod.rs rename to embassy-stm32/src/rcc/l1.rs index e46bee32..746433c1 100644 --- a/embassy-stm32/src/rcc/l1/mod.rs +++ b/embassy-stm32/src/rcc/l1.rs @@ -254,7 +254,7 @@ impl RccExt for RCC { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/l4/mod.rs b/embassy-stm32/src/rcc/l4.rs similarity index 99% rename from embassy-stm32/src/rcc/l4/mod.rs rename to embassy-stm32/src/rcc/l4.rs index a0eedf0b..510cbddf 100644 --- a/embassy-stm32/src/rcc/l4/mod.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -482,7 +482,7 @@ impl RccExt for RCC { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 0a7edb37..bf612464 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -4,6 +4,23 @@ use crate::peripherals; use crate::time::Hertz; use core::mem::MaybeUninit; +#[cfg_attr(any(rcc_f0, rcc_f0x0), path = "f0.rs")] +#[cfg_attr(rcc_f1, path = "f1.rs")] +#[cfg_attr(rcc_f3, path = "f3.rs")] +#[cfg_attr(any(rcc_f4, rcc_f410), path = "f4.rs")] +#[cfg_attr(rcc_f7, path = "f7.rs")] +#[cfg_attr(rcc_g0, path = "g0.rs")] +#[cfg_attr(rcc_g4, path = "g4.rs")] +#[cfg_attr(any(rcc_h7, rcc_h7ab), path = "h7.rs")] +#[cfg_attr(rcc_l0, path = "l0.rs")] +#[cfg_attr(rcc_l1, path = "l1.rs")] +#[cfg_attr(rcc_l4, path = "l4.rs")] +#[cfg_attr(rcc_u5, path = "u5.rs")] +#[cfg_attr(rcc_wb, path = "wb.rs")] +#[cfg_attr(rcc_wl5, path = "wl5.rs")] +mod _version; +pub use _version::*; + #[derive(Clone, Copy)] pub struct Clocks { pub sys: Hertz, @@ -59,61 +76,15 @@ static mut CLOCK_FREQS: MaybeUninit = MaybeUninit::uninit(); /// Sets the clock frequencies /// /// Safety: Sets a mutable global. -pub unsafe fn set_freqs(freqs: Clocks) { +pub(crate) unsafe fn set_freqs(freqs: Clocks) { CLOCK_FREQS.as_mut_ptr().write(freqs); } /// Safety: Reads a mutable global. -pub unsafe fn get_freqs() -> &'static Clocks { +pub(crate) unsafe fn get_freqs() -> &'static Clocks { &*CLOCK_FREQS.as_ptr() } -cfg_if::cfg_if! { - if #[cfg(rcc_h7)] { - mod h7; - pub use h7::*; - } else if #[cfg(rcc_l0)] { - mod l0; - pub use l0::*; - } else if #[cfg(rcc_l1)] { - mod l1; - pub use l1::*; - } else if #[cfg(rcc_l4)] { - mod l4; - pub use l4::*; - } else if #[cfg(rcc_f1)] { - mod f1; - pub use f1::*; - } else if #[cfg(rcc_f3)] { - mod f3; - pub use f3::*; - } else if #[cfg(rcc_f4)] { - mod f4; - pub use f4::*; - } else if #[cfg(rcc_f7)] { - mod f7; - pub use f7::*; - } else if #[cfg(rcc_wb)] { - mod wb; - pub use wb::*; - } else if #[cfg(rcc_wl5)] { - mod wl5x; - pub use wl5x::*; - } else if #[cfg(any(rcc_f0, rcc_f0x0))] { - mod f0; - pub use f0::*; - } else if #[cfg(any(rcc_g0))] { - mod g0; - pub use g0::*; - } else if #[cfg(any(rcc_g4))] { - mod g4; - pub use g4::*; - } else if #[cfg(any(rcc_u5))] { - mod u5; - pub use u5::*; - } -} - pub(crate) mod sealed { pub trait RccPeripheral { fn frequency() -> crate::time::Hertz; diff --git a/embassy-stm32/src/rcc/u5/mod.rs b/embassy-stm32/src/rcc/u5.rs similarity index 99% rename from embassy-stm32/src/rcc/u5/mod.rs rename to embassy-stm32/src/rcc/u5.rs index a3df3a02..e8bd8271 100644 --- a/embassy-stm32/src/rcc/u5/mod.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -502,7 +502,7 @@ impl RccExt for RCC { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let power = Power::new(::steal()); let clocks = r.freeze(config, &power); diff --git a/embassy-stm32/src/rcc/wb/mod.rs b/embassy-stm32/src/rcc/wb.rs similarity index 99% rename from embassy-stm32/src/rcc/wb/mod.rs rename to embassy-stm32/src/rcc/wb.rs index 73835cac..58146d4b 100644 --- a/embassy-stm32/src/rcc/wb/mod.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -206,7 +206,7 @@ impl RccExt for RCC { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/wl5x/mod.rs b/embassy-stm32/src/rcc/wl5.rs similarity index 99% rename from embassy-stm32/src/rcc/wl5x/mod.rs rename to embassy-stm32/src/rcc/wl5.rs index edf603ee..00b91dfe 100644 --- a/embassy-stm32/src/rcc/wl5x/mod.rs +++ b/embassy-stm32/src/rcc/wl5.rs @@ -229,7 +229,7 @@ impl RccExt for RCC { } } -pub unsafe fn init(config: Config) { +pub(crate) unsafe fn init(config: Config) { let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks);