aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Melchior Jacobsen <[email protected]>2023-03-25 05:59:40 +0100
committerRasmus Melchior Jacobsen <[email protected]>2023-03-25 05:59:40 +0100
commit6c73b23f384b4814ad9d13e8d108ef71464f72af (patch)
tree257f6e208f4e9b7eb67a0f746597f02ef7e522d7
parent6b44027eab273d1589eb289044d1bd4d172477f6 (diff)
Align F4 family
-rw-r--r--embassy-stm32/src/flash/f4.rs70
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 @@
1use core::convert::TryInto; 1use core::convert::TryInto;
2use core::mem::size_of;
2use core::ptr::write_volatile; 3use core::ptr::write_volatile;
3use core::sync::atomic::{fence, Ordering}; 4use core::sync::atomic::{fence, Ordering};
4 5
5use super::{ERASE_SIZE, FLASH_BASE, FLASH_SIZE}; 6use embassy_hal_common::stm32::flash::f4::{get_sector, SECOND_BANK_SECTOR_OFFSET};
7
8use super::{FlashRegion, FLASH_SIZE, MAINC};
6use crate::flash::Error; 9use crate::flash::Error;
7use crate::pac; 10use crate::pac;
8 11
9const SECOND_BANK_SECTOR_START: u32 = 12; 12pub(crate) const MAX_WRITE_SIZE: usize = MAINC::WRITE_SIZE;
13pub(crate) const MAX_ERASE_SIZE: usize = MAINC::ERASE_SIZE;
10 14
11unsafe fn is_dual_bank() -> bool { 15unsafe 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
37pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error> { 41pub(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
68struct FlashSector { 74pub(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
73fn 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
106pub(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
119unsafe fn erase_sector(sector: u8) -> Result<(), Error> { 87unsafe 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