From ace52210802a18a551f506bc3ad163703e3f9efa Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 01:56:28 +0100 Subject: [PATCH] stm32/rcc: unify f2 into f4/f7. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/{f4f7.rs => f.rs} | 143 ++++++++--- embassy-stm32/src/rcc/f2.rs | 320 ------------------------ embassy-stm32/src/rcc/mod.rs | 9 +- examples/stm32f2/src/bin/pll.rs | 55 ++-- tests/stm32/src/common.rs | 21 +- 6 files changed, 161 insertions(+), 391 deletions(-) rename embassy-stm32/src/rcc/{f4f7.rs => f.rs} (71%) delete mode 100644 embassy-stm32/src/rcc/f2.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 37317276..4b650cc8 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -58,7 +58,7 @@ rand_core = "0.6.3" sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f.rs similarity index 71% rename from embassy-stm32/src/rcc/f4f7.rs rename to embassy-stm32/src/rcc/f.rs index 718ba9b7..36d9f178 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f.rs @@ -1,9 +1,12 @@ -use crate::pac::pwr::vals::Vos; +use stm32_metapac::flash::vals::Latency; + pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, }; -use crate::pac::{FLASH, PWR, RCC}; +#[cfg(any(stm32f4, stm32f7))] +use crate::pac::PWR; +use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -56,6 +59,22 @@ pub struct Pll { pub divr: Option, } +/// Voltage range of the power supply used. +/// +/// Used to calculate flash waitstates. See +/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency +#[cfg(stm32f2)] +pub enum VoltageScale { + /// 2.7 to 3.6 V + Range0, + /// 2.4 to 2.7 V + Range1, + /// 2.1 to 2.4 V + Range2, + /// 1.8 to 2.1 V + Range3, +} + /// Configuration of the core clocks #[non_exhaustive] pub struct Config { @@ -66,7 +85,7 @@ pub struct Config { pub pll_src: PllSource, pub pll: Option, - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] pub plli2s: Option, #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] pub pllsai: Option, @@ -76,6 +95,9 @@ pub struct Config { pub apb2_pre: APBPrescaler, pub ls: super::LsConfig, + + #[cfg(stm32f2)] + pub voltage: VoltageScale, } impl Default for Config { @@ -86,7 +108,7 @@ impl Default for Config { sys: Sysclk::HSI, pll_src: PllSource::HSI, pll: None, - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] plli2s: None, #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] pllsai: None, @@ -96,6 +118,9 @@ impl Default for Config { apb2_pre: APBPrescaler::DIV1, ls: Default::default(), + + #[cfg(stm32f2)] + voltage: VoltageScale::Range3, } } } @@ -103,14 +128,13 @@ impl Default for Config { pub(crate) unsafe fn init(config: Config) { // set VOS to SCALE1, if use PLL // TODO: check real clock speed before set VOS + #[cfg(any(stm32f4, stm32f7))] if config.pll.is_some() { - PWR.cr1().modify(|w| w.set_vos(Vos::SCALE1)); + PWR.cr1().modify(|w| w.set_vos(crate::pac::pwr::vals::Vos::SCALE1)); } // always enable overdrive for now. Make it configurable in the future. - #[cfg(not(any( - stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f405, stm32f407, stm32f415, stm32f417 - )))] + #[cfg(any(stm32f446, stm32f4x9, stm32f427, stm32f437, stm32f7))] { PWR.cr1().modify(|w| w.set_oden(true)); while !PWR.csr1().read().odrdy() {} @@ -158,7 +182,7 @@ pub(crate) unsafe fn init(config: Config) { source: config.pll_src, }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); @@ -182,7 +206,48 @@ pub(crate) unsafe fn init(config: Config) { let rtc = config.ls.init(); - flash_setup(hclk); + #[cfg(stm32f2)] + let latency = match (config.voltage, hclk.0) { + (VoltageScale::Range3, ..=16_000_000) => Latency::WS0, + (VoltageScale::Range3, ..=32_000_000) => Latency::WS1, + (VoltageScale::Range3, ..=48_000_000) => Latency::WS2, + (VoltageScale::Range3, ..=64_000_000) => Latency::WS3, + (VoltageScale::Range3, ..=80_000_000) => Latency::WS4, + (VoltageScale::Range3, ..=96_000_000) => Latency::WS5, + (VoltageScale::Range3, ..=112_000_000) => Latency::WS6, + (VoltageScale::Range3, ..=120_000_000) => Latency::WS7, + (VoltageScale::Range2, ..=18_000_000) => Latency::WS0, + (VoltageScale::Range2, ..=36_000_000) => Latency::WS1, + (VoltageScale::Range2, ..=54_000_000) => Latency::WS2, + (VoltageScale::Range2, ..=72_000_000) => Latency::WS3, + (VoltageScale::Range2, ..=90_000_000) => Latency::WS4, + (VoltageScale::Range2, ..=108_000_000) => Latency::WS5, + (VoltageScale::Range2, ..=120_000_000) => Latency::WS6, + (VoltageScale::Range1, ..=24_000_000) => Latency::WS0, + (VoltageScale::Range1, ..=48_000_000) => Latency::WS1, + (VoltageScale::Range1, ..=72_000_000) => Latency::WS2, + (VoltageScale::Range1, ..=96_000_000) => Latency::WS3, + (VoltageScale::Range1, ..=120_000_000) => Latency::WS4, + (VoltageScale::Range0, ..=30_000_000) => Latency::WS0, + (VoltageScale::Range0, ..=60_000_000) => Latency::WS1, + (VoltageScale::Range0, ..=90_000_000) => Latency::WS2, + (VoltageScale::Range0, ..=120_000_000) => Latency::WS3, + _ => unreachable!(), + }; + + #[cfg(any(stm32f4, stm32f7))] + let latency = { + // Be conservative with voltage ranges + const FLASH_LATENCY_STEP: u32 = 30_000_000; + + let latency = (hclk.0 - 1) / FLASH_LATENCY_STEP; + debug!("flash: latency={}", latency); + + Latency::from_bits(latency as u8) + }; + + FLASH.acr().write(|w| w.set_latency(latency)); + while FLASH.acr().read().latency() != latency {} RCC.cfgr().modify(|w| { w.set_sw(config.sys); @@ -232,7 +297,7 @@ struct PllOutput { #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] Plli2s, #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] Pllsai, @@ -244,7 +309,7 @@ fn pll_enable(instance: PllInstance, enabled: bool) { RCC.cr().modify(|w| w.set_pllon(enabled)); while RCC.cr().read().pllrdy() != enabled {} } - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] PllInstance::Plli2s => { RCC.cr().modify(|w| w.set_plli2son(enabled)); while RCC.cr().read().plli2srdy() != enabled {} @@ -275,6 +340,18 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let vco_freq = in_freq * pll.mul; assert!(max::PLL_VCO.contains(&vco_freq)); + // stm32f2 plls are like swiss cheese + #[cfg(stm32f2)] + match instance { + PllInstance::Pll => { + assert!(pll.divr.is_none()); + } + PllInstance::Plli2s => { + assert!(pll.divp.is_none()); + assert!(pll.divq.is_none()); + } + } + let p = pll.divp.map(|div| vco_freq / div); let q = pll.divq.map(|div| vco_freq / div); let r = pll.divr.map(|div| vco_freq / div); @@ -288,6 +365,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll if let Some(divq) = pll.divq { $w.set_pllq(divq); } + #[cfg(any(stm32f4, stm32f7))] if let Some(divr) = pll.divr { $w.set_pllr(divr); } @@ -304,6 +382,12 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { write_fields!(w); }), + #[cfg(stm32f2)] + PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { + if let Some(divr) = pll.divr { + w.set_pllr(divr); + } + }), #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] PllInstance::Pllsai => RCC.pllsaicfgr().write(|w| { write_fields!(w); @@ -316,22 +400,6 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll PllOutput { p, q, r } } -fn flash_setup(clk: Hertz) { - use crate::pac::flash::vals::Latency; - - // Be conservative with voltage ranges - const FLASH_LATENCY_STEP: u32 = 30_000_000; - - let latency = (clk.0 - 1) / FLASH_LATENCY_STEP; - debug!("flash: latency={}", latency); - - let latency = Latency::from_bits(latency as u8); - FLASH.acr().write(|w| { - w.set_latency(latency); - }); - while FLASH.acr().read().latency() != latency {} -} - #[cfg(stm32f7)] mod max { use core::ops::RangeInclusive; @@ -380,3 +448,22 @@ mod max { pub(crate) const PLL_IN: RangeInclusive = Hertz(1_000_000)..=Hertz(2_100_000); pub(crate) const PLL_VCO: RangeInclusive = Hertz(100_000_000)..=Hertz(432_000_000); } + +#[cfg(stm32f2)] +mod max { + use core::ops::RangeInclusive; + + use crate::time::Hertz; + + pub(crate) const HSE_OSC: RangeInclusive = Hertz(4_000_000)..=Hertz(26_000_000); + pub(crate) const HSE_BYP: RangeInclusive = Hertz(1_000_000)..=Hertz(26_000_000); + + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(120_000_000); + + pub(crate) const HCLK: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0); + pub(crate) const PCLK1: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0 / 4); + pub(crate) const PCLK2: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0 / 2); + + pub(crate) const PLL_IN: RangeInclusive = Hertz(0_950_000)..=Hertz(2_100_000); + pub(crate) const PLL_VCO: RangeInclusive = Hertz(192_000_000)..=Hertz(432_000_000); +} diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs deleted file mode 100644 index 00480222..00000000 --- a/embassy-stm32/src/rcc/f2.rs +++ /dev/null @@ -1,320 +0,0 @@ -use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::Sw; -pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllsrc as PllSource, - Ppre as APBPrescaler, -}; -use crate::pac::{FLASH, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -#[derive(Clone, Copy)] -pub struct HSEConfig { - pub frequency: Hertz, - pub source: HSESrc, -} - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - HSE, - HSI, - PLL, -} - -/// HSE clock source -#[derive(Clone, Copy)] -pub enum HSESrc { - /// Crystal/ceramic resonator - Crystal, - /// External clock source, HSE bypassed - Bypass, -} - -#[derive(Clone, Copy)] -pub struct Pll { - pub pre_div: PllPreDiv, - pub mul: PllMul, - pub divp: PllPDiv, - pub divq: PllQDiv, -} - -impl Default for Pll { - fn default() -> Self { - Pll { - pre_div: PllPreDiv::DIV16, - mul: PllMul::MUL192, - divp: PllPDiv::DIV2, - divq: PllQDiv::DIV4, - } - } -} - -impl Pll { - pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { - let in_freq = src_freq / self.pre_div; - let vco_freq = src_freq / self.pre_div * self.mul; - let main_freq = vco_freq / self.divp; - let pll48_freq = vco_freq / self.divq; - PLLClocks { - in_freq, - vco_freq, - main_freq, - pll48_freq, - } - } -} -#[derive(Clone, Copy, PartialEq)] -pub struct PLLClocks { - pub in_freq: Hertz, - pub vco_freq: Hertz, - pub main_freq: Hertz, - pub pll48_freq: Hertz, -} - -/// Voltage range of the power supply used. -/// -/// Used to calculate flash waitstates. See -/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency -pub enum VoltageScale { - /// 2.7 to 3.6 V - Range0, - /// 2.4 to 2.7 V - Range1, - /// 2.1 to 2.4 V - Range2, - /// 1.8 to 2.1 V - Range3, -} - -impl VoltageScale { - const fn wait_states(&self, ahb_freq: Hertz) -> Option { - let ahb_freq = ahb_freq.0; - // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock - // frequency - match self { - VoltageScale::Range3 => { - if ahb_freq <= 16_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 32_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 48_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 64_000_000 { - Some(Latency::WS3) - } else if ahb_freq <= 80_000_000 { - Some(Latency::WS4) - } else if ahb_freq <= 96_000_000 { - Some(Latency::WS5) - } else if ahb_freq <= 112_000_000 { - Some(Latency::WS6) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS7) - } else { - None - } - } - VoltageScale::Range2 => { - if ahb_freq <= 18_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 36_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 54_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 72_000_000 { - Some(Latency::WS3) - } else if ahb_freq <= 90_000_000 { - Some(Latency::WS4) - } else if ahb_freq <= 108_000_000 { - Some(Latency::WS5) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS6) - } else { - None - } - } - VoltageScale::Range1 => { - if ahb_freq <= 24_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 48_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 72_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 96_000_000 { - Some(Latency::WS3) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS4) - } else { - None - } - } - VoltageScale::Range0 => { - if ahb_freq <= 30_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 60_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 90_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS3) - } else { - None - } - } - } - } -} - -/// Clocks configuration -pub struct Config { - pub hse: Option, - pub hsi: bool, - pub pll_mux: PllSource, - pub pll: Pll, - pub mux: ClockSrc, - pub voltage: VoltageScale, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - hse: None, - hsi: true, - pll_mux: PllSource::HSI, - pll: Pll::default(), - voltage: VoltageScale::Range3, - mux: ClockSrc::HSI, - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - // Make sure HSI is enabled - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - if let Some(hse_config) = config.hse { - RCC.cr().modify(|w| { - w.set_hsebyp(match hse_config.source { - HSESrc::Bypass => true, - HSESrc::Crystal => false, - }); - w.set_hseon(true) - }); - while !RCC.cr().read().hserdy() {} - } - - let pll_src_freq = match config.pll_mux { - PllSource::HSE => { - let hse_config = config - .hse - .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input")); - hse_config.frequency - } - PllSource::HSI => HSI_FREQ, - }; - - // Reference: STM32F215xx/217xx datasheet Table 33. Main PLL characteristics - let pll_clocks = config.pll.clocks(pll_src_freq); - assert!(Hertz(950_000) <= pll_clocks.in_freq && pll_clocks.in_freq <= Hertz(2_100_000)); - assert!(Hertz(192_000_000) <= pll_clocks.vco_freq && pll_clocks.vco_freq <= Hertz(432_000_000)); - assert!(Hertz(24_000_000) <= pll_clocks.main_freq && pll_clocks.main_freq <= Hertz(120_000_000)); - // USB actually requires == 48 MHz, but other PLL48 peripherals are fine with <= 48MHz - assert!(pll_clocks.pll48_freq <= Hertz(48_000_000)); - - RCC.pllcfgr().write(|w| { - w.set_pllsrc(config.pll_mux); - w.set_pllm(config.pll.pre_div); - w.set_plln(config.pll.mul); - w.set_pllp(config.pll.divp); - w.set_pllq(config.pll.divq); - }); - - let (sys_clk, sw) = match config.mux { - ClockSrc::HSI => { - assert!(config.hsi, "HSI must be enabled to be used as system clock"); - (HSI_FREQ, Sw::HSI) - } - ClockSrc::HSE => { - let hse_config = config - .hse - .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input")); - (hse_config.frequency, Sw::HSE) - } - ClockSrc::PLL => { - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - (pll_clocks.main_freq, Sw::PLL1_P) - } - }; - // RM0033 Figure 9. Clock tree suggests max SYSCLK/HCLK is 168 MHz, but datasheet specifies PLL - // max output to be 120 MHz, so there's no way to get higher frequencies - assert!(sys_clk <= Hertz(120_000_000)); - - let ahb_freq = sys_clk / config.ahb_pre; - // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions - assert!(ahb_freq <= Hertz(120_000_000)); - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, Hertz(freq.0 * 2)) - } - }; - // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions - assert!(apb1_freq <= Hertz(30_000_000)); - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, Hertz(freq.0 * 2)) - } - }; - // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions - assert!(apb2_freq <= Hertz(60_000_000)); - - let flash_ws = unwrap!(config.voltage.wait_states(ahb_freq)); - FLASH.acr().modify(|w| w.set_latency(flash_ws)); - - RCC.cfgr().modify(|w| { - w.set_sw(sw.into()); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - while RCC.cfgr().read().sws().to_bits() != sw.to_bits() {} - - // Turn off HSI to save power if we don't need it - if !config.hsi { - RCC.cr().modify(|w| w.set_hsion(false)); - } - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: sys_clk, - hclk1: ahb_freq, - hclk2: ahb_freq, - hclk3: ahb_freq, - pclk1: apb1_freq, - pclk1_tim: apb1_tim_freq, - pclk2: apb2_freq, - pclk2_tim: apb2_tim_freq, - pll1_q: Some(pll_clocks.pll48_freq), - rtc, - }); -} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index debd16ca..2e144dc7 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -15,14 +15,13 @@ mod hsi48; pub use hsi48::*; #[cfg_attr(rcc_f0, path = "f0.rs")] -#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")] -#[cfg_attr(rcc_f2, path = "f2.rs")] -#[cfg_attr(any(rcc_f3, rcc_f3_v2), path = "f3.rs")] -#[cfg_attr(any(rcc_f4, rcc_f410, rcc_f7), path = "f4f7.rs")] +#[cfg_attr(any(stm32f1), path = "f1.rs")] +#[cfg_attr(any(stm32f3), path = "f3.rs")] +#[cfg_attr(any(stm32f2, stm32f4, stm32f7), path = "f.rs")] #[cfg_attr(rcc_c0, path = "c0.rs")] #[cfg_attr(rcc_g0, path = "g0.rs")] #[cfg_attr(rcc_g4, path = "g4.rs")] -#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] +#[cfg_attr(any(stm32h5, stm32h7), path = "h.rs")] #[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index feec9001..aae7637d 100644 --- a/examples/stm32f2/src/bin/pll.rs +++ b/examples/stm32f2/src/bin/pll.rs @@ -6,9 +6,6 @@ use core::convert::TryFrom; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ - APBPrescaler, ClockSrc, HSEConfig, HSESrc, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllSource, -}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; use embassy_time::Timer; @@ -19,29 +16,35 @@ async fn main(_spawner: Spawner) { // Example config for maximum performance on a NUCLEO-F207ZG board let mut config = Config::default(); - // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) - config.rcc.hse = Some(HSEConfig { - frequency: Hertz(8_000_000), - source: HSESrc::Bypass, - }); - // PLL uses HSE as the clock source - config.rcc.pll_mux = PllSource::HSE; - config.rcc.pll = Pll { - // 8 MHz clock source / 8 = 1 MHz PLL input - pre_div: unwrap!(PllPreDiv::try_from(8)), - // 1 MHz PLL input * 240 = 240 MHz PLL VCO - mul: unwrap!(PllMul::try_from(240)), - // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - divp: PllPDiv::DIV2, - // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - divq: PllQDiv::DIV5, - }; - // System clock comes from PLL (= the 120 MHz main PLL output) - config.rcc.mux = ClockSrc::PLL; - // 120 MHz / 4 = 30 MHz APB1 frequency - config.rcc.apb1_pre = APBPrescaler::DIV4; - // 120 MHz / 2 = 60 MHz APB2 frequency - config.rcc.apb2_pre = APBPrescaler::DIV2; + + { + use embassy_stm32::rcc::*; + + // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + // PLL uses HSE as the clock source + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + // 8 MHz clock source / 8 = 1 MHz PLL input + prediv: unwrap!(PllPreDiv::try_from(8)), + // 1 MHz PLL input * 240 = 240 MHz PLL VCO + mul: unwrap!(PllMul::try_from(240)), + // 240 MHz PLL VCO / 2 = 120 MHz main PLL output + divp: Some(PllPDiv::DIV2), + // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output + divq: Some(PllQDiv::DIV5), + divr: None, + }); + // System clock comes from PLL (= the 120 MHz main PLL output) + config.rcc.sys = Sysclk::PLL1_P; + // 120 MHz / 4 = 30 MHz APB1 frequency + config.rcc.apb1_pre = APBPrescaler::DIV4; + // 120 MHz / 2 = 60 MHz APB2 frequency + config.rcc.apb2_pre = APBPrescaler::DIV2; + } let _p = embassy_stm32::init(config); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index fe694cbe..a44e8230 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -236,24 +236,25 @@ pub fn config() -> Config { { use embassy_stm32::rcc::*; // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) - config.rcc.hse = Some(HSEConfig { - frequency: Hertz(8_000_000), - source: HSESrc::Bypass, + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, }); // PLL uses HSE as the clock source - config.rcc.pll_mux = PllSource::HSE; - config.rcc.pll = Pll { + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { // 8 MHz clock source / 8 = 1 MHz PLL input - pre_div: unwrap!(PllPreDiv::try_from(8)), + prediv: unwrap!(PllPreDiv::try_from(8)), // 1 MHz PLL input * 240 = 240 MHz PLL VCO mul: unwrap!(PllMul::try_from(240)), // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - divp: PllPDiv::DIV2, + divp: Some(PllPDiv::DIV2), // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - divq: PllQDiv::DIV5, - }; + divq: Some(PllQDiv::DIV5), + divr: None, + }); // System clock comes from PLL (= the 120 MHz main PLL output) - config.rcc.mux = ClockSrc::PLL; + config.rcc.sys = Sysclk::PLL1_P; // 120 MHz / 4 = 30 MHz APB1 frequency config.rcc.apb1_pre = APBPrescaler::DIV4; // 120 MHz / 2 = 60 MHz APB2 frequency