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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user