Buffer data to be written to flash in ram if it does not already reside in ram
This commit is contained in:
parent
80e58426fc
commit
1669e39565
@ -55,6 +55,8 @@ pub struct Flash<'d, T: Instance, const FLASH_SIZE: usize>(PhantomData<&'d mut T
|
|||||||
|
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
||||||
pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self {
|
pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self {
|
||||||
|
// FIXME: WHY is this needed?!
|
||||||
|
cortex_m::asm::delay(50_000);
|
||||||
Self(PhantomData)
|
Self(PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,15 +165,24 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S
|
|||||||
// Write aligned slice of length in multiples of 256 bytes
|
// Write aligned slice of length in multiples of 256 bytes
|
||||||
// If the remaining bytes to be written is more than a full page.
|
// If the remaining bytes to be written is more than a full page.
|
||||||
if remaining_len >= PAGE_SIZE {
|
if remaining_len >= PAGE_SIZE {
|
||||||
let aligned_data = &bytes[start_padding..end_padding];
|
let mut aligned_offset = if start_padding > 0 {
|
||||||
|
|
||||||
let aligned_offset = if start_padding > 0 {
|
|
||||||
offset as usize + padded_offset
|
offset as usize + padded_offset
|
||||||
} else {
|
} else {
|
||||||
offset as usize
|
offset as usize
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if bytes.as_ptr() as usize >= 0x2000_0000 {
|
||||||
|
let aligned_data = &bytes[start_padding..end_padding];
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data, true)) }
|
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data, true)) }
|
||||||
|
} else {
|
||||||
|
for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) {
|
||||||
|
let mut ram_buf = [0xFF_u8; PAGE_SIZE];
|
||||||
|
ram_buf.copy_from_slice(chunk);
|
||||||
|
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf, true)) }
|
||||||
|
aligned_offset += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad in the end
|
// Pad in the end
|
||||||
@ -273,11 +284,14 @@ mod ram_helpers {
|
|||||||
pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) {
|
pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if use_boot2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256);
|
||||||
flash_function_pointers_with_boot2(true, false, &boot2)
|
flash_function_pointers_with_boot2(true, false, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(true, false)
|
flash_function_pointers(true, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
write_flash_inner(addr, len, None, &ptrs as *const FlashFunctionPointers);
|
write_flash_inner(addr, len, None, &ptrs as *const FlashFunctionPointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,11 +314,14 @@ mod ram_helpers {
|
|||||||
pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) {
|
pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if use_boot2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256);
|
||||||
flash_function_pointers_with_boot2(true, true, &boot2)
|
flash_function_pointers_with_boot2(true, true, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(true, true)
|
flash_function_pointers(true, true)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
write_flash_inner(
|
write_flash_inner(
|
||||||
addr,
|
addr,
|
||||||
data.len() as u32,
|
data.len() as u32,
|
||||||
@ -332,11 +349,14 @@ mod ram_helpers {
|
|||||||
pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) {
|
pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if use_boot2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256);
|
||||||
flash_function_pointers_with_boot2(false, true, &boot2)
|
flash_function_pointers_with_boot2(false, true, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(false, true)
|
flash_function_pointers(false, true)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
write_flash_inner(
|
write_flash_inner(
|
||||||
addr,
|
addr,
|
||||||
data.len() as u32,
|
data.len() as u32,
|
||||||
|
@ -18,7 +18,6 @@ async fn main(_spawner: Spawner) {
|
|||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH);
|
let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH);
|
||||||
|
|
||||||
erase_write_sector(&mut flash, 0x00);
|
erase_write_sector(&mut flash, 0x00);
|
||||||
|
|
||||||
multiwrite_bytes(&mut flash, ERASE_SIZE as u32);
|
multiwrite_bytes(&mut flash, ERASE_SIZE as u32);
|
||||||
|
Loading…
Reference in New Issue
Block a user