mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
rp2040: move in_ram helper outside of Flash's impl
Allow it to be called from other modules.
This commit is contained in:
parent
f30fc949ff
commit
c6d53e7bce
@ -131,7 +131,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
|
|||||||
|
|
||||||
let len = to - from;
|
let len = to - from;
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len))? };
|
unsafe { in_ram(|| ram_helpers::flash_range_erase(from, len))? };
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
|
|||||||
|
|
||||||
let unaligned_offset = offset as usize - start;
|
let unaligned_offset = offset as usize - start;
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
|
unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
|
||||||
}
|
}
|
||||||
|
|
||||||
let remaining_len = bytes.len() - start_padding;
|
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
|
|||||||
if bytes.as_ptr() as usize >= 0x2000_0000 {
|
if bytes.as_ptr() as usize >= 0x2000_0000 {
|
||||||
let aligned_data = &bytes[start_padding..end_padding];
|
let aligned_data = &bytes[start_padding..end_padding];
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? }
|
unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? }
|
||||||
} else {
|
} else {
|
||||||
for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) {
|
for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) {
|
||||||
let mut ram_buf = [0xFF_u8; PAGE_SIZE];
|
let mut ram_buf = [0xFF_u8; PAGE_SIZE];
|
||||||
ram_buf.copy_from_slice(chunk);
|
ram_buf.copy_from_slice(chunk);
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? }
|
unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? }
|
||||||
aligned_offset += PAGE_SIZE;
|
aligned_offset += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,47 +194,15 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
|
|||||||
|
|
||||||
let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset);
|
let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset);
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
|
unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make sure to uphold the contract points with rp2040-flash.
|
|
||||||
/// - interrupts must be disabled
|
|
||||||
/// - DMA must not access flash memory
|
|
||||||
unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> {
|
|
||||||
// Make sure we're running on CORE0
|
|
||||||
let core_id: u32 = pac::SIO.cpuid().read();
|
|
||||||
if core_id != 0 {
|
|
||||||
return Err(Error::InvalidCore);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure CORE1 is paused during the entire duration of the RAM function
|
|
||||||
crate::multicore::pause_core1();
|
|
||||||
|
|
||||||
critical_section::with(|_| {
|
|
||||||
// Wait for all DMA channels in flash to finish before ram operation
|
|
||||||
const SRAM_LOWER: u32 = 0x2000_0000;
|
|
||||||
for n in 0..crate::dma::CHANNEL_COUNT {
|
|
||||||
let ch = crate::pac::DMA.ch(n);
|
|
||||||
while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
|
|
||||||
}
|
|
||||||
// Wait for completion of any background reads
|
|
||||||
while pac::XIP_CTRL.stream_ctr().read().0 > 0 {}
|
|
||||||
|
|
||||||
// Run our flash operation in RAM
|
|
||||||
operation();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Resume CORE1 execution
|
|
||||||
crate::multicore::resume_core1();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read SPI flash unique ID
|
/// Read SPI flash unique ID
|
||||||
pub fn blocking_unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> {
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid))? };
|
unsafe { in_ram(|| ram_helpers::flash_unique_id(uid))? };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +210,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
|
|||||||
pub fn blocking_jedec_id(&mut self) -> Result<u32, Error> {
|
pub fn blocking_jedec_id(&mut self) -> Result<u32, Error> {
|
||||||
let mut jedec = None;
|
let mut jedec = None;
|
||||||
unsafe {
|
unsafe {
|
||||||
self.in_ram(|| {
|
in_ram(|| {
|
||||||
jedec.replace(ram_helpers::flash_jedec_id());
|
jedec.replace(ram_helpers::flash_jedec_id());
|
||||||
})?;
|
})?;
|
||||||
};
|
};
|
||||||
@ -871,6 +839,38 @@ mod ram_helpers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Make sure to uphold the contract points with rp2040-flash.
|
||||||
|
/// - interrupts must be disabled
|
||||||
|
/// - DMA must not access flash memory
|
||||||
|
pub(crate) unsafe fn in_ram(operation: impl FnOnce()) -> Result<(), Error> {
|
||||||
|
// Make sure we're running on CORE0
|
||||||
|
let core_id: u32 = pac::SIO.cpuid().read();
|
||||||
|
if core_id != 0 {
|
||||||
|
return Err(Error::InvalidCore);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure CORE1 is paused during the entire duration of the RAM function
|
||||||
|
crate::multicore::pause_core1();
|
||||||
|
|
||||||
|
critical_section::with(|_| {
|
||||||
|
// Wait for all DMA channels in flash to finish before ram operation
|
||||||
|
const SRAM_LOWER: u32 = 0x2000_0000;
|
||||||
|
for n in 0..crate::dma::CHANNEL_COUNT {
|
||||||
|
let ch = crate::pac::DMA.ch(n);
|
||||||
|
while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
|
||||||
|
}
|
||||||
|
// Wait for completion of any background reads
|
||||||
|
while pac::XIP_CTRL.stream_ctr().read().0 > 0 {}
|
||||||
|
|
||||||
|
// Run our flash operation in RAM
|
||||||
|
operation();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Resume CORE1 execution
|
||||||
|
crate::multicore::resume_core1();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
mod sealed {
|
mod sealed {
|
||||||
pub trait Instance {}
|
pub trait Instance {}
|
||||||
pub trait Mode {}
|
pub trait Mode {}
|
||||||
|
Loading…
Reference in New Issue
Block a user