aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/flash.rs34
-rw-r--r--examples/rp/src/bin/flash.rs1
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
56impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { 56impl<'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);