use embedded_hal::{delay::DelayNs, spi::SpiDevice};
use crate::pins::SpiSdPins;
pub const DEFAULT_SPI_HZ: u32 = 25_000_000;
pub const CARD_DETECT_P0_BIT: u8 = 4;
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SdCardSlot {
pub spi: SpiSdPins,
pub spi_hz: u32,
pub detect: SdCardDetect,
}
impl SdCardSlot {
pub const CORE_S3: Self = Self {
spi: SpiSdPins::TF_CARD,
spi_hz: DEFAULT_SPI_HZ,
detect: SdCardDetect::AW9523B_P0_4_ACTIVE_LOW,
};
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SdCardDetect {
pub port: u8,
pub bit: u8,
pub active_low: bool,
}
impl SdCardDetect {
pub const AW9523B_P0_4_ACTIVE_LOW: Self = Self {
port: 0,
bit: CARD_DETECT_P0_BIT,
active_low: true,
};
pub const fn present_from_port_value(self, value: u8) -> bool {
let high = (value & (1 << self.bit)) != 0;
if self.active_low { !high } else { high }
}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CoreS3SdSlot {
pub sclk_gpio: u8,
pub mosi_gpio: u8,
pub miso_gpio: u8,
pub cs_gpio: u8,
pub max_frequency_hz: u32,
pub card_detect_gpio: Option<u8>,
pub power_enable_gpio: Option<u8>,
}
impl CoreS3SdSlot {
pub const CORE_S3: Self = Self {
sclk_gpio: 36,
mosi_gpio: 37,
miso_gpio: 35,
cs_gpio: 4,
max_frequency_hz: DEFAULT_SPI_HZ,
card_detect_gpio: None,
power_enable_gpio: None,
};
}
impl From<SdCardSlot> for CoreS3SdSlot {
fn from(slot: SdCardSlot) -> Self {
Self {
sclk_gpio: slot.spi.sclk.0,
mosi_gpio: slot.spi.mosi.0,
miso_gpio: slot.spi.miso.0,
cs_gpio: slot.spi.cs.0,
max_frequency_hz: slot.spi_hz,
card_detect_gpio: None,
power_enable_gpio: None,
}
}
}
pub struct CoreS3SdParts<SPI, DELAY> {
pub spi_device: SPI,
pub delay: DELAY,
pub slot: CoreS3SdSlot,
}
impl<SPI, DELAY> CoreS3SdParts<SPI, DELAY>
where
SPI: SpiDevice,
DELAY: DelayNs,
{
#[cfg(feature = "sdmmc")]
pub fn into_sdmmc(self) -> embedded_sdmmc::SdCard<SPI, DELAY> {
embedded_sdmmc::SdCard::new(self.spi_device, self.delay)
}
}
pub const fn core_s3_card_present_from_aw9523_p0(value: u8) -> bool {
SdCardDetect::AW9523B_P0_4_ACTIVE_LOW.present_from_port_value(value)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn card_detect_is_active_low_on_p0_bit4() {
assert!(core_s3_card_present_from_aw9523_p0(0b1110_1111));
assert!(!core_s3_card_present_from_aw9523_p0(0b0001_0000));
}
}