aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchemicstry <[email protected]>2022-07-14 20:58:01 +0300
committerchemicstry <[email protected]>2022-07-14 20:58:01 +0300
commit5a265661bb432de4d91a50f6250afde696b7f0f3 (patch)
treebc5ea99d2c47572e9745cb89bc7663757e9cd6ee
parent039acda3a8b9549a6056aafdc4344ea4c76b9f60 (diff)
Fix erasing across banks
-rw-r--r--embassy-stm32/src/flash/f4.rs64
-rw-r--r--examples/stm32f4/src/bin/flash.rs8
2 files changed, 38 insertions, 34 deletions
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index ad71f145c..b8327ce4e 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};
7use crate::flash::Error; 7use crate::flash::Error;
8use crate::pac; 8use crate::pac;
9 9
10// Only available on some devices
11const SECOND_BANK_OFFSET: usize = FLASH_SIZE / 2;
12const SECOND_BANK_SECTOR_START: u32 = 12; 10const SECOND_BANK_SECTOR_START: u32 = 12;
13 11
14unsafe fn is_dual_bank() -> bool { 12unsafe fn is_dual_bank() -> bool {
@@ -68,44 +66,52 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error
68 ret 66 ret
69} 67}
70 68
71unsafe fn get_sector(addr: u32) -> u8 { 69struct FlashSector {
70 index: u8,
71 size: u32,
72}
73
74fn get_sector(addr: u32, dual_bank: bool) -> FlashSector {
72 let offset = addr - FLASH_BASE as u32; 75 let offset = addr - FLASH_BASE as u32;
73 76
74 let sector = if is_dual_bank() { 77 let bank_size = match dual_bank {
75 let bank = offset / SECOND_BANK_OFFSET as u32; 78 true => FLASH_SIZE / 2,
76 let offset_in_bank = offset % SECOND_BANK_OFFSET as u32; 79 false => FLASH_SIZE,
80 } as u32;
77 81
78 let sector_in_bank = if offset_in_bank >= ERASE_SIZE as u32 / 2 { 82 let bank = offset / bank_size;
79 4 + offset_in_bank / ERASE_SIZE as u32 83 let offset_in_bank = offset % bank_size;
80 } else {
81 offset_in_bank / (ERASE_SIZE as u32 / 8)
82 };
83 84
84 if bank == 1 { 85 let index_in_bank = if offset_in_bank >= ERASE_SIZE as u32 / 2 {
85 SECOND_BANK_SECTOR_START + sector_in_bank 86 4 + offset_in_bank / ERASE_SIZE as u32
86 } else {
87 sector_in_bank
88 }
89 } else { 87 } else {
90 if offset >= ERASE_SIZE as u32 / 2 { 88 offset_in_bank / (ERASE_SIZE as u32 / 8)
91 4 + offset / ERASE_SIZE as u32
92 } else {
93 offset / (ERASE_SIZE as u32 / 8)
94 }
95 }; 89 };
96 90
97 sector as u8 91 // First 4 sectors are 16KB, then one 64KB, and rest are 128KB
92 let size = match index_in_bank {
93 0..=3 => 16 * 1024,
94 4 => 64 * 1024,
95 _ => 128 * 1024,
96 };
97
98 let index = if bank == 1 {
99 SECOND_BANK_SECTOR_START + index_in_bank
100 } else {
101 index_in_bank
102 } as u8;
103
104 FlashSector { index, size }
98} 105}
99 106
100pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> { 107pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> {
101 let start_sector = get_sector(from); 108 let mut addr = from;
102 let end_sector = get_sector(to - 1); // end range is exclusive 109 let dual_bank = is_dual_bank();
103 110
104 for sector in start_sector..=end_sector { 111 while addr < to {
105 let ret = erase_sector(sector as u8); 112 let sector = get_sector(addr, dual_bank);
106 if ret.is_err() { 113 erase_sector(sector.index)?;
107 return ret; 114 addr += sector.size;
108 }
109 } 115 }
110 116
111 Ok(()) 117 Ok(())
diff --git a/examples/stm32f4/src/bin/flash.rs b/examples/stm32f4/src/bin/flash.rs
index ad45df825..265072aea 100644
--- a/examples/stm32f4/src/bin/flash.rs
+++ b/examples/stm32f4/src/bin/flash.rs
@@ -7,6 +7,7 @@ use embassy::executor::Spawner;
7use embassy::time::{Duration, Timer}; 7use embassy::time::{Duration, Timer};
8use embassy_stm32::flash::Flash; 8use embassy_stm32::flash::Flash;
9use embassy_stm32::Peripherals; 9use embassy_stm32::Peripherals;
10use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
10use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
11 12
12#[embassy::main] 13#[embassy::main]
@@ -18,11 +19,8 @@ async fn main(_spawner: Spawner, p: Peripherals) {
18 // Sector 5 19 // Sector 5
19 test_flash(&mut f, 128 * 1024, 128 * 1024); 20 test_flash(&mut f, 128 * 1024, 128 * 1024);
20 21
21 // Sector 11, last in bank 1 22 // Sectors 11..=16, across banks (128K, 16K, 16K, 16K, 16K, 64K)
22 test_flash(&mut f, (1024 - 128) * 1024, 128 * 1024); 23 test_flash(&mut f, (1024 - 128) * 1024, 256 * 1024);
23
24 // Sectors 12..=16, start of bank 2 (16K, 16K, 16K, 16K, 64K)
25 test_flash(&mut f, 1024 * 1024, 128 * 1024);
26 24
27 // Sectors 23, last in bank 2 25 // Sectors 23, last in bank 2
28 test_flash(&mut f, (2048 - 128) * 1024, 128 * 1024); 26 test_flash(&mut f, (2048 - 128) * 1024, 128 * 1024);