From 5bc0175be9482be4737dfffd3a615cee3301e775 Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Fri, 18 Aug 2023 22:10:13 +0200 Subject: [PATCH] configure flash latency after axi clock and handle different flash in STM32H7A/B devices --- embassy-stm32/Cargo.toml | 4 +-- embassy-stm32/src/flash/h7.rs | 12 +++++++-- embassy-stm32/src/flash/mod.rs | 4 ++- embassy-stm32/src/rcc/h7.rs | 49 ++++++++++++++++++++++++++++++++-- 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index c3f5706e..fe5dc443 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -57,7 +57,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7eddb78e705905af4c1dd2359900db3e78a3c500" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7eddb78e705905af4c1dd2359900db3e78a3c500", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7", default-features = false, features = ["metadata"]} [features] default = ["rt"] diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs index bb429d77..625bf13f 100644 --- a/embassy-stm32/src/flash/h7.rs +++ b/embassy-stm32/src/flash/h7.rs @@ -11,7 +11,7 @@ pub const fn is_default_layout() -> bool { } const fn is_dual_bank() -> bool { - FLASH_REGIONS.len() == 2 + FLASH_REGIONS.len() >= 2 } pub fn get_flash_regions() -> &'static [&'static FlashRegion] { @@ -49,6 +49,7 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) }; bank.cr().write(|w| { w.set_pg(true); + #[cfg(flash_h7)] w.set_psize(2); // 32 bits at once }); cortex_m::asm::isb(); @@ -85,7 +86,10 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E let bank = pac::FLASH.bank(sector.bank as usize); bank.cr().modify(|w| { w.set_ser(true); - w.set_snb(sector.index_in_bank) + #[cfg(flash_h7)] + w.set_snb(sector.index_in_bank); + #[cfg(flash_h7ab)] + w.set_ssn(sector.index_in_bank); }); bank.cr().modify(|w| { @@ -126,6 +130,10 @@ unsafe fn blocking_wait_ready(bank: pac::flash::Bank) -> Result<(), Error> { error!("incerr"); return Err(Error::Seq); } + if sr.crcrderr() { + error!("crcrderr"); + return Err(Error::Seq); + } if sr.operr() { return Err(Error::Prog); } diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs index 4308037f..fb20dcd3 100644 --- a/embassy-stm32/src/flash/mod.rs +++ b/embassy-stm32/src/flash/mod.rs @@ -65,9 +65,11 @@ impl FlashRegion { #[cfg_attr(flash_f7, path = "f7.rs")] #[cfg_attr(flash_g0, path = "g0.rs")] #[cfg_attr(flash_h7, path = "h7.rs")] +#[cfg_attr(flash_h7ab, path = "h7.rs")] #[cfg_attr( not(any( - flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f3, flash_f4, flash_f7, flash_g0, flash_h7 + flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f3, flash_f4, flash_f7, flash_g0, flash_h7, + flash_h7ab )), path = "other.rs" )] diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs index 0788b064..7fb4fb95 100644 --- a/embassy-stm32/src/rcc/h7.rs +++ b/embassy-stm32/src/rcc/h7.rs @@ -200,6 +200,7 @@ fn flash_setup(rcc_aclk: u32, vos: VoltageScale) { // See RM0433 Rev 7 Table 17. FLASH recommended number of wait // states and programming delay + #[cfg(flash_h7)] let (wait_states, progr_delay) = match vos { // VOS 0 range VCORE 1.26V - 1.40V VoltageScale::Scale0 => match rcc_aclk_mhz { @@ -239,6 +240,50 @@ fn flash_setup(rcc_aclk: u32, vos: VoltageScale) { }, }; + // See RM0455 Rev 10 Table 16. FLASH recommended number of wait + // states and programming delay + #[cfg(flash_h7ab)] + let (wait_states, progr_delay) = match vos { + // VOS 0 range VCORE 1.25V - 1.35V + VoltageScale::Scale0 => match rcc_aclk_mhz { + 0..=42 => (0, 0), + 43..=84 => (1, 0), + 85..=126 => (2, 1), + 127..=168 => (3, 1), + 169..=210 => (4, 2), + 211..=252 => (5, 2), + 253..=280 => (6, 3), + _ => (7, 3), + }, + // VOS 1 range VCORE 1.15V - 1.25V + VoltageScale::Scale1 => match rcc_aclk_mhz { + 0..=38 => (0, 0), + 39..=76 => (1, 0), + 77..=114 => (2, 1), + 115..=152 => (3, 1), + 153..=190 => (4, 2), + 191..=225 => (5, 2), + _ => (7, 3), + }, + // VOS 2 range VCORE 1.05V - 1.15V + VoltageScale::Scale2 => match rcc_aclk_mhz { + 0..=34 => (0, 0), + 35..=68 => (1, 0), + 69..=102 => (2, 1), + 103..=136 => (3, 1), + 137..=160 => (4, 2), + _ => (7, 3), + }, + // VOS 3 range VCORE 0.95V - 1.05V + VoltageScale::Scale3 => match rcc_aclk_mhz { + 0..=22 => (0, 0), + 23..=44 => (1, 0), + 45..=66 => (2, 1), + 67..=88 => (3, 1), + _ => (7, 3), + }, + }; + FLASH.acr().write(|w| { w.set_wrhighfreq(progr_delay); w.set_latency(wait_states) @@ -538,8 +583,6 @@ pub(crate) unsafe fn init(mut config: Config) { let requested_pclk4 = config.pclk4.map(|v| v.0).unwrap_or_else(|| pclk_max.min(rcc_hclk / 2)); let (rcc_pclk4, ppre4_bits, ppre4, _) = ppre_calculate(requested_pclk4, rcc_hclk, pclk_max, None); - flash_setup(rcc_aclk, pwr_vos); - // Start switching clocks ------------------- // Ensure CSI is on and stable @@ -595,6 +638,8 @@ pub(crate) unsafe fn init(mut config: Config) { // core voltage while RCC.d1cfgr().read().d1cpre().to_bits() != d1cpre_bits {} + flash_setup(rcc_aclk, pwr_vos); + // APB1 / APB2 Prescaler RCC.d2cfgr().modify(|w| { w.set_d2ppre1(Dppre::from_bits(ppre1_bits));