rp2040: move in_ram helper outside of Flash's impl
Allow it to be called from other modules.
This commit is contained in:
		
				
					committed by
					
						
						Dario Nieuwenhuis
					
				
			
			
				
	
			
			
			
						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 {}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user