aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/flash/h7.rs41
1 files changed, 19 insertions, 22 deletions
diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs
index 7de95ac11..6ab8e7b74 100644
--- a/embassy-stm32/src/flash/h7.rs
+++ b/embassy-stm32/src/flash/h7.rs
@@ -1,13 +1,19 @@
1use core::convert::TryInto; 1use core::convert::TryInto;
2use core::mem::size_of;
2use core::ptr::write_volatile; 3use core::ptr::write_volatile;
3 4
5use super::{FlashRegion, FLASH_SIZE};
4use crate::flash::Error; 6use crate::flash::Error;
5use crate::pac; 7use crate::pac;
6 8
9const WRITE_SIZE: usize = super::BANK1::WRITE_SIZE;
10const ERASE_SIZE: usize = super::BANK1::ERASE_SIZE;
11pub(crate) const MAX_WRITE_SIZE: usize = WRITE_SIZE;
12pub(crate) const MAX_ERASE_SIZE: usize = ERASE_SIZE;
7const SECOND_BANK_OFFSET: usize = 0x0010_0000; 13const SECOND_BANK_OFFSET: usize = 0x0010_0000;
8 14
9const fn is_dual_bank() -> bool { 15const fn is_dual_bank() -> bool {
10 super::FLASH_SIZE / 2 > super::ERASE_SIZE 16 FLASH_SIZE / 2 > ERASE_SIZE
11} 17}
12 18
13pub(crate) unsafe fn lock() { 19pub(crate) unsafe fn lock() {
@@ -27,8 +33,8 @@ pub(crate) unsafe fn unlock() {
27 } 33 }
28} 34}
29 35
30pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error> { 36pub(crate) unsafe fn blocking_write(first_address: u32, buf: &[u8]) -> Result<(), Error> {
31 let bank = if !is_dual_bank() || (offset - super::FLASH_BASE as u32) < SECOND_BANK_OFFSET as u32 { 37 let bank = if !is_dual_bank() || (first_address - super::FLASH_BASE as u32) < SECOND_BANK_OFFSET as u32 {
32 pac::FLASH.bank(0) 38 pac::FLASH.bank(0)
33 } else { 39 } else {
34 pac::FLASH.bank(1) 40 pac::FLASH.bank(1)
@@ -45,12 +51,13 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error
45 51
46 let ret = { 52 let ret = {
47 let mut ret: Result<(), Error> = Ok(()); 53 let mut ret: Result<(), Error> = Ok(());
48 let mut offset = offset; 54 let mut address = first_address;
49 'outer: for chunk in buf.chunks(super::WRITE_SIZE) { 55 'outer: for chunk in buf.chunks(WRITE_SIZE) {
50 for val in chunk.chunks(4) { 56 let vals = chunk.chunks_exact(size_of::<u32>());
51 trace!("Writing at {:x}", offset); 57 assert!(vals.remainder().is_empty());
52 write_volatile(offset as *mut u32, u32::from_le_bytes(val[0..4].try_into().unwrap())); 58 for val in vals {
53 offset += val.len() as u32; 59 write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap()));
60 address += val.len() as u32;
54 61
55 ret = blocking_wait_ready(bank); 62 ret = blocking_wait_ready(bank);
56 bank.sr().modify(|w| { 63 bank.sr().modify(|w| {
@@ -76,20 +83,10 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error
76} 83}
77 84
78pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> { 85pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> {
79 let from = from - super::FLASH_BASE as u32; 86 let start_sector = (from - super::FLASH_BASE as u32) / ERASE_SIZE as u32;
80 let to = to - super::FLASH_BASE as u32; 87 let end_sector = (to - super::FLASH_BASE as u32) / ERASE_SIZE as u32;
81 88
82 let (start, end) = if to <= super::FLASH_SIZE as u32 { 89 for sector in start_sector..end_sector {
83 let start_sector = from / super::ERASE_SIZE as u32;
84 let end_sector = to / super::ERASE_SIZE as u32;
85 (start_sector, end_sector)
86 } else {
87 error!("Attempting to write outside of defined sectors {:x} {:x}", from, to);
88 return Err(Error::Unaligned);
89 };
90
91 trace!("Erasing sectors from {} to {}", start, end);
92 for sector in start..end {
93 let bank = if sector >= 8 { 1 } else { 0 }; 90 let bank = if sector >= 8 { 1 } else { 0 };
94 let ret = erase_sector(pac::FLASH.bank(bank), (sector % 8) as u8); 91 let ret = erase_sector(pac::FLASH.bank(bank), (sector % 8) as u8);
95 if ret.is_err() { 92 if ret.is_err() {