aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/flash/f4.rs
diff options
context:
space:
mode:
authorRasmus Melchior Jacobsen <[email protected]>2023-05-24 17:24:28 +0200
committerRasmus Melchior Jacobsen <[email protected]>2023-05-25 20:07:42 +0200
commit44b6494ab7ec3e742aa9f82a8ca9ebdfc23ebbba (patch)
treeb1266b7f9f0488017098bcca3f7ba3fb9e93603e /embassy-stm32/src/flash/f4.rs
parent6df62397048778ce521c14b21b4aced7c22567c2 (diff)
Let FlashLayout and FlashRegion depends on a Blocking/Async mode generic
Diffstat (limited to 'embassy-stm32/src/flash/f4.rs')
-rw-r--r--embassy-stm32/src/flash/f4.rs114
1 files changed, 50 insertions, 64 deletions
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index 084bbdc6e..d50a35b41 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -11,6 +11,8 @@ use crate::pac;
11 11
12#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f469, stm32f479))] 12#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f469, stm32f479))]
13mod alt_regions { 13mod alt_regions {
14 use core::marker::PhantomData;
15
14 use embassy_hal_common::PeripheralRef; 16 use embassy_hal_common::PeripheralRef;
15 use stm32_metapac::FLASH_SIZE; 17 use stm32_metapac::FLASH_SIZE;
16 18
@@ -18,8 +20,7 @@ mod alt_regions {
18 #[cfg(feature = "nightly")] 20 #[cfg(feature = "nightly")]
19 use crate::flash::asynch; 21 use crate::flash::asynch;
20 use crate::flash::{ 22 use crate::flash::{
21 common, Bank1Region1, Bank1Region2, BlockingFlashRegion, Error, Flash, FlashBank, FlashRegion, READ_SIZE, 23 common, Async, Bank1Region1, Bank1Region2, Blocking, Error, Flash, FlashBank, FlashRegion, READ_SIZE,
22 REGION_ACCESS,
23 }; 24 };
24 use crate::peripherals::FLASH; 25 use crate::peripherals::FLASH;
25 26
@@ -53,101 +54,86 @@ mod alt_regions {
53 &ALT_BANK2_REGION3, 54 &ALT_BANK2_REGION3,
54 ]; 55 ];
55 56
56 pub struct AltBank1Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 57 pub struct AltBank1Region3<'d, MODE>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>);
57 pub struct AltBank2Region1<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 58 pub struct AltBank2Region1<'d, MODE>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>);
58 pub struct AltBank2Region2<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 59 pub struct AltBank2Region2<'d, MODE>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>);
59 pub struct AltBank2Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); 60 pub struct AltBank2Region3<'d, MODE>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>);
60 61
61 pub type BlockingAltBank1Region3<'d> = 62 pub struct AltFlashLayout<'d, MODE> {
62 BlockingFlashRegion<'d, { ALT_BANK1_REGION3.write_size }, { ALT_BANK1_REGION3.erase_size }>; 63 pub bank1_region1: Bank1Region1<'d, MODE>,
63 pub type BlockingAltBank2Region1<'d> = 64 pub bank1_region2: Bank1Region2<'d, MODE>,
64 BlockingFlashRegion<'d, { ALT_BANK2_REGION1.write_size }, { ALT_BANK2_REGION1.erase_size }>; 65 pub bank1_region3: AltBank1Region3<'d, MODE>,
65 pub type BlockingAltBank2Region2<'d> = 66 pub bank2_region1: AltBank2Region1<'d, MODE>,
66 BlockingFlashRegion<'d, { ALT_BANK2_REGION2.write_size }, { ALT_BANK2_REGION2.erase_size }>; 67 pub bank2_region2: AltBank2Region2<'d, MODE>,
67 pub type BlockingAltBank2Region3<'d> = 68 pub bank2_region3: AltBank2Region3<'d, MODE>,
68 BlockingFlashRegion<'d, { ALT_BANK2_REGION3.write_size }, { ALT_BANK2_REGION3.erase_size }>; 69 pub otp_region: OTPRegion<'d, MODE>,
69
70 pub struct AltFlashLayout<'d> {
71 pub bank1_region1: Bank1Region1<'d>,
72 pub bank1_region2: Bank1Region2<'d>,
73 pub bank1_region3: AltBank1Region3<'d>,
74 pub bank2_region1: AltBank2Region1<'d>,
75 pub bank2_region2: AltBank2Region2<'d>,
76 pub bank2_region3: AltBank2Region3<'d>,
77 pub otp_region: OTPRegion<'d>,
78 } 70 }
79 71
80 impl<'d> Flash<'d> { 72 impl<'d> Flash<'d> {
81 pub fn into_alt_regions(self) -> AltFlashLayout<'d> { 73 pub fn into_alt_regions(self) -> AltFlashLayout<'d, Async> {
74 unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) };
75
76 // SAFETY: We never expose the cloned peripheral references, and their instance is not public.
77 // Also, all async flash region operations are protected with a mutex.
78 let p = self.inner;
79 AltFlashLayout {
80 bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }, PhantomData),
81 bank1_region2: Bank1Region2(&BANK1_REGION2, unsafe { p.clone_unchecked() }, PhantomData),
82 bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3, unsafe { p.clone_unchecked() }, PhantomData),
83 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData),
84 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData),
85 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData),
86 otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }, PhantomData),
87 }
88 }
89
90 pub fn into_alt_blocking_regions(self) -> AltFlashLayout<'d, Blocking> {
82 unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) }; 91 unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) };
83 92
84 // SAFETY: We never expose the cloned peripheral references, and their instance is not public. 93 // SAFETY: We never expose the cloned peripheral references, and their instance is not public.
85 // Also, all blocking flash region operations are protected with a cs. 94 // Also, all blocking flash region operations are protected with a cs.
86 let p = self.inner; 95 let p = self.inner;
87 AltFlashLayout { 96 AltFlashLayout {
88 bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }), 97 bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }, PhantomData),
89 bank1_region2: Bank1Region2(&BANK1_REGION2, unsafe { p.clone_unchecked() }), 98 bank1_region2: Bank1Region2(&BANK1_REGION2, unsafe { p.clone_unchecked() }, PhantomData),
90 bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3, unsafe { p.clone_unchecked() }), 99 bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3, unsafe { p.clone_unchecked() }, PhantomData),
91 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }), 100 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData),
92 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }), 101 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData),
93 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }), 102 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData),
94 otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }), 103 otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }, PhantomData),
95 } 104 }
96 } 105 }
97 } 106 }
98 107
99 macro_rules! foreach_altflash_region { 108 macro_rules! foreach_altflash_region {
100 ($type_name:ident, $region:ident) => { 109 ($type_name:ident, $region:ident) => {
101 impl $type_name<'_> { 110 #[cfg(feature = "nightly")]
102 pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { 111 impl $type_name<'_, Async> {
112 pub async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
103 common::read_blocking(self.0.base, self.0.size, offset, bytes) 113 common::read_blocking(self.0.base, self.0.size, offset, bytes)
104 } 114 }
105 115
106 #[cfg(feature = "nightly")]
107 pub async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { 116 pub async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
108 let _guard = REGION_ACCESS.lock().await; 117 let _guard = asynch::REGION_ACCESS.lock().await;
109 unsafe { asynch::write_chunked(self.0.base, self.0.size, offset, bytes).await } 118 unsafe { asynch::write_chunked(self.0.base, self.0.size, offset, bytes).await }
110 } 119 }
111 120
112 #[cfg(feature = "nightly")]
113 pub async fn erase(&mut self, from: u32, to: u32) -> Result<(), Error> { 121 pub async fn erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
114 let _guard = REGION_ACCESS.lock().await; 122 let _guard = asynch::REGION_ACCESS.lock().await;
115 unsafe { asynch::erase_sectored(self.0.base, from, to).await } 123 unsafe { asynch::erase_sectored(self.0.base, from, to).await }
116 } 124 }
117
118 pub fn try_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
119 let _guard = REGION_ACCESS.try_lock().map_err(|_| Error::TryLockError)?;
120 unsafe { common::write_chunked_blocking(self.0.base, self.0.size, offset, bytes) }
121 }
122
123 pub fn try_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
124 let _guard = REGION_ACCESS.try_lock().map_err(|_| Error::TryLockError)?;
125 unsafe { common::erase_sectored_blocking(self.0.base, from, to) }
126 }
127 } 125 }
128 126
129 impl embedded_storage::nor_flash::ErrorType for $type_name<'_> { 127 impl embedded_storage::nor_flash::ErrorType for $type_name<'_, Async> {
130 type Error = Error; 128 type Error = Error;
131 } 129 }
132 130
133 impl embedded_storage::nor_flash::ReadNorFlash for $type_name<'_> {
134 const READ_SIZE: usize = READ_SIZE;
135
136 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
137 self.read(offset, bytes)
138 }
139
140 fn capacity(&self) -> usize {
141 self.0.size as usize
142 }
143 }
144
145 #[cfg(feature = "nightly")] 131 #[cfg(feature = "nightly")]
146 impl embedded_storage_async::nor_flash::ReadNorFlash for $type_name<'_> { 132 impl embedded_storage_async::nor_flash::ReadNorFlash for $type_name<'_, Async> {
147 const READ_SIZE: usize = READ_SIZE; 133 const READ_SIZE: usize = READ_SIZE;
148 134
149 async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { 135 async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
150 self.read(offset, bytes) 136 self.read(offset, bytes).await
151 } 137 }
152 138
153 fn capacity(&self) -> usize { 139 fn capacity(&self) -> usize {
@@ -156,7 +142,7 @@ mod alt_regions {
156 } 142 }
157 143
158 #[cfg(feature = "nightly")] 144 #[cfg(feature = "nightly")]
159 impl embedded_storage_async::nor_flash::NorFlash for $type_name<'_> { 145 impl embedded_storage_async::nor_flash::NorFlash for $type_name<'_, Async> {
160 const WRITE_SIZE: usize = $region.write_size as usize; 146 const WRITE_SIZE: usize = $region.write_size as usize;
161 const ERASE_SIZE: usize = $region.erase_size as usize; 147 const ERASE_SIZE: usize = $region.erase_size as usize;
162 148