From e5e85ba02bc91a47d80ba89dee27e6ccb20f0ccd Mon Sep 17 00:00:00 2001 From: Oliver Rockstedt Date: Fri, 15 Dec 2023 11:42:58 +0100 Subject: [PATCH 1/4] STM32H7: Allow PLL1 DIVP of 1 for certain series --- embassy-stm32/src/rcc/h.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 1889eb280..18dff9f29 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -70,7 +70,9 @@ pub struct Pll { pub mul: PllMul, /// PLL P division factor. If None, PLL P output is disabled. - /// On PLL1, it must be even (in particular, it cannot be 1.) + /// On PLL1, it must be even for most series (in particular, + /// it cannot be 1 in series other than STM32H723/733, + /// STM32H725/735 and STM32H730.) pub divp: Option, /// PLL Q division factor. If None, PLL Q output is disabled. pub divq: Option, @@ -729,9 +731,12 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { let p = config.divp.map(|div| { if num == 0 { - // on PLL1, DIVP must be even. + // on PLL1, DIVP must be even for most series. // The enum value is 1 less than the divider, so check it's odd. + #[cfg(not(pwr_h7rm0468))] assert!(div.to_bits() % 2 == 1); + #[cfg(pwr_h7rm0468)] + assert!(div.to_bits() % 2 == 1 || div.to_bits() == 0); } vco_clk / div From a8d0da91dc7b43bb05b200e7f530e58e25f20194 Mon Sep 17 00:00:00 2001 From: Oliver Rockstedt Date: Fri, 15 Dec 2023 12:22:17 +0100 Subject: [PATCH 2/4] STM32H7: adjust frequency limits for series in RM0468 --- embassy-stm32/src/rcc/h.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 18dff9f29..f28bd0b9d 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -478,7 +478,14 @@ pub(crate) unsafe fn init(config: Config) { VoltageScale::Scale2 => (Hertz(160_000_000), Hertz(160_000_000), Hertz(80_000_000)), VoltageScale::Scale3 => (Hertz(88_000_000), Hertz(88_000_000), Hertz(44_000_000)), }; - #[cfg(all(stm32h7, not(pwr_h7rm0455)))] + #[cfg(pwr_h7rm0468)] + let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { + VoltageScale::Scale0 => (Hertz(550_000_000), Hertz(275_000_000), Hertz(137_500_000)), + VoltageScale::Scale1 => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)), + VoltageScale::Scale2 => (Hertz(300_000_000), Hertz(150_000_000), Hertz(75_000_000)), + VoltageScale::Scale3 => (Hertz(170_000_000), Hertz(85_000_000), Hertz(42_500_000)), + }; + #[cfg(all(stm32h7, not(any(pwr_h7rm0455, pwr_h7rm0468))))] let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { VoltageScale::Scale0 => (Hertz(480_000_000), Hertz(240_000_000), Hertz(120_000_000)), VoltageScale::Scale1 => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)), From c17fee27bb37233df7300bea3c2658f87df9dd6b Mon Sep 17 00:00:00 2001 From: Oliver Rockstedt Date: Fri, 15 Dec 2023 13:53:06 +0100 Subject: [PATCH 3/4] STM32H7: limit max frequency to 520MHz until cpu frequency boost option is implemented --- embassy-stm32/src/rcc/h.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index f28bd0b9d..389b2a871 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -480,7 +480,7 @@ pub(crate) unsafe fn init(config: Config) { }; #[cfg(pwr_h7rm0468)] let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { - VoltageScale::Scale0 => (Hertz(550_000_000), Hertz(275_000_000), Hertz(137_500_000)), + VoltageScale::Scale0 => (Hertz(520_000_000), Hertz(275_000_000), Hertz(137_500_000)), VoltageScale::Scale1 => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)), VoltageScale::Scale2 => (Hertz(300_000_000), Hertz(150_000_000), Hertz(75_000_000)), VoltageScale::Scale3 => (Hertz(170_000_000), Hertz(85_000_000), Hertz(42_500_000)), From 560e72813292e0ceb32b25daf887bb69b48af771 Mon Sep 17 00:00:00 2001 From: Oliver Rockstedt Date: Fri, 15 Dec 2023 14:14:30 +0100 Subject: [PATCH 4/4] STM32H7: adjust flash latency and programming delay for series in RM0468 --- embassy-stm32/src/rcc/h.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 389b2a871..15b51a398 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -832,7 +832,7 @@ fn flash_setup(clk: Hertz, vos: VoltageScale) { _ => unreachable!(), }; - #[cfg(flash_h7)] + #[cfg(all(flash_h7, not(pwr_h7rm0468)))] let (latency, wrhighfreq) = match (vos, clk.0) { // VOS 0 range VCORE 1.26V - 1.40V (VoltageScale::Scale0, ..=70_000_000) => (0, 0), @@ -861,6 +861,30 @@ fn flash_setup(clk: Hertz, vos: VoltageScale) { _ => unreachable!(), }; + // See RM0468 Rev 3 Table 16. FLASH recommended number of wait + // states and programming delay + #[cfg(all(flash_h7, pwr_h7rm0468))] + let (latency, wrhighfreq) = match (vos, clk.0) { + // VOS 0 range VCORE 1.26V - 1.40V + (VoltageScale::Scale0, ..=70_000_000) => (0, 0), + (VoltageScale::Scale0, ..=140_000_000) => (1, 1), + (VoltageScale::Scale0, ..=210_000_000) => (2, 2), + (VoltageScale::Scale0, ..=275_000_000) => (3, 3), + // VOS 1 range VCORE 1.15V - 1.26V + (VoltageScale::Scale1, ..=67_000_000) => (0, 0), + (VoltageScale::Scale1, ..=133_000_000) => (1, 1), + (VoltageScale::Scale1, ..=200_000_000) => (2, 2), + // VOS 2 range VCORE 1.05V - 1.15V + (VoltageScale::Scale2, ..=50_000_000) => (0, 0), + (VoltageScale::Scale2, ..=100_000_000) => (1, 1), + (VoltageScale::Scale2, ..=150_000_000) => (2, 2), + // VOS 3 range VCORE 0.95V - 1.05V + (VoltageScale::Scale3, ..=35_000_000) => (0, 0), + (VoltageScale::Scale3, ..=70_000_000) => (1, 1), + (VoltageScale::Scale3, ..=85_000_000) => (2, 2), + _ => unreachable!(), + }; + // See RM0455 Rev 10 Table 16. FLASH recommended number of wait // states and programming delay #[cfg(flash_h7ab)]