aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/flash/common.rs18
-rw-r--r--embassy-stm32/src/flash/f4.rs69
2 files changed, 70 insertions, 17 deletions
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs
index a9bf3c3cd..432c8a43b 100644
--- a/embassy-stm32/src/flash/common.rs
+++ b/embassy-stm32/src/flash/common.rs
@@ -26,11 +26,11 @@ impl<'d> Flash<'d> {
26 } 26 }
27 27
28 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { 28 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
29 unsafe { blocking_write(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes) } 29 unsafe { blocking_write_chunked(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes) }
30 } 30 }
31 31
32 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { 32 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
33 unsafe { blocking_erase(FLASH_BASE as u32, from, to) } 33 unsafe { blocking_erase_sectored(FLASH_BASE as u32, from, to) }
34 } 34 }
35 35
36 pub(crate) fn release(self) -> PeripheralRef<'d, crate::peripherals::FLASH> { 36 pub(crate) fn release(self) -> PeripheralRef<'d, crate::peripherals::FLASH> {
@@ -38,7 +38,7 @@ impl<'d> Flash<'d> {
38 } 38 }
39} 39}
40 40
41fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { 41pub(super) fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
42 if offset + bytes.len() as u32 > size { 42 if offset + bytes.len() as u32 > size {
43 return Err(Error::Size); 43 return Err(Error::Size);
44 } 44 }
@@ -49,7 +49,7 @@ fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<
49 Ok(()) 49 Ok(())
50} 50}
51 51
52unsafe fn blocking_write(base: u32, size: u32, offset: u32, bytes: &[u8]) -> Result<(), Error> { 52pub(super) unsafe fn blocking_write_chunked(base: u32, size: u32, offset: u32, bytes: &[u8]) -> Result<(), Error> {
53 if offset + bytes.len() as u32 > size { 53 if offset + bytes.len() as u32 > size {
54 return Err(Error::Size); 54 return Err(Error::Size);
55 } 55 }
@@ -82,7 +82,7 @@ unsafe fn blocking_write(base: u32, size: u32, offset: u32, bytes: &[u8]) -> Res
82 Ok(()) 82 Ok(())
83} 83}
84 84
85unsafe fn blocking_erase(base: u32, from: u32, to: u32) -> Result<(), Error> { 85pub(super) unsafe fn blocking_erase_sectored(base: u32, from: u32, to: u32) -> Result<(), Error> {
86 let start_address = base + from; 86 let start_address = base + from;
87 let end_address = base + to; 87 let end_address = base + to;
88 let regions = family::get_flash_regions(); 88 let regions = family::get_flash_regions();
@@ -155,11 +155,11 @@ impl FlashRegion {
155 } 155 }
156 156
157 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { 157 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
158 unsafe { blocking_write(self.base, self.size, offset, bytes) } 158 unsafe { blocking_write_chunked(self.base, self.size, offset, bytes) }
159 } 159 }
160 160
161 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { 161 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
162 unsafe { blocking_erase(self.base, from, to) } 162 unsafe { blocking_erase_sectored(self.base, from, to) }
163 } 163 }
164} 164}
165 165
@@ -200,11 +200,11 @@ foreach_flash_region! {
200 } 200 }
201 201
202 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { 202 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
203 unsafe { blocking_write(self.0.base, self.0.size, offset, bytes) } 203 unsafe { blocking_write_chunked(self.0.base, self.0.size, offset, bytes) }
204 } 204 }
205 205
206 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { 206 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
207 unsafe { blocking_erase(self.0.base, from, to) } 207 unsafe { blocking_erase_sectored(self.0.base, from, to) }
208 } 208 }
209 } 209 }
210 210
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index 63293c052..7f1c5f671 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -11,8 +11,11 @@ mod alt_regions {
11 use embassy_hal_common::PeripheralRef; 11 use embassy_hal_common::PeripheralRef;
12 use stm32_metapac::FLASH_SIZE; 12 use stm32_metapac::FLASH_SIZE;
13 13
14 use crate::_generated::flash_regions::{BANK1_REGION1, BANK1_REGION2, BANK1_REGION3}; 14 use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION};
15 use crate::flash::{Bank1Region1, Bank1Region2, Flash, FlashBank, FlashRegion}; 15 use crate::flash::{
16 blocking_erase_sectored, blocking_read, blocking_write_chunked, Bank1Region1, Bank1Region2, Error, Flash,
17 FlashBank, FlashRegion,
18 };
16 use crate::peripherals::FLASH; 19 use crate::peripherals::FLASH;
17 20
18 pub const ALT_BANK1_REGION3: FlashRegion = FlashRegion { 21 pub const ALT_BANK1_REGION3: FlashRegion = FlashRegion {
@@ -45,20 +48,19 @@ mod alt_regions {
45 &ALT_BANK2_REGION3, 48 &ALT_BANK2_REGION3,
46 ]; 49 ];
47 50
48 pub type AltBank1Region1<'d> = Bank1Region1<'d>;
49 pub type AltBank1Region2<'d> = Bank1Region2<'d>;
50 pub struct AltBank1Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 51 pub struct AltBank1Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
51 pub struct AltBank2Region1<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 52 pub struct AltBank2Region1<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
52 pub struct AltBank2Region2<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 53 pub struct AltBank2Region2<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
53 pub struct AltBank2Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 54 pub struct AltBank2Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
54 55
55 pub struct AltFlashLayout<'d> { 56 pub struct AltFlashLayout<'d> {
56 pub bank1_region1: AltBank1Region1<'d>, 57 pub bank1_region1: Bank1Region1<'d>,
57 pub bank1_region2: AltBank1Region2<'d>, 58 pub bank1_region2: Bank1Region2<'d>,
58 pub bank1_region3: AltBank1Region3<'d>, 59 pub bank1_region3: AltBank1Region3<'d>,
59 pub bank2_region1: AltBank2Region1<'d>, 60 pub bank2_region1: AltBank2Region1<'d>,
60 pub bank2_region2: AltBank2Region2<'d>, 61 pub bank2_region2: AltBank2Region2<'d>,
61 pub bank2_region3: AltBank2Region3<'d>, 62 pub bank2_region3: AltBank2Region3<'d>,
63 pub otp_region: OTPRegion<'d>,
62 } 64 }
63 65
64 impl<'d> Flash<'d> { 66 impl<'d> Flash<'d> {
@@ -66,7 +68,7 @@ mod alt_regions {
66 unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) }; 68 unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) };
67 69
68 // SAFETY: We never expose the cloned peripheral references, and their instance is not public. 70 // SAFETY: We never expose the cloned peripheral references, and their instance is not public.
69 // Also, all flash region operations are protected with a cs. 71 // Also, all blocking flash region operations are protected with a cs.
70 let p = self.release(); 72 let p = self.release();
71 AltFlashLayout { 73 AltFlashLayout {
72 bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }), 74 bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }),
@@ -75,15 +77,66 @@ mod alt_regions {
75 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }), 77 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }),
76 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }), 78 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }),
77 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }), 79 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }),
80 otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }),
78 } 81 }
79 } 82 }
80 } 83 }
81 84
85 macro_rules! foreach_altflash_region {
86 ($type_name:ident, $region:ident) => {
87 impl $type_name<'_> {
88 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
89 blocking_read(self.0.base, self.0.size, offset, bytes)
90 }
91
92 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
93 unsafe { blocking_write_chunked(self.0.base, self.0.size, offset, bytes) }
94 }
95
96 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
97 unsafe { blocking_erase_sectored(self.0.base, from, to) }
98 }
99 }
100
101 impl embedded_storage::nor_flash::ErrorType for $type_name<'_> {
102 type Error = Error;
103 }
104
105 impl embedded_storage::nor_flash::ReadNorFlash for $type_name<'_> {
106 const READ_SIZE: usize = 1;
107
108 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
109 self.blocking_read(offset, bytes)
110 }
111
112 fn capacity(&self) -> usize {
113 self.0.size as usize
114 }
115 }
116
117 impl embedded_storage::nor_flash::NorFlash for $type_name<'_> {
118 const WRITE_SIZE: usize = $region.write_size as usize;
119 const ERASE_SIZE: usize = $region.erase_size as usize;
120
121 fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
122 self.blocking_write(offset, bytes)
123 }
124
125 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
126 self.blocking_erase(from, to)
127 }
128 }
129 };
82 } 130 }
131
132 foreach_altflash_region!(AltBank1Region3, ALT_BANK1_REGION3);
133 foreach_altflash_region!(AltBank2Region1, ALT_BANK2_REGION1);
134 foreach_altflash_region!(AltBank2Region2, ALT_BANK2_REGION2);
135 foreach_altflash_region!(AltBank2Region3, ALT_BANK2_REGION3);
83} 136}
84 137
85#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f469, stm32f479))] 138#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f469, stm32f479))]
86pub use alt_regions::{AltFlashLayout, ALT_FLASH_REGIONS}; 139pub use alt_regions::*;
87 140
88#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f469, stm32f479))] 141#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f469, stm32f479))]
89pub fn set_default_layout() { 142pub fn set_default_layout() {