use core::ffi::c_int;
use std::path::{Path, PathBuf};
use crate::Error;
pub const SD_MOUNT_PATH: &str = "/sdcard";
pub fn sd_begin() -> bool {
unsafe { m5unified_sys::m5u_sd_begin() }
}
pub fn sd_begin_with_config(config: &SdSpiConfig) -> bool {
let raw = config.to_raw();
unsafe { m5unified_sys::m5u_sd_begin_spi(&raw) }
}
pub fn sd_is_mounted() -> bool {
unsafe { m5unified_sys::m5u_sd_is_mounted() }
}
pub fn sd_end() {
unsafe { m5unified_sys::m5u_sd_end() }
}
#[derive(Debug)]
pub struct SdCard;
impl SdCard {
pub fn mount() -> Result<Self, Error> {
sd_begin()
.then_some(Self)
.ok_or(Error::Unavailable("sd card"))
}
pub fn mount_with_config(config: &SdSpiConfig) -> Result<Self, Error> {
sd_begin_with_config(config)
.then_some(Self)
.ok_or(Error::Unavailable("sd card"))
}
pub fn is_mounted(&self) -> bool {
sd_is_mounted()
}
pub const fn mount_path(&self) -> &'static str {
SD_MOUNT_PATH
}
pub fn path_for(path: impl AsRef<Path>) -> PathBuf {
let path = path.as_ref();
if path.is_absolute() {
path.to_path_buf()
} else {
Path::new(SD_MOUNT_PATH).join(path)
}
}
pub fn read(&self, path: impl AsRef<Path>) -> std::io::Result<Vec<u8>> {
std::fs::read(Self::path_for(path))
}
}
impl Drop for SdCard {
fn drop(&mut self) {
sd_end();
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct SdSpiConfig {
pub pin_sclk: i32,
pub pin_mosi: i32,
pub pin_miso: i32,
pub pin_cs: i32,
pub host_id: i32,
pub frequency_khz: u32,
pub max_files: i32,
pub format_if_mount_failed: bool,
}
impl SdSpiConfig {
fn to_raw(self) -> m5unified_sys::m5u_sd_spi_config_t {
m5unified_sys::m5u_sd_spi_config_t {
pin_sclk: self.pin_sclk as c_int,
pin_mosi: self.pin_mosi as c_int,
pin_miso: self.pin_miso as c_int,
pin_cs: self.pin_cs as c_int,
host_id: self.host_id as c_int,
frequency_khz: self.frequency_khz,
max_files: self.max_files as c_int,
format_if_mount_failed: u8::from(self.format_if_mount_failed),
}
}
}
impl Default for SdSpiConfig {
fn default() -> Self {
let raw = m5unified_sys::m5u_sd_spi_config_t::default();
Self {
pin_sclk: raw.pin_sclk,
pin_mosi: raw.pin_mosi,
pin_miso: raw.pin_miso,
pin_cs: raw.pin_cs,
host_id: raw.host_id,
frequency_khz: raw.frequency_khz,
max_files: raw.max_files,
format_if_mount_failed: raw.format_if_mount_failed != 0,
}
}
}