rp: add async flash

Implement an async flash mode using the XIP background best effort
read interface.  Only reads are actually async, write and erase remain
blocking.
This commit is contained in:
Derek Hageman
2023-07-25 15:54:33 -06:00
parent e3cc0d168c
commit 7ed9e29326
6 changed files with 254 additions and 26 deletions

View File

@ -6,7 +6,7 @@ mod fmt;
#[cfg(feature = "nightly")]
pub use embassy_boot::FirmwareUpdater;
pub use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State};
use embassy_rp::flash::{Flash, ERASE_SIZE};
use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE};
use embassy_rp::peripherals::{FLASH, WATCHDOG};
use embassy_rp::watchdog::Watchdog;
use embassy_time::Duration;
@ -58,14 +58,14 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
/// A flash implementation that will feed a watchdog when touching flash.
pub struct WatchdogFlash<'d, const SIZE: usize> {
flash: Flash<'d, FLASH, SIZE>,
flash: Flash<'d, FLASH, Blocking, SIZE>,
watchdog: Watchdog,
}
impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> {
/// Start a new watchdog with a given flash and watchdog peripheral and a timeout
pub fn start(flash: FLASH, watchdog: WATCHDOG, timeout: Duration) -> Self {
let flash: Flash<'_, FLASH, SIZE> = Flash::new(flash);
let flash = Flash::<_, Blocking, SIZE>::new(flash);
let mut watchdog = Watchdog::new(watchdog);
watchdog.start(timeout);
Self { flash, watchdog }
@ -73,12 +73,12 @@ impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> {
}
impl<'d, const SIZE: usize> ErrorType for WatchdogFlash<'d, SIZE> {
type Error = <Flash<'d, FLASH, SIZE> as ErrorType>::Error;
type Error = <Flash<'d, FLASH, Blocking, SIZE> as ErrorType>::Error;
}
impl<'d, const SIZE: usize> NorFlash for WatchdogFlash<'d, SIZE> {
const WRITE_SIZE: usize = <Flash<'d, FLASH, SIZE> as NorFlash>::WRITE_SIZE;
const ERASE_SIZE: usize = <Flash<'d, FLASH, SIZE> as NorFlash>::ERASE_SIZE;
const WRITE_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as NorFlash>::WRITE_SIZE;
const ERASE_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as NorFlash>::ERASE_SIZE;
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
self.watchdog.feed();
@ -91,7 +91,7 @@ impl<'d, const SIZE: usize> NorFlash for WatchdogFlash<'d, SIZE> {
}
impl<'d, const SIZE: usize> ReadNorFlash for WatchdogFlash<'d, SIZE> {
const READ_SIZE: usize = <Flash<'d, FLASH, SIZE> as ReadNorFlash>::READ_SIZE;
const READ_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as ReadNorFlash>::READ_SIZE;
fn read(&mut self, offset: u32, data: &mut [u8]) -> Result<(), Self::Error> {
self.watchdog.feed();
self.flash.read(offset, data)