Merge pull request #1923 from embassy-rs/pac-vos
stm32: use PAC enums for VOS.
This commit is contained in:
commit
fdfe12fe1c
2
ci.sh
2
ci.sh
@ -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 \
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"]
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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| {
|
||||||
|
@ -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 {
|
||||||
|
@ -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| {
|
||||||
|
@ -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!");
|
||||||
|
|
||||||
|
@ -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!");
|
||||||
|
Loading…
Reference in New Issue
Block a user