use atsamd_hal::{
clock::{GenericClockController, Sercom6CoreClock},
delay::Delay,
pac::{Mclk, Qspi},
prelude::*,
qspi,
sercom::{spi, IoSet1, Sercom6},
time::Hertz,
typelevel::NoneT,
};
use embedded_hal_bus::spi::{ExclusiveDevice, NoDelay};
use embedded_sdmmc::{SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager};
use super::pins::aliases::*;
pub struct QSPIFlash {
pub sck: QspiSckReset,
pub cs: QspiCsReset,
pub d0: QspiD0Reset,
pub d1: QspiD1Reset,
pub d2: QspiD2Reset,
pub d3: QspiD3Reset,
}
impl QSPIFlash {
pub fn init(self, mclk: &mut Mclk, qspi: Qspi) -> qspi::Qspi<qspi::OneShot> {
qspi::Qspi::new(
mclk, qspi, self.sck, self.cs, self.d0, self.d1, self.d2, self.d3,
)
}
}
pub struct SDCard {
pub cs: SdCsReset,
pub mosi: SdMosiReset,
pub sck: SdSckReset,
pub miso: SdMisoReset,
pub det: SdDetReset,
}
pub type SdPads = spi::Pads<Sercom6, IoSet1, SdMiso, SdMosi, SdSck>;
pub type SdSpi = spi::Spi<spi::Config<SdPads>, spi::Duplex>;
type Controller<TS> = embedded_sdmmc::VolumeManager<
embedded_sdmmc::SdCard<ExclusiveDevice<SdSpi, SdCs, NoDelay>, Delay>,
TS,
>;
pub struct SDCardController<TS: TimeSource> {
pub volume: Controller<TS>,
sercom6_clk: Sercom6CoreClock,
}
impl<TS: TimeSource> core::ops::Deref for SDCardController<TS> {
type Target = Controller<TS>;
fn deref(&self) -> &Self::Target {
&self.volume
}
}
impl<TS: TimeSource> core::ops::DerefMut for SDCardController<TS> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.volume
}
}
impl SDCard {
pub fn init<TS: TimeSource>(
self,
clocks: &mut GenericClockController,
sercom6: Sercom6,
mclk: &mut Mclk,
delay: Delay,
ts: TS,
) -> Result<(SDCardController<TS>, SdDet), ()> {
let gclk0 = clocks.gclk0();
let sercom6_clk = clocks.sercom6_core(&gclk0).ok_or(())?;
let pads = spi::Pads::default()
.data_out(self.mosi)
.data_in(self.miso)
.sclk(self.sck);
let sdmmc_spi_bus = spi::Config::new(mclk, sercom6, pads, sercom6_clk.freq())
.spi_mode(spi::MODE_0)
.baud(400.kHz())
.enable();
let sdmmc_cs = self.cs.into_push_pull_output();
let sdmmc_spi = ExclusiveDevice::new_no_delay(sdmmc_spi_bus, sdmmc_cs)
.expect("Failed to create SpiDevice");
let card = embedded_sdmmc::SdCard::new(sdmmc_spi, delay);
let mut volume_mgr = VolumeManager::new(card, ts);
Ok((
SDCardController {
volume: volume_mgr,
sercom6_clk,
},
self.det.into(),
))
}
}