aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-04-27 15:28:11 +0000
committerGitHub <[email protected]>2023-04-27 15:28:11 +0000
commit03d6363d5af5dcaf21b52734994a466ca593d2b6 (patch)
tree1b3fb2b715d2bd60385cbb8d795aac7bd85b498e
parent1cf26f0eb3181b04ce2c520a4814c4b3a99bb407 (diff)
parent31b54e0fbd086178090b4899c2f788277bf5daac (diff)
Merge #1406
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 <[email protected]>
-rw-r--r--embassy-rp/src/flash.rs22
1 files changed, 5 insertions, 17 deletions
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs
index f2137ebe1..6ab05ff0b 100644
--- a/embassy-rp/src/flash.rs
+++ b/embassy-rp/src/flash.rs
@@ -162,8 +162,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
162 /// - interrupts must be disabled 162 /// - interrupts must be disabled
163 /// - DMA must not access flash memory 163 /// - DMA must not access flash memory
164 unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> { 164 unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> {
165 let dma_status = &mut [false; crate::dma::CHANNEL_COUNT];
166
167 // Make sure we're running on CORE0 165 // Make sure we're running on CORE0
168 let core_id: u32 = unsafe { pac::SIO.cpuid().read() }; 166 let core_id: u32 = unsafe { pac::SIO.cpuid().read() };
169 if core_id != 0 { 167 if core_id != 0 {
@@ -174,25 +172,15 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
174 crate::multicore::pause_core1(); 172 crate::multicore::pause_core1();
175 173
176 critical_section::with(|_| { 174 critical_section::with(|_| {
177 // Pause all DMA channels for the duration of the ram operation 175 // Wait for all DMA channels in flash to finish before ram operation
178 for (number, status) in dma_status.iter_mut().enumerate() { 176 const SRAM_LOWER: u32 = 0x2000_0000;
179 let ch = crate::pac::DMA.ch(number as _); 177 for n in 0..crate::dma::CHANNEL_COUNT {
180 *status = ch.ctrl_trig().read().en(); 178 let ch = crate::pac::DMA.ch(n);
181 if *status { 179 while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
182 ch.ctrl_trig().modify(|w| w.set_en(false));
183 }
184 } 180 }
185 181
186 // Run our flash operation in RAM 182 // Run our flash operation in RAM
187 operation(); 183 operation();
188
189 // Re-enable previously enabled DMA channels
190 for (number, status) in dma_status.iter().enumerate() {
191 let ch = crate::pac::DMA.ch(number as _);
192 if *status {
193 ch.ctrl_trig().modify(|w| w.set_en(true));
194 }
195 }
196 }); 184 });
197 185
198 // Resume CORE1 execution 186 // Resume CORE1 execution