Remove random delay from example, and move flash functions to allow using without embedded-storage in scope
This commit is contained in:
parent
1669e39565
commit
3c6c382465
@ -55,51 +55,10 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make sure to uphold the contract points with rp2040-flash.
|
pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
|
||||||
/// - interrupts must be disabled
|
|
||||||
/// - DMA must not access flash memory
|
|
||||||
unsafe fn in_ram(&mut self, operation: impl FnOnce()) {
|
|
||||||
let dma_status = &mut [false; crate::dma::CHANNEL_COUNT];
|
|
||||||
|
|
||||||
// TODO: Make sure CORE1 is paused during the entire duration of the RAM function
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, FLASH_SIZE> {
|
|
||||||
type Error = Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLASH_SIZE> {
|
|
||||||
const READ_SIZE: usize = READ_SIZE;
|
|
||||||
|
|
||||||
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
check_read(self, offset, bytes.len())?;
|
check_read(self, offset, bytes.len())?;
|
||||||
|
|
||||||
let flash_data = unsafe { core::slice::from_raw_parts((FLASH_BASE as u32 + offset) as *const u8, bytes.len()) };
|
let flash_data = unsafe { core::slice::from_raw_parts((FLASH_BASE as u32 + offset) as *const u8, bytes.len()) };
|
||||||
@ -108,19 +67,11 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLA
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
FLASH_SIZE
|
FLASH_SIZE
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, FLASH_SIZE> {}
|
pub fn erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
|
||||||
|
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_SIZE> {
|
|
||||||
const WRITE_SIZE: usize = WRITE_SIZE;
|
|
||||||
|
|
||||||
const ERASE_SIZE: usize = ERASE_SIZE;
|
|
||||||
|
|
||||||
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
|
|
||||||
check_erase(self, from, to)?;
|
check_erase(self, from, to)?;
|
||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
@ -136,7 +87,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
|
pub fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
|
||||||
check_write(self, offset, bytes.len())?;
|
check_write(self, offset, bytes.len())?;
|
||||||
|
|
||||||
trace!("Writing {:?} bytes to 0x{:x}", bytes.len(), FLASH_BASE as u32 + offset);
|
trace!("Writing {:?} bytes to 0x{:x}", bytes.len(), FLASH_BASE as u32 + offset);
|
||||||
@ -199,6 +150,69 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S
|
|||||||
|
|
||||||
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()) {
|
||||||
|
let dma_status = &mut [false; crate::dma::CHANNEL_COUNT];
|
||||||
|
|
||||||
|
// TODO: Make sure CORE1 is paused during the entire duration of the RAM function
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, FLASH_SIZE> {
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLASH_SIZE> {
|
||||||
|
const READ_SIZE: usize = READ_SIZE;
|
||||||
|
|
||||||
|
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.read(offset, bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn capacity(&self) -> usize {
|
||||||
|
self.capacity()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, FLASH_SIZE> {}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_SIZE> {
|
||||||
|
const WRITE_SIZE: usize = WRITE_SIZE;
|
||||||
|
|
||||||
|
const ERASE_SIZE: usize = ERASE_SIZE;
|
||||||
|
|
||||||
|
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
|
||||||
|
self.erase(from, to)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.write(offset, bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -6,7 +6,7 @@ use defmt::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::flash::{ERASE_SIZE, FLASH_BASE};
|
use embassy_rp::flash::{ERASE_SIZE, FLASH_BASE};
|
||||||
use embassy_rp::peripherals::FLASH;
|
use embassy_rp::peripherals::FLASH;
|
||||||
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
|
use embassy_time::{Duration, Timer};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
const ADDR_OFFSET: u32 = 0x100000;
|
const ADDR_OFFSET: u32 = 0x100000;
|
||||||
@ -17,6 +17,12 @@ async fn main(_spawner: Spawner) {
|
|||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
|
// add some delay to give an attached debug probe time to parse the
|
||||||
|
// defmt RTT header. Reading that header might touch flash memory, which
|
||||||
|
// interferes with flash write operations.
|
||||||
|
// https://github.com/knurling-rs/defmt/pull/683
|
||||||
|
Timer::after(Duration::from_millis(10)).await;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user