1406: rp: DMA behaviour during flash operations r=Dirbaio a=kalkyl

This PR changes the old behaviour during flash operations where all DMA transfers were paused during the flash operation.
The new approach is to wait for any DMA operating in flash region to finish and let RAM transfers continue.

Co-authored-by: kalkyl <henrik.alser@me.com>
This commit is contained in:
bors[bot] 2023-04-27 15:28:11 +00:00 committed by GitHub
commit 03d6363d5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -162,8 +162,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
/// - interrupts must be disabled
/// - DMA must not access flash memory
unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> {
let dma_status = &mut [false; crate::dma::CHANNEL_COUNT];
// Make sure we're running on CORE0
let core_id: u32 = unsafe { pac::SIO.cpuid().read() };
if core_id != 0 {
@ -174,25 +172,15 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
crate::multicore::pause_core1();
critical_section::with(|_| {
// Pause all DMA channels for the duration of the ram operation
for (number, status) in dma_status.iter_mut().enumerate() {
let ch = crate::pac::DMA.ch(number as _);
*status = ch.ctrl_trig().read().en();
if *status {
ch.ctrl_trig().modify(|w| w.set_en(false));
}
// 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() {}
}
// Run our flash operation in RAM
operation();
// Re-enable previously enabled DMA channels
for (number, status) in dma_status.iter().enumerate() {
let ch = crate::pac::DMA.ch(number as _);
if *status {
ch.ctrl_trig().modify(|w| w.set_en(true));
}
}
});
// Resume CORE1 execution