diff options
| author | Mathias <[email protected]> | 2022-10-26 14:47:32 +0200 |
|---|---|---|
| committer | Mathias <[email protected]> | 2022-10-26 15:02:39 +0200 |
| commit | 1669e395654430dff6dffda0cef9522f9ccfd213 (patch) | |
| tree | 95b139db7c1dd06c0d4f23a91723a889f894c83f | |
| parent | 80e58426fcf40b6cea28368e43a7289e827461cf (diff) | |
Buffer data to be written to flash in ram if it does not already reside in ram
| -rw-r--r-- | embassy-rp/src/flash.rs | 34 | ||||
| -rw-r--r-- | examples/rp/src/bin/flash.rs | 1 |
2 files changed, 27 insertions, 8 deletions
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 62f68bd3c..0f86684e2 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs | |||
| @@ -55,6 +55,8 @@ pub struct Flash<'d, T: Instance, const FLASH_SIZE: usize>(PhantomData<&'d mut T | |||
| 55 | 55 | ||
| 56 | impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | 56 | impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { |
| 57 | pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self { | 57 | pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self { |
| 58 | // FIXME: WHY is this needed?! | ||
| 59 | cortex_m::asm::delay(50_000); | ||
| 58 | Self(PhantomData) | 60 | Self(PhantomData) |
| 59 | } | 61 | } |
| 60 | 62 | ||
| @@ -163,15 +165,24 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S | |||
| 163 | // Write aligned slice of length in multiples of 256 bytes | 165 | // Write aligned slice of length in multiples of 256 bytes |
| 164 | // If the remaining bytes to be written is more than a full page. | 166 | // If the remaining bytes to be written is more than a full page. |
| 165 | if remaining_len >= PAGE_SIZE { | 167 | if remaining_len >= PAGE_SIZE { |
| 166 | let aligned_data = &bytes[start_padding..end_padding]; | 168 | let mut aligned_offset = if start_padding > 0 { |
| 167 | |||
| 168 | let aligned_offset = if start_padding > 0 { | ||
| 169 | offset as usize + padded_offset | 169 | offset as usize + padded_offset |
| 170 | } else { | 170 | } else { |
| 171 | offset as usize | 171 | offset as usize |
| 172 | }; | 172 | }; |
| 173 | 173 | ||
| 174 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data, true)) } | 174 | if bytes.as_ptr() as usize >= 0x2000_0000 { |
| 175 | let aligned_data = &bytes[start_padding..end_padding]; | ||
| 176 | |||
| 177 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data, true)) } | ||
| 178 | } else { | ||
| 179 | for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) { | ||
| 180 | let mut ram_buf = [0xFF_u8; PAGE_SIZE]; | ||
| 181 | ram_buf.copy_from_slice(chunk); | ||
| 182 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf, true)) } | ||
| 183 | aligned_offset += PAGE_SIZE; | ||
| 184 | } | ||
| 185 | } | ||
| 175 | } | 186 | } |
| 176 | 187 | ||
| 177 | // Pad in the end | 188 | // Pad in the end |
| @@ -273,11 +284,14 @@ mod ram_helpers { | |||
| 273 | pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) { | 284 | pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) { |
| 274 | let mut boot2 = [0u32; 256 / 4]; | 285 | let mut boot2 = [0u32; 256 / 4]; |
| 275 | let ptrs = if use_boot2 { | 286 | let ptrs = if use_boot2 { |
| 276 | rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256); | 287 | rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); |
| 277 | flash_function_pointers_with_boot2(true, false, &boot2) | 288 | flash_function_pointers_with_boot2(true, false, &boot2) |
| 278 | } else { | 289 | } else { |
| 279 | flash_function_pointers(true, false) | 290 | flash_function_pointers(true, false) |
| 280 | }; | 291 | }; |
| 292 | |||
| 293 | core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); | ||
| 294 | |||
| 281 | write_flash_inner(addr, len, None, &ptrs as *const FlashFunctionPointers); | 295 | write_flash_inner(addr, len, None, &ptrs as *const FlashFunctionPointers); |
| 282 | } | 296 | } |
| 283 | 297 | ||
| @@ -300,11 +314,14 @@ mod ram_helpers { | |||
| 300 | pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) { | 314 | pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) { |
| 301 | let mut boot2 = [0u32; 256 / 4]; | 315 | let mut boot2 = [0u32; 256 / 4]; |
| 302 | let ptrs = if use_boot2 { | 316 | let ptrs = if use_boot2 { |
| 303 | rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256); | 317 | rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); |
| 304 | flash_function_pointers_with_boot2(true, true, &boot2) | 318 | flash_function_pointers_with_boot2(true, true, &boot2) |
| 305 | } else { | 319 | } else { |
| 306 | flash_function_pointers(true, true) | 320 | flash_function_pointers(true, true) |
| 307 | }; | 321 | }; |
| 322 | |||
| 323 | core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); | ||
| 324 | |||
| 308 | write_flash_inner( | 325 | write_flash_inner( |
| 309 | addr, | 326 | addr, |
| 310 | data.len() as u32, | 327 | data.len() as u32, |
| @@ -332,11 +349,14 @@ mod ram_helpers { | |||
| 332 | pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) { | 349 | pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) { |
| 333 | let mut boot2 = [0u32; 256 / 4]; | 350 | let mut boot2 = [0u32; 256 / 4]; |
| 334 | let ptrs = if use_boot2 { | 351 | let ptrs = if use_boot2 { |
| 335 | rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256); | 352 | rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); |
| 336 | flash_function_pointers_with_boot2(false, true, &boot2) | 353 | flash_function_pointers_with_boot2(false, true, &boot2) |
| 337 | } else { | 354 | } else { |
| 338 | flash_function_pointers(false, true) | 355 | flash_function_pointers(false, true) |
| 339 | }; | 356 | }; |
| 357 | |||
| 358 | core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); | ||
| 359 | |||
| 340 | write_flash_inner( | 360 | write_flash_inner( |
| 341 | addr, | 361 | addr, |
| 342 | data.len() as u32, | 362 | data.len() as u32, |
diff --git a/examples/rp/src/bin/flash.rs b/examples/rp/src/bin/flash.rs index 17549e4be..d4dfca759 100644 --- a/examples/rp/src/bin/flash.rs +++ b/examples/rp/src/bin/flash.rs | |||
| @@ -18,7 +18,6 @@ async fn main(_spawner: Spawner) { | |||
| 18 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 19 | 19 | ||
| 20 | let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH); | 20 | let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH); |
| 21 | |||
| 22 | erase_write_sector(&mut flash, 0x00); | 21 | erase_write_sector(&mut flash, 0x00); |
| 23 | 22 | ||
| 24 | multiwrite_bytes(&mut flash, ERASE_SIZE as u32); | 23 | multiwrite_bytes(&mut flash, ERASE_SIZE as u32); |
