mod adma2;
mod card_info;
mod command;
mod consts;
mod control;
mod init;
mod read;
mod write;
pub use adma2::{
ADMA2_ATTR_ACT_TRAN, ADMA2_ATTR_END, ADMA2_ATTR_INT, ADMA2_ATTR_VALID, ADMA2_MAX_PER_DESC,
Adma2Desc,
};
pub use card_info::{SdCardInfo, parse_sd_card_info};
pub use consts::{BLOCK_SIZE, CmdError, CommandType, PowerLevel, ResponseType};
pub use consts::{SD_DRIVER_BASE, SdmmcRegisters, TOP_BASE};
use consts::{PRESENT_STATE, TopRegisters};
use core::cell::Cell;
use tock_registers::interfaces::Readable;
use crate::pinmux::Pinmux;
pub struct Sdmmc {
regs: &'static SdmmcRegisters,
top_regs: &'static TopRegisters,
pinmux: Option<Pinmux>,
card_info: Cell<SdCardInfo>,
}
impl Sdmmc {
pub unsafe fn new(sd_base: usize, top_base: usize) -> Self {
unsafe {
Self {
regs: &*(sd_base as *const SdmmcRegisters),
top_regs: &*(top_base as *const TopRegisters),
pinmux: None,
card_info: Cell::new(SdCardInfo::default()),
}
}
}
pub fn set_pinmux(&mut self, pinmux: Pinmux) {
self.pinmux = Some(pinmux);
}
pub fn is_card_inserted(&self) -> bool {
self.regs.present_state.is_set(PRESENT_STATE::CARD_INSERTED)
}
}
pub unsafe fn init(
sd_base: usize,
top_base: usize,
fmux_base: usize,
ioblk_base: usize,
ioblk_grtc_base: usize,
) -> Result<Sdmmc, CmdError> {
let mut sdmmc = unsafe { Sdmmc::new(sd_base, top_base) };
sdmmc.set_pinmux(unsafe { Pinmux::new(fmux_base, ioblk_base, ioblk_grtc_base) });
sdmmc.init()?;
Ok(sdmmc)
}