aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales Fragoso <[email protected]>2021-05-09 02:19:00 -0300
committerThales Fragoso <[email protected]>2021-05-14 23:40:28 -0300
commit72fb3a75200e143dbdfc1df6aec29a99adb7491d (patch)
tree59d9c83ae7dcb74a786a9381a92c2de3b49c980d
parent0b607ca80a990d7d3696cf95389e35e1dc5dc761 (diff)
Init working :)
-rw-r--r--embassy-stm32/src/sdmmc_v2.rs92
1 files changed, 80 insertions, 12 deletions
diff --git a/embassy-stm32/src/sdmmc_v2.rs b/embassy-stm32/src/sdmmc_v2.rs
index b96b9154e..5ab5313e1 100644
--- a/embassy-stm32/src/sdmmc_v2.rs
+++ b/embassy-stm32/src/sdmmc_v2.rs
@@ -363,7 +363,6 @@ impl<'d> Sdmmc<'d> {
363 // NOTE(unsafe) We have exclusive access to the peripheral 363 // NOTE(unsafe) We have exclusive access to the peripheral
364 unsafe { 364 unsafe {
365 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8)); 365 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8));
366 defmt::info!("pwr");
367 self.cmd(Cmd::idle(), false)?; 366 self.cmd(Cmd::idle(), false)?;
368 367
369 // Check if cards supports CMD8 (with pattern) 368 // Check if cards supports CMD8 (with pattern)
@@ -377,8 +376,6 @@ impl<'d> Sdmmc<'d> {
377 return Err(Error::UnsupportedCardVersion); 376 return Err(Error::UnsupportedCardVersion);
378 }; 377 };
379 378
380 defmt::info!("CMD8");
381
382 let ocr = loop { 379 let ocr = loop {
383 // Signal that next command is a app command 380 // Signal that next command is a app command
384 self.cmd(Cmd::app_cmd(0), false)?; // CMD55 381 self.cmd(Cmd::app_cmd(0), false)?; // CMD55
@@ -408,7 +405,6 @@ impl<'d> Sdmmc<'d> {
408 card.card_type = CardCapacity::SDSC; 405 card.card_type = CardCapacity::SDSC;
409 } 406 }
410 card.ocr = ocr; 407 card.ocr = ocr;
411 defmt::info!("OCR");
412 408
413 self.cmd(Cmd::all_send_cid(), false)?; // CMD2 409 self.cmd(Cmd::all_send_cid(), false)?; // CMD2
414 let cid0 = regs.respr(0).read().cardstatus1() as u128; 410 let cid0 = regs.respr(0).read().cardstatus1() as u128;
@@ -430,12 +426,8 @@ impl<'d> Sdmmc<'d> {
430 card.csd = csd.into(); 426 card.csd = csd.into();
431 427
432 self.select_card(Some(&card))?; 428 self.select_card(Some(&card))?;
433
434 defmt::info!("select");
435 self.get_scr(&mut card).await?; 429 self.get_scr(&mut card).await?;
436 430
437 defmt::info!("scr");
438
439 // Set bus width 431 // Set bus width
440 let (width, acmd_arg) = match self.bus_width { 432 let (width, acmd_arg) = match self.bus_width {
441 BusWidth::Eight => unimplemented!(), 433 BusWidth::Eight => unimplemented!(),
@@ -472,7 +464,7 @@ impl<'d> Sdmmc<'d> {
472 464
473 if freq.0 > 25_000_000 { 465 if freq.0 > 25_000_000 {
474 // Switch to SDR25 466 // Switch to SDR25
475 self.signalling = self.switch_signalling_mode(Signalling::SDR25)?; 467 self.signalling = self.switch_signalling_mode(Signalling::SDR25).await?;
476 468
477 if self.signalling == Signalling::SDR25 { 469 if self.signalling == Signalling::SDR25 {
478 // Set final clock frequency 470 // Set final clock frequency
@@ -598,8 +590,84 @@ impl<'d> Sdmmc<'d> {
598 /// Attempt to set a new signalling mode. The selected 590 /// Attempt to set a new signalling mode. The selected
599 /// signalling mode is returned. Expects the current clock 591 /// signalling mode is returned. Expects the current clock
600 /// frequency to be > 12.5MHz. 592 /// frequency to be > 12.5MHz.
601 fn switch_signalling_mode(&self, signalling: Signalling) -> Result<Signalling, Error> { 593 async fn switch_signalling_mode(
602 self::todo!() 594 &mut self,
595 signalling: Signalling,
596 ) -> Result<Signalling, Error> {
597 // NB PLSS v7_10 4.3.10.4: "the use of SET_BLK_LEN command is not
598 // necessary"
599
600 let set_function = 0x8000_0000
601 | match signalling {
602 // See PLSS v7_10 Table 4-11
603 Signalling::DDR50 => 0xFF_FF04,
604 Signalling::SDR104 => 0xFF_1F03,
605 Signalling::SDR50 => 0xFF_1F02,
606 Signalling::SDR25 => 0xFF_FF01,
607 Signalling::SDR12 => 0xFF_FF00,
608 };
609
610 let mut status = [0u32; 16];
611 let status_addr = &mut status as *mut [u32; 16] as u32;
612
613 // Arm `OnDrop` after the buffer, so it will be dropped first
614 let regs = self.regs();
615 let on_drop = OnDrop::new(move || unsafe { Self::on_drop(regs) });
616
617 unsafe {
618 self.prepare_datapath_transfer(status_addr, 64, 6, Dir::CardToHost);
619 Self::data_interrupts(regs, true);
620 }
621 self.cmd(Cmd::cmd6(set_function), true)?; // CMD6
622
623 let res = poll_fn(|cx| {
624 self.store_waker_and_unmask(&cx);
625 let status = unsafe { regs.star().read() };
626
627 if status.dcrcfail() {
628 return Poll::Ready(Err(Error::Crc));
629 } else if status.dtimeout() {
630 return Poll::Ready(Err(Error::Timeout));
631 } else if status.dataend() {
632 return Poll::Ready(Ok(()));
633 }
634 Poll::Pending
635 })
636 .await;
637
638 unsafe {
639 Self::data_interrupts(regs, false);
640 }
641 Self::clear_interrupt_flags(regs);
642
643 // Host is allowed to use the new functions at least 8
644 // clocks after the end of the switch command
645 // transaction. We know the current clock period is < 80ns,
646 // so a total delay of 640ns is required here
647 for _ in 0..300 {
648 cortex_m::asm::nop();
649 }
650
651 match res {
652 Ok(_) => {
653 on_drop.defuse();
654 unsafe {
655 regs.idmactrlr().modify(|w| w.set_idmaen(false));
656 }
657 // Function Selection of Function Group 1
658 let selection = (u32::from_be(status[4]) >> 24) & 0xF;
659
660 match selection {
661 0 => Ok(Signalling::SDR12),
662 1 => Ok(Signalling::SDR25),
663 2 => Ok(Signalling::SDR50),
664 3 => Ok(Signalling::SDR104),
665 4 => Ok(Signalling::DDR50),
666 _ => Err(Error::UnsupportedCardType),
667 }
668 }
669 Err(e) => Err(e),
670 }
603 } 671 }
604 672
605 /// Query the card status (CMD13, returns R1) 673 /// Query the card status (CMD13, returns R1)
@@ -695,6 +763,7 @@ impl<'d> Sdmmc<'d> {
695 w.set_dtimeoutc(true); 763 w.set_dtimeoutc(true);
696 w.set_txunderrc(true); 764 w.set_txunderrc(true);
697 w.set_rxoverrc(true); 765 w.set_rxoverrc(true);
766 w.set_cmdrendc(true);
698 w.set_cmdsentc(true); 767 w.set_cmdsentc(true);
699 w.set_dataendc(true); 768 w.set_dataendc(true);
700 w.set_dholdc(true); 769 w.set_dholdc(true);
@@ -786,7 +855,6 @@ impl<'d> Sdmmc<'d> {
786 unsafe { 855 unsafe {
787 // CP state machine must be idle 856 // CP state machine must be idle
788 while regs.star().read().cpsmact() {} 857 while regs.star().read().cpsmact() {}
789 defmt::info!("cpsma idle");
790 858
791 // Command arg 859 // Command arg
792 regs.argr().write(|w| w.set_cmdarg(cmd.arg)); 860 regs.argr().write(|w| w.set_cmdarg(cmd.arg));