Skip to main content

embassy_utils/flash/
flash_lock.rs

1use embassy_rp_plus::embassy_rp::flash;
2use embassy_rp_plus::embassy_rp::flash::{Async, Flash, Instance, Mode};
3use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
4use embassy_sync::mutex::Mutex;
5use crate::flash::flash_util::FlashUtil;
6
7/// flash lock
8pub struct FlashLock<'a, T: Instance, M: Mode, const FLASH_SIZE: usize> {
9    /// flash
10    flash: Mutex<CriticalSectionRawMutex, Flash<'a, T, M, FLASH_SIZE>>,
11}
12
13/// custom method
14impl<'a, T: Instance, M: Mode, const FLASH_SIZE: usize> FlashLock<'a, T, M, FLASH_SIZE> {
15    /// create flash lock
16    #[inline]
17    pub fn new(flash: Flash<'a, T, M, FLASH_SIZE>) -> Self {
18        Self { flash: Mutex::new(flash) }
19    }
20
21    /// build flash util, more see [FlashUtil::new]
22    #[inline]
23    pub fn build_flash_util(&'a self, offset: u32, erase_size: u32) -> FlashUtil<'a, T, M, FLASH_SIZE> {
24        FlashUtil::new(self, offset, erase_size)
25    }
26
27    /// build flash util default, more see [FlashUtil::new_default]
28    #[inline]
29    pub fn build_flash_util_default(&'a self) -> FlashUtil<'a, T, M, FLASH_SIZE> {
30        FlashUtil::new_default(self)
31    }
32
33    /// Flash capacity. more see [Flash::capacity]
34    #[inline]
35    pub async fn capacity(&self) -> usize {
36        self.flash.lock().await.capacity()
37    }
38
39    /// Read SPI flash JEDEC ID, more see [Flash::blocking_jedec_id]
40    #[inline]
41    pub async fn blocking_jedec_id(&self) -> Result<u32, flash::Error> {
42        self.flash.lock().await.blocking_jedec_id()
43    }
44
45    /// Read SPI flash unique ID, more see [Flash::blocking_unique_id]
46    #[inline]
47    pub async fn blocking_unique_id(&self, uid: &mut [u8]) -> Result<(), flash::Error> {
48        self.flash.lock().await.blocking_unique_id(uid)
49    }
50
51    /// Blocking read. more see [Flash::blocking_read]
52    #[inline]
53    pub async fn blocking_read(&self, offset: u32, bytes: &mut [u8]) -> Result<(), flash::Error> {
54        self.flash.lock().await.blocking_read(offset, bytes)
55    }
56
57    /// Blocking erase. more see [Flash::blocking_erase]
58    #[inline]
59    pub async fn blocking_erase(&self, from: u32, to: u32) -> Result<(), flash::Error> {
60        self.flash.lock().await.blocking_erase(from, to)
61    }
62
63    /// Blocking write. more see [Flash::blocking_write]
64    #[inline]
65    pub async fn blocking_write(&self, offset: u32, bytes: &[u8]) -> Result<(), flash::Error> {
66        self.flash.lock().await.blocking_write(offset, bytes)
67    }
68
69    /// try erase and write, flash memory in areas [offset - to] will be erased<br />
70    /// note that the area length of [offset - to] needs to meet the multiple relationship of the erase block size<br />
71    /// such as rp2040 (to - offset) % 4096 must equal 0, because the minimum erase block size of rp2040 flash memory is 4096
72    pub async fn try_erase_write(&self, offset: u32, to: u32, buf: &[u8]) -> Result<(), flash::Error> {
73        let mut flash = self.flash.lock().await;
74        flash.blocking_erase(offset, to)?;
75        flash.blocking_write(offset, buf)
76    }
77}
78
79/// custom method
80impl<'a, T: Instance, const FLASH_SIZE: usize> FlashLock<'a, T, Async, FLASH_SIZE> {
81    /// Async read. more see [Flash::<'a,T,Async,FLASH_SIZE>::read]
82    #[inline]
83    pub async fn read(&self, offset: u32, bytes: &mut [u8]) -> Result<(), flash::Error> {
84        self.flash.lock().await.read(offset, bytes).await
85    }
86}