diff options
| author | Scott Mansell <[email protected]> | 2023-09-23 17:34:08 +1200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-10-07 01:39:29 +0200 |
| commit | c6d53e7bce9a9f04b2d479a150c4e1aee1bb4ea8 (patch) | |
| tree | 4f0c9a079617041a0c81c64d8d46d878cded67b5 /embassy-rp/src/flash.rs | |
| parent | f30fc949ff34683bd9b9330d09583da4a35428ea (diff) | |
rp2040: move in_ram helper outside of Flash's impl
Allow it to be called from other modules.
Diffstat (limited to 'embassy-rp/src/flash.rs')
| -rw-r--r-- | embassy-rp/src/flash.rs | 78 |
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 | ||
| 845 | pub(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 | |||
| 874 | mod sealed { | 874 | mod sealed { |
| 875 | pub trait Instance {} | 875 | pub trait Instance {} |
| 876 | pub trait Mode {} | 876 | pub trait Mode {} |
