Merge pull request #1803 from randomplum/flash_h7ab
configure flash latency after axi clock and handle different flash on STM32H7A/B devices
This commit is contained in:
		| @@ -57,7 +57,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-7eddb78e705905af4c1dd2359900db3e78a3c500" } | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7" } | ||||||
| vcell = "0.1.3" | vcell = "0.1.3" | ||||||
| bxcan = "0.7.0" | bxcan = "0.7.0" | ||||||
| nb = "1.0.0" | nb = "1.0.0" | ||||||
| @@ -76,7 +76,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-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] | [features] | ||||||
| default = ["rt"] | default = ["rt"] | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ pub const fn is_default_layout() -> bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| const fn is_dual_bank() -> bool { | const fn is_dual_bank() -> bool { | ||||||
|     FLASH_REGIONS.len() == 2 |     FLASH_REGIONS.len() >= 2 | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn get_flash_regions() -> &'static [&'static FlashRegion] { | 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| { |     bank.cr().write(|w| { | ||||||
|         w.set_pg(true); |         w.set_pg(true); | ||||||
|  |         #[cfg(flash_h7)] | ||||||
|         w.set_psize(2); // 32 bits at once |         w.set_psize(2); // 32 bits at once | ||||||
|     }); |     }); | ||||||
|     cortex_m::asm::isb(); |     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); |     let bank = pac::FLASH.bank(sector.bank as usize); | ||||||
|     bank.cr().modify(|w| { |     bank.cr().modify(|w| { | ||||||
|         w.set_ser(true); |         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| { |     bank.cr().modify(|w| { | ||||||
| @@ -126,6 +130,10 @@ unsafe fn blocking_wait_ready(bank: pac::flash::Bank) -> Result<(), Error> { | |||||||
|                 error!("incerr"); |                 error!("incerr"); | ||||||
|                 return Err(Error::Seq); |                 return Err(Error::Seq); | ||||||
|             } |             } | ||||||
|  |             if sr.crcrderr() { | ||||||
|  |                 error!("crcrderr"); | ||||||
|  |                 return Err(Error::Seq); | ||||||
|  |             } | ||||||
|             if sr.operr() { |             if sr.operr() { | ||||||
|                 return Err(Error::Prog); |                 return Err(Error::Prog); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -65,9 +65,11 @@ impl FlashRegion { | |||||||
| #[cfg_attr(flash_f7, path = "f7.rs")] | #[cfg_attr(flash_f7, path = "f7.rs")] | ||||||
| #[cfg_attr(flash_g0, path = "g0.rs")] | #[cfg_attr(flash_g0, path = "g0.rs")] | ||||||
| #[cfg_attr(flash_h7, path = "h7.rs")] | #[cfg_attr(flash_h7, path = "h7.rs")] | ||||||
|  | #[cfg_attr(flash_h7ab, path = "h7.rs")] | ||||||
| #[cfg_attr( | #[cfg_attr( | ||||||
|     not(any( |     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" |     path = "other.rs" | ||||||
| )] | )] | ||||||
|   | |||||||
| @@ -200,6 +200,7 @@ fn flash_setup(rcc_aclk: u32, 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 | ||||||
|  |     #[cfg(flash_h7)] | ||||||
|     let (wait_states, progr_delay) = match vos { |     let (wait_states, progr_delay) = match vos { | ||||||
|         // VOS 0 range VCORE 1.26V - 1.40V |         // VOS 0 range VCORE 1.26V - 1.40V | ||||||
|         VoltageScale::Scale0 => match rcc_aclk_mhz { |         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| { |     FLASH.acr().write(|w| { | ||||||
|         w.set_wrhighfreq(progr_delay); |         w.set_wrhighfreq(progr_delay); | ||||||
|         w.set_latency(wait_states) |         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 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); |     let (rcc_pclk4, ppre4_bits, ppre4, _) = ppre_calculate(requested_pclk4, rcc_hclk, pclk_max, None); | ||||||
|  |  | ||||||
|     flash_setup(rcc_aclk, pwr_vos); |  | ||||||
|  |  | ||||||
|     // Start switching clocks ------------------- |     // Start switching clocks ------------------- | ||||||
|  |  | ||||||
|     // Ensure CSI is on and stable |     // Ensure CSI is on and stable | ||||||
| @@ -595,6 +638,8 @@ 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); | ||||||
|  |  | ||||||
|     // APB1 / APB2 Prescaler |     // APB1 / APB2 Prescaler | ||||||
|     RCC.d2cfgr().modify(|w| { |     RCC.d2cfgr().modify(|w| { | ||||||
|         w.set_d2ppre1(Dppre::from_bits(ppre1_bits)); |         w.set_d2ppre1(Dppre::from_bits(ppre1_bits)); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user