diff --git a/embassy-stm32/src/flash/f3.rs b/embassy-stm32/src/flash/f3.rs index 99ac1a15..3da3962e 100644 --- a/embassy-stm32/src/flash/f3.rs +++ b/embassy-stm32/src/flash/f3.rs @@ -3,11 +3,11 @@ use core::ptr::write_volatile; use atomic_polyfill::{fence, Ordering}; -use super::{FlashRegion, BANK1, WRITE_SIZE}; +use super::{FlashRegion, FlashSector, BANK1, WRITE_SIZE}; use crate::flash::Error; use crate::pac; -const ERASE_SIZE: usize = BANK1::ERASE_SIZE; +const ERASE_SIZE: usize = BANK1::SETTINGS.erase_size; pub(crate) unsafe fn lock() { pac::FLASH.cr().modify(|w| w.set_lock(true)); @@ -41,10 +41,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) blocking_wait_ready() } -pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool { - start_address % ERASE_SIZE as u32 == 0 && end_address % ERASE_SIZE as u32 == 0 -} - pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> { for page in (start_address..end_address).step_by(ERASE_SIZE) { pac::FLASH.cr().modify(|w| { @@ -107,3 +103,13 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> { } } } + +pub(crate) fn get_sector(address: u32) -> FlashSector { + let sector_size = BANK1::SETTINGS.erase_size as u32; + let index = address / sector_size; + FlashSector { + index: index as u8, + start: BANK1::SETTINGS.base as u32 + index * sector_size, + size: sector_size, + } +} diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 0fdfecb9..306359be 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -63,24 +63,10 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) blocking_wait_ready() } -pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool { - let dual_bank = is_dual_bank(); - let mut address = start_address; - while address < end_address { - let sector = get_sector(address, dual_bank, FLASH_SIZE as u32); - if sector.start != address { - return false; - } - address += sector.size; - } - address == end_address -} - pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> { - let dual_bank = is_dual_bank(); let mut address = start_address; while address < end_address { - let sector = get_sector(address, dual_bank, FLASH_SIZE as u32); + let sector = get_sector(address); erase_sector(sector.index)?; address += sector.size; } @@ -145,7 +131,11 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> { } } -fn get_sector(address: u32, dual_bank: bool, flash_size: u32) -> FlashSector { +pub(crate) fn get_sector(address: u32) -> FlashSector { + get_sector_inner(address, is_dual_bank(), FLASH_SIZE) +} + +fn get_sector_inner(address: u32, dual_bank: bool, flash_size: u32) -> FlashSector { let offset = address - FLASH_BASE as u32; if !dual_bank { get_single_bank_sector(offset) @@ -187,7 +177,10 @@ fn get_single_bank_sector(offset: u32) -> FlashSector { let large_sector_index = i - 1; FlashSector { index: (5 + large_sector_index) as u8, - start: FLASH_BASE as u32 + 4 * SMALL_SECTOR_SIZE + MEDIUM_SECTOR_SIZE + large_sector_index * LARGE_SECTOR_SIZE, + start: FLASH_BASE as u32 + + 4 * SMALL_SECTOR_SIZE + + MEDIUM_SECTOR_SIZE + + large_sector_index * LARGE_SECTOR_SIZE, size: LARGE_SECTOR_SIZE, } } @@ -201,7 +194,10 @@ mod tests { #[test] fn can_get_sector_single_bank() { let assert_sector = |index: u8, start: u32, size: u32, addr: u32| { - assert_eq!(FlashSector { index, start, size }, get_sector(addr, false, 1024 * 1024)) + assert_eq!( + FlashSector { index, start, size }, + get_sector_inner(addr, false, 1024 * 1024) + ) }; assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); @@ -221,7 +217,10 @@ mod tests { #[test] fn can_get_sector_dual_bank() { let assert_sector = |index: u8, start: u32, size: u32, addr: u32| { - assert_eq!(FlashSector { index, start, size }, get_sector(addr, true, 1024 * 1024)) + assert_eq!( + FlashSector { index, start, size }, + get_sector_inner(addr, true, 1024 * 1024) + ) }; assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs index 0d3b738c..588fc7a5 100644 --- a/embassy-stm32/src/flash/f7.rs +++ b/embassy-stm32/src/flash/f7.rs @@ -45,18 +45,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) blocking_wait_ready() } -pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool { - let mut address = start_address; - while address < end_address { - let sector = get_sector(address); - if sector.start != address { - return false; - } - address += sector.size; - } - address == end_address -} - pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> { let mut address = start_address; while address < end_address { @@ -132,7 +120,7 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> { } } -fn get_sector(address: u32) -> FlashSector { +pub(crate) fn get_sector(address: u32) -> FlashSector { // First 4 sectors are 32KB, then one 128KB, and rest are 256KB let offset = address - FLASH_BASE as u32; match offset / LARGE_SECTOR_SIZE { @@ -156,7 +144,10 @@ fn get_sector(address: u32) -> FlashSector { let large_sector_index = i - 1; FlashSector { index: (5 + large_sector_index) as u8, - start: FLASH_BASE as u32 + 4 * SMALL_SECTOR_SIZE + MEDIUM_SECTOR_SIZE + large_sector_index * LARGE_SECTOR_SIZE, + start: FLASH_BASE as u32 + + 4 * SMALL_SECTOR_SIZE + + MEDIUM_SECTOR_SIZE + + large_sector_index * LARGE_SECTOR_SIZE, size: LARGE_SECTOR_SIZE, } } diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs index 21a9e45d..732af853 100644 --- a/embassy-stm32/src/flash/h7.rs +++ b/embassy-stm32/src/flash/h7.rs @@ -3,11 +3,11 @@ use core::ptr::write_volatile; use atomic_polyfill::{fence, Ordering}; -use super::{FlashRegion, FLASH_SIZE, WRITE_SIZE}; +use super::{FlashRegion, FlashSector, BANK1, FLASH_SIZE, WRITE_SIZE}; use crate::flash::Error; use crate::pac; -const ERASE_SIZE: usize = super::BANK1::ERASE_SIZE; +const ERASE_SIZE: usize = BANK1::SETTINGS.erase_size; const SECOND_BANK_OFFSET: usize = 0x0010_0000; const fn is_dual_bank() -> bool { @@ -78,10 +78,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) res.unwrap() } -pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool { - start_address % ERASE_SIZE as u32 == 0 && end_address % ERASE_SIZE as u32 == 0 -} - pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> { let start_sector = (start_address - super::FLASH_BASE as u32) / ERASE_SIZE as u32; let end_sector = (end_address - super::FLASH_BASE as u32) / ERASE_SIZE as u32; @@ -194,3 +190,13 @@ unsafe fn blocking_wait_ready(bank: pac::flash::Bank) -> Result<(), Error> { } } } + +pub(crate) fn get_sector(address: u32) -> FlashSector { + let sector_size = BANK1::SETTINGS.erase_size as u32; + let index = address / sector_size; + FlashSector { + index: index as u8, + start: BANK1::SETTINGS.base as u32 + index * sector_size, + size: sector_size, + } +} diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs index 57989625..56a21885 100644 --- a/embassy-stm32/src/flash/l.rs +++ b/embassy-stm32/src/flash/l.rs @@ -2,11 +2,11 @@ use core::ptr::write_volatile; use atomic_polyfill::{fence, Ordering}; -use super::{FlashRegion, WRITE_SIZE}; +use super::{FlashRegion, FlashSector, BANK1, WRITE_SIZE}; use crate::flash::Error; use crate::pac; -const ERASE_SIZE: usize = super::BANK1::ERASE_SIZE; +const ERASE_SIZE: usize = BANK1::SETTINGS.erase_size; pub(crate) unsafe fn lock() { #[cfg(any(flash_wl, flash_wb, flash_l4))] @@ -62,10 +62,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) blocking_wait_ready() } -pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool { - start_address % ERASE_SIZE as u32 == 0 && end_address % ERASE_SIZE as u32 == 0 -} - pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> { for page in (start_address..end_address).step_by(ERASE_SIZE) { #[cfg(any(flash_l0, flash_l1))] @@ -191,3 +187,13 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> { } } } + +pub(crate) fn get_sector(address: u32) -> FlashSector { + let sector_size = BANK1::SETTINGS.erase_size as u32; + let index = address / sector_size; + FlashSector { + index: index as u8, + start: BANK1::SETTINGS.base as u32 + index * sector_size, + size: sector_size, + } +} diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs index 1d1f034a..29cf3cc5 100644 --- a/embassy-stm32/src/flash/mod.rs +++ b/embassy-stm32/src/flash/mod.rs @@ -104,7 +104,7 @@ impl<'d> Flash<'d> { let start_address = FLASH_BASE as u32 + from; let end_address = FLASH_BASE as u32 + to; - if !family::is_eraseable_range(start_address, end_address) { + if !is_eraseable_range(start_address, end_address) { return Err(Error::Unaligned); } trace!("Erasing from 0x{:x} to 0x{:x}", start_address, end_address); @@ -193,6 +193,18 @@ pub trait FlashRegion { } } +fn is_eraseable_range(start_address: u32, end_address: u32) -> bool { + let mut address = start_address; + while address < end_address { + let sector = family::get_sector(address); + if sector.start != address { + return false; + } + address += sector.size; + } + address == end_address +} + fn take_lock_spin() -> MutexGuard<'static, CriticalSectionRawMutex, ()> { loop { if let Ok(guard) = REGION_LOCK.try_lock() { diff --git a/embassy-stm32/src/flash/other.rs b/embassy-stm32/src/flash/other.rs index c9836d09..4ffb4cc3 100644 --- a/embassy-stm32/src/flash/other.rs +++ b/embassy-stm32/src/flash/other.rs @@ -1,7 +1,11 @@ pub trait FlashRegion { - const BASE: usize; - const SIZE: usize; - const ERASE_SIZE: usize; - const WRITE_SIZE: usize; - const ERASE_VALUE: u8; + const SETTINGS: FlashRegionSettings; +} + +pub struct FlashRegionSettings { + pub base: usize, + pub size: usize, + pub erase_size: usize, + pub write_size: usize, + pub erase_value: u8, }