aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-09-18 03:00:59 +0200
committerDario Nieuwenhuis <[email protected]>2023-09-18 03:15:15 +0200
commit4bfbcd6c72fadd97ef71403a1406ff437f4aa6e8 (patch)
treee38ea7030abd1c9d69d1471411268227ddc75131
parent0da793e5de229eb7ff2e50da69b95c435f4e45a9 (diff)
stm32: use PAC enums for VOS.
-rwxr-xr-xci.sh2
-rw-r--r--embassy-lora/src/iv.rs14
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/rcc/bus.rs16
-rw-r--r--embassy-stm32/src/rcc/f2.rs25
-rw-r--r--embassy-stm32/src/rcc/h5.rs70
-rw-r--r--embassy-stm32/src/rcc/h7.rs97
-rw-r--r--embassy-stm32/src/rcc/u5.rs20
-rw-r--r--embassy-stm32/src/rcc/wl.rs16
-rw-r--r--examples/stm32h5/src/bin/eth.rs2
-rw-r--r--examples/stm32h5/src/bin/usb_serial.rs2
11 files changed, 159 insertions, 109 deletions
diff --git a/ci.sh b/ci.sh
index 87f47487d..37d3e7783 100755
--- a/ci.sh
+++ b/ci.sh
@@ -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"
59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
60critical-section = "1.1" 60critical-section = "1.1"
61atomic-polyfill = "1.0.1" 61atomic-polyfill = "1.0.1"
62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-907dd82c848bc912252c61509944e85c2a48c919" } 62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2dba1f1ddee697e616aff2a4db57a6ffaf1b29b7" }
63vcell = "0.1.3" 63vcell = "0.1.3"
64bxcan = "0.7.0" 64bxcan = "0.7.0"
65nb = "1.0.0" 65nb = "1.0.0"
@@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] }
78[build-dependencies] 78[build-dependencies]
79proc-macro2 = "1.0.36" 79proc-macro2 = "1.0.36"
80quote = "1.0.15" 80quote = "1.0.15"
81stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-907dd82c848bc912252c61509944e85c2a48c919", default-features = false, features = ["metadata"]} 81stm32-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]
84default = ["rt"] 84default = ["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;
5pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; 5pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
6use crate::time::Hertz; 6use 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)]
15pub 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
24impl Div<AHBPrescaler> for Hertz { 8impl 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
206pub 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
210pub 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
208impl VoltageScale { 221impl 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
3use stm32_metapac::rcc::vals::Timpre; 3use stm32_metapac::rcc::vals::Timpre;
4 4
5use crate::pac::pwr::vals::Vos;
6use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw}; 5use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw};
7use crate::pac::{FLASH, PWR, RCC}; 6use crate::pac::{FLASH, PWR, RCC};
8use crate::rcc::{set_freqs, Clocks}; 7use crate::rcc::{set_freqs, Clocks};
@@ -26,7 +25,8 @@ const VCO_MAX: u32 = 420_000_000;
26const VCO_WIDE_MIN: u32 = 128_000_000; 25const VCO_WIDE_MIN: u32 = 128_000_000;
27const VCO_WIDE_MAX: u32 = 560_000_000; 26const VCO_WIDE_MAX: u32 = 560_000_000;
28 27
29pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; 28pub use super::bus::{AHBPrescaler, APBPrescaler};
29pub use crate::pac::pwr::vals::Vos as VoltageScale;
30 30
31pub enum HseMode { 31pub 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
224pub(crate) unsafe fn init(config: Config) { 224pub(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 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_internal::into_ref; 3use embassy_hal_internal::into_ref;
4pub use pll::PllConfig; 4use stm32_metapac::pwr::vals::Vos;
5use stm32_metapac::rcc::vals::{Mco1, Mco2}; 5use stm32_metapac::rcc::vals::{Mco1, Mco2};
6 6
7pub use self::pll::PllConfig;
7use crate::gpio::sealed::AFType; 8use crate::gpio::sealed::AFType;
8use crate::gpio::Speed; 9use crate::gpio::Speed;
9use crate::pac::rcc::vals::{Adcsel, Ckpersel, Hpre, Hsidiv, Pllsrc, Ppre, Sw, Timpre}; 10use 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
25pub const LSI_FREQ: Hertz = Hertz(32_000); 26pub const LSI_FREQ: Hertz = Hertz(32_000);
26 27
27pub use super::bus::VoltageScale; 28#[derive(Clone, Copy)]
29pub enum VoltageScale {
30 Scale0,
31 Scale1,
32 Scale2,
33 Scale3,
34}
28 35
29#[derive(Clone, Copy)] 36#[derive(Clone, Copy)]
30pub enum AdcClockSource { 37pub 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)]
89pub struct Config { 95pub 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
112impl 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
433pub(crate) unsafe fn init(mut config: Config) { 461pub(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
12pub const LSI_FREQ: Hertz = Hertz(32_000); 12pub const LSI_FREQ: Hertz = Hertz(32_000);
13 13
14pub use super::bus::VoltageScale; 14pub use crate::pac::pwr::vals::Vos as VoltageScale;
15 15
16#[derive(Copy, Clone)] 16#[derive(Copy, Clone)]
17pub enum ClockSrc { 17pub 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 @@
1pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; 1pub use super::bus::{AHBPrescaler, APBPrescaler};
2pub use crate::pac::pwr::vals::Vos as VoltageScale;
2use crate::pac::rcc::vals::Adcsel; 3use crate::pac::rcc::vals::Adcsel;
3use crate::pac::{FLASH, RCC}; 4use crate::pac::{FLASH, RCC};
4use crate::rcc::bd::{BackupDomain, RtcClockSource}; 5use 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
171pub(crate) unsafe fn init(config: Config) { 172pub(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!");