aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/flash/f7.rs
diff options
context:
space:
mode:
authorRasmus Melchior Jacobsen <[email protected]>2023-03-25 16:04:45 +0100
committerRasmus Melchior Jacobsen <[email protected]>2023-03-25 16:04:45 +0100
commitbc69eb596e2496a5eb0cf1252ada12f2710aaff2 (patch)
treed2a4c233d439cba49e2512fce076155b30d20d3c /embassy-stm32/src/flash/f7.rs
parent245147634bfbdcd325eea20be19286708bb29c9f (diff)
Add is_eraseable_range and split write into consecutive parts
Diffstat (limited to 'embassy-stm32/src/flash/f7.rs')
-rw-r--r--embassy-stm32/src/flash/f7.rs70
1 files changed, 34 insertions, 36 deletions
diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs
index 8b8076e0c..16b684580 100644
--- a/embassy-stm32/src/flash/f7.rs
+++ b/embassy-stm32/src/flash/f7.rs
@@ -1,17 +1,13 @@
1use core::convert::TryInto; 1use core::convert::TryInto;
2use core::mem::size_of;
3use core::ptr::write_volatile; 2use core::ptr::write_volatile;
4use core::sync::atomic::{fence, Ordering}; 3use core::sync::atomic::{fence, Ordering};
5 4
6use embassy_hal_common::stm32::flash::f7::get_sector; 5use embassy_hal_common::stm32::flash::f7::get_sector;
7 6
8use super::FlashRegion; 7use super::WRITE_SIZE;
9use crate::flash::Error; 8use crate::flash::Error;
10use crate::pac; 9use crate::pac;
11 10
12pub(crate) const MAX_WRITE_SIZE: usize = super::BANK1_REGION3::WRITE_SIZE;
13pub(crate) const MAX_ERASE_SIZE: usize = super::BANK1_REGION3::ERASE_SIZE;
14
15pub(crate) unsafe fn lock() { 11pub(crate) unsafe fn lock() {
16 pac::FLASH.cr().modify(|w| w.set_lock(true)); 12 pac::FLASH.cr().modify(|w| w.set_lock(true));
17} 13}
@@ -21,49 +17,51 @@ pub(crate) unsafe fn unlock() {
21 pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB)); 17 pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB));
22} 18}
23 19
24pub(crate) unsafe fn blocking_write(first_address: u32, buf: &[u8]) -> Result<(), Error> { 20pub(crate) unsafe fn begin_write() {
21 assert_eq!(0, WRITE_SIZE % 4);
22
25 pac::FLASH.cr().write(|w| { 23 pac::FLASH.cr().write(|w| {
26 w.set_pg(true); 24 w.set_pg(true);
27 w.set_psize(pac::flash::vals::Psize::PSIZE32); 25 w.set_psize(pac::flash::vals::Psize::PSIZE32);
28 }); 26 });
27}
29 28
30 let ret = { 29pub(crate) unsafe fn end_write() {
31 let mut ret: Result<(), Error> = Ok(()); 30 pac::FLASH.cr().write(|w| w.set_pg(false));
32 let mut address = first_address; 31}
33 for chunk in buf.chunks(MAX_WRITE_SIZE) {
34 let vals = chunk.chunks_exact(size_of::<u32>());
35 assert!(vals.remainder().is_empty());
36 for val in vals {
37 write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap()));
38 address += val.len() as u32;
39
40 // prevents parallelism errors
41 fence(Ordering::SeqCst);
42 }
43 32
44 ret = blocking_wait_ready(); 33pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> {
45 if ret.is_err() { 34 let mut address = start_address;
46 break; 35 for val in buf.chunks(4) {
47 } 36 write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap()));
48 } 37 address += val.len() as u32;
49 ret
50 };
51 38
52 pac::FLASH.cr().write(|w| w.set_pg(false)); 39 // prevents parallelism errors
40 fence(Ordering::SeqCst);
41 }
53 42
54 ret 43 blocking_wait_ready()
55} 44}
56 45
57pub(crate) unsafe fn blocking_erase(from_address: u32, to_address: u32) -> Result<(), Error> { 46pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool {
58 let start_sector = get_sector(from_address); 47 let mut address = start_address;
59 let end_sector = get_sector(to_address); 48 while address < end_address {
60 for sector in start_sector.index..end_sector.index { 49 let sector = get_sector(address);
61 let ret = erase_sector(sector as u8); 50 if sector.start != address {
62 if ret.is_err() { 51 return false;
63 return ret;
64 } 52 }
53 address += sector.size;
65 } 54 }
55 address == end_address
56}
66 57
58pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> {
59 let mut address = start_address;
60 while address < end_address {
61 let sector = get_sector(address);
62 erase_sector(sector.index)?;
63 address += sector.size;
64 }
67 Ok(()) 65 Ok(())
68} 66}
69 67
@@ -106,7 +104,7 @@ pub(crate) unsafe fn clear_all_err() {
106 }); 104 });
107} 105}
108 106
109pub(crate) unsafe fn blocking_wait_ready() -> Result<(), Error> { 107unsafe fn blocking_wait_ready() -> Result<(), Error> {
110 loop { 108 loop {
111 let sr = pac::FLASH.sr().read(); 109 let sr = pac::FLASH.sr().read();
112 110