diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index df6e9047..6a932634 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -1,5 +1,6 @@ +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::{Hpre, Hsidiv, Ppre, Sw}; +use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -45,58 +46,6 @@ impl Into for HSIPrescaler { } } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - -impl Into for APBPrescaler { - fn into(self) -> Ppre { - match self { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl Into for AHBPrescaler { - fn into(self) -> Hpre { - match self { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, diff --git a/embassy-stm32/src/rcc/common.rs b/embassy-stm32/src/rcc/common.rs new file mode 100644 index 00000000..7debb143 --- /dev/null +++ b/embassy-stm32/src/rcc/common.rs @@ -0,0 +1,174 @@ +use core::ops::Div; + +#[allow(unused_imports)] +use crate::pac::rcc; +use crate::time::Hertz; + +/// Voltage Scale +/// +/// Represents the voltage range feeding the CPU core. The maximum core +/// clock frequency depends on this value. +/// +/// Scale0 represents the highest voltage range +#[derive(Copy, Clone, PartialEq)] +pub enum VoltageScale { + Scale0, + Scale1, + #[cfg(not(any(rcc_wl5, rcc_wle)))] + Scale2, + #[cfg(not(any(rcc_wl5, rcc_wle)))] + Scale3, +} + +/// AHB prescaler +#[derive(Clone, Copy, PartialEq)] +pub enum AHBPrescaler { + NotDivided, + Div2, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + Div3, + Div4, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + Div5, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + Div6, + Div8, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + Div10, + Div16, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + Div32, + Div64, + Div128, + Div256, + Div512, +} + +impl Div for Hertz { + type Output = Hertz; + + fn div(self, rhs: AHBPrescaler) -> Self::Output { + let divisor = match rhs { + AHBPrescaler::NotDivided => 1, + AHBPrescaler::Div2 => 2, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + AHBPrescaler::Div3 => 3, + AHBPrescaler::Div4 => 4, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + AHBPrescaler::Div5 => 5, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + AHBPrescaler::Div6 => 6, + AHBPrescaler::Div8 => 8, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + AHBPrescaler::Div10 => 10, + AHBPrescaler::Div16 => 16, + #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] + AHBPrescaler::Div32 => 32, + AHBPrescaler::Div64 => 64, + AHBPrescaler::Div128 => 128, + AHBPrescaler::Div256 => 256, + AHBPrescaler::Div512 => 512, + }; + Hertz(self.0 / divisor) + } +} + +#[cfg(not(any(rcc_g4, rcc_wb, rcc_wl5, rcc_wle)))] +impl From for rcc::vals::Hpre { + fn from(val: AHBPrescaler) -> rcc::vals::Hpre { + use rcc::vals::Hpre; + + match val { + #[cfg(not(rcc_u5))] + AHBPrescaler::NotDivided => Hpre::DIV1, + #[cfg(rcc_u5)] + AHBPrescaler::NotDivided => Hpre::NONE, + AHBPrescaler::Div2 => Hpre::DIV2, + AHBPrescaler::Div4 => Hpre::DIV4, + AHBPrescaler::Div8 => Hpre::DIV8, + AHBPrescaler::Div16 => Hpre::DIV16, + AHBPrescaler::Div64 => Hpre::DIV64, + AHBPrescaler::Div128 => Hpre::DIV128, + AHBPrescaler::Div256 => Hpre::DIV256, + AHBPrescaler::Div512 => Hpre::DIV512, + } + } +} + +#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] +impl From for u8 { + fn from(val: AHBPrescaler) -> u8 { + match val { + AHBPrescaler::NotDivided => 0x0, + AHBPrescaler::Div2 => 0x08, + AHBPrescaler::Div3 => 0x01, + AHBPrescaler::Div4 => 0x09, + AHBPrescaler::Div5 => 0x02, + AHBPrescaler::Div6 => 0x05, + AHBPrescaler::Div8 => 0x0a, + AHBPrescaler::Div10 => 0x06, + AHBPrescaler::Div16 => 0x0b, + AHBPrescaler::Div32 => 0x07, + AHBPrescaler::Div64 => 0x0c, + AHBPrescaler::Div128 => 0x0d, + AHBPrescaler::Div256 => 0x0e, + AHBPrescaler::Div512 => 0x0f, + } + } +} + +/// APB prescaler +#[derive(Clone, Copy)] +pub enum APBPrescaler { + NotDivided, + Div2, + Div4, + Div8, + Div16, +} + +impl Div for Hertz { + type Output = Hertz; + + fn div(self, rhs: APBPrescaler) -> Self::Output { + let divisor = match rhs { + APBPrescaler::NotDivided => 1, + APBPrescaler::Div2 => 2, + APBPrescaler::Div4 => 4, + APBPrescaler::Div8 => 8, + APBPrescaler::Div16 => 16, + }; + Hertz(self.0 / divisor) + } +} + +#[cfg(not(any(rcc_f1, rcc_g4, rcc_h7, rcc_wb, rcc_wl5, rcc_wle)))] +impl From for rcc::vals::Ppre { + fn from(val: APBPrescaler) -> rcc::vals::Ppre { + use rcc::vals::Ppre; + + match val { + #[cfg(not(rcc_u5))] + APBPrescaler::NotDivided => Ppre::DIV1, + #[cfg(rcc_u5)] + APBPrescaler::NotDivided => Ppre::NONE, + APBPrescaler::Div2 => Ppre::DIV2, + APBPrescaler::Div4 => Ppre::DIV4, + APBPrescaler::Div8 => Ppre::DIV8, + APBPrescaler::Div16 => Ppre::DIV16, + } + } +} + +#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] +impl From for u8 { + fn from(val: APBPrescaler) -> u8 { + match val { + APBPrescaler::NotDivided => 1, + APBPrescaler::Div2 => 0x04, + APBPrescaler::Div4 => 0x05, + APBPrescaler::Div8 => 0x06, + APBPrescaler::Div16 => 0x07, + } + } +} diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 1525cc3c..69e89113 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -1,8 +1,9 @@ use core::convert::TryFrom; use core::ops::{Div, Mul}; +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::{Hpre, Pllp, Pllsrc, Ppre, Sw}; +use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -200,114 +201,15 @@ pub struct PLLClocks { pub pll48_freq: Hertz, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} +pub use super::common::VoltageScale; -impl Div for Hertz { - type Output = Hertz; - - fn div(self, rhs: AHBPrescaler) -> Self::Output { - let divisor = match rhs { - AHBPrescaler::NotDivided => 1, - AHBPrescaler::Div2 => 2, - AHBPrescaler::Div4 => 4, - AHBPrescaler::Div8 => 8, - AHBPrescaler::Div16 => 16, - AHBPrescaler::Div64 => 64, - AHBPrescaler::Div128 => 128, - AHBPrescaler::Div256 => 256, - AHBPrescaler::Div512 => 512, - }; - Hertz(self.0 / divisor) - } -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - -impl Div for Hertz { - type Output = Hertz; - - fn div(self, rhs: APBPrescaler) -> Self::Output { - let divisor = match rhs { - APBPrescaler::NotDivided => 1, - APBPrescaler::Div2 => 2, - APBPrescaler::Div4 => 4, - APBPrescaler::Div8 => 8, - APBPrescaler::Div16 => 16, - }; - Hertz(self.0 / divisor) - } -} - -impl Into for APBPrescaler { - fn into(self) -> Ppre { - match self { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl Into for AHBPrescaler { - fn into(self) -> Hpre { - match self { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - -/// Voltage Range -/// -/// Represents the system supply voltage range -#[derive(Copy, Clone, PartialEq)] -pub enum VoltageRange { - /// 1.8 to 3.6 V - Min1V8, - /// 2.1 to 3.6 V - Min2V1, - /// 2.4 to 3.6 V - Min2V4, - /// 2.7 to 3.6 V - Min2V7, -} - -impl VoltageRange { +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 { - VoltageRange::Min1V8 => { + VoltageScale::Scale3 => { if ahb_freq <= 16_000_000 { Some(Latency::WS0) } else if ahb_freq <= 32_000_000 { @@ -328,7 +230,7 @@ impl VoltageRange { None } } - VoltageRange::Min2V1 => { + VoltageScale::Scale2 => { if ahb_freq <= 18_000_000 { Some(Latency::WS0) } else if ahb_freq <= 36_000_000 { @@ -347,7 +249,7 @@ impl VoltageRange { None } } - VoltageRange::Min2V4 => { + VoltageScale::Scale1 => { if ahb_freq <= 24_000_000 { Some(Latency::WS0) } else if ahb_freq <= 48_000_000 { @@ -362,7 +264,7 @@ impl VoltageRange { None } } - VoltageRange::Min2V7 => { + VoltageScale::Scale0 => { if ahb_freq <= 30_000_000 { Some(Latency::WS0) } else if ahb_freq <= 60_000_000 { @@ -386,7 +288,7 @@ pub struct Config { pub pll_mux: PLLSrc, pub pll: PLLConfig, pub mux: ClockSrc, - pub voltage: VoltageRange, + pub voltage: VoltageScale, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, @@ -400,7 +302,7 @@ impl Default for Config { hsi: true, pll_mux: PLLSrc::HSI, pll: PLLConfig::default(), - voltage: VoltageRange::Min1V8, + voltage: VoltageScale::Scale3, mux: ClockSrc::HSI, ahb_pre: AHBPrescaler::NotDivided, apb1_pre: APBPrescaler::NotDivided, diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 5e3a7911..1aaf983a 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -1,5 +1,6 @@ +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::{self, Hpre, Hsidiv, Ppre, Sw}; +use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -172,58 +173,6 @@ impl From for u32 { } } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - -impl Into for APBPrescaler { - fn into(self) -> Ppre { - match self { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl Into for AHBPrescaler { - fn into(self) -> Hpre { - match self { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -425,25 +374,14 @@ pub(crate) unsafe fn init(config: Config) { FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); } - let ahb_div = match config.ahb_pre { - AHBPrescaler::NotDivided => 1, - AHBPrescaler::Div2 => 2, - AHBPrescaler::Div4 => 4, - AHBPrescaler::Div8 => 8, - AHBPrescaler::Div16 => 16, - AHBPrescaler::Div64 => 64, - AHBPrescaler::Div128 => 128, - AHBPrescaler::Div256 => 256, - AHBPrescaler::Div512 => 512, - }; - let ahb_freq = sys_clk / ahb_div; + let ahb_freq = Hertz(sys_clk) / config.ahb_pre; let (apb_freq, apb_tim_freq) = match config.apb_pre { - APBPrescaler::NotDivided => (ahb_freq, ahb_freq), + APBPrescaler::NotDivided => (ahb_freq.0, ahb_freq.0), pre => { let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; + let pre: u8 = 1 << (pre.0 - 3); + let freq = ahb_freq.0 / pre as u32; (freq, freq * 2) } }; @@ -455,7 +393,7 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), + ahb1: ahb_freq, apb1: Hertz(apb_freq), apb1_tim: Hertz(apb_tim_freq), }); diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index ff8f9754..5489b718 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -2,6 +2,7 @@ use stm32_metapac::flash::vals::Latency; use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw}; use stm32_metapac::FLASH; +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::{PWR, RCC}; use crate::rcc::sealed::RccPeripheral; use crate::rcc::{set_freqs, Clocks}; @@ -21,39 +22,8 @@ pub enum ClockSrc { PLL, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - -/// PLL clock input source -#[derive(Clone, Copy, Debug)] -pub enum PllSrc { - HSI16, - HSE(Hertz), -} - -impl Into for PllSrc { - fn into(self) -> Pllsrc { +impl Into for APBPrescaler { + fn into(self) -> u8 { match self { PllSrc::HSE(..) => Pllsrc::HSE, PllSrc::HSI16 => Pllsrc::HSI16, diff --git a/embassy-stm32/src/rcc/h5.rs b/embassy-stm32/src/rcc/h5.rs index 7e2f75ab..2e72b193 100644 --- a/embassy-stm32/src/rcc/h5.rs +++ b/embassy-stm32/src/rcc/h5.rs @@ -1,6 +1,6 @@ use core::marker::PhantomData; -use stm32_metapac::rcc::vals::{Hpre, Ppre, Timpre}; +use stm32_metapac::rcc::vals::Timpre; use crate::pac::pwr::vals::Vos; use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw}; @@ -26,21 +26,7 @@ const VCO_MAX: u32 = 420_000_000; const VCO_WIDE_MIN: u32 = 128_000_000; const VCO_WIDE_MAX: u32 = 560_000_000; -/// Voltage Scale -/// -/// Represents the voltage range feeding the CPU core. The maximum core -/// clock frequency depends on this value. -#[derive(Copy, Clone, PartialEq)] -pub enum VoltageScale { - /// VOS 0 range VCORE 1.30V - 1.40V - Scale0, - /// VOS 1 range VCORE 1.15V - 1.26V - Scale1, - /// VOS 2 range VCORE 1.05V - 1.15V - Scale2, - /// VOS 3 range VCORE 0.95V - 1.05V - Scale3, -} +pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; pub enum HseMode { /// crystal/ceramic oscillator (HSEBYP=0) @@ -105,57 +91,7 @@ pub struct Pll { pub divr: Option, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -impl AHBPrescaler { - fn div(&self, clk: Hertz) -> Hertz { - match self { - Self::NotDivided => clk, - Self::Div2 => clk / 2u32, - Self::Div4 => clk / 4u32, - Self::Div8 => clk / 8u32, - Self::Div16 => clk / 16u32, - Self::Div64 => clk / 64u32, - Self::Div128 => clk / 128u32, - Self::Div256 => clk / 256u32, - Self::Div512 => clk / 512u32, - } - } -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - impl APBPrescaler { - fn div(&self, clk: Hertz) -> Hertz { - match self { - Self::NotDivided => clk, - Self::Div2 => clk / 2u32, - Self::Div4 => clk / 4u32, - Self::Div8 => clk / 8u32, - Self::Div16 => clk / 16u32, - } - } - fn div_tim(&self, clk: Hertz, tim: TimerPrescaler) -> Hertz { match (tim, self) { // The timers kernel clock is equal to rcc_hclk1 if PPRE1 or PPRE2 corresponds to a @@ -193,34 +129,6 @@ impl From for Timpre { } } -impl From for Ppre { - fn from(val: APBPrescaler) -> Ppre { - match val { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl From for Hpre { - fn from(val: AHBPrescaler) -> Hpre { - match val { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - /// Configuration of the core clocks #[non_exhaustive] pub struct Config { @@ -406,13 +314,13 @@ pub(crate) unsafe fn init(config: Config) { }; assert!(sys <= max_clk); - let hclk = config.ahb_pre.div(sys); + let hclk = sys / config.ahb_pre; - let apb1 = config.apb1_pre.div(hclk); + let apb1 = hclk / config.apb1_pre; let apb1_tim = config.apb1_pre.div_tim(hclk, config.timer_prescaler); - let apb2 = config.apb2_pre.div(hclk); + let apb2 = hclk / config.apb2_pre; let apb2_tim = config.apb2_pre.div_tim(hclk, config.timer_prescaler); - let apb3 = config.apb3_pre.div(hclk); + let apb3 = hclk / config.apb3_pre; flash_setup(hclk, config.voltage_scale); diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs index bbc0e083..0788b064 100644 --- a/embassy-stm32/src/rcc/h7.rs +++ b/embassy-stm32/src/rcc/h7.rs @@ -24,21 +24,7 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(32_000); -/// Voltage Scale -/// -/// Represents the voltage range feeding the CPU core. The maximum core -/// clock frequency depends on this value. -#[derive(Copy, Clone, PartialEq)] -pub enum VoltageScale { - /// VOS 0 range VCORE 1.26V - 1.40V - Scale0, - /// VOS 1 range VCORE 1.15V - 1.26V - Scale1, - /// VOS 2 range VCORE 1.05V - 1.15V - Scale2, - /// VOS 3 range VCORE 0.95V - 1.05V - Scale3, -} +pub use super::common::VoltageScale; #[derive(Clone, Copy)] pub enum AdcClockSource { diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index 46a528e3..46b58ca7 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs @@ -1,3 +1,4 @@ +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; use crate::pac::RCC; #[cfg(crs)] @@ -70,30 +71,6 @@ pub enum PLLMul { Mul48, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -136,34 +113,6 @@ impl From for Pllsrc { } } -impl From for Ppre { - fn from(val: APBPrescaler) -> Ppre { - match val { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl From for Hpre { - fn from(val: AHBPrescaler) -> Hpre { - match val { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - impl From for Msirange { fn from(val: MSIRange) -> Msirange { match val { diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs index 59a6eac8..bdfc5b87 100644 --- a/embassy-stm32/src/rcc/l1.rs +++ b/embassy-stm32/src/rcc/l1.rs @@ -1,3 +1,4 @@ +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -68,30 +69,6 @@ pub enum PLLMul { Mul48, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -134,34 +111,6 @@ impl From for Pllsrc { } } -impl From for Ppre { - fn from(val: APBPrescaler) -> Ppre { - match val { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl From for Hpre { - fn from(val: AHBPrescaler) -> Hpre { - match val { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - impl From for Msirange { fn from(val: MSIRange) -> Msirange { match val { diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index dc5f55d0..237b7bc9 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -4,6 +4,7 @@ use embassy_hal_internal::into_ref; use stm32_metapac::rcc::regs::Cfgr; use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::gpio::sealed::AFType; use crate::gpio::Speed; use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; @@ -78,30 +79,6 @@ pub enum PLLDiv { Div4, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -209,34 +186,6 @@ impl From for Pllsrc { } } -impl From for Ppre { - fn from(val: APBPrescaler) -> Ppre { - match val { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl From for Hpre { - fn from(val: AHBPrescaler) -> Hpre { - match val { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - impl From for Msirange { fn from(val: MSIRange) -> Msirange { match val { diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index 16da65d5..a85e1488 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs @@ -1,5 +1,6 @@ use stm32_metapac::PWR; +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -71,30 +72,6 @@ pub enum PLLDiv { Div4, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -202,34 +179,6 @@ impl From for Pllsrc { } } -impl From for Ppre { - fn from(val: APBPrescaler) -> Ppre { - match val { - APBPrescaler::NotDivided => Ppre::DIV1, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - -impl From for Hpre { - fn from(val: AHBPrescaler) -> Hpre { - match val { - AHBPrescaler::NotDivided => Hpre::DIV1, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - impl From for Msirange { fn from(val: MSIRange) -> Msirange { match val { diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 4ae65d3e..5c69037e 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -1,5 +1,7 @@ #![macro_use] +pub mod common; + use core::mem::MaybeUninit; use crate::time::Hertz; diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index cfc07f06..b5feeb0c 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -1,5 +1,6 @@ -use stm32_metapac::rcc::vals::{Hpre, Msirange, Msirgsel, Pllm, Pllsrc, Ppre, Sw}; +use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw}; +pub use super::common::{AHBPrescaler, APBPrescaler}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -10,19 +11,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(32_000); -/// Voltage Scale -/// -/// Represents the voltage range feeding the CPU core. The maximum core -/// clock frequency depends on this value. -#[derive(Copy, Clone, PartialEq)] -pub enum VoltageScale { - // Highest frequency - Range1, - Range2, - Range3, - // Lowest power - Range4, -} +pub use super::common::VoltageScale; #[derive(Copy, Clone)] pub enum ClockSrc { @@ -130,36 +119,6 @@ impl Into for PllM { } } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div64, - Div128, - Div256, - Div512, -} - -impl Into for AHBPrescaler { - fn into(self) -> Hpre { - match self { - AHBPrescaler::NotDivided => Hpre::NONE, - AHBPrescaler::Div2 => Hpre::DIV2, - AHBPrescaler::Div4 => Hpre::DIV4, - AHBPrescaler::Div8 => Hpre::DIV8, - AHBPrescaler::Div16 => Hpre::DIV16, - AHBPrescaler::Div64 => Hpre::DIV64, - AHBPrescaler::Div128 => Hpre::DIV128, - AHBPrescaler::Div256 => Hpre::DIV256, - AHBPrescaler::Div512 => Hpre::DIV512, - } - } -} - impl Into for AHBPrescaler { fn into(self) -> u8 { match self { @@ -182,28 +141,6 @@ impl Default for AHBPrescaler { } } -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - -impl Into for APBPrescaler { - fn into(self) -> Ppre { - match self { - APBPrescaler::NotDivided => Ppre::NONE, - APBPrescaler::Div2 => Ppre::DIV2, - APBPrescaler::Div4 => Ppre::DIV4, - APBPrescaler::Div8 => Ppre::DIV8, - APBPrescaler::Div16 => Ppre::DIV16, - } - } -} - impl Default for APBPrescaler { fn default() -> Self { APBPrescaler::NotDivided @@ -389,12 +326,12 @@ pub(crate) unsafe fn init(config: Config) { } // TODO make configurable - let power_vos = VoltageScale::Range4; + let power_vos = VoltageScale::Scale3; // states and programming delay let wait_states = match power_vos { // VOS 0 range VCORE 1.26V - 1.40V - VoltageScale::Range1 => { + VoltageScale::Scale0 => { if sys_clk < 32_000_000 { 0 } else if sys_clk < 64_000_000 { @@ -408,7 +345,7 @@ pub(crate) unsafe fn init(config: Config) { } } // VOS 1 range VCORE 1.15V - 1.26V - VoltageScale::Range2 => { + VoltageScale::Scale1 => { if sys_clk < 30_000_000 { 0 } else if sys_clk < 60_000_000 { @@ -420,7 +357,7 @@ pub(crate) unsafe fn init(config: Config) { } } // VOS 2 range VCORE 1.05V - 1.15V - VoltageScale::Range3 => { + VoltageScale::Scale2 => { if sys_clk < 24_000_000 { 0 } else if sys_clk < 48_000_000 { @@ -430,7 +367,7 @@ pub(crate) unsafe fn init(config: Config) { } } // VOS 3 range VCORE 0.95V - 1.05V - VoltageScale::Range4 => { + VoltageScale::Scale3 => { if sys_clk < 12_000_000 { 0 } else { diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index 4322b950..b8ef01a9 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -1,5 +1,7 @@ -use crate::rcc::Clocks; -use crate::time::{khz, mhz, Hertz}; +pub use super::common::{AHBPrescaler, APBPrescaler}; +use crate::pac::RCC; +use crate::rcc::{set_freqs, Clocks, Clocks}; +use crate::time::{khz, mhz, Hertz, Hertz}; /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, /// and with the addition of the init function to configure a system clock. @@ -102,68 +104,6 @@ pub struct Pll { pub divr: Option, } -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div3, - Div4, - Div5, - Div6, - Div8, - Div10, - Div16, - Div32, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - -impl Into for APBPrescaler { - fn into(self) -> u8 { - match self { - APBPrescaler::NotDivided => 1, - APBPrescaler::Div2 => 0x04, - APBPrescaler::Div4 => 0x05, - APBPrescaler::Div8 => 0x06, - APBPrescaler::Div16 => 0x07, - } - } -} - -impl Into for AHBPrescaler { - fn into(self) -> u8 { - match self { - AHBPrescaler::NotDivided => 0x0, - AHBPrescaler::Div2 => 0x08, - AHBPrescaler::Div3 => 0x01, - AHBPrescaler::Div4 => 0x09, - AHBPrescaler::Div5 => 0x02, - AHBPrescaler::Div6 => 0x05, - AHBPrescaler::Div8 => 0x0a, - AHBPrescaler::Div10 => 0x06, - AHBPrescaler::Div16 => 0x0b, - AHBPrescaler::Div32 => 0x07, - AHBPrescaler::Div64 => 0x0c, - AHBPrescaler::Div128 => 0x0d, - AHBPrescaler::Div256 => 0x0e, - AHBPrescaler::Div512 => 0x0f, - } - } -} - /// Clocks configutation pub struct Config { pub hse: Option, diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 6b69bb1c..eca1f613 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -1,5 +1,6 @@ +pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; use crate::pac::pwr::vals::Dbp; -use crate::pac::{FLASH, PWR, RCC}; +use crate::pac::{FLASH, FLASH, PWR, RCC, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -73,9 +74,9 @@ impl MSIRange { fn vos(&self) -> VoltageScale { if self > &MSIRange::Range8 { - VoltageScale::Range1 + VoltageScale::Scale0 } else { - VoltageScale::Range2 + VoltageScale::Scale1 } } } @@ -105,78 +106,6 @@ impl Into for MSIRange { } } -/// Voltage Scale -/// -/// Represents the voltage range feeding the CPU core. The maximum core -/// clock frequency depends on this value. -#[derive(Copy, Clone, PartialEq)] -pub enum VoltageScale { - Range1, - Range2, -} - -/// AHB prescaler -#[derive(Clone, Copy, PartialEq)] -pub enum AHBPrescaler { - NotDivided, - Div2, - Div3, - Div4, - Div5, - Div6, - Div8, - Div10, - Div16, - Div32, - Div64, - Div128, - Div256, - Div512, -} - -/// APB prescaler -#[derive(Clone, Copy)] -pub enum APBPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, -} - -impl Into for APBPrescaler { - fn into(self) -> u8 { - match self { - APBPrescaler::NotDivided => 1, - APBPrescaler::Div2 => 0x04, - APBPrescaler::Div4 => 0x05, - APBPrescaler::Div8 => 0x06, - APBPrescaler::Div16 => 0x07, - } - } -} - -impl Into for AHBPrescaler { - fn into(self) -> u8 { - match self { - AHBPrescaler::NotDivided => 0x0, - AHBPrescaler::Div2 => 0x08, - AHBPrescaler::Div3 => 0x01, - AHBPrescaler::Div4 => 0x09, - AHBPrescaler::Div5 => 0x02, - AHBPrescaler::Div6 => 0x05, - AHBPrescaler::Div8 => 0x0a, - AHBPrescaler::Div10 => 0x06, - AHBPrescaler::Div16 => 0x0b, - AHBPrescaler::Div32 => 0x07, - AHBPrescaler::Div64 => 0x0c, - AHBPrescaler::Div128 => 0x0d, - AHBPrescaler::Div256 => 0x0e, - AHBPrescaler::Div512 => 0x0f, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -220,8 +149,8 @@ pub enum Lsedrv { pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw, vos) = match config.mux { - ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Range2), - ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Range1), + ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Scale1), + ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Scale0), ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), }; @@ -266,12 +195,12 @@ pub(crate) unsafe fn init(config: Config) { // Adjust flash latency let flash_clk_src_freq: u32 = shd_ahb_freq; let ws = match vos { - VoltageScale::Range1 => match flash_clk_src_freq { + VoltageScale::Scale0 => match flash_clk_src_freq { 0..=18_000_000 => 0b000, 18_000_001..=36_000_000 => 0b001, _ => 0b010, }, - VoltageScale::Range2 => match flash_clk_src_freq { + VoltageScale::Scale1 => match flash_clk_src_freq { 0..=6_000_000 => 0b000, 6_000_001..=12_000_000 => 0b001, _ => 0b010,