#![cfg(feature = "sdcard")]
use embassy_time::Delay;
#[allow(unused)]
use embedded_hal::delay::DelayNs;
use embedded_sdmmc::{SdCard, TimeSource, Timestamp, Volume, VolumeIdx, VolumeManager};
use static_cell::StaticCell;
use super::targets::SdCardSpiDevice;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StorageVolumeError {
LowSpeedHandshakeFailed,
HighSpeedReopenFailed,
}
#[allow(unused)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StorageError {
NotImplemented,
FileSystemCorruptedOrMissing,
LogFileCreationFailed,
}
#[derive(Default)]
pub struct SdCardTimeSource;
impl TimeSource for SdCardTimeSource {
fn get_timestamp(&self) -> Timestamp {
Timestamp { year_since_1970: 0, zero_indexed_month: 0, zero_indexed_day: 0, hours: 0, minutes: 0, seconds: 0 }
}
}
pub type SdCardBlockDevice = SdCard<&'static mut SdCardSpiDevice, Delay>;
pub type SdCardVolume = Volume<
'static,
SdCardBlockDevice,
SdCardTimeSource,
1, 1, 1, >;
type ConcreteVolumeManager = VolumeManager<SdCardBlockDevice, SdCardTimeSource, 1, 1, 1>;
static VOLUME_MGR_CELL: StaticCell<ConcreteVolumeManager> = StaticCell::new();
pub fn open_volume(spi_device: &mut SdCardSpiDevice) -> Result<SdCardVolume, StorageVolumeError> {
{
let sd_card = SdCard::new(&mut *spi_device, embassy_time::Delay);
let volume_mgr = VolumeManager::new(sd_card, SdCardTimeSource);
let _volume = volume_mgr.open_volume(VolumeIdx(0)).map_err(|_| StorageVolumeError::LowSpeedHandshakeFailed)?;
}
log::info!("SD CARD: Handshake verified. Shifting master clock registers to 20 MHz...");
#[cfg(any(feature = "rp2040", feature = "rp235xa", feature = "rp235xb"))]
spi_device.bus_mut().set_frequency(20_000_000);
let static_spi: &'static mut SdCardSpiDevice = unsafe { core::mem::transmute(spi_device) };
let sd_card = SdCard::new(static_spi, embassy_time::Delay);
let volume_manager: &mut ConcreteVolumeManager =
VOLUME_MGR_CELL.init(VolumeManager::new_with_limits(sd_card, SdCardTimeSource, 0));
let sdcard_volume =
volume_manager.open_volume(VolumeIdx(0)).map_err(|_| StorageVolumeError::HighSpeedReopenFailed)?;
Ok(sdcard_volume)
}