diff --git a/embassy-stm32/src/pwr/mod.rs b/embassy-stm32/src/pwr/mod.rs index 18f462bd2..d948c398d 100644 --- a/embassy-stm32/src/pwr/mod.rs +++ b/embassy-stm32/src/pwr/mod.rs @@ -7,6 +7,7 @@ #[cfg_attr(pwr_g4, path = "g4.rs")] #[cfg_attr(pwr_l1, path = "l1.rs")] #[cfg_attr(pwr_u5, path = "u5.rs")] +#[cfg_attr(pwr_wb55, path = "wb55.rs")] mod _version; pub use _version::*; diff --git a/embassy-stm32/src/pwr/wb55.rs b/embassy-stm32/src/pwr/wb55.rs new file mode 100644 index 000000000..e69de29bb diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index 08a9bc9b4..58a08adbf 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -7,17 +7,18 @@ use embassy::util::Unborrow; const HSI: u32 = 16_000_000; -/// Clocks configutation +/// Clocks configuration #[non_exhaustive] #[derive(Default)] pub struct Config { pub hse: Option, pub bypass_hse: bool, - pub pll48: bool, - pub sys_ck: Option, pub hclk: Option, + pub sys_ck: Option, pub pclk1: Option, pub pclk2: Option, + + pub pll48: bool, } /// RCC peripheral @@ -38,6 +39,8 @@ impl<'d> Rcc<'d> { use super::sealed::RccPeripheral; use crate::pac::rcc::vals::{Hpre, Hsebyp, Ppre, Sw}; + peripherals::PWR::enable(); + let pllsrcclk = self.config.hse.map(|hse| hse.0).unwrap_or(HSI); let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); let sysclk_on_pll = sysclk != pllsrcclk; @@ -50,12 +53,9 @@ impl<'d> Rcc<'d> { ); if self.config.pll48 { - assert!( - // USB specification allows +-0.25% - plls.pll48clk - .map(|freq| (48_000_000 - freq as i32).abs() <= 120_000) - .unwrap_or(false) - ); + let freq = unwrap!(plls.pll48clk); + + assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32); } let sysclk = if sysclk_on_pll { @@ -64,6 +64,7 @@ impl<'d> Rcc<'d> { sysclk }; + // AHB prescaler let hclk = self.config.hclk.map(|h| h.0).unwrap_or(sysclk); let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk { 0 => unreachable!(), @@ -86,6 +87,7 @@ impl<'d> Rcc<'d> { .pclk1 .map(|p| p.0) .unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk)); + let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 { 0 => unreachable!(), 1 => (0b000, 1), @@ -136,14 +138,12 @@ impl<'d> Rcc<'d> { unsafe { RCC.cr().modify(|w| w.set_pllon(true)); - if hclk > 168_000_000 { - peripherals::PWR::enable(); + if hclk > max::HCLK_OVERDRIVE_FREQUENCY { + PWR.cr1().modify(|w| w.set_oden(true)); + while !PWR.csr1().read().odrdy() {} - PWR.cr().modify(|w| w.set_oden(true)); - while !PWR.csr().read().odrdy() {} - - PWR.cr().modify(|w| w.set_odswen(true)); - while !PWR.csr().read().odswrdy() {} + PWR.cr1().modify(|w| w.set_odswen(true)); + while !PWR.csr1().read().odswrdy() {} } while !RCC.cr().read().pllrdy() {} @@ -310,23 +310,24 @@ struct PllResults { 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; + pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 168_000_000; + + pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2; + #[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; + 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.rs b/embassy-stm32/src/rcc/f7.rs index 25f78c701..d29ba31f0 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -7,6 +7,7 @@ use embassy::util::Unborrow; const HSI: u32 = 16_000_000; +/// Clocks configuration #[non_exhaustive] #[derive(Default)] pub struct Config { @@ -46,27 +47,25 @@ impl<'d> Rcc<'d> { use crate::pac::pwr::vals::Vos; use crate::pac::rcc::vals::{Hpre, Hsebyp, Ppre, Sw}; - let base_clock = self.config.hse.map(|hse| hse.0).unwrap_or(HSI); - let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(base_clock); - let sysclk_on_pll = sysclk != base_clock; + peripherals::PWR::enable(); + + let pllsrcclk = self.config.hse.map(|hse| hse.0).unwrap_or(HSI); + let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); + let sysclk_on_pll = sysclk != pllsrcclk; assert!((max::SYSCLK_MIN..=max::SYSCLK_MAX).contains(&sysclk)); let plls = self.setup_pll( - base_clock, + pllsrcclk, self.config.hse.is_some(), if sysclk_on_pll { Some(sysclk) } else { None }, self.config.pll48, ); if self.config.pll48 { - assert!( - // USB specification allows +-0.25% - plls.pll48clk - .map(|freq| (max::PLL_48_CLK as i32 - freq as i32).abs() - <= max::PLL_48_TOLERANCE as i32) - .unwrap_or(false) - ); + let freq = unwrap!(plls.pll48clk); + + assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32); } let sysclk = if sysclk_on_pll { @@ -173,11 +172,7 @@ impl<'d> Rcc<'d> { RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - if hclk > max::HCLK_OVERDRIVE_FREQUENCY { - peripherals::PWR::enable(); - PWR.cr1().modify(|w| w.set_oden(true)); while !PWR.csr1().read().odrdy() {} @@ -222,6 +217,8 @@ impl<'d> Rcc<'d> { ahb1: Hertz(hclk), ahb2: Hertz(hclk), ahb3: Hertz(hclk), + + pll48: plls.pll48clk.map(Hertz), } } @@ -362,6 +359,7 @@ mod max { pub(crate) const PCLK2_MIN: u32 = SYSCLK_MIN; pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; + // USB specification allows +-0.25% 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/mod.rs b/embassy-stm32/src/rcc/mod.rs index bf612464f..d0b6e5a18 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -61,7 +61,7 @@ pub struct Clocks { #[cfg(any(rcc_h7))] pub apb4: Hertz, - #[cfg(rcc_f4)] + #[cfg(any(rcc_f4, rcc_f7))] pub pll48: Option, #[cfg(rcc_f1)] diff --git a/stm32-data b/stm32-data index 27f9d6dc2..8530a19ff 160000 --- a/stm32-data +++ b/stm32-data @@ -1 +1 @@ -Subproject commit 27f9d6dc2c5afaa5003ce9afc06def9b16d30adb +Subproject commit 8530a19ffdcdcbc608a97b40895827d09e670eb7