aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp
diff options
context:
space:
mode:
authorScott Mansell <[email protected]>2023-09-23 17:34:08 +1200
committerDario Nieuwenhuis <[email protected]>2023-10-07 01:39:29 +0200
commitc6d53e7bce9a9f04b2d479a150c4e1aee1bb4ea8 (patch)
tree4f0c9a079617041a0c81c64d8d46d878cded67b5 /embassy-rp
parentf30fc949ff34683bd9b9330d09583da4a35428ea (diff)
rp2040: move in_ram helper outside of Flash's impl
Allow it to be called from other modules.
Diffstat (limited to 'embassy-rp')
-rw-r--r--embassy-rp/src/flash.rs78
1 files changed, 39 insertions, 39 deletions
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs
index 1c1c2449e..8fb5542f1 100644
--- a/embassy-rp/src/flash.rs
+++ b/embassy-rp/src/flash.rs
@@ -131,7 +131,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
131 131
132 let len = to - from; 132 let len = to - from;
133 133
134 unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len))? }; 134 unsafe { in_ram(|| ram_helpers::flash_range_erase(from, len))? };
135 135
136 Ok(()) 136 Ok(())
137 } 137 }
@@ -156,7 +156,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
156 156
157 let unaligned_offset = offset as usize - start; 157 let unaligned_offset = offset as usize - start;
158 158
159 unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } 159 unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
160 } 160 }
161 161
162 let remaining_len = bytes.len() - start_padding; 162 let remaining_len = bytes.len() - start_padding;
@@ -174,12 +174,12 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
174 if bytes.as_ptr() as usize >= 0x2000_0000 { 174 if bytes.as_ptr() as usize >= 0x2000_0000 {
175 let aligned_data = &bytes[start_padding..end_padding]; 175 let aligned_data = &bytes[start_padding..end_padding];
176 176
177 unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? } 177 unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? }
178 } else { 178 } else {
179 for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) { 179 for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) {
180 let mut ram_buf = [0xFF_u8; PAGE_SIZE]; 180 let mut ram_buf = [0xFF_u8; PAGE_SIZE];
181 ram_buf.copy_from_slice(chunk); 181 ram_buf.copy_from_slice(chunk);
182 unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? } 182 unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? }
183 aligned_offset += PAGE_SIZE; 183 aligned_offset += PAGE_SIZE;
184 } 184 }
185 } 185 }
@@ -194,47 +194,15 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
194 194
195 let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset); 195 let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset);
196 196
197 unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } 197 unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
198 } 198 }
199 199
200 Ok(()) 200 Ok(())
201 } 201 }
202 202
203 /// Make sure to uphold the contract points with rp2040-flash.
204 /// - interrupts must be disabled
205 /// - DMA must not access flash memory
206 unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> {
207 // Make sure we're running on CORE0
208 let core_id: u32 = pac::SIO.cpuid().read();
209 if core_id != 0 {
210 return Err(Error::InvalidCore);
211 }
212
213 // Make sure CORE1 is paused during the entire duration of the RAM function
214 crate::multicore::pause_core1();
215
216 critical_section::with(|_| {
217 // Wait for all DMA channels in flash to finish before ram operation
218 const SRAM_LOWER: u32 = 0x2000_0000;
219 for n in 0..crate::dma::CHANNEL_COUNT {
220 let ch = crate::pac::DMA.ch(n);
221 while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
222 }
223 // Wait for completion of any background reads
224 while pac::XIP_CTRL.stream_ctr().read().0 > 0 {}
225
226 // Run our flash operation in RAM
227 operation();
228 });
229
230 // Resume CORE1 execution
231 crate::multicore::resume_core1();
232 Ok(())
233 }
234
235 /// Read SPI flash unique ID 203 /// Read SPI flash unique ID
236 pub fn blocking_unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> { 204 pub fn blocking_unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> {
237 unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid))? }; 205 unsafe { in_ram(|| ram_helpers::flash_unique_id(uid))? };
238 Ok(()) 206 Ok(())
239 } 207 }
240 208
@@ -242,7 +210,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
242 pub fn blocking_jedec_id(&mut self) -> Result<u32, Error> { 210 pub fn blocking_jedec_id(&mut self) -> Result<u32, Error> {
243 let mut jedec = None; 211 let mut jedec = None;
244 unsafe { 212 unsafe {
245 self.in_ram(|| { 213 in_ram(|| {
246 jedec.replace(ram_helpers::flash_jedec_id()); 214 jedec.replace(ram_helpers::flash_jedec_id());
247 })?; 215 })?;
248 }; 216 };
@@ -871,6 +839,38 @@ mod ram_helpers {
871 } 839 }
872} 840}
873 841
842/// Make sure to uphold the contract points with rp2040-flash.
843/// - interrupts must be disabled
844/// - DMA must not access flash memory
845pub(crate) unsafe fn in_ram(operation: impl FnOnce()) -> Result<(), Error> {
846 // Make sure we're running on CORE0
847 let core_id: u32 = pac::SIO.cpuid().read();
848 if core_id != 0 {
849 return Err(Error::InvalidCore);
850 }
851
852 // Make sure CORE1 is paused during the entire duration of the RAM function
853 crate::multicore::pause_core1();
854
855 critical_section::with(|_| {
856 // Wait for all DMA channels in flash to finish before ram operation
857 const SRAM_LOWER: u32 = 0x2000_0000;
858 for n in 0..crate::dma::CHANNEL_COUNT {
859 let ch = crate::pac::DMA.ch(n);
860 while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
861 }
862 // Wait for completion of any background reads
863 while pac::XIP_CTRL.stream_ctr().read().0 > 0 {}
864
865 // Run our flash operation in RAM
866 operation();
867 });
868
869 // Resume CORE1 execution
870 crate::multicore::resume_core1();
871 Ok(())
872}
873
874mod sealed { 874mod sealed {
875 pub trait Instance {} 875 pub trait Instance {}
876 pub trait Mode {} 876 pub trait Mode {}