embassy_utils/flash/
flash_util.rs1use embassy_rp_plus::embassy_rp::flash;
2use embassy_rp_plus::embassy_rp::flash::{Instance, Mode};
3use crate::flash::err::FlashResult;
4use crate::flash::flash_lock::FlashLock;
5
6pub struct FlashUtil<'a, T: Instance, M: Mode, const FLASH_SIZE: usize> {
8 pub flash: &'a FlashLock<'a, T, M, FLASH_SIZE>,
10 pub offset: u32,
12 erase_size: u32,
14}
15
16impl<'a, T: Instance, M: Mode, const FLASH_SIZE: usize> FlashUtil<'a, T, M, FLASH_SIZE> {
18 #[inline]
20 pub fn new(flash: &'a FlashLock<'a, T, M, FLASH_SIZE>, offset: u32, erase_size: u32) -> Self {
21 Self { flash, offset, erase_size }
22 }
23
24 #[inline]
26 pub fn new_default(flash: &'a FlashLock<'a, T, M, FLASH_SIZE>) -> Self {
27 Self::new(flash, 0x100000, 4096)
28 }
29
30 #[inline]
32 pub async fn try_read(&self, buf: &mut [u8]) -> Result<(), flash::Error> {
33 self.flash.blocking_read(self.offset, buf).await
34 }
35
36 pub async fn try_erase(&self, num: u32) -> Result<(), flash::Error> {
38 if num == 0 { return Ok(()); }
39 self.flash.blocking_erase(self.offset, self.offset + self.erase_size * num).await
40 }
41
42 pub async fn try_erase_write(&self, buf: &[u8]) -> FlashResult<()> {
46 if buf.is_empty() { return Ok(()); }
47
48 let len = u32::try_from(buf.len())?;
50 let sub_to = if len % self.offset == 0 { 0 } else { 1 };
51 let to = self.erase_size * (len / self.offset + sub_to) + self.offset;
52
53 self.flash.try_erase_write(self.offset, to, buf).await?;
55 Ok(())
56 }
57
58 #[inline]
62 pub async fn erase_write(&self, buf: &[u8]) {
63 self.try_erase_write(buf).await.ok();
64 }
65}