diff options
| author | chemicstry <[email protected]> | 2022-07-14 19:41:39 +0300 |
|---|---|---|
| committer | chemicstry <[email protected]> | 2022-07-14 19:41:39 +0300 |
| commit | 039acda3a8b9549a6056aafdc4344ea4c76b9f60 (patch) | |
| tree | 296db6c63f322586b224401f9d7dce9f151ad430 | |
| parent | e4cacc3bb812c8870584c513020f0747146c860a (diff) | |
Fix writing to last sector of F4 flash
| -rw-r--r-- | embassy-stm32/src/flash/f4.rs | 6 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/flash.rs | 30 |
2 files changed, 24 insertions, 12 deletions
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index f6dc7e955..ad71f145c 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs | |||
| @@ -99,9 +99,9 @@ unsafe fn get_sector(addr: u32) -> u8 { | |||
| 99 | 99 | ||
| 100 | pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> { | 100 | pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> { |
| 101 | let start_sector = get_sector(from); | 101 | let start_sector = get_sector(from); |
| 102 | let end_sector = get_sector(to); | 102 | let end_sector = get_sector(to - 1); // end range is exclusive |
| 103 | 103 | ||
| 104 | for sector in start_sector..end_sector { | 104 | for sector in start_sector..=end_sector { |
| 105 | let ret = erase_sector(sector as u8); | 105 | let ret = erase_sector(sector as u8); |
| 106 | if ret.is_err() { | 106 | if ret.is_err() { |
| 107 | return ret; | 107 | return ret; |
| @@ -115,6 +115,8 @@ unsafe fn erase_sector(sector: u8) -> Result<(), Error> { | |||
| 115 | let bank = sector / SECOND_BANK_SECTOR_START as u8; | 115 | let bank = sector / SECOND_BANK_SECTOR_START as u8; |
| 116 | let snb = (bank << 4) + (sector % SECOND_BANK_SECTOR_START as u8); | 116 | let snb = (bank << 4) + (sector % SECOND_BANK_SECTOR_START as u8); |
| 117 | 117 | ||
| 118 | trace!("Erasing sector: {}", sector); | ||
| 119 | |||
| 118 | pac::FLASH.cr().modify(|w| { | 120 | pac::FLASH.cr().modify(|w| { |
| 119 | w.set_ser(true); | 121 | w.set_ser(true); |
| 120 | w.set_snb(snb) | 122 | w.set_snb(snb) |
diff --git a/examples/stm32f4/src/bin/flash.rs b/examples/stm32f4/src/bin/flash.rs index b531d6f13..ad45df825 100644 --- a/examples/stm32f4/src/bin/flash.rs +++ b/examples/stm32f4/src/bin/flash.rs | |||
| @@ -7,36 +7,46 @@ use embassy::executor::Spawner; | |||
| 7 | use embassy::time::{Duration, Timer}; | 7 | use embassy::time::{Duration, Timer}; |
| 8 | use embassy_stm32::flash::Flash; | 8 | use embassy_stm32::flash::Flash; |
| 9 | use embassy_stm32::Peripherals; | 9 | use embassy_stm32::Peripherals; |
| 10 | use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 11 | ||
| 13 | #[embassy::main] | 12 | #[embassy::main] |
| 14 | async fn main(_spawner: Spawner, p: Peripherals) { | 13 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 15 | info!("Hello Flash!"); | 14 | info!("Hello Flash!"); |
| 16 | 15 | ||
| 17 | const ADDR: u32 = 0x10_0000; | 16 | let mut f = Flash::unlock(p.FLASH); |
| 18 | 17 | ||
| 19 | // wait a bit before accessing the flash | 18 | // Sector 5 |
| 20 | Timer::after(Duration::from_millis(300)).await; | 19 | test_flash(&mut f, 128 * 1024, 128 * 1024); |
| 21 | 20 | ||
| 22 | let mut f = Flash::unlock(p.FLASH); | 21 | // Sector 11, last in bank 1 |
| 22 | test_flash(&mut f, (1024 - 128) * 1024, 128 * 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 | |||
| 27 | // Sectors 23, last in bank 2 | ||
| 28 | test_flash(&mut f, (2048 - 128) * 1024, 128 * 1024); | ||
| 29 | } | ||
| 30 | |||
| 31 | fn test_flash(f: &mut Flash, offset: u32, size: u32) { | ||
| 32 | info!("Testing offset: {=u32:#X}, size: {=u32:#X}", offset, size); | ||
| 23 | 33 | ||
| 24 | info!("Reading..."); | 34 | info!("Reading..."); |
| 25 | let mut buf = [0u8; 32]; | 35 | let mut buf = [0u8; 32]; |
| 26 | unwrap!(f.read(ADDR, &mut buf)); | 36 | unwrap!(f.read(offset, &mut buf)); |
| 27 | info!("Read: {=[u8]:x}", buf); | 37 | info!("Read: {=[u8]:x}", buf); |
| 28 | 38 | ||
| 29 | info!("Erasing..."); | 39 | info!("Erasing..."); |
| 30 | unwrap!(f.erase(ADDR, ADDR + 128 * 1024)); | 40 | unwrap!(f.erase(offset, offset + size)); |
| 31 | 41 | ||
| 32 | info!("Reading..."); | 42 | info!("Reading..."); |
| 33 | let mut buf = [0u8; 32]; | 43 | let mut buf = [0u8; 32]; |
| 34 | unwrap!(f.read(ADDR, &mut buf)); | 44 | unwrap!(f.read(offset, &mut buf)); |
| 35 | info!("Read after erase: {=[u8]:x}", buf); | 45 | info!("Read after erase: {=[u8]:x}", buf); |
| 36 | 46 | ||
| 37 | info!("Writing..."); | 47 | info!("Writing..."); |
| 38 | unwrap!(f.write( | 48 | unwrap!(f.write( |
| 39 | ADDR, | 49 | offset, |
| 40 | &[ | 50 | &[ |
| 41 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, | 51 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, |
| 42 | 30, 31, 32 | 52 | 30, 31, 32 |
| @@ -45,7 +55,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 45 | 55 | ||
| 46 | info!("Reading..."); | 56 | info!("Reading..."); |
| 47 | let mut buf = [0u8; 32]; | 57 | let mut buf = [0u8; 32]; |
| 48 | unwrap!(f.read(ADDR, &mut buf)); | 58 | unwrap!(f.read(offset, &mut buf)); |
| 49 | info!("Read: {=[u8]:x}", buf); | 59 | info!("Read: {=[u8]:x}", buf); |
| 50 | assert_eq!( | 60 | assert_eq!( |
| 51 | &buf[..], | 61 | &buf[..], |
