diff options
| author | Rasmus Melchior Jacobsen <[email protected]> | 2023-03-25 05:59:40 +0100 |
|---|---|---|
| committer | Rasmus Melchior Jacobsen <[email protected]> | 2023-03-25 05:59:40 +0100 |
| commit | 6c73b23f384b4814ad9d13e8d108ef71464f72af (patch) | |
| tree | 257f6e208f4e9b7eb67a0f746597f02ef7e522d7 | |
| parent | 6b44027eab273d1589eb289044d1bd4d172477f6 (diff) | |
Align F4 family
| -rw-r--r-- | embassy-stm32/src/flash/f4.rs | 70 |
1 files changed, 19 insertions, 51 deletions
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 9e23a8adf..d739c46b6 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs | |||
| @@ -1,12 +1,16 @@ | |||
| 1 | use core::convert::TryInto; | 1 | use core::convert::TryInto; |
| 2 | use core::mem::size_of; | ||
| 2 | use core::ptr::write_volatile; | 3 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, Ordering}; | 4 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 5 | ||
| 5 | use super::{ERASE_SIZE, FLASH_BASE, FLASH_SIZE}; | 6 | use embassy_hal_common::stm32::flash::f4::{get_sector, SECOND_BANK_SECTOR_OFFSET}; |
| 7 | |||
| 8 | use super::{FlashRegion, FLASH_SIZE, MAINC}; | ||
| 6 | use crate::flash::Error; | 9 | use crate::flash::Error; |
| 7 | use crate::pac; | 10 | use crate::pac; |
| 8 | 11 | ||
| 9 | const SECOND_BANK_SECTOR_START: u32 = 12; | 12 | pub(crate) const MAX_WRITE_SIZE: usize = MAINC::WRITE_SIZE; |
| 13 | pub(crate) const MAX_ERASE_SIZE: usize = MAINC::ERASE_SIZE; | ||
| 10 | 14 | ||
| 11 | unsafe fn is_dual_bank() -> bool { | 15 | unsafe fn is_dual_bank() -> bool { |
| 12 | match FLASH_SIZE / 1024 { | 16 | match FLASH_SIZE / 1024 { |
| @@ -34,7 +38,7 @@ pub(crate) unsafe fn unlock() { | |||
| 34 | pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB)); | 38 | pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB)); |
| 35 | } | 39 | } |
| 36 | 40 | ||
| 37 | pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error> { | 41 | pub(crate) unsafe fn blocking_write(first_address: u32, buf: &[u8]) -> Result<(), Error> { |
| 38 | pac::FLASH.cr().write(|w| { | 42 | pac::FLASH.cr().write(|w| { |
| 39 | w.set_pg(true); | 43 | w.set_pg(true); |
| 40 | w.set_psize(pac::flash::vals::Psize::PSIZE32); | 44 | w.set_psize(pac::flash::vals::Psize::PSIZE32); |
| @@ -42,10 +46,12 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error | |||
| 42 | 46 | ||
| 43 | let ret = { | 47 | let ret = { |
| 44 | let mut ret: Result<(), Error> = Ok(()); | 48 | let mut ret: Result<(), Error> = Ok(()); |
| 45 | let mut offset = offset; | 49 | let mut offset = first_address; |
| 46 | for chunk in buf.chunks(super::WRITE_SIZE) { | 50 | for chunk in buf.chunks(MAX_WRITE_SIZE) { |
| 47 | for val in chunk.chunks(4) { | 51 | let vals = chunk.chunks_exact(size_of::<u32>()); |
| 48 | write_volatile(offset as *mut u32, u32::from_le_bytes(val[0..4].try_into().unwrap())); | 52 | assert!(vals.remainder().is_empty()); |
| 53 | for val in vals { | ||
| 54 | write_volatile(offset as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | ||
| 49 | offset += val.len() as u32; | 55 | offset += val.len() as u32; |
| 50 | 56 | ||
| 51 | // prevents parallelism errors | 57 | // prevents parallelism errors |
| @@ -65,50 +71,12 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error | |||
| 65 | ret | 71 | ret |
| 66 | } | 72 | } |
| 67 | 73 | ||
| 68 | struct FlashSector { | 74 | pub(crate) unsafe fn blocking_erase(from_address: u32, to_address: u32) -> Result<(), Error> { |
| 69 | index: u8, | 75 | let mut addr = from_address; |
| 70 | size: u32, | ||
| 71 | } | ||
| 72 | |||
| 73 | fn get_sector(addr: u32, dual_bank: bool) -> FlashSector { | ||
| 74 | let offset = addr - FLASH_BASE as u32; | ||
| 75 | |||
| 76 | let bank_size = match dual_bank { | ||
| 77 | true => FLASH_SIZE / 2, | ||
| 78 | false => FLASH_SIZE, | ||
| 79 | } as u32; | ||
| 80 | |||
| 81 | let bank = offset / bank_size; | ||
| 82 | let offset_in_bank = offset % bank_size; | ||
| 83 | |||
| 84 | let index_in_bank = if offset_in_bank >= ERASE_SIZE as u32 / 2 { | ||
| 85 | 4 + offset_in_bank / ERASE_SIZE as u32 | ||
| 86 | } else { | ||
| 87 | offset_in_bank / (ERASE_SIZE as u32 / 8) | ||
| 88 | }; | ||
| 89 | |||
| 90 | // First 4 sectors are 16KB, then one 64KB, and rest are 128KB | ||
| 91 | let size = match index_in_bank { | ||
| 92 | 0..=3 => 16 * 1024, | ||
| 93 | 4 => 64 * 1024, | ||
| 94 | _ => 128 * 1024, | ||
| 95 | }; | ||
| 96 | |||
| 97 | let index = if bank == 1 { | ||
| 98 | SECOND_BANK_SECTOR_START + index_in_bank | ||
| 99 | } else { | ||
| 100 | index_in_bank | ||
| 101 | } as u8; | ||
| 102 | |||
| 103 | FlashSector { index, size } | ||
| 104 | } | ||
| 105 | |||
| 106 | pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> { | ||
| 107 | let mut addr = from; | ||
| 108 | let dual_bank = is_dual_bank(); | 76 | let dual_bank = is_dual_bank(); |
| 109 | 77 | ||
| 110 | while addr < to { | 78 | while addr < to_address { |
| 111 | let sector = get_sector(addr, dual_bank); | 79 | let sector = get_sector(addr, dual_bank, FLASH_SIZE as u32); |
| 112 | erase_sector(sector.index)?; | 80 | erase_sector(sector.index)?; |
| 113 | addr += sector.size; | 81 | addr += sector.size; |
| 114 | } | 82 | } |
| @@ -117,8 +85,8 @@ pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> { | |||
| 117 | } | 85 | } |
| 118 | 86 | ||
| 119 | unsafe fn erase_sector(sector: u8) -> Result<(), Error> { | 87 | unsafe fn erase_sector(sector: u8) -> Result<(), Error> { |
| 120 | let bank = sector / SECOND_BANK_SECTOR_START as u8; | 88 | let bank = sector / SECOND_BANK_SECTOR_OFFSET as u8; |
| 121 | let snb = (bank << 4) + (sector % SECOND_BANK_SECTOR_START as u8); | 89 | let snb = (bank << 4) + (sector % SECOND_BANK_SECTOR_OFFSET as u8); |
| 122 | 90 | ||
| 123 | trace!("Erasing sector: {}", sector); | 91 | trace!("Erasing sector: {}", sector); |
| 124 | 92 | ||
