stm32: use PAC enums for VOS.

This commit is contained in:
Dario Nieuwenhuis 2023-09-18 03:00:59 +02:00
parent 0da793e5de
commit 4bfbcd6c72
11 changed files with 156 additions and 106 deletions

2
ci.sh
View File

@ -85,6 +85,8 @@ cargo batch \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \

View File

@ -67,24 +67,20 @@ where
self.board_type = board_type; self.board_type = board_type;
} }
async fn set_nss_low(&mut self) -> Result<(), RadioError> { async fn set_nss_low(&mut self) -> Result<(), RadioError> {
let pwr = pac::PWR; pac::PWR.subghzspicr().modify(|w| w.set_nss(false));
pwr.subghzspicr().modify(|w| w.set_nss(pac::pwr::vals::Nss::LOW));
Ok(()) Ok(())
} }
async fn set_nss_high(&mut self) -> Result<(), RadioError> { async fn set_nss_high(&mut self) -> Result<(), RadioError> {
let pwr = pac::PWR; pac::PWR.subghzspicr().modify(|w| w.set_nss(true));
pwr.subghzspicr().modify(|w| w.set_nss(pac::pwr::vals::Nss::HIGH));
Ok(()) Ok(())
} }
async fn reset(&mut self, _delay: &mut impl DelayUs) -> Result<(), RadioError> { async fn reset(&mut self, _delay: &mut impl DelayUs) -> Result<(), RadioError> {
let rcc = pac::RCC; pac::RCC.csr().modify(|w| w.set_rfrst(true));
rcc.csr().modify(|w| w.set_rfrst(true)); pac::RCC.csr().modify(|w| w.set_rfrst(false));
rcc.csr().modify(|w| w.set_rfrst(false));
Ok(()) Ok(())
} }
async fn wait_on_busy(&mut self) -> Result<(), RadioError> { async fn wait_on_busy(&mut self) -> Result<(), RadioError> {
let pwr = pac::PWR; while pac::PWR.sr2().read().rfbusys() {}
while pwr.sr2().read().rfbusys() == pac::pwr::vals::Rfbusys::BUSY {}
Ok(()) Ok(())
} }

View File

@ -59,7 +59,7 @@ sdio-host = "0.5.0"
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
critical-section = "1.1" critical-section = "1.1"
atomic-polyfill = "1.0.1" atomic-polyfill = "1.0.1"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-907dd82c848bc912252c61509944e85c2a48c919" } stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2dba1f1ddee697e616aff2a4db57a6ffaf1b29b7" }
vcell = "0.1.3" vcell = "0.1.3"
bxcan = "0.7.0" bxcan = "0.7.0"
nb = "1.0.0" nb = "1.0.0"
@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] }
[build-dependencies] [build-dependencies]
proc-macro2 = "1.0.36" proc-macro2 = "1.0.36"
quote = "1.0.15" quote = "1.0.15"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-907dd82c848bc912252c61509944e85c2a48c919", default-features = false, features = ["metadata"]} stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2dba1f1ddee697e616aff2a4db57a6ffaf1b29b7", default-features = false, features = ["metadata"]}
[features] [features]
default = ["rt"] default = ["rt"]

View File

@ -5,22 +5,6 @@ use crate::pac::rcc;
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
use crate::time::Hertz; 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,
}
impl Div<AHBPrescaler> for Hertz { impl Div<AHBPrescaler> for Hertz {
type Output = Hertz; type Output = Hertz;

View File

@ -203,7 +203,20 @@ pub struct PLLClocks {
pub pll48_freq: Hertz, pub pll48_freq: Hertz,
} }
pub use super::bus::VoltageScale; /// 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.7v to 4.6v
Range0,
/// 2.4v to 2.7v
Range1,
/// 2.1v to 2.4v
Range2,
/// 1.8v to 2.1v
Range3,
}
impl VoltageScale { impl VoltageScale {
const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> {
@ -211,7 +224,7 @@ impl VoltageScale {
// Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock
// frequency // frequency
match self { match self {
VoltageScale::Scale3 => { VoltageScale::Range3 => {
if ahb_freq <= 16_000_000 { if ahb_freq <= 16_000_000 {
Some(Latency::WS0) Some(Latency::WS0)
} else if ahb_freq <= 32_000_000 { } else if ahb_freq <= 32_000_000 {
@ -232,7 +245,7 @@ impl VoltageScale {
None None
} }
} }
VoltageScale::Scale2 => { VoltageScale::Range2 => {
if ahb_freq <= 18_000_000 { if ahb_freq <= 18_000_000 {
Some(Latency::WS0) Some(Latency::WS0)
} else if ahb_freq <= 36_000_000 { } else if ahb_freq <= 36_000_000 {
@ -251,7 +264,7 @@ impl VoltageScale {
None None
} }
} }
VoltageScale::Scale1 => { VoltageScale::Range1 => {
if ahb_freq <= 24_000_000 { if ahb_freq <= 24_000_000 {
Some(Latency::WS0) Some(Latency::WS0)
} else if ahb_freq <= 48_000_000 { } else if ahb_freq <= 48_000_000 {
@ -266,7 +279,7 @@ impl VoltageScale {
None None
} }
} }
VoltageScale::Scale0 => { VoltageScale::Range0 => {
if ahb_freq <= 30_000_000 { if ahb_freq <= 30_000_000 {
Some(Latency::WS0) Some(Latency::WS0)
} else if ahb_freq <= 60_000_000 { } else if ahb_freq <= 60_000_000 {
@ -307,7 +320,7 @@ impl Default for Config {
hsi: true, hsi: true,
pll_mux: PLLSrc::HSI, pll_mux: PLLSrc::HSI,
pll: PLLConfig::default(), pll: PLLConfig::default(),
voltage: VoltageScale::Scale3, voltage: VoltageScale::Range3,
mux: ClockSrc::HSI, mux: ClockSrc::HSI,
rtc: None, rtc: None,
lsi: false, lsi: false,

View File

@ -2,7 +2,6 @@ use core::marker::PhantomData;
use stm32_metapac::rcc::vals::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}; use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw};
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
@ -26,7 +25,8 @@ const VCO_MAX: u32 = 420_000_000;
const VCO_WIDE_MIN: u32 = 128_000_000; const VCO_WIDE_MIN: u32 = 128_000_000;
const VCO_WIDE_MAX: u32 = 560_000_000; const VCO_WIDE_MAX: u32 = 560_000_000;
pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; pub use super::bus::{AHBPrescaler, APBPrescaler};
pub use crate::pac::pwr::vals::Vos as VoltageScale;
pub enum HseMode { pub enum HseMode {
/// crystal/ceramic oscillator (HSEBYP=0) /// crystal/ceramic oscillator (HSEBYP=0)
@ -171,7 +171,7 @@ impl Default for Config {
apb3_pre: APBPrescaler::DIV1, apb3_pre: APBPrescaler::DIV1,
timer_prescaler: TimerPrescaler::DefaultX2, timer_prescaler: TimerPrescaler::DefaultX2,
voltage_scale: VoltageScale::Scale3, voltage_scale: VoltageScale::SCALE3,
} }
} }
} }
@ -222,15 +222,15 @@ impl<'d, T: McoInstance> Mco<'d, T> {
} }
pub(crate) unsafe fn init(config: Config) { pub(crate) unsafe fn init(config: Config) {
let (vos, max_clk) = match config.voltage_scale { let max_clk = match config.voltage_scale {
VoltageScale::Scale0 => (Vos::SCALE0, Hertz(250_000_000)), VoltageScale::SCALE0 => Hertz(250_000_000),
VoltageScale::Scale1 => (Vos::SCALE1, Hertz(200_000_000)), VoltageScale::SCALE1 => Hertz(200_000_000),
VoltageScale::Scale2 => (Vos::SCALE2, Hertz(150_000_000)), VoltageScale::SCALE2 => Hertz(150_000_000),
VoltageScale::Scale3 => (Vos::SCALE3, Hertz(100_000_000)), VoltageScale::SCALE3 => Hertz(100_000_000),
}; };
// Configure voltage scale. // Configure voltage scale.
PWR.voscr().modify(|w| w.set_vos(vos)); PWR.voscr().modify(|w| w.set_vos(config.voltage_scale));
while !PWR.vossr().read().vosrdy() {} while !PWR.vossr().read().vosrdy() {}
// Configure HSI // Configure HSI
@ -472,36 +472,36 @@ fn flash_setup(clk: Hertz, vos: VoltageScale) {
// See RM0433 Rev 7 Table 17. FLASH recommended number of wait // See RM0433 Rev 7 Table 17. FLASH recommended number of wait
// states and programming delay // states and programming delay
let (latency, wrhighfreq) = match (vos, clk.0) { let (latency, wrhighfreq) = match (vos, clk.0) {
(VoltageScale::Scale0, ..=42_000_000) => (0, 0), (VoltageScale::SCALE0, ..=42_000_000) => (0, 0),
(VoltageScale::Scale0, ..=84_000_000) => (1, 0), (VoltageScale::SCALE0, ..=84_000_000) => (1, 0),
(VoltageScale::Scale0, ..=126_000_000) => (2, 1), (VoltageScale::SCALE0, ..=126_000_000) => (2, 1),
(VoltageScale::Scale0, ..=168_000_000) => (3, 1), (VoltageScale::SCALE0, ..=168_000_000) => (3, 1),
(VoltageScale::Scale0, ..=210_000_000) => (4, 2), (VoltageScale::SCALE0, ..=210_000_000) => (4, 2),
(VoltageScale::Scale0, ..=250_000_000) => (5, 2), (VoltageScale::SCALE0, ..=250_000_000) => (5, 2),
(VoltageScale::Scale1, ..=34_000_000) => (0, 0), (VoltageScale::SCALE1, ..=34_000_000) => (0, 0),
(VoltageScale::Scale1, ..=68_000_000) => (1, 0), (VoltageScale::SCALE1, ..=68_000_000) => (1, 0),
(VoltageScale::Scale1, ..=102_000_000) => (2, 1), (VoltageScale::SCALE1, ..=102_000_000) => (2, 1),
(VoltageScale::Scale1, ..=136_000_000) => (3, 1), (VoltageScale::SCALE1, ..=136_000_000) => (3, 1),
(VoltageScale::Scale1, ..=170_000_000) => (4, 2), (VoltageScale::SCALE1, ..=170_000_000) => (4, 2),
(VoltageScale::Scale1, ..=200_000_000) => (5, 2), (VoltageScale::SCALE1, ..=200_000_000) => (5, 2),
(VoltageScale::Scale2, ..=30_000_000) => (0, 0), (VoltageScale::SCALE2, ..=30_000_000) => (0, 0),
(VoltageScale::Scale2, ..=60_000_000) => (1, 0), (VoltageScale::SCALE2, ..=60_000_000) => (1, 0),
(VoltageScale::Scale2, ..=90_000_000) => (2, 1), (VoltageScale::SCALE2, ..=90_000_000) => (2, 1),
(VoltageScale::Scale2, ..=120_000_000) => (3, 1), (VoltageScale::SCALE2, ..=120_000_000) => (3, 1),
(VoltageScale::Scale2, ..=150_000_000) => (4, 2), (VoltageScale::SCALE2, ..=150_000_000) => (4, 2),
(VoltageScale::Scale3, ..=20_000_000) => (0, 0), (VoltageScale::SCALE3, ..=20_000_000) => (0, 0),
(VoltageScale::Scale3, ..=40_000_000) => (1, 0), (VoltageScale::SCALE3, ..=40_000_000) => (1, 0),
(VoltageScale::Scale3, ..=60_000_000) => (2, 1), (VoltageScale::SCALE3, ..=60_000_000) => (2, 1),
(VoltageScale::Scale3, ..=80_000_000) => (3, 1), (VoltageScale::SCALE3, ..=80_000_000) => (3, 1),
(VoltageScale::Scale3, ..=100_000_000) => (4, 2), (VoltageScale::SCALE3, ..=100_000_000) => (4, 2),
_ => unreachable!(), _ => unreachable!(),
}; };
defmt::debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq); debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq);
FLASH.acr().write(|w| { FLASH.acr().write(|w| {
w.set_wrhighfreq(wrhighfreq); w.set_wrhighfreq(wrhighfreq);

View File

@ -1,9 +1,10 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
pub use pll::PllConfig; use stm32_metapac::pwr::vals::Vos;
use stm32_metapac::rcc::vals::{Mco1, Mco2}; use stm32_metapac::rcc::vals::{Mco1, Mco2};
pub use self::pll::PllConfig;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::gpio::Speed; use crate::gpio::Speed;
use crate::pac::rcc::vals::{Adcsel, Ckpersel, Hpre, Hsidiv, Pllsrc, Ppre, Sw, Timpre}; use crate::pac::rcc::vals::{Adcsel, Ckpersel, Hpre, Hsidiv, Pllsrc, Ppre, Sw, Timpre};
@ -24,7 +25,13 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
/// LSI speed /// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000); pub const LSI_FREQ: Hertz = Hertz(32_000);
pub use super::bus::VoltageScale; #[derive(Clone, Copy)]
pub enum VoltageScale {
Scale0,
Scale1,
Scale2,
Scale3,
}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum AdcClockSource { pub enum AdcClockSource {
@ -85,7 +92,6 @@ pub struct CoreClocks {
/// Configuration of the core clocks /// Configuration of the core clocks
#[non_exhaustive] #[non_exhaustive]
#[derive(Default)]
pub struct Config { pub struct Config {
pub hse: Option<Hertz>, pub hse: Option<Hertz>,
pub bypass_hse: bool, pub bypass_hse: bool,
@ -100,6 +106,28 @@ pub struct Config {
pub pll2: PllConfig, pub pll2: PllConfig,
pub pll3: PllConfig, pub pll3: PllConfig,
pub adc_clock_source: AdcClockSource, pub adc_clock_source: AdcClockSource,
pub voltage_scale: VoltageScale,
}
impl Default for Config {
fn default() -> Self {
Self {
hse: None,
bypass_hse: false,
sys_ck: None,
per_ck: None,
hclk: None,
pclk1: None,
pclk2: None,
pclk3: None,
pclk4: None,
pll1: Default::default(),
pll2: Default::default(),
pll3: Default::default(),
adc_clock_source: Default::default(),
voltage_scale: VoltageScale::Scale1,
}
}
} }
/// Setup traceclk /// Setup traceclk
@ -431,9 +459,6 @@ impl<'d, T: McoInstance> Mco<'d, T> {
} }
pub(crate) unsafe fn init(mut config: Config) { pub(crate) unsafe fn init(mut config: Config) {
// TODO make configurable?
let enable_overdrive = false;
// NB. The lower bytes of CR3 can only be written once after // NB. The lower bytes of CR3 can only be written once after
// POR, and must be written with a valid combination. Refer to // POR, and must be written with a valid combination. Refer to
// RM0433 Rev 7 6.8.4. This is partially enforced by dropping // RM0433 Rev 7 6.8.4. This is partially enforced by dropping
@ -461,21 +486,49 @@ pub(crate) unsafe fn init(mut config: Config) {
// 1.0V. // 1.0V.
while !PWR.csr1().read().actvosrdy() {} while !PWR.csr1().read().actvosrdy() {}
// Go to Scale 1 #[cfg(syscfg_h7)]
PWR.d3cr().modify(|w| w.set_vos(0b11)); {
while !PWR.d3cr().read().vosrdy() {} // in chips without the overdrive bit, we can go from any scale to any scale directly.
PWR.d3cr().modify(|w| {
let pwr_vos = if !enable_overdrive { w.set_vos(match config.voltage_scale {
VoltageScale::Scale1 VoltageScale::Scale0 => Vos::SCALE0,
} else { VoltageScale::Scale1 => Vos::SCALE1,
critical_section::with(|_| { VoltageScale::Scale2 => Vos::SCALE2,
RCC.apb4enr().modify(|w| w.set_syscfgen(true)); VoltageScale::Scale3 => Vos::SCALE3,
})
SYSCFG.pwrcr().modify(|w| w.set_oden(1));
}); });
while !PWR.d3cr().read().vosrdy() {} while !PWR.d3cr().read().vosrdy() {}
VoltageScale::Scale0 }
};
#[cfg(syscfg_h7od)]
{
match config.voltage_scale {
VoltageScale::Scale0 => {
// to go to scale0, we must go to Scale1 first...
PWR.d3cr().modify(|w| w.set_vos(Vos::SCALE1));
while !PWR.d3cr().read().vosrdy() {}
// Then enable overdrive.
critical_section::with(|_| {
RCC.apb4enr().modify(|w| w.set_syscfgen(true));
SYSCFG.pwrcr().modify(|w| w.set_oden(1));
});
while !PWR.d3cr().read().vosrdy() {}
}
_ => {
// for all other scales, we can go directly.
PWR.d3cr().modify(|w| {
w.set_vos(match config.voltage_scale {
VoltageScale::Scale0 => unreachable!(),
VoltageScale::Scale1 => Vos::SCALE1,
VoltageScale::Scale2 => Vos::SCALE2,
VoltageScale::Scale3 => Vos::SCALE3,
})
});
while !PWR.d3cr().read().vosrdy() {}
}
}
}
// Freeze the core clocks, returning a Core Clocks Distribution // Freeze the core clocks, returning a Core Clocks Distribution
// and Reset (CCDR) structure. The actual frequency of the clocks // and Reset (CCDR) structure. The actual frequency of the clocks
@ -538,11 +591,11 @@ pub(crate) unsafe fn init(mut config: Config) {
// Refer to part datasheet "General operating conditions" // Refer to part datasheet "General operating conditions"
// table for (rev V). We do not assert checks for earlier // table for (rev V). We do not assert checks for earlier
// revisions which may have lower limits. // revisions which may have lower limits.
let (sys_d1cpre_ck_max, rcc_hclk_max, pclk_max) = match pwr_vos { let (sys_d1cpre_ck_max, rcc_hclk_max, pclk_max) = match config.voltage_scale {
VoltageScale::Scale0 => (480_000_000, 240_000_000, 120_000_000), VoltageScale::Scale0 => (480_000_000, 240_000_000, 120_000_000),
VoltageScale::Scale1 => (400_000_000, 200_000_000, 100_000_000), VoltageScale::Scale1 => (400_000_000, 200_000_000, 100_000_000),
VoltageScale::Scale2 => (300_000_000, 150_000_000, 75_000_000), VoltageScale::Scale2 => (300_000_000, 150_000_000, 75_000_000),
_ => (200_000_000, 100_000_000, 50_000_000), VoltageScale::Scale3 => (200_000_000, 100_000_000, 50_000_000),
}; };
assert!(sys_d1cpre_ck <= sys_d1cpre_ck_max); assert!(sys_d1cpre_ck <= sys_d1cpre_ck_max);
@ -638,7 +691,7 @@ pub(crate) unsafe fn init(mut config: Config) {
// core voltage // core voltage
while RCC.d1cfgr().read().d1cpre().to_bits() != d1cpre_bits {} while RCC.d1cfgr().read().d1cpre().to_bits() != d1cpre_bits {}
flash_setup(rcc_aclk, pwr_vos); flash_setup(rcc_aclk, config.voltage_scale);
// APB1 / APB2 Prescaler // APB1 / APB2 Prescaler
RCC.d2cfgr().modify(|w| { RCC.d2cfgr().modify(|w| {

View File

@ -11,7 +11,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed /// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000); pub const LSI_FREQ: Hertz = Hertz(32_000);
pub use super::bus::VoltageScale; pub use crate::pac::pwr::vals::Vos as VoltageScale;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum ClockSrc { pub enum ClockSrc {
@ -286,12 +286,12 @@ pub(crate) unsafe fn init(config: Config) {
} }
// TODO make configurable // TODO make configurable
let power_vos = VoltageScale::Scale3; let power_vos = VoltageScale::RANGE3;
// states and programming delay // states and programming delay
let wait_states = match power_vos { let wait_states = match power_vos {
// VOS 0 range VCORE 1.26V - 1.40V // VOS 1 range VCORE 1.26V - 1.40V
VoltageScale::Scale0 => { VoltageScale::RANGE1 => {
if sys_clk < 32_000_000 { if sys_clk < 32_000_000 {
0 0
} else if sys_clk < 64_000_000 { } else if sys_clk < 64_000_000 {
@ -304,8 +304,8 @@ pub(crate) unsafe fn init(config: Config) {
4 4
} }
} }
// VOS 1 range VCORE 1.15V - 1.26V // VOS 2 range VCORE 1.15V - 1.26V
VoltageScale::Scale1 => { VoltageScale::RANGE2 => {
if sys_clk < 30_000_000 { if sys_clk < 30_000_000 {
0 0
} else if sys_clk < 60_000_000 { } else if sys_clk < 60_000_000 {
@ -316,8 +316,8 @@ pub(crate) unsafe fn init(config: Config) {
3 3
} }
} }
// VOS 2 range VCORE 1.05V - 1.15V // VOS 3 range VCORE 1.05V - 1.15V
VoltageScale::Scale2 => { VoltageScale::RANGE3 => {
if sys_clk < 24_000_000 { if sys_clk < 24_000_000 {
0 0
} else if sys_clk < 48_000_000 { } else if sys_clk < 48_000_000 {
@ -326,8 +326,8 @@ pub(crate) unsafe fn init(config: Config) {
2 2
} }
} }
// VOS 3 range VCORE 0.95V - 1.05V // VOS 4 range VCORE 0.95V - 1.05V
VoltageScale::Scale3 => { VoltageScale::RANGE4 => {
if sys_clk < 12_000_000 { if sys_clk < 12_000_000 {
0 0
} else { } else {

View File

@ -1,4 +1,5 @@
pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; pub use super::bus::{AHBPrescaler, APBPrescaler};
pub use crate::pac::pwr::vals::Vos as VoltageScale;
use crate::pac::rcc::vals::Adcsel; use crate::pac::rcc::vals::Adcsel;
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::bd::{BackupDomain, RtcClockSource};
@ -75,9 +76,9 @@ impl MSIRange {
fn vos(&self) -> VoltageScale { fn vos(&self) -> VoltageScale {
if self > &MSIRange::Range8 { if self > &MSIRange::Range8 {
VoltageScale::Scale0 VoltageScale::RANGE1
} else { } else {
VoltageScale::Scale1 VoltageScale::RANGE2
} }
} }
} }
@ -170,8 +171,8 @@ pub enum Lsedrv {
pub(crate) unsafe fn init(config: Config) { pub(crate) unsafe fn init(config: Config) {
let (sys_clk, sw, vos) = match config.mux { let (sys_clk, sw, vos) = match config.mux {
ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Scale1), ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::RANGE2),
ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Scale0), ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::RANGE1),
ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()),
}; };
@ -216,16 +217,17 @@ pub(crate) unsafe fn init(config: Config) {
// Adjust flash latency // Adjust flash latency
let flash_clk_src_freq: u32 = shd_ahb_freq; let flash_clk_src_freq: u32 = shd_ahb_freq;
let ws = match vos { let ws = match vos {
VoltageScale::Scale0 => match flash_clk_src_freq { VoltageScale::RANGE1 => match flash_clk_src_freq {
0..=18_000_000 => 0b000, 0..=18_000_000 => 0b000,
18_000_001..=36_000_000 => 0b001, 18_000_001..=36_000_000 => 0b001,
_ => 0b010, _ => 0b010,
}, },
VoltageScale::Scale1 => match flash_clk_src_freq { VoltageScale::RANGE2 => match flash_clk_src_freq {
0..=6_000_000 => 0b000, 0..=6_000_000 => 0b000,
6_000_001..=12_000_000 => 0b001, 6_000_001..=12_000_000 => 0b001,
_ => 0b010, _ => 0b010,
}, },
_ => unreachable!(),
}; };
FLASH.acr().modify(|w| { FLASH.acr().modify(|w| {

View File

@ -53,7 +53,7 @@ async fn main(spawner: Spawner) -> ! {
config.rcc.apb2_pre = APBPrescaler::DIV1; config.rcc.apb2_pre = APBPrescaler::DIV1;
config.rcc.apb3_pre = APBPrescaler::DIV1; config.rcc.apb3_pre = APBPrescaler::DIV1;
config.rcc.sys = Sysclk::Pll1P; config.rcc.sys = Sysclk::Pll1P;
config.rcc.voltage_scale = VoltageScale::Scale0; config.rcc.voltage_scale = VoltageScale::SCALE0;
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
info!("Hello World!"); info!("Hello World!");

View File

@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) {
config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.apb2_pre = APBPrescaler::DIV2;
config.rcc.apb3_pre = APBPrescaler::DIV4; config.rcc.apb3_pre = APBPrescaler::DIV4;
config.rcc.sys = Sysclk::Pll1P; config.rcc.sys = Sysclk::Pll1P;
config.rcc.voltage_scale = VoltageScale::Scale0; config.rcc.voltage_scale = VoltageScale::SCALE0;
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
info!("Hello World!"); info!("Hello World!");