diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-09-18 03:00:59 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-09-18 03:15:15 +0200 |
| commit | 4bfbcd6c72fadd97ef71403a1406ff437f4aa6e8 (patch) | |
| tree | e38ea7030abd1c9d69d1471411268227ddc75131 | |
| parent | 0da793e5de229eb7ff2e50da69b95c435f4e45a9 (diff) | |
stm32: use PAC enums for VOS.
| -rwxr-xr-x | ci.sh | 2 | ||||
| -rw-r--r-- | embassy-lora/src/iv.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/bus.rs | 16 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/f2.rs | 25 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/h5.rs | 70 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/h7.rs | 97 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/u5.rs | 20 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wl.rs | 16 | ||||
| -rw-r--r-- | examples/stm32h5/src/bin/eth.rs | 2 | ||||
| -rw-r--r-- | examples/stm32h5/src/bin/usb_serial.rs | 2 |
11 files changed, 159 insertions, 109 deletions
| @@ -85,6 +85,8 @@ cargo batch \ | |||
| 85 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \ | 85 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \ |
| 86 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \ | 86 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \ |
| 87 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \ | 87 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \ |
| 88 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits \ | ||
| 89 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits \ | ||
| 88 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \ | 90 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \ |
| 89 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \ | 91 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \ |
| 90 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \ | 92 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \ |
diff --git a/embassy-lora/src/iv.rs b/embassy-lora/src/iv.rs index de6a18342..d22beb337 100644 --- a/embassy-lora/src/iv.rs +++ b/embassy-lora/src/iv.rs | |||
| @@ -67,24 +67,20 @@ where | |||
| 67 | self.board_type = board_type; | 67 | self.board_type = board_type; |
| 68 | } | 68 | } |
| 69 | async fn set_nss_low(&mut self) -> Result<(), RadioError> { | 69 | async fn set_nss_low(&mut self) -> Result<(), RadioError> { |
| 70 | let pwr = pac::PWR; | 70 | pac::PWR.subghzspicr().modify(|w| w.set_nss(false)); |
| 71 | pwr.subghzspicr().modify(|w| w.set_nss(pac::pwr::vals::Nss::LOW)); | ||
| 72 | Ok(()) | 71 | Ok(()) |
| 73 | } | 72 | } |
| 74 | async fn set_nss_high(&mut self) -> Result<(), RadioError> { | 73 | async fn set_nss_high(&mut self) -> Result<(), RadioError> { |
| 75 | let pwr = pac::PWR; | 74 | pac::PWR.subghzspicr().modify(|w| w.set_nss(true)); |
| 76 | pwr.subghzspicr().modify(|w| w.set_nss(pac::pwr::vals::Nss::HIGH)); | ||
| 77 | Ok(()) | 75 | Ok(()) |
| 78 | } | 76 | } |
| 79 | async fn reset(&mut self, _delay: &mut impl DelayUs) -> Result<(), RadioError> { | 77 | async fn reset(&mut self, _delay: &mut impl DelayUs) -> Result<(), RadioError> { |
| 80 | let rcc = pac::RCC; | 78 | pac::RCC.csr().modify(|w| w.set_rfrst(true)); |
| 81 | rcc.csr().modify(|w| w.set_rfrst(true)); | 79 | pac::RCC.csr().modify(|w| w.set_rfrst(false)); |
| 82 | rcc.csr().modify(|w| w.set_rfrst(false)); | ||
| 83 | Ok(()) | 80 | Ok(()) |
| 84 | } | 81 | } |
| 85 | async fn wait_on_busy(&mut self) -> Result<(), RadioError> { | 82 | async fn wait_on_busy(&mut self) -> Result<(), RadioError> { |
| 86 | let pwr = pac::PWR; | 83 | while pac::PWR.sr2().read().rfbusys() {} |
| 87 | while pwr.sr2().read().rfbusys() == pac::pwr::vals::Rfbusys::BUSY {} | ||
| 88 | Ok(()) | 84 | Ok(()) |
| 89 | } | 85 | } |
| 90 | 86 | ||
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 0cae981c7..1a024e9a9 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -59,7 +59,7 @@ sdio-host = "0.5.0" | |||
| 59 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | 59 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } |
| 60 | critical-section = "1.1" | 60 | critical-section = "1.1" |
| 61 | atomic-polyfill = "1.0.1" | 61 | atomic-polyfill = "1.0.1" |
| 62 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-907dd82c848bc912252c61509944e85c2a48c919" } | 62 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2dba1f1ddee697e616aff2a4db57a6ffaf1b29b7" } |
| 63 | vcell = "0.1.3" | 63 | vcell = "0.1.3" |
| 64 | bxcan = "0.7.0" | 64 | bxcan = "0.7.0" |
| 65 | nb = "1.0.0" | 65 | nb = "1.0.0" |
| @@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 78 | [build-dependencies] | 78 | [build-dependencies] |
| 79 | proc-macro2 = "1.0.36" | 79 | proc-macro2 = "1.0.36" |
| 80 | quote = "1.0.15" | 80 | quote = "1.0.15" |
| 81 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-907dd82c848bc912252c61509944e85c2a48c919", default-features = false, features = ["metadata"]} | 81 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2dba1f1ddee697e616aff2a4db57a6ffaf1b29b7", default-features = false, features = ["metadata"]} |
| 82 | 82 | ||
| 83 | [features] | 83 | [features] |
| 84 | default = ["rt"] | 84 | default = ["rt"] |
diff --git a/embassy-stm32/src/rcc/bus.rs b/embassy-stm32/src/rcc/bus.rs index 9c9de5486..495cf7fe1 100644 --- a/embassy-stm32/src/rcc/bus.rs +++ b/embassy-stm32/src/rcc/bus.rs | |||
| @@ -5,22 +5,6 @@ use crate::pac::rcc; | |||
| 5 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | 5 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; |
| 6 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| 7 | 7 | ||
| 8 | /// Voltage Scale | ||
| 9 | /// | ||
| 10 | /// Represents the voltage range feeding the CPU core. The maximum core | ||
| 11 | /// clock frequency depends on this value. | ||
| 12 | /// | ||
| 13 | /// Scale0 represents the highest voltage range | ||
| 14 | #[derive(Copy, Clone, PartialEq)] | ||
| 15 | pub enum VoltageScale { | ||
| 16 | Scale0, | ||
| 17 | Scale1, | ||
| 18 | #[cfg(not(any(rcc_wl5, rcc_wle)))] | ||
| 19 | Scale2, | ||
| 20 | #[cfg(not(any(rcc_wl5, rcc_wle)))] | ||
| 21 | Scale3, | ||
| 22 | } | ||
| 23 | |||
| 24 | impl Div<AHBPrescaler> for Hertz { | 8 | impl Div<AHBPrescaler> for Hertz { |
| 25 | type Output = Hertz; | 9 | type Output = Hertz; |
| 26 | 10 | ||
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 56ccdcbd8..af90a9c3f 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs | |||
| @@ -203,7 +203,20 @@ pub struct PLLClocks { | |||
| 203 | pub pll48_freq: Hertz, | 203 | pub pll48_freq: Hertz, |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | pub use super::bus::VoltageScale; | 206 | /// Voltage range of the power supply used. |
| 207 | /// | ||
| 208 | /// Used to calculate flash waitstates. See | ||
| 209 | /// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency | ||
| 210 | pub enum VoltageScale { | ||
| 211 | /// 2.7v to 4.6v | ||
| 212 | Range0, | ||
| 213 | /// 2.4v to 2.7v | ||
| 214 | Range1, | ||
| 215 | /// 2.1v to 2.4v | ||
| 216 | Range2, | ||
| 217 | /// 1.8v to 2.1v | ||
| 218 | Range3, | ||
| 219 | } | ||
| 207 | 220 | ||
| 208 | impl VoltageScale { | 221 | impl VoltageScale { |
| 209 | const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { | 222 | const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { |
| @@ -211,7 +224,7 @@ impl VoltageScale { | |||
| 211 | // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock | 224 | // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock |
| 212 | // frequency | 225 | // frequency |
| 213 | match self { | 226 | match self { |
| 214 | VoltageScale::Scale3 => { | 227 | VoltageScale::Range3 => { |
| 215 | if ahb_freq <= 16_000_000 { | 228 | if ahb_freq <= 16_000_000 { |
| 216 | Some(Latency::WS0) | 229 | Some(Latency::WS0) |
| 217 | } else if ahb_freq <= 32_000_000 { | 230 | } else if ahb_freq <= 32_000_000 { |
| @@ -232,7 +245,7 @@ impl VoltageScale { | |||
| 232 | None | 245 | None |
| 233 | } | 246 | } |
| 234 | } | 247 | } |
| 235 | VoltageScale::Scale2 => { | 248 | VoltageScale::Range2 => { |
| 236 | if ahb_freq <= 18_000_000 { | 249 | if ahb_freq <= 18_000_000 { |
| 237 | Some(Latency::WS0) | 250 | Some(Latency::WS0) |
| 238 | } else if ahb_freq <= 36_000_000 { | 251 | } else if ahb_freq <= 36_000_000 { |
| @@ -251,7 +264,7 @@ impl VoltageScale { | |||
| 251 | None | 264 | None |
| 252 | } | 265 | } |
| 253 | } | 266 | } |
| 254 | VoltageScale::Scale1 => { | 267 | VoltageScale::Range1 => { |
| 255 | if ahb_freq <= 24_000_000 { | 268 | if ahb_freq <= 24_000_000 { |
| 256 | Some(Latency::WS0) | 269 | Some(Latency::WS0) |
| 257 | } else if ahb_freq <= 48_000_000 { | 270 | } else if ahb_freq <= 48_000_000 { |
| @@ -266,7 +279,7 @@ impl VoltageScale { | |||
| 266 | None | 279 | None |
| 267 | } | 280 | } |
| 268 | } | 281 | } |
| 269 | VoltageScale::Scale0 => { | 282 | VoltageScale::Range0 => { |
| 270 | if ahb_freq <= 30_000_000 { | 283 | if ahb_freq <= 30_000_000 { |
| 271 | Some(Latency::WS0) | 284 | Some(Latency::WS0) |
| 272 | } else if ahb_freq <= 60_000_000 { | 285 | } else if ahb_freq <= 60_000_000 { |
| @@ -307,7 +320,7 @@ impl Default for Config { | |||
| 307 | hsi: true, | 320 | hsi: true, |
| 308 | pll_mux: PLLSrc::HSI, | 321 | pll_mux: PLLSrc::HSI, |
| 309 | pll: PLLConfig::default(), | 322 | pll: PLLConfig::default(), |
| 310 | voltage: VoltageScale::Scale3, | 323 | voltage: VoltageScale::Range3, |
| 311 | mux: ClockSrc::HSI, | 324 | mux: ClockSrc::HSI, |
| 312 | rtc: None, | 325 | rtc: None, |
| 313 | lsi: false, | 326 | lsi: false, |
diff --git a/embassy-stm32/src/rcc/h5.rs b/embassy-stm32/src/rcc/h5.rs index ac45605f7..15f28c5dc 100644 --- a/embassy-stm32/src/rcc/h5.rs +++ b/embassy-stm32/src/rcc/h5.rs | |||
| @@ -2,7 +2,6 @@ use core::marker::PhantomData; | |||
| 2 | 2 | ||
| 3 | use stm32_metapac::rcc::vals::Timpre; | 3 | use stm32_metapac::rcc::vals::Timpre; |
| 4 | 4 | ||
| 5 | use crate::pac::pwr::vals::Vos; | ||
| 6 | use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw}; | 5 | use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw}; |
| 7 | use crate::pac::{FLASH, PWR, RCC}; | 6 | use crate::pac::{FLASH, PWR, RCC}; |
| 8 | use crate::rcc::{set_freqs, Clocks}; | 7 | use crate::rcc::{set_freqs, Clocks}; |
| @@ -26,7 +25,8 @@ const VCO_MAX: u32 = 420_000_000; | |||
| 26 | const VCO_WIDE_MIN: u32 = 128_000_000; | 25 | const VCO_WIDE_MIN: u32 = 128_000_000; |
| 27 | const VCO_WIDE_MAX: u32 = 560_000_000; | 26 | const VCO_WIDE_MAX: u32 = 560_000_000; |
| 28 | 27 | ||
| 29 | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; | 28 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 29 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | ||
| 30 | 30 | ||
| 31 | pub enum HseMode { | 31 | pub enum HseMode { |
| 32 | /// crystal/ceramic oscillator (HSEBYP=0) | 32 | /// crystal/ceramic oscillator (HSEBYP=0) |
| @@ -171,7 +171,7 @@ impl Default for Config { | |||
| 171 | apb3_pre: APBPrescaler::DIV1, | 171 | apb3_pre: APBPrescaler::DIV1, |
| 172 | timer_prescaler: TimerPrescaler::DefaultX2, | 172 | timer_prescaler: TimerPrescaler::DefaultX2, |
| 173 | 173 | ||
| 174 | voltage_scale: VoltageScale::Scale3, | 174 | voltage_scale: VoltageScale::SCALE3, |
| 175 | } | 175 | } |
| 176 | } | 176 | } |
| 177 | } | 177 | } |
| @@ -222,15 +222,15 @@ impl<'d, T: McoInstance> Mco<'d, T> { | |||
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | pub(crate) unsafe fn init(config: Config) { | 224 | pub(crate) unsafe fn init(config: Config) { |
| 225 | let (vos, max_clk) = match config.voltage_scale { | 225 | let max_clk = match config.voltage_scale { |
| 226 | VoltageScale::Scale0 => (Vos::SCALE0, Hertz(250_000_000)), | 226 | VoltageScale::SCALE0 => Hertz(250_000_000), |
| 227 | VoltageScale::Scale1 => (Vos::SCALE1, Hertz(200_000_000)), | 227 | VoltageScale::SCALE1 => Hertz(200_000_000), |
| 228 | VoltageScale::Scale2 => (Vos::SCALE2, Hertz(150_000_000)), | 228 | VoltageScale::SCALE2 => Hertz(150_000_000), |
| 229 | VoltageScale::Scale3 => (Vos::SCALE3, Hertz(100_000_000)), | 229 | VoltageScale::SCALE3 => Hertz(100_000_000), |
| 230 | }; | 230 | }; |
| 231 | 231 | ||
| 232 | // Configure voltage scale. | 232 | // Configure voltage scale. |
| 233 | PWR.voscr().modify(|w| w.set_vos(vos)); | 233 | PWR.voscr().modify(|w| w.set_vos(config.voltage_scale)); |
| 234 | while !PWR.vossr().read().vosrdy() {} | 234 | while !PWR.vossr().read().vosrdy() {} |
| 235 | 235 | ||
| 236 | // Configure HSI | 236 | // Configure HSI |
| @@ -472,36 +472,36 @@ fn flash_setup(clk: Hertz, vos: VoltageScale) { | |||
| 472 | // See RM0433 Rev 7 Table 17. FLASH recommended number of wait | 472 | // See RM0433 Rev 7 Table 17. FLASH recommended number of wait |
| 473 | // states and programming delay | 473 | // states and programming delay |
| 474 | let (latency, wrhighfreq) = match (vos, clk.0) { | 474 | let (latency, wrhighfreq) = match (vos, clk.0) { |
| 475 | (VoltageScale::Scale0, ..=42_000_000) => (0, 0), | 475 | (VoltageScale::SCALE0, ..=42_000_000) => (0, 0), |
| 476 | (VoltageScale::Scale0, ..=84_000_000) => (1, 0), | 476 | (VoltageScale::SCALE0, ..=84_000_000) => (1, 0), |
| 477 | (VoltageScale::Scale0, ..=126_000_000) => (2, 1), | 477 | (VoltageScale::SCALE0, ..=126_000_000) => (2, 1), |
| 478 | (VoltageScale::Scale0, ..=168_000_000) => (3, 1), | 478 | (VoltageScale::SCALE0, ..=168_000_000) => (3, 1), |
| 479 | (VoltageScale::Scale0, ..=210_000_000) => (4, 2), | 479 | (VoltageScale::SCALE0, ..=210_000_000) => (4, 2), |
| 480 | (VoltageScale::Scale0, ..=250_000_000) => (5, 2), | 480 | (VoltageScale::SCALE0, ..=250_000_000) => (5, 2), |
| 481 | 481 | ||
| 482 | (VoltageScale::Scale1, ..=34_000_000) => (0, 0), | 482 | (VoltageScale::SCALE1, ..=34_000_000) => (0, 0), |
| 483 | (VoltageScale::Scale1, ..=68_000_000) => (1, 0), | 483 | (VoltageScale::SCALE1, ..=68_000_000) => (1, 0), |
| 484 | (VoltageScale::Scale1, ..=102_000_000) => (2, 1), | 484 | (VoltageScale::SCALE1, ..=102_000_000) => (2, 1), |
| 485 | (VoltageScale::Scale1, ..=136_000_000) => (3, 1), | 485 | (VoltageScale::SCALE1, ..=136_000_000) => (3, 1), |
| 486 | (VoltageScale::Scale1, ..=170_000_000) => (4, 2), | 486 | (VoltageScale::SCALE1, ..=170_000_000) => (4, 2), |
| 487 | (VoltageScale::Scale1, ..=200_000_000) => (5, 2), | 487 | (VoltageScale::SCALE1, ..=200_000_000) => (5, 2), |
| 488 | 488 | ||
| 489 | (VoltageScale::Scale2, ..=30_000_000) => (0, 0), | 489 | (VoltageScale::SCALE2, ..=30_000_000) => (0, 0), |
| 490 | (VoltageScale::Scale2, ..=60_000_000) => (1, 0), | 490 | (VoltageScale::SCALE2, ..=60_000_000) => (1, 0), |
| 491 | (VoltageScale::Scale2, ..=90_000_000) => (2, 1), | 491 | (VoltageScale::SCALE2, ..=90_000_000) => (2, 1), |
| 492 | (VoltageScale::Scale2, ..=120_000_000) => (3, 1), | 492 | (VoltageScale::SCALE2, ..=120_000_000) => (3, 1), |
| 493 | (VoltageScale::Scale2, ..=150_000_000) => (4, 2), | 493 | (VoltageScale::SCALE2, ..=150_000_000) => (4, 2), |
| 494 | 494 | ||
| 495 | (VoltageScale::Scale3, ..=20_000_000) => (0, 0), | 495 | (VoltageScale::SCALE3, ..=20_000_000) => (0, 0), |
| 496 | (VoltageScale::Scale3, ..=40_000_000) => (1, 0), | 496 | (VoltageScale::SCALE3, ..=40_000_000) => (1, 0), |
| 497 | (VoltageScale::Scale3, ..=60_000_000) => (2, 1), | 497 | (VoltageScale::SCALE3, ..=60_000_000) => (2, 1), |
| 498 | (VoltageScale::Scale3, ..=80_000_000) => (3, 1), | 498 | (VoltageScale::SCALE3, ..=80_000_000) => (3, 1), |
| 499 | (VoltageScale::Scale3, ..=100_000_000) => (4, 2), | 499 | (VoltageScale::SCALE3, ..=100_000_000) => (4, 2), |
| 500 | 500 | ||
| 501 | _ => unreachable!(), | 501 | _ => unreachable!(), |
| 502 | }; | 502 | }; |
| 503 | 503 | ||
| 504 | defmt::debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq); | 504 | debug!("flash: latency={} wrhighfreq={}", latency, wrhighfreq); |
| 505 | 505 | ||
| 506 | FLASH.acr().write(|w| { | 506 | FLASH.acr().write(|w| { |
| 507 | w.set_wrhighfreq(wrhighfreq); | 507 | w.set_wrhighfreq(wrhighfreq); |
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs index 23e186943..585e1faac 100644 --- a/embassy-stm32/src/rcc/h7.rs +++ b/embassy-stm32/src/rcc/h7.rs | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_internal::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | pub use pll::PllConfig; | 4 | use stm32_metapac::pwr::vals::Vos; |
| 5 | use stm32_metapac::rcc::vals::{Mco1, Mco2}; | 5 | use stm32_metapac::rcc::vals::{Mco1, Mco2}; |
| 6 | 6 | ||
| 7 | pub use self::pll::PllConfig; | ||
| 7 | use crate::gpio::sealed::AFType; | 8 | use crate::gpio::sealed::AFType; |
| 8 | use crate::gpio::Speed; | 9 | use crate::gpio::Speed; |
| 9 | use crate::pac::rcc::vals::{Adcsel, Ckpersel, Hpre, Hsidiv, Pllsrc, Ppre, Sw, Timpre}; | 10 | 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); | |||
| 24 | /// LSI speed | 25 | /// LSI speed |
| 25 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 26 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 26 | 27 | ||
| 27 | pub use super::bus::VoltageScale; | 28 | #[derive(Clone, Copy)] |
| 29 | pub enum VoltageScale { | ||
| 30 | Scale0, | ||
| 31 | Scale1, | ||
| 32 | Scale2, | ||
| 33 | Scale3, | ||
| 34 | } | ||
| 28 | 35 | ||
| 29 | #[derive(Clone, Copy)] | 36 | #[derive(Clone, Copy)] |
| 30 | pub enum AdcClockSource { | 37 | pub enum AdcClockSource { |
| @@ -85,7 +92,6 @@ pub struct CoreClocks { | |||
| 85 | 92 | ||
| 86 | /// Configuration of the core clocks | 93 | /// Configuration of the core clocks |
| 87 | #[non_exhaustive] | 94 | #[non_exhaustive] |
| 88 | #[derive(Default)] | ||
| 89 | pub struct Config { | 95 | pub struct Config { |
| 90 | pub hse: Option<Hertz>, | 96 | pub hse: Option<Hertz>, |
| 91 | pub bypass_hse: bool, | 97 | pub bypass_hse: bool, |
| @@ -100,6 +106,28 @@ pub struct Config { | |||
| 100 | pub pll2: PllConfig, | 106 | pub pll2: PllConfig, |
| 101 | pub pll3: PllConfig, | 107 | pub pll3: PllConfig, |
| 102 | pub adc_clock_source: AdcClockSource, | 108 | pub adc_clock_source: AdcClockSource, |
| 109 | pub voltage_scale: VoltageScale, | ||
| 110 | } | ||
| 111 | |||
| 112 | impl Default for Config { | ||
| 113 | fn default() -> Self { | ||
| 114 | Self { | ||
| 115 | hse: None, | ||
| 116 | bypass_hse: false, | ||
| 117 | sys_ck: None, | ||
| 118 | per_ck: None, | ||
| 119 | hclk: None, | ||
| 120 | pclk1: None, | ||
| 121 | pclk2: None, | ||
| 122 | pclk3: None, | ||
| 123 | pclk4: None, | ||
| 124 | pll1: Default::default(), | ||
| 125 | pll2: Default::default(), | ||
| 126 | pll3: Default::default(), | ||
| 127 | adc_clock_source: Default::default(), | ||
| 128 | voltage_scale: VoltageScale::Scale1, | ||
| 129 | } | ||
| 130 | } | ||
| 103 | } | 131 | } |
| 104 | 132 | ||
| 105 | /// Setup traceclk | 133 | /// Setup traceclk |
| @@ -431,9 +459,6 @@ impl<'d, T: McoInstance> Mco<'d, T> { | |||
| 431 | } | 459 | } |
| 432 | 460 | ||
| 433 | pub(crate) unsafe fn init(mut config: Config) { | 461 | pub(crate) unsafe fn init(mut config: Config) { |
| 434 | // TODO make configurable? | ||
| 435 | let enable_overdrive = false; | ||
| 436 | |||
| 437 | // NB. The lower bytes of CR3 can only be written once after | 462 | // NB. The lower bytes of CR3 can only be written once after |
| 438 | // POR, and must be written with a valid combination. Refer to | 463 | // POR, and must be written with a valid combination. Refer to |
| 439 | // RM0433 Rev 7 6.8.4. This is partially enforced by dropping | 464 | // RM0433 Rev 7 6.8.4. This is partially enforced by dropping |
| @@ -461,21 +486,49 @@ pub(crate) unsafe fn init(mut config: Config) { | |||
| 461 | // 1.0V. | 486 | // 1.0V. |
| 462 | while !PWR.csr1().read().actvosrdy() {} | 487 | while !PWR.csr1().read().actvosrdy() {} |
| 463 | 488 | ||
| 464 | // Go to Scale 1 | 489 | #[cfg(syscfg_h7)] |
| 465 | PWR.d3cr().modify(|w| w.set_vos(0b11)); | 490 | { |
| 466 | while !PWR.d3cr().read().vosrdy() {} | 491 | // in chips without the overdrive bit, we can go from any scale to any scale directly. |
| 467 | 492 | PWR.d3cr().modify(|w| { | |
| 468 | let pwr_vos = if !enable_overdrive { | 493 | w.set_vos(match config.voltage_scale { |
| 469 | VoltageScale::Scale1 | 494 | VoltageScale::Scale0 => Vos::SCALE0, |
| 470 | } else { | 495 | VoltageScale::Scale1 => Vos::SCALE1, |
| 471 | critical_section::with(|_| { | 496 | VoltageScale::Scale2 => Vos::SCALE2, |
| 472 | RCC.apb4enr().modify(|w| w.set_syscfgen(true)); | 497 | VoltageScale::Scale3 => Vos::SCALE3, |
| 473 | 498 | }) | |
| 474 | SYSCFG.pwrcr().modify(|w| w.set_oden(1)); | ||
| 475 | }); | 499 | }); |
| 476 | while !PWR.d3cr().read().vosrdy() {} | 500 | while !PWR.d3cr().read().vosrdy() {} |
| 477 | VoltageScale::Scale0 | 501 | } |
| 478 | }; | 502 | |
| 503 | #[cfg(syscfg_h7od)] | ||
| 504 | { | ||
| 505 | match config.voltage_scale { | ||
| 506 | VoltageScale::Scale0 => { | ||
| 507 | // to go to scale0, we must go to Scale1 first... | ||
| 508 | PWR.d3cr().modify(|w| w.set_vos(Vos::SCALE1)); | ||
| 509 | while !PWR.d3cr().read().vosrdy() {} | ||
| 510 | |||
| 511 | // Then enable overdrive. | ||
| 512 | critical_section::with(|_| { | ||
| 513 | RCC.apb4enr().modify(|w| w.set_syscfgen(true)); | ||
| 514 | SYSCFG.pwrcr().modify(|w| w.set_oden(1)); | ||
| 515 | }); | ||
| 516 | while !PWR.d3cr().read().vosrdy() {} | ||
| 517 | } | ||
| 518 | _ => { | ||
| 519 | // for all other scales, we can go directly. | ||
| 520 | PWR.d3cr().modify(|w| { | ||
| 521 | w.set_vos(match config.voltage_scale { | ||
| 522 | VoltageScale::Scale0 => unreachable!(), | ||
| 523 | VoltageScale::Scale1 => Vos::SCALE1, | ||
| 524 | VoltageScale::Scale2 => Vos::SCALE2, | ||
| 525 | VoltageScale::Scale3 => Vos::SCALE3, | ||
| 526 | }) | ||
| 527 | }); | ||
| 528 | while !PWR.d3cr().read().vosrdy() {} | ||
| 529 | } | ||
| 530 | } | ||
| 531 | } | ||
| 479 | 532 | ||
| 480 | // Freeze the core clocks, returning a Core Clocks Distribution | 533 | // Freeze the core clocks, returning a Core Clocks Distribution |
| 481 | // and Reset (CCDR) structure. The actual frequency of the clocks | 534 | // and Reset (CCDR) structure. The actual frequency of the clocks |
| @@ -538,11 +591,11 @@ pub(crate) unsafe fn init(mut config: Config) { | |||
| 538 | // Refer to part datasheet "General operating conditions" | 591 | // Refer to part datasheet "General operating conditions" |
| 539 | // table for (rev V). We do not assert checks for earlier | 592 | // table for (rev V). We do not assert checks for earlier |
| 540 | // revisions which may have lower limits. | 593 | // revisions which may have lower limits. |
| 541 | let (sys_d1cpre_ck_max, rcc_hclk_max, pclk_max) = match pwr_vos { | 594 | let (sys_d1cpre_ck_max, rcc_hclk_max, pclk_max) = match config.voltage_scale { |
| 542 | VoltageScale::Scale0 => (480_000_000, 240_000_000, 120_000_000), | 595 | VoltageScale::Scale0 => (480_000_000, 240_000_000, 120_000_000), |
| 543 | VoltageScale::Scale1 => (400_000_000, 200_000_000, 100_000_000), | 596 | VoltageScale::Scale1 => (400_000_000, 200_000_000, 100_000_000), |
| 544 | VoltageScale::Scale2 => (300_000_000, 150_000_000, 75_000_000), | 597 | VoltageScale::Scale2 => (300_000_000, 150_000_000, 75_000_000), |
| 545 | _ => (200_000_000, 100_000_000, 50_000_000), | 598 | VoltageScale::Scale3 => (200_000_000, 100_000_000, 50_000_000), |
| 546 | }; | 599 | }; |
| 547 | assert!(sys_d1cpre_ck <= sys_d1cpre_ck_max); | 600 | assert!(sys_d1cpre_ck <= sys_d1cpre_ck_max); |
| 548 | 601 | ||
| @@ -638,7 +691,7 @@ pub(crate) unsafe fn init(mut config: Config) { | |||
| 638 | // core voltage | 691 | // core voltage |
| 639 | while RCC.d1cfgr().read().d1cpre().to_bits() != d1cpre_bits {} | 692 | while RCC.d1cfgr().read().d1cpre().to_bits() != d1cpre_bits {} |
| 640 | 693 | ||
| 641 | flash_setup(rcc_aclk, pwr_vos); | 694 | flash_setup(rcc_aclk, config.voltage_scale); |
| 642 | 695 | ||
| 643 | // APB1 / APB2 Prescaler | 696 | // APB1 / APB2 Prescaler |
| 644 | RCC.d2cfgr().modify(|w| { | 697 | RCC.d2cfgr().modify(|w| { |
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index ff43c5eb7..d9a531285 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -11,7 +11,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); | |||
| 11 | /// LSI speed | 11 | /// LSI speed |
| 12 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 12 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 13 | 13 | ||
| 14 | pub use super::bus::VoltageScale; | 14 | pub use crate::pac::pwr::vals::Vos as VoltageScale; |
| 15 | 15 | ||
| 16 | #[derive(Copy, Clone)] | 16 | #[derive(Copy, Clone)] |
| 17 | pub enum ClockSrc { | 17 | pub enum ClockSrc { |
| @@ -286,12 +286,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | // TODO make configurable | 288 | // TODO make configurable |
| 289 | let power_vos = VoltageScale::Scale3; | 289 | let power_vos = VoltageScale::RANGE3; |
| 290 | 290 | ||
| 291 | // states and programming delay | 291 | // states and programming delay |
| 292 | let wait_states = match power_vos { | 292 | let wait_states = match power_vos { |
| 293 | // VOS 0 range VCORE 1.26V - 1.40V | 293 | // VOS 1 range VCORE 1.26V - 1.40V |
| 294 | VoltageScale::Scale0 => { | 294 | VoltageScale::RANGE1 => { |
| 295 | if sys_clk < 32_000_000 { | 295 | if sys_clk < 32_000_000 { |
| 296 | 0 | 296 | 0 |
| 297 | } else if sys_clk < 64_000_000 { | 297 | } else if sys_clk < 64_000_000 { |
| @@ -304,8 +304,8 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 304 | 4 | 304 | 4 |
| 305 | } | 305 | } |
| 306 | } | 306 | } |
| 307 | // VOS 1 range VCORE 1.15V - 1.26V | 307 | // VOS 2 range VCORE 1.15V - 1.26V |
| 308 | VoltageScale::Scale1 => { | 308 | VoltageScale::RANGE2 => { |
| 309 | if sys_clk < 30_000_000 { | 309 | if sys_clk < 30_000_000 { |
| 310 | 0 | 310 | 0 |
| 311 | } else if sys_clk < 60_000_000 { | 311 | } else if sys_clk < 60_000_000 { |
| @@ -316,8 +316,8 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 316 | 3 | 316 | 3 |
| 317 | } | 317 | } |
| 318 | } | 318 | } |
| 319 | // VOS 2 range VCORE 1.05V - 1.15V | 319 | // VOS 3 range VCORE 1.05V - 1.15V |
| 320 | VoltageScale::Scale2 => { | 320 | VoltageScale::RANGE3 => { |
| 321 | if sys_clk < 24_000_000 { | 321 | if sys_clk < 24_000_000 { |
| 322 | 0 | 322 | 0 |
| 323 | } else if sys_clk < 48_000_000 { | 323 | } else if sys_clk < 48_000_000 { |
| @@ -326,8 +326,8 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 326 | 2 | 326 | 2 |
| 327 | } | 327 | } |
| 328 | } | 328 | } |
| 329 | // VOS 3 range VCORE 0.95V - 1.05V | 329 | // VOS 4 range VCORE 0.95V - 1.05V |
| 330 | VoltageScale::Scale3 => { | 330 | VoltageScale::RANGE4 => { |
| 331 | if sys_clk < 12_000_000 { | 331 | if sys_clk < 12_000_000 { |
| 332 | 0 | 332 | 0 |
| 333 | } else { | 333 | } else { |
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 5db942fca..6643d278a 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 2 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | ||
| 2 | use crate::pac::rcc::vals::Adcsel; | 3 | use crate::pac::rcc::vals::Adcsel; |
| 3 | use crate::pac::{FLASH, RCC}; | 4 | use crate::pac::{FLASH, RCC}; |
| 4 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | 5 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; |
| @@ -75,9 +76,9 @@ impl MSIRange { | |||
| 75 | 76 | ||
| 76 | fn vos(&self) -> VoltageScale { | 77 | fn vos(&self) -> VoltageScale { |
| 77 | if self > &MSIRange::Range8 { | 78 | if self > &MSIRange::Range8 { |
| 78 | VoltageScale::Scale0 | 79 | VoltageScale::RANGE1 |
| 79 | } else { | 80 | } else { |
| 80 | VoltageScale::Scale1 | 81 | VoltageScale::RANGE2 |
| 81 | } | 82 | } |
| 82 | } | 83 | } |
| 83 | } | 84 | } |
| @@ -170,8 +171,8 @@ pub enum Lsedrv { | |||
| 170 | 171 | ||
| 171 | pub(crate) unsafe fn init(config: Config) { | 172 | pub(crate) unsafe fn init(config: Config) { |
| 172 | let (sys_clk, sw, vos) = match config.mux { | 173 | let (sys_clk, sw, vos) = match config.mux { |
| 173 | ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Scale1), | 174 | ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::RANGE2), |
| 174 | ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Scale0), | 175 | ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::RANGE1), |
| 175 | ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), | 176 | ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), |
| 176 | }; | 177 | }; |
| 177 | 178 | ||
| @@ -216,16 +217,17 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 216 | // Adjust flash latency | 217 | // Adjust flash latency |
| 217 | let flash_clk_src_freq: u32 = shd_ahb_freq; | 218 | let flash_clk_src_freq: u32 = shd_ahb_freq; |
| 218 | let ws = match vos { | 219 | let ws = match vos { |
| 219 | VoltageScale::Scale0 => match flash_clk_src_freq { | 220 | VoltageScale::RANGE1 => match flash_clk_src_freq { |
| 220 | 0..=18_000_000 => 0b000, | 221 | 0..=18_000_000 => 0b000, |
| 221 | 18_000_001..=36_000_000 => 0b001, | 222 | 18_000_001..=36_000_000 => 0b001, |
| 222 | _ => 0b010, | 223 | _ => 0b010, |
| 223 | }, | 224 | }, |
| 224 | VoltageScale::Scale1 => match flash_clk_src_freq { | 225 | VoltageScale::RANGE2 => match flash_clk_src_freq { |
| 225 | 0..=6_000_000 => 0b000, | 226 | 0..=6_000_000 => 0b000, |
| 226 | 6_000_001..=12_000_000 => 0b001, | 227 | 6_000_001..=12_000_000 => 0b001, |
| 227 | _ => 0b010, | 228 | _ => 0b010, |
| 228 | }, | 229 | }, |
| 230 | _ => unreachable!(), | ||
| 229 | }; | 231 | }; |
| 230 | 232 | ||
| 231 | FLASH.acr().modify(|w| { | 233 | FLASH.acr().modify(|w| { |
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index fdba6cd5c..41ef2acaa 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs | |||
| @@ -53,7 +53,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 53 | config.rcc.apb2_pre = APBPrescaler::DIV1; | 53 | config.rcc.apb2_pre = APBPrescaler::DIV1; |
| 54 | config.rcc.apb3_pre = APBPrescaler::DIV1; | 54 | config.rcc.apb3_pre = APBPrescaler::DIV1; |
| 55 | config.rcc.sys = Sysclk::Pll1P; | 55 | config.rcc.sys = Sysclk::Pll1P; |
| 56 | config.rcc.voltage_scale = VoltageScale::Scale0; | 56 | config.rcc.voltage_scale = VoltageScale::SCALE0; |
| 57 | let p = embassy_stm32::init(config); | 57 | let p = embassy_stm32::init(config); |
| 58 | info!("Hello World!"); | 58 | info!("Hello World!"); |
| 59 | 59 | ||
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index cbe540a06..63c694aff 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs | |||
| @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) { | |||
| 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 41 | config.rcc.apb3_pre = APBPrescaler::DIV4; | 41 | config.rcc.apb3_pre = APBPrescaler::DIV4; |
| 42 | config.rcc.sys = Sysclk::Pll1P; | 42 | config.rcc.sys = Sysclk::Pll1P; |
| 43 | config.rcc.voltage_scale = VoltageScale::Scale0; | 43 | config.rcc.voltage_scale = VoltageScale::SCALE0; |
| 44 | let p = embassy_stm32::init(config); | 44 | let p = embassy_stm32::init(config); |
| 45 | 45 | ||
| 46 | info!("Hello World!"); | 46 | info!("Hello World!"); |
