diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-07-15 06:19:05 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-07-15 06:19:05 +0000 |
| commit | 9d388d357aefcb87677a70716e727bc91933191a (patch) | |
| tree | 772ab06aa35aadd14b37f52baf62e97ac4ead287 /examples | |
| parent | 5318fe404bed68a38a1d81eb7359ebc38e6fad15 (diff) | |
| parent | 0b70cc554ed7fef7dc1c720c3d5e634039dd729a (diff) | |
Merge #866
866: F4 flash fixes r=Dirbaio a=chemicstry
This discontinuous flash sector layout is too cursed and I left some mistakes in last PR. Erasing last sector did not work and it wasn't possible to erase between memory banks for 1MB dual-bank devices. So I changed the erase function to iterate over memory addresses (which is continuous) instead of sector numbers.
It should also be possible to implement erase across memory banks for H7, but it requires special handling for write too. I don't have an H7 to test now so left it as is.
I wasn't sure how to add tests to `embassy-stm32` and it seems that there are none, except for `subghz`, but no test runner? Anyway, I tested the `get_sector` on playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=13b59339fe6c70a3249e6183e81f869e
Also fixed erase alignment requirements on `Flash::blocking_erase()`, as it previously only checked alignment on size, but not on offsets.
P.S. the diff is a bit messed up, I recommend looking at files directly
Co-authored-by: chemicstry <[email protected]>
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/stm32f4/src/bin/flash.rs | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/examples/stm32f4/src/bin/flash.rs b/examples/stm32f4/src/bin/flash.rs index b531d6f13..13fd2c90b 100644 --- a/examples/stm32f4/src/bin/flash.rs +++ b/examples/stm32f4/src/bin/flash.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::{info, unwrap}; | 5 | use defmt::{info, unwrap}; |
| 6 | use embassy::executor::Spawner; | 6 | use embassy::executor::Spawner; |
| 7 | use embassy::time::{Duration, Timer}; | ||
| 8 | use embassy_stm32::flash::Flash; | 7 | use embassy_stm32::flash::Flash; |
| 9 | use embassy_stm32::Peripherals; | 8 | use embassy_stm32::Peripherals; |
| 10 | use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; | 9 | use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; |
| @@ -14,29 +13,37 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 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 | // Sectors 11..=16, across banks (128K, 16K, 16K, 16K, 16K, 64K) |
| 22 | test_flash(&mut f, (1024 - 128) * 1024, 256 * 1024); | ||
| 23 | |||
| 24 | // Sectors 23, last in bank 2 | ||
| 25 | test_flash(&mut f, (2048 - 128) * 1024, 128 * 1024); | ||
| 26 | } | ||
| 27 | |||
| 28 | fn test_flash(f: &mut Flash, offset: u32, size: u32) { | ||
| 29 | info!("Testing offset: {=u32:#X}, size: {=u32:#X}", offset, size); | ||
| 23 | 30 | ||
| 24 | info!("Reading..."); | 31 | info!("Reading..."); |
| 25 | let mut buf = [0u8; 32]; | 32 | let mut buf = [0u8; 32]; |
| 26 | unwrap!(f.read(ADDR, &mut buf)); | 33 | unwrap!(f.read(offset, &mut buf)); |
| 27 | info!("Read: {=[u8]:x}", buf); | 34 | info!("Read: {=[u8]:x}", buf); |
| 28 | 35 | ||
| 29 | info!("Erasing..."); | 36 | info!("Erasing..."); |
| 30 | unwrap!(f.erase(ADDR, ADDR + 128 * 1024)); | 37 | unwrap!(f.erase(offset, offset + size)); |
| 31 | 38 | ||
| 32 | info!("Reading..."); | 39 | info!("Reading..."); |
| 33 | let mut buf = [0u8; 32]; | 40 | let mut buf = [0u8; 32]; |
| 34 | unwrap!(f.read(ADDR, &mut buf)); | 41 | unwrap!(f.read(offset, &mut buf)); |
| 35 | info!("Read after erase: {=[u8]:x}", buf); | 42 | info!("Read after erase: {=[u8]:x}", buf); |
| 36 | 43 | ||
| 37 | info!("Writing..."); | 44 | info!("Writing..."); |
| 38 | unwrap!(f.write( | 45 | unwrap!(f.write( |
| 39 | ADDR, | 46 | offset, |
| 40 | &[ | 47 | &[ |
| 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, | 48 | 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 | 49 | 30, 31, 32 |
| @@ -45,7 +52,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 45 | 52 | ||
| 46 | info!("Reading..."); | 53 | info!("Reading..."); |
| 47 | let mut buf = [0u8; 32]; | 54 | let mut buf = [0u8; 32]; |
| 48 | unwrap!(f.read(ADDR, &mut buf)); | 55 | unwrap!(f.read(offset, &mut buf)); |
| 49 | info!("Read: {=[u8]:x}", buf); | 56 | info!("Read: {=[u8]:x}", buf); |
| 50 | assert_eq!( | 57 | assert_eq!( |
| 51 | &buf[..], | 58 | &buf[..], |
