fatfs_embedded/fatfs/
diskio.rs

1mod diskio_bindings;
2
3use crate::fatfs::diskio::diskio_bindings::*;
4use crate::fatfs::*;
5use core::ptr;
6use alloc::boxed::Box;
7use embassy_sync::{mutex::Mutex, blocking_mutex::raw::ThreadModeRawMutex};
8
9#[cfg(feature = "chrono")]
10use chrono::{ Datelike, NaiveDateTime, Timelike };
11
12pub enum IoctlCommand {
13    CtrlSync(()),
14    GetSectorCount(DWORD),
15    GetSectorSize(WORD),
16    GetBlockSize(DWORD)
17}
18
19pub enum DiskResult {
20    Ok = DRESULT_RES_OK as isize,
21    Error = DRESULT_RES_ERROR as isize,
22    WriteProtected = DRESULT_RES_WRPRT as isize,
23    NotReady = DRESULT_RES_NOTRDY as isize,
24    ParameterError = DRESULT_RES_PARERR as isize
25}
26
27pub enum DiskStatus {
28    Ok = 0,
29    NotInitialized = STA_NOINIT as isize,
30    NoDisk = STA_NODISK as isize,
31    WriteProtected = STA_PROTECT as isize
32}
33
34/// Implement this trait for a block storage device, such as an SDMMC driver.
35/// When feature `chrono` is enabled time must also be supplied.
36pub trait FatFsDriver: Send + Sync {
37    fn disk_status(&self, drive: u8) -> u8;
38    fn disk_initialize(&mut self, drive: u8) -> u8;
39    fn disk_read(&mut self, drive: u8, buffer: &mut [u8], sector: u32) -> DiskResult;
40    fn disk_write(&mut self, drive: u8, buffer: &[u8], sector: u32) -> DiskResult;
41    fn disk_ioctl(&self, data: &mut IoctlCommand) -> DiskResult;
42    
43    #[cfg(feature = "chrono")]
44    fn get_fattime(&self) -> NaiveDateTime;
45}
46
47/// Installed driver singleton. A call to `install()` places the driver here.
48/// Only one driver instance is supported.
49static DRIVER: Mutex<ThreadModeRawMutex, Option<Box<dyn FatFsDriver>>> = Mutex::new(None);
50
51/// Installs a driver for the file system. Only one driver can be installed at a time.
52/// The driver must implement the `FatFsDriver` trait.
53/// The driver is placed on the heap using `Box` so that it lives for the lifetime of 
54/// the program.
55pub async fn install(driver: impl FatFsDriver + 'static) {
56    let boxed_driver = Box::new(driver);
57    (*(DRIVER.lock().await)).replace(boxed_driver);
58}