summaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorchemicstry <chemicstry@gmail.com>2022-07-14 20:58:01 +0300
committerchemicstry <chemicstry@gmail.com>2022-07-14 20:58:01 +0300
commit5a265661bb432de4d91a50f6250afde696b7f0f3 (patch)
treebc5ea99d2c47572e9745cb89bc7663757e9cd6ee /embassy-stm32
parent039acda3a8b9549a6056aafdc4344ea4c76b9f60 (diff)
downloadembassy-5a265661bb432de4d91a50f6250afde696b7f0f3.zip
Fix erasing across banks
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/flash/f4.rs64
1 files changed, 35 insertions, 29 deletions
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index ad71f145..b8327ce4 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -7,8 +7,6 @@ use super::{ERASE_SIZE, FLASH_BASE, FLASH_SIZE};
use crate::flash::Error;
use crate::pac;
-// Only available on some devices
-const SECOND_BANK_OFFSET: usize = FLASH_SIZE / 2;
const SECOND_BANK_SECTOR_START: u32 = 12;
unsafe fn is_dual_bank() -> bool {
@@ -68,44 +66,52 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error
ret
}
-unsafe fn get_sector(addr: u32) -> u8 {
+struct FlashSector {
+ index: u8,
+ size: u32,
+}
+
+fn get_sector(addr: u32, dual_bank: bool) -> FlashSector {
let offset = addr - FLASH_BASE as u32;
- let sector = if is_dual_bank() {
- let bank = offset / SECOND_BANK_OFFSET as u32;
- let offset_in_bank = offset % SECOND_BANK_OFFSET as u32;
+ let bank_size = match dual_bank {
+ true => FLASH_SIZE / 2,
+ false => FLASH_SIZE,
+ } as u32;
- let sector_in_bank = if offset_in_bank >= ERASE_SIZE as u32 / 2 {
- 4 + offset_in_bank / ERASE_SIZE as u32
- } else {
- offset_in_bank / (ERASE_SIZE as u32 / 8)
- };
+ let bank = offset / bank_size;
+ let offset_in_bank = offset % bank_size;
- if bank == 1 {
- SECOND_BANK_SECTOR_START + sector_in_bank
- } else {
- sector_in_bank
- }
+ let index_in_bank = if offset_in_bank >= ERASE_SIZE as u32 / 2 {
+ 4 + offset_in_bank / ERASE_SIZE as u32
} else {
- if offset >= ERASE_SIZE as u32 / 2 {
- 4 + offset / ERASE_SIZE as u32
- } else {
- offset / (ERASE_SIZE as u32 / 8)
- }
+ offset_in_bank / (ERASE_SIZE as u32 / 8)
};
- sector as u8
+ // First 4 sectors are 16KB, then one 64KB, and rest are 128KB
+ let size = match index_in_bank {
+ 0..=3 => 16 * 1024,
+ 4 => 64 * 1024,
+ _ => 128 * 1024,
+ };
+
+ let index = if bank == 1 {
+ SECOND_BANK_SECTOR_START + index_in_bank
+ } else {
+ index_in_bank
+ } as u8;
+
+ FlashSector { index, size }
}
pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> {
- let start_sector = get_sector(from);
- let end_sector = get_sector(to - 1); // end range is exclusive
+ let mut addr = from;
+ let dual_bank = is_dual_bank();
- for sector in start_sector..=end_sector {
- let ret = erase_sector(sector as u8);
- if ret.is_err() {
- return ret;
- }
+ while addr < to {
+ let sector = get_sector(addr, dual_bank);
+ erase_sector(sector.index)?;
+ addr += sector.size;
}
Ok(())