Init working :)

This commit is contained in:
Thales Fragoso 2021-05-09 02:19:00 -03:00
parent 0b607ca80a
commit 72fb3a7520

View File

@ -363,7 +363,6 @@ impl<'d> Sdmmc<'d> {
// NOTE(unsafe) We have exclusive access to the peripheral // NOTE(unsafe) We have exclusive access to the peripheral
unsafe { unsafe {
regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8)); regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8));
defmt::info!("pwr");
self.cmd(Cmd::idle(), false)?; self.cmd(Cmd::idle(), false)?;
// Check if cards supports CMD8 (with pattern) // Check if cards supports CMD8 (with pattern)
@ -377,8 +376,6 @@ impl<'d> Sdmmc<'d> {
return Err(Error::UnsupportedCardVersion); return Err(Error::UnsupportedCardVersion);
}; };
defmt::info!("CMD8");
let ocr = loop { let ocr = loop {
// Signal that next command is a app command // Signal that next command is a app command
self.cmd(Cmd::app_cmd(0), false)?; // CMD55 self.cmd(Cmd::app_cmd(0), false)?; // CMD55
@ -408,7 +405,6 @@ impl<'d> Sdmmc<'d> {
card.card_type = CardCapacity::SDSC; card.card_type = CardCapacity::SDSC;
} }
card.ocr = ocr; card.ocr = ocr;
defmt::info!("OCR");
self.cmd(Cmd::all_send_cid(), false)?; // CMD2 self.cmd(Cmd::all_send_cid(), false)?; // CMD2
let cid0 = regs.respr(0).read().cardstatus1() as u128; let cid0 = regs.respr(0).read().cardstatus1() as u128;
@ -430,12 +426,8 @@ impl<'d> Sdmmc<'d> {
card.csd = csd.into(); card.csd = csd.into();
self.select_card(Some(&card))?; self.select_card(Some(&card))?;
defmt::info!("select");
self.get_scr(&mut card).await?; self.get_scr(&mut card).await?;
defmt::info!("scr");
// Set bus width // Set bus width
let (width, acmd_arg) = match self.bus_width { let (width, acmd_arg) = match self.bus_width {
BusWidth::Eight => unimplemented!(), BusWidth::Eight => unimplemented!(),
@ -472,7 +464,7 @@ impl<'d> Sdmmc<'d> {
if freq.0 > 25_000_000 { if freq.0 > 25_000_000 {
// Switch to SDR25 // Switch to SDR25
self.signalling = self.switch_signalling_mode(Signalling::SDR25)?; self.signalling = self.switch_signalling_mode(Signalling::SDR25).await?;
if self.signalling == Signalling::SDR25 { if self.signalling == Signalling::SDR25 {
// Set final clock frequency // Set final clock frequency
@ -598,8 +590,84 @@ impl<'d> Sdmmc<'d> {
/// Attempt to set a new signalling mode. The selected /// Attempt to set a new signalling mode. The selected
/// signalling mode is returned. Expects the current clock /// signalling mode is returned. Expects the current clock
/// frequency to be > 12.5MHz. /// frequency to be > 12.5MHz.
fn switch_signalling_mode(&self, signalling: Signalling) -> Result<Signalling, Error> { async fn switch_signalling_mode(
self::todo!() &mut self,
signalling: Signalling,
) -> Result<Signalling, Error> {
// NB PLSS v7_10 4.3.10.4: "the use of SET_BLK_LEN command is not
// necessary"
let set_function = 0x8000_0000
| match signalling {
// See PLSS v7_10 Table 4-11
Signalling::DDR50 => 0xFF_FF04,
Signalling::SDR104 => 0xFF_1F03,
Signalling::SDR50 => 0xFF_1F02,
Signalling::SDR25 => 0xFF_FF01,
Signalling::SDR12 => 0xFF_FF00,
};
let mut status = [0u32; 16];
let status_addr = &mut status as *mut [u32; 16] as u32;
// Arm `OnDrop` after the buffer, so it will be dropped first
let regs = self.regs();
let on_drop = OnDrop::new(move || unsafe { Self::on_drop(regs) });
unsafe {
self.prepare_datapath_transfer(status_addr, 64, 6, Dir::CardToHost);
Self::data_interrupts(regs, true);
}
self.cmd(Cmd::cmd6(set_function), true)?; // CMD6
let res = poll_fn(|cx| {
self.store_waker_and_unmask(&cx);
let status = unsafe { regs.star().read() };
if status.dcrcfail() {
return Poll::Ready(Err(Error::Crc));
} else if status.dtimeout() {
return Poll::Ready(Err(Error::Timeout));
} else if status.dataend() {
return Poll::Ready(Ok(()));
}
Poll::Pending
})
.await;
unsafe {
Self::data_interrupts(regs, false);
}
Self::clear_interrupt_flags(regs);
// Host is allowed to use the new functions at least 8
// clocks after the end of the switch command
// transaction. We know the current clock period is < 80ns,
// so a total delay of 640ns is required here
for _ in 0..300 {
cortex_m::asm::nop();
}
match res {
Ok(_) => {
on_drop.defuse();
unsafe {
regs.idmactrlr().modify(|w| w.set_idmaen(false));
}
// Function Selection of Function Group 1
let selection = (u32::from_be(status[4]) >> 24) & 0xF;
match selection {
0 => Ok(Signalling::SDR12),
1 => Ok(Signalling::SDR25),
2 => Ok(Signalling::SDR50),
3 => Ok(Signalling::SDR104),
4 => Ok(Signalling::DDR50),
_ => Err(Error::UnsupportedCardType),
}
}
Err(e) => Err(e),
}
} }
/// Query the card status (CMD13, returns R1) /// Query the card status (CMD13, returns R1)
@ -695,6 +763,7 @@ impl<'d> Sdmmc<'d> {
w.set_dtimeoutc(true); w.set_dtimeoutc(true);
w.set_txunderrc(true); w.set_txunderrc(true);
w.set_rxoverrc(true); w.set_rxoverrc(true);
w.set_cmdrendc(true);
w.set_cmdsentc(true); w.set_cmdsentc(true);
w.set_dataendc(true); w.set_dataendc(true);
w.set_dholdc(true); w.set_dholdc(true);
@ -786,7 +855,6 @@ impl<'d> Sdmmc<'d> {
unsafe { unsafe {
// CP state machine must be idle // CP state machine must be idle
while regs.star().read().cpsmact() {} while regs.star().read().cpsmact() {}
defmt::info!("cpsma idle");
// Command arg // Command arg
regs.argr().write(|w| w.set_cmdarg(cmd.arg)); regs.argr().write(|w| w.set_cmdarg(cmd.arg));