aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs394
1 files changed, 212 insertions, 182 deletions
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index 37ef7099f..74a6f13fa 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -9,6 +9,7 @@ use core::task::Poll;
9 9
10use embassy_hal_internal::drop::OnDrop; 10use embassy_hal_internal::drop::OnDrop;
11use embassy_hal_internal::{Peri, PeripheralType}; 11use embassy_hal_internal::{Peri, PeripheralType};
12use embassy_sync::mutex::Mutex;
12use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
13use sdio_host::common_cmd::{self, Resp, ResponseLen}; 14use sdio_host::common_cmd::{self, Resp, ResponseLen};
14use sdio_host::emmc::{EMMC, ExtCSD}; 15use sdio_host::emmc::{EMMC, ExtCSD};
@@ -22,7 +23,7 @@ use crate::gpio::Pull;
22use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; 23use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
23use crate::interrupt::typelevel::Interrupt; 24use crate::interrupt::typelevel::Interrupt;
24use crate::pac::sdmmc::Sdmmc as RegBlock; 25use crate::pac::sdmmc::Sdmmc as RegBlock;
25use crate::rcc::{self, RccPeripheral}; 26use crate::rcc::{self, RccInfo, RccPeripheral, SealedRccPeripheral};
26use crate::time::Hertz; 27use crate::time::Hertz;
27use crate::{interrupt, peripherals}; 28use crate::{interrupt, peripherals};
28 29
@@ -31,28 +32,11 @@ pub struct InterruptHandler<T: Instance> {
31 _phantom: PhantomData<T>, 32 _phantom: PhantomData<T>,
32} 33}
33 34
34impl<T: Instance> InterruptHandler<T> {
35 fn enable_interrupts() {
36 let regs = T::regs();
37 regs.maskr().write(|w| {
38 w.set_dcrcfailie(true);
39 w.set_dtimeoutie(true);
40 w.set_dataendie(true);
41 w.set_dbckendie(true);
42
43 #[cfg(sdmmc_v1)]
44 w.set_stbiterre(true);
45 #[cfg(sdmmc_v2)]
46 w.set_dabortie(true);
47 });
48 }
49}
50
51impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { 35impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
52 unsafe fn on_interrupt() { 36 unsafe fn on_interrupt() {
53 T::state().wake(); 37 T::state().waker.wake();
54 let status = T::regs().star().read(); 38 let status = T::info().regs.star().read();
55 T::regs().maskr().modify(|w| { 39 T::info().regs.maskr().modify(|w| {
56 if status.dcrcfail() { 40 if status.dcrcfail() {
57 w.set_dcrcfailie(false) 41 w.set_dcrcfailie(false)
58 } 42 }
@@ -379,8 +363,10 @@ impl SdmmcPeripheral {
379} 363}
380 364
381/// Sdmmc device 365/// Sdmmc device
382pub struct Sdmmc<'d, T: Instance> { 366pub struct Sdmmc<'d> {
383 _peri: Peri<'d, T>, 367 info: &'static Info,
368 state: &'static State,
369 ker_clk: Hertz,
384 #[cfg(sdmmc_v1)] 370 #[cfg(sdmmc_v1)]
385 dma: ChannelAndRequest<'d>, 371 dma: ChannelAndRequest<'d>,
386 372
@@ -416,9 +402,9 @@ const CMD_AF: AfType = AfType::output_pull(OutputType::PushPull, Speed::VeryHigh
416const DATA_AF: AfType = CMD_AF; 402const DATA_AF: AfType = CMD_AF;
417 403
418#[cfg(sdmmc_v1)] 404#[cfg(sdmmc_v1)]
419impl<'d, T: Instance> Sdmmc<'d, T> { 405impl<'d> Sdmmc<'d> {
420 /// Create a new SDMMC driver, with 1 data lane. 406 /// Create a new SDMMC driver, with 1 data lane.
421 pub fn new_1bit( 407 pub fn new_1bit<T: Instance>(
422 sdmmc: Peri<'d, T>, 408 sdmmc: Peri<'d, T>,
423 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 409 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
424 dma: Peri<'d, impl SdmmcDma<T>>, 410 dma: Peri<'d, impl SdmmcDma<T>>,
@@ -451,7 +437,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
451 } 437 }
452 438
453 /// Create a new SDMMC driver, with 4 data lanes. 439 /// Create a new SDMMC driver, with 4 data lanes.
454 pub fn new_4bit( 440 pub fn new_4bit<T: Instance>(
455 sdmmc: Peri<'d, T>, 441 sdmmc: Peri<'d, T>,
456 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 442 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
457 dma: Peri<'d, impl SdmmcDma<T>>, 443 dma: Peri<'d, impl SdmmcDma<T>>,
@@ -491,9 +477,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
491} 477}
492 478
493#[cfg(sdmmc_v1)] 479#[cfg(sdmmc_v1)]
494impl<'d, T: Instance> Sdmmc<'d, T> { 480impl<'d> Sdmmc<'d> {
495 /// Create a new SDMMC driver, with 8 data lanes. 481 /// Create a new SDMMC driver, with 8 data lanes.
496 pub fn new_8bit( 482 pub fn new_8bit<T: Instance>(
497 sdmmc: Peri<'d, T>, 483 sdmmc: Peri<'d, T>,
498 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 484 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
499 dma: Peri<'d, impl SdmmcDma<T>>, 485 dma: Peri<'d, impl SdmmcDma<T>>,
@@ -541,9 +527,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
541} 527}
542 528
543#[cfg(sdmmc_v2)] 529#[cfg(sdmmc_v2)]
544impl<'d, T: Instance> Sdmmc<'d, T> { 530impl<'d> Sdmmc<'d> {
545 /// Create a new SDMMC driver, with 1 data lane. 531 /// Create a new SDMMC driver, with 1 data lane.
546 pub fn new_1bit( 532 pub fn new_1bit<T: Instance>(
547 sdmmc: Peri<'d, T>, 533 sdmmc: Peri<'d, T>,
548 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 534 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
549 clk: Peri<'d, impl CkPin<T>>, 535 clk: Peri<'d, impl CkPin<T>>,
@@ -574,7 +560,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
574 } 560 }
575 561
576 /// Create a new SDMMC driver, with 4 data lanes. 562 /// Create a new SDMMC driver, with 4 data lanes.
577 pub fn new_4bit( 563 pub fn new_4bit<T: Instance>(
578 sdmmc: Peri<'d, T>, 564 sdmmc: Peri<'d, T>,
579 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 565 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
580 clk: Peri<'d, impl CkPin<T>>, 566 clk: Peri<'d, impl CkPin<T>>,
@@ -612,9 +598,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
612} 598}
613 599
614#[cfg(sdmmc_v2)] 600#[cfg(sdmmc_v2)]
615impl<'d, T: Instance> Sdmmc<'d, T> { 601impl<'d> Sdmmc<'d> {
616 /// Create a new SDMMC driver, with 8 data lanes. 602 /// Create a new SDMMC driver, with 8 data lanes.
617 pub fn new_8bit( 603 pub fn new_8bit<T: Instance>(
618 sdmmc: Peri<'d, T>, 604 sdmmc: Peri<'d, T>,
619 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 605 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
620 clk: Peri<'d, impl CkPin<T>>, 606 clk: Peri<'d, impl CkPin<T>>,
@@ -659,9 +645,24 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
659 } 645 }
660} 646}
661 647
662impl<'d, T: Instance> Sdmmc<'d, T> { 648impl<'d> Sdmmc<'d> {
663 fn new_inner( 649 fn enable_interrupts(&self) {
664 sdmmc: Peri<'d, T>, 650 let regs = self.info.regs;
651 regs.maskr().write(|w| {
652 w.set_dcrcfailie(true);
653 w.set_dtimeoutie(true);
654 w.set_dataendie(true);
655 w.set_dbckendie(true);
656
657 #[cfg(sdmmc_v1)]
658 w.set_stbiterre(true);
659 #[cfg(sdmmc_v2)]
660 w.set_dabortie(true);
661 });
662 }
663
664 fn new_inner<T: Instance>(
665 _sdmmc: Peri<'d, T>,
665 #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>, 666 #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>,
666 clk: Peri<'d, AnyPin>, 667 clk: Peri<'d, AnyPin>,
667 cmd: Peri<'d, AnyPin>, 668 cmd: Peri<'d, AnyPin>,
@@ -680,8 +681,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
680 T::Interrupt::unpend(); 681 T::Interrupt::unpend();
681 unsafe { T::Interrupt::enable() }; 682 unsafe { T::Interrupt::enable() };
682 683
683 let regs = T::regs(); 684 let info = T::info();
684 regs.clkcr().write(|w| { 685 let state = T::state();
686 let ker_clk = T::frequency();
687
688 info.regs.clkcr().write(|w| {
685 w.set_pwrsav(false); 689 w.set_pwrsav(false);
686 w.set_negedge(false); 690 w.set_negedge(false);
687 691
@@ -698,10 +702,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
698 702
699 // Power off, writen 00: Clock to the card is stopped; 703 // Power off, writen 00: Clock to the card is stopped;
700 // D[7:0], CMD, and CK are driven high. 704 // D[7:0], CMD, and CK are driven high.
701 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::Off as u8)); 705 info.regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::Off as u8));
702 706
703 Self { 707 Self {
704 _peri: sdmmc, 708 info,
709 state,
710 ker_clk,
705 #[cfg(sdmmc_v1)] 711 #[cfg(sdmmc_v1)]
706 dma, 712 dma,
707 713
@@ -726,8 +732,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
726 732
727 /// Data transfer is in progress 733 /// Data transfer is in progress
728 #[inline] 734 #[inline]
729 fn data_active() -> bool { 735 fn data_active(&self) -> bool {
730 let regs = T::regs(); 736 let regs = self.info.regs;
731 737
732 let status = regs.star().read(); 738 let status = regs.star().read();
733 #[cfg(sdmmc_v1)] 739 #[cfg(sdmmc_v1)]
@@ -738,8 +744,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
738 744
739 /// Coammand transfer is in progress 745 /// Coammand transfer is in progress
740 #[inline] 746 #[inline]
741 fn cmd_active() -> bool { 747 fn cmd_active(&self) -> bool {
742 let regs = T::regs(); 748 let regs = self.info.regs;
743 749
744 let status = regs.star().read(); 750 let status = regs.star().read();
745 #[cfg(sdmmc_v1)] 751 #[cfg(sdmmc_v1)]
@@ -750,8 +756,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
750 756
751 /// Wait idle on CMDACT, RXACT and TXACT (v1) or DOSNACT and CPSMACT (v2) 757 /// Wait idle on CMDACT, RXACT and TXACT (v1) or DOSNACT and CPSMACT (v2)
752 #[inline] 758 #[inline]
753 fn wait_idle() { 759 fn wait_idle(&self) {
754 while Self::data_active() || Self::cmd_active() {} 760 while self.data_active() || self.cmd_active() {}
755 } 761 }
756 762
757 /// # Safety 763 /// # Safety
@@ -759,6 +765,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
759 /// `buffer` must be valid for the whole transfer and word aligned 765 /// `buffer` must be valid for the whole transfer and word aligned
760 #[allow(unused_variables)] 766 #[allow(unused_variables)]
761 fn prepare_datapath_read<'a>( 767 fn prepare_datapath_read<'a>(
768 &self,
762 config: &Config, 769 config: &Config,
763 #[cfg(sdmmc_v1)] dma: &'a mut ChannelAndRequest<'d>, 770 #[cfg(sdmmc_v1)] dma: &'a mut ChannelAndRequest<'d>,
764 buffer: &'a mut [u32], 771 buffer: &'a mut [u32],
@@ -766,11 +773,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
766 block_size: u8, 773 block_size: u8,
767 ) -> Transfer<'a> { 774 ) -> Transfer<'a> {
768 assert!(block_size <= 14, "Block size up to 2^14 bytes"); 775 assert!(block_size <= 14, "Block size up to 2^14 bytes");
769 let regs = T::regs(); 776 let regs = self.info.regs;
770 777
771 // Command AND Data state machines must be idle 778 // Command AND Data state machines must be idle
772 Self::wait_idle(); 779 self.wait_idle();
773 Self::clear_interrupt_flags(); 780 self.clear_interrupt_flags();
774 781
775 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 782 regs.dlenr().write(|w| w.set_datalength(length_bytes));
776 783
@@ -801,13 +808,13 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
801 /// # Safety 808 /// # Safety
802 /// 809 ///
803 /// `buffer` must be valid for the whole transfer and word aligned 810 /// `buffer` must be valid for the whole transfer and word aligned
804 fn prepare_datapath_write<'a>(&'a mut self, buffer: &'a [u32], length_bytes: u32, block_size: u8) -> Transfer<'a> { 811 fn prepare_datapath_write<'a>(&self, buffer: &'a [u32], length_bytes: u32, block_size: u8) -> Transfer<'a> {
805 assert!(block_size <= 14, "Block size up to 2^14 bytes"); 812 assert!(block_size <= 14, "Block size up to 2^14 bytes");
806 let regs = T::regs(); 813 let regs = self.info.regs;
807 814
808 // Command AND Data state machines must be idle 815 // Command AND Data state machines must be idle
809 Self::wait_idle(); 816 self.wait_idle();
810 Self::clear_interrupt_flags(); 817 self.clear_interrupt_flags();
811 818
812 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 819 regs.dlenr().write(|w| w.set_datalength(length_bytes));
813 820
@@ -839,8 +846,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
839 } 846 }
840 847
841 /// Stops the DMA datapath 848 /// Stops the DMA datapath
842 fn stop_datapath() { 849 fn stop_datapath(&self) {
843 let regs = T::regs(); 850 let regs = self.info.regs;
844 851
845 #[cfg(sdmmc_v1)] 852 #[cfg(sdmmc_v1)]
846 regs.dctrl().modify(|w| { 853 regs.dctrl().modify(|w| {
@@ -853,7 +860,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
853 860
854 /// Sets the CLKDIV field in CLKCR. Updates clock field in self 861 /// Sets the CLKDIV field in CLKCR. Updates clock field in self
855 fn clkcr_set_clkdiv(&mut self, freq: u32, width: BusWidth) -> Result<(), Error> { 862 fn clkcr_set_clkdiv(&mut self, freq: u32, width: BusWidth) -> Result<(), Error> {
856 let regs = T::regs(); 863 let regs = self.info.regs;
857 864
858 let width_u32 = match width { 865 let width_u32 = match width {
859 BusWidth::One => 1u32, 866 BusWidth::One => 1u32,
@@ -862,17 +869,16 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
862 _ => panic!("Invalid Bus Width"), 869 _ => panic!("Invalid Bus Width"),
863 }; 870 };
864 871
865 let ker_ck = T::frequency(); 872 let (_bypass, clkdiv, new_clock) = clk_div(self.ker_clk, freq)?;
866 let (_bypass, clkdiv, new_clock) = clk_div(ker_ck, freq)?;
867 873
868 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7 874 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7
869 // Section 55.5.8 875 // Section 55.5.8
870 let sdmmc_bus_bandwidth = new_clock.0 * width_u32; 876 let sdmmc_bus_bandwidth = new_clock.0 * width_u32;
871 assert!(ker_ck.0 > 3 * sdmmc_bus_bandwidth / 32); 877 assert!(self.ker_clk.0 > 3 * sdmmc_bus_bandwidth / 32);
872 self.clock = new_clock; 878 self.clock = new_clock;
873 879
874 // CPSMACT and DPSMACT must be 0 to set CLKDIV 880 // CPSMACT and DPSMACT must be 0 to set CLKDIV
875 Self::wait_idle(); 881 self.wait_idle();
876 regs.clkcr().modify(|w| { 882 regs.clkcr().modify(|w| {
877 w.set_clkdiv(clkdiv); 883 w.set_clkdiv(clkdiv);
878 #[cfg(sdmmc_v1)] 884 #[cfg(sdmmc_v1)]
@@ -887,10 +893,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
887 where 893 where
888 CardStatus<Ext>: From<u32>, 894 CardStatus<Ext>: From<u32>,
889 { 895 {
890 let regs = T::regs(); 896 let regs = self.info.regs;
891 let rca = card.get_address(); 897 let rca = card.get_address();
892 898
893 Self::cmd(common_cmd::card_status(rca, false), false)?; // CMD13 899 self.cmd(common_cmd::card_status(rca, false), false)?; // CMD13
894 900
895 let r1 = regs.respr(0).read().cardstatus(); 901 let r1 = regs.respr(0).read().cardstatus();
896 Ok(r1.into()) 902 Ok(r1.into())
@@ -904,7 +910,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
904 // Determine Relative Card Address (RCA) of given card 910 // Determine Relative Card Address (RCA) of given card
905 let rca = rca.unwrap_or(0); 911 let rca = rca.unwrap_or(0);
906 912
907 let r = Self::cmd(common_cmd::select_card(rca), false); 913 let r = self.cmd(common_cmd::select_card(rca), false);
908 match (r, rca) { 914 match (r, rca) {
909 (Err(Error::Timeout), 0) => Ok(()), 915 (Err(Error::Timeout), 0) => Ok(()),
910 _ => r, 916 _ => r,
@@ -913,8 +919,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
913 919
914 /// Clear flags in interrupt clear register 920 /// Clear flags in interrupt clear register
915 #[inline] 921 #[inline]
916 fn clear_interrupt_flags() { 922 fn clear_interrupt_flags(&self) {
917 let regs = T::regs(); 923 let regs = self.info.regs;
918 regs.icr().write(|w| { 924 regs.icr().write(|w| {
919 w.set_ccrcfailc(true); 925 w.set_ccrcfailc(true);
920 w.set_dcrcfailc(true); 926 w.set_dcrcfailc(true);
@@ -947,12 +953,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
947 953
948 /// Send command to card 954 /// Send command to card
949 #[allow(unused_variables)] 955 #[allow(unused_variables)]
950 fn cmd<R: Resp>(cmd: Cmd<R>, data: bool) -> Result<(), Error> { 956 fn cmd<R: Resp>(&self, cmd: Cmd<R>, data: bool) -> Result<(), Error> {
951 let regs = T::regs(); 957 let regs = self.info.regs;
952 958
953 Self::clear_interrupt_flags(); 959 self.clear_interrupt_flags();
954 // CP state machine must be idle 960 // CP state machine must be idle
955 while Self::cmd_active() {} 961 while self.cmd_active() {}
956 962
957 // Command arg 963 // Command arg
958 regs.argr().write(|w| w.set_cmdarg(cmd.arg)); 964 regs.argr().write(|w| w.set_cmdarg(cmd.arg));
@@ -997,13 +1003,13 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
997 Ok(()) 1003 Ok(())
998 } 1004 }
999 1005
1000 fn on_drop() { 1006 fn on_drop(&self) {
1001 let regs = T::regs(); 1007 let regs = self.info.regs;
1002 if Self::data_active() { 1008 if self.data_active() {
1003 Self::clear_interrupt_flags(); 1009 self.clear_interrupt_flags();
1004 // Send abort 1010 // Send abort
1005 // CP state machine must be idle 1011 // CP state machine must be idle
1006 while Self::cmd_active() {} 1012 while self.cmd_active() {}
1007 1013
1008 // Command arg 1014 // Command arg
1009 regs.argr().write(|w| w.set_cmdarg(0)); 1015 regs.argr().write(|w| w.set_cmdarg(0));
@@ -1023,22 +1029,22 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1023 }); 1029 });
1024 1030
1025 // Wait for the abort 1031 // Wait for the abort
1026 while Self::data_active() {} 1032 while self.data_active() {}
1027 } 1033 }
1028 regs.maskr().write(|_| ()); // disable irqs 1034 regs.maskr().write(|_| ()); // disable irqs
1029 Self::clear_interrupt_flags(); 1035 self.clear_interrupt_flags();
1030 Self::stop_datapath(); 1036 self.stop_datapath();
1031 } 1037 }
1032 1038
1033 /// Wait for a previously started datapath transfer to complete from an interrupt. 1039 /// Wait for a previously started datapath transfer to complete from an interrupt.
1034 #[inline] 1040 #[inline]
1035 #[allow(unused)] 1041 #[allow(unused)]
1036 async fn complete_datapath_transfer(block: bool) -> Result<(), Error> { 1042 async fn complete_datapath_transfer(&self, block: bool) -> Result<(), Error> {
1037 let res = poll_fn(|cx| { 1043 let res = poll_fn(|cx| {
1038 // Compiler might not be sufficiently constrained here 1044 // Compiler might not be sufficiently constrained here
1039 // https://github.com/embassy-rs/embassy/issues/4723 1045 // https://github.com/embassy-rs/embassy/issues/4723
1040 T::state().register(cx.waker()); 1046 self.state.waker.register(cx.waker());
1041 let status = T::regs().star().read(); 1047 let status = self.info.regs.star().read();
1042 1048
1043 if status.dcrcfail() { 1049 if status.dcrcfail() {
1044 return Poll::Ready(Err(Error::Crc)); 1050 return Poll::Ready(Err(Error::Crc));
@@ -1067,7 +1073,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1067 }) 1073 })
1068 .await; 1074 .await;
1069 1075
1070 Self::clear_interrupt_flags(); 1076 self.clear_interrupt_flags();
1071 1077
1072 res 1078 res
1073 } 1079 }
@@ -1075,7 +1081,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1075 /// Read a data block. 1081 /// Read a data block.
1076 #[inline] 1082 #[inline]
1077 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> { 1083 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> {
1078 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1084 let _scoped_block_stop = self.info.rcc.block_stop();
1079 let card_capacity = self.card()?.get_capacity(); 1085 let card_capacity = self.card()?.get_capacity();
1080 1086
1081 // NOTE(unsafe) DataBlock uses align 4 1087 // NOTE(unsafe) DataBlock uses align 4
@@ -1087,11 +1093,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1087 CardCapacity::StandardCapacity => block_idx * 512, 1093 CardCapacity::StandardCapacity => block_idx * 512,
1088 _ => block_idx, 1094 _ => block_idx,
1089 }; 1095 };
1090 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1096 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1091 1097
1092 let on_drop = OnDrop::new(|| Self::on_drop()); 1098 let on_drop = OnDrop::new(|| self.on_drop());
1093 1099
1094 let transfer = Self::prepare_datapath_read( 1100 let transfer = self.prepare_datapath_read(
1095 &self.config, 1101 &self.config,
1096 #[cfg(sdmmc_v1)] 1102 #[cfg(sdmmc_v1)]
1097 &mut self.dma, 1103 &mut self.dma,
@@ -1099,14 +1105,14 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1099 512, 1105 512,
1100 9, 1106 9,
1101 ); 1107 );
1102 InterruptHandler::<T>::enable_interrupts(); 1108 self.enable_interrupts();
1103 Self::cmd(common_cmd::read_single_block(address), true)?; 1109 self.cmd(common_cmd::read_single_block(address), true)?;
1104 1110
1105 let res = Self::complete_datapath_transfer(true).await; 1111 let res = self.complete_datapath_transfer(true).await;
1106 1112
1107 if res.is_ok() { 1113 if res.is_ok() {
1108 on_drop.defuse(); 1114 on_drop.defuse();
1109 Self::stop_datapath(); 1115 self.stop_datapath();
1110 drop(transfer); 1116 drop(transfer);
1111 } 1117 }
1112 res 1118 res
@@ -1115,7 +1121,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1115 /// Read multiple data blocks. 1121 /// Read multiple data blocks.
1116 #[inline] 1122 #[inline]
1117 pub async fn read_blocks(&mut self, block_idx: u32, blocks: &mut [DataBlock]) -> Result<(), Error> { 1123 pub async fn read_blocks(&mut self, block_idx: u32, blocks: &mut [DataBlock]) -> Result<(), Error> {
1118 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1124 let _scoped_block_stop = self.info.rcc.block_stop();
1119 let card_capacity = self.card()?.get_capacity(); 1125 let card_capacity = self.card()?.get_capacity();
1120 1126
1121 // NOTE(unsafe) reinterpret buffer as &mut [u32] 1127 // NOTE(unsafe) reinterpret buffer as &mut [u32]
@@ -1131,11 +1137,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1131 CardCapacity::StandardCapacity => block_idx * 512, 1137 CardCapacity::StandardCapacity => block_idx * 512,
1132 _ => block_idx, 1138 _ => block_idx,
1133 }; 1139 };
1134 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1140 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1135 1141
1136 let on_drop = OnDrop::new(|| Self::on_drop()); 1142 let on_drop = OnDrop::new(|| self.on_drop());
1137 1143
1138 let transfer = Self::prepare_datapath_read( 1144 let transfer = self.prepare_datapath_read(
1139 &self.config, 1145 &self.config,
1140 #[cfg(sdmmc_v1)] 1146 #[cfg(sdmmc_v1)]
1141 &mut self.dma, 1147 &mut self.dma,
@@ -1143,18 +1149,18 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1143 512 * blocks.len() as u32, 1149 512 * blocks.len() as u32,
1144 9, 1150 9,
1145 ); 1151 );
1146 InterruptHandler::<T>::enable_interrupts(); 1152 self.enable_interrupts();
1147 1153
1148 Self::cmd(common_cmd::read_multiple_blocks(address), true)?; 1154 self.cmd(common_cmd::read_multiple_blocks(address), true)?;
1149 1155
1150 let res = Self::complete_datapath_transfer(false).await; 1156 let res = self.complete_datapath_transfer(false).await;
1151 1157
1152 Self::cmd(common_cmd::stop_transmission(), false)?; // CMD12 1158 self.cmd(common_cmd::stop_transmission(), false)?; // CMD12
1153 Self::clear_interrupt_flags(); 1159 self.clear_interrupt_flags();
1154 1160
1155 if res.is_ok() { 1161 if res.is_ok() {
1156 on_drop.defuse(); 1162 on_drop.defuse();
1157 Self::stop_datapath(); 1163 self.stop_datapath();
1158 drop(transfer); 1164 drop(transfer);
1159 } 1165 }
1160 res 1166 res
@@ -1162,7 +1168,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1162 1168
1163 /// Write a data block. 1169 /// Write a data block.
1164 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> { 1170 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> {
1165 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1171 let _scoped_block_stop = self.info.rcc.block_stop();
1166 let card = self.card.as_mut().ok_or(Error::NoCard)?; 1172 let card = self.card.as_mut().ok_or(Error::NoCard)?;
1167 1173
1168 // NOTE(unsafe) DataBlock uses align 4 1174 // NOTE(unsafe) DataBlock uses align 4
@@ -1174,26 +1180,26 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1174 CardCapacity::StandardCapacity => block_idx * 512, 1180 CardCapacity::StandardCapacity => block_idx * 512,
1175 _ => block_idx, 1181 _ => block_idx,
1176 }; 1182 };
1177 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1183 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1178 1184
1179 let on_drop = OnDrop::new(|| Self::on_drop()); 1185 let on_drop = OnDrop::new(|| self.on_drop());
1180 1186
1181 // sdmmc_v1 uses different cmd/dma order than v2, but only for writes 1187 // sdmmc_v1 uses different cmd/dma order than v2, but only for writes
1182 #[cfg(sdmmc_v1)] 1188 #[cfg(sdmmc_v1)]
1183 Self::cmd(common_cmd::write_single_block(address), true)?; 1189 self.cmd(common_cmd::write_single_block(address), true)?;
1184 1190
1185 let transfer = self.prepare_datapath_write(buffer, 512, 9); 1191 let transfer = self.prepare_datapath_write(buffer, 512, 9);
1186 InterruptHandler::<T>::enable_interrupts(); 1192 self.enable_interrupts();
1187 1193
1188 #[cfg(sdmmc_v2)] 1194 #[cfg(sdmmc_v2)]
1189 Self::cmd(common_cmd::write_single_block(address), true)?; 1195 self.cmd(common_cmd::write_single_block(address), true)?;
1190 1196
1191 let res = Self::complete_datapath_transfer(true).await; 1197 let res = self.complete_datapath_transfer(true).await;
1192 1198
1193 match res { 1199 match res {
1194 Ok(_) => { 1200 Ok(_) => {
1195 on_drop.defuse(); 1201 on_drop.defuse();
1196 Self::stop_datapath(); 1202 self.stop_datapath();
1197 drop(transfer); 1203 drop(transfer);
1198 1204
1199 // TODO: Make this configurable 1205 // TODO: Make this configurable
@@ -1219,7 +1225,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1219 1225
1220 /// Write multiple data blocks. 1226 /// Write multiple data blocks.
1221 pub async fn write_blocks(&mut self, block_idx: u32, blocks: &[DataBlock]) -> Result<(), Error> { 1227 pub async fn write_blocks(&mut self, block_idx: u32, blocks: &[DataBlock]) -> Result<(), Error> {
1222 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1228 let _scoped_block_stop = self.info.rcc.block_stop();
1223 let card = self.card.as_mut().ok_or(Error::NoCard)?; 1229 let card = self.card.as_mut().ok_or(Error::NoCard)?;
1224 1230
1225 // NOTE(unsafe) reinterpret buffer as &[u32] 1231 // NOTE(unsafe) reinterpret buffer as &[u32]
@@ -1236,31 +1242,31 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1236 _ => block_idx, 1242 _ => block_idx,
1237 }; 1243 };
1238 1244
1239 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1245 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1240 1246
1241 let block_count = blocks.len(); 1247 let block_count = blocks.len();
1242 1248
1243 let on_drop = OnDrop::new(|| Self::on_drop()); 1249 let on_drop = OnDrop::new(|| self.on_drop());
1244 1250
1245 #[cfg(sdmmc_v1)] 1251 #[cfg(sdmmc_v1)]
1246 Self::cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 1252 self.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25
1247 1253
1248 // Setup write command 1254 // Setup write command
1249 let transfer = self.prepare_datapath_write(buffer, 512 * block_count as u32, 9); 1255 let transfer = self.prepare_datapath_write(buffer, 512 * block_count as u32, 9);
1250 InterruptHandler::<T>::enable_interrupts(); 1256 self.enable_interrupts();
1251 1257
1252 #[cfg(sdmmc_v2)] 1258 #[cfg(sdmmc_v2)]
1253 Self::cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 1259 self.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25
1254 1260
1255 let res = Self::complete_datapath_transfer(false).await; 1261 let res = self.complete_datapath_transfer(false).await;
1256 1262
1257 Self::cmd(common_cmd::stop_transmission(), false)?; // CMD12 1263 self.cmd(common_cmd::stop_transmission(), false)?; // CMD12
1258 Self::clear_interrupt_flags(); 1264 self.clear_interrupt_flags();
1259 1265
1260 match res { 1266 match res {
1261 Ok(_) => { 1267 Ok(_) => {
1262 on_drop.defuse(); 1268 on_drop.defuse();
1263 Self::stop_datapath(); 1269 self.stop_datapath();
1264 drop(transfer); 1270 drop(transfer);
1265 1271
1266 // TODO: Make this configurable 1272 // TODO: Make this configurable
@@ -1306,8 +1312,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1306 } 1312 }
1307 1313
1308 async fn init_internal(&mut self, freq: Hertz, mut card: SdmmcPeripheral) -> Result<(), Error> { 1314 async fn init_internal(&mut self, freq: Hertz, mut card: SdmmcPeripheral) -> Result<(), Error> {
1309 let regs = T::regs(); 1315 let regs = self.info.regs;
1310 let ker_ck = T::frequency();
1311 1316
1312 let bus_width = match (self.d3.is_some(), self.d7.is_some()) { 1317 let bus_width = match (self.d3.is_some(), self.d7.is_some()) {
1313 (true, true) => { 1318 (true, true) => {
@@ -1322,11 +1327,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1322 1327
1323 // While the SD/SDIO card or eMMC is in identification mode, 1328 // While the SD/SDIO card or eMMC is in identification mode,
1324 // the SDMMC_CK frequency must be no more than 400 kHz. 1329 // the SDMMC_CK frequency must be no more than 400 kHz.
1325 let (_bypass, clkdiv, init_clock) = unwrap!(clk_div(ker_ck, SD_INIT_FREQ.0)); 1330 let (_bypass, clkdiv, init_clock) = unwrap!(clk_div(self.ker_clk, SD_INIT_FREQ.0));
1326 self.clock = init_clock; 1331 self.clock = init_clock;
1327 1332
1328 // CPSMACT and DPSMACT must be 0 to set WIDBUS 1333 // CPSMACT and DPSMACT must be 0 to set WIDBUS
1329 Self::wait_idle(); 1334 self.wait_idle();
1330 1335
1331 regs.clkcr().modify(|w| { 1336 regs.clkcr().modify(|w| {
1332 w.set_widbus(0); 1337 w.set_widbus(0);
@@ -1338,12 +1343,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1338 .write(|w| w.set_datatime(self.config.data_transfer_timeout)); 1343 .write(|w| w.set_datatime(self.config.data_transfer_timeout));
1339 1344
1340 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8)); 1345 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8));
1341 Self::cmd(common_cmd::idle(), false)?; 1346 self.cmd(common_cmd::idle(), false)?;
1342 1347
1343 match card { 1348 match card {
1344 SdmmcPeripheral::SdCard(ref mut card) => { 1349 SdmmcPeripheral::SdCard(ref mut card) => {
1345 // Check if cards supports CMD8 (with pattern) 1350 // Check if cards supports CMD8 (with pattern)
1346 Self::cmd(sd_cmd::send_if_cond(1, 0xAA), false)?; 1351 self.cmd(sd_cmd::send_if_cond(1, 0xAA), false)?;
1347 let cic = CIC::from(regs.respr(0).read().cardstatus()); 1352 let cic = CIC::from(regs.respr(0).read().cardstatus());
1348 1353
1349 if cic.pattern() != 0xAA { 1354 if cic.pattern() != 0xAA {
@@ -1356,12 +1361,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1356 1361
1357 let ocr = loop { 1362 let ocr = loop {
1358 // Signal that next command is a app command 1363 // Signal that next command is a app command
1359 Self::cmd(common_cmd::app_cmd(0), false)?; // CMD55 1364 self.cmd(common_cmd::app_cmd(0), false)?; // CMD55
1360 1365
1361 // 3.2-3.3V 1366 // 3.2-3.3V
1362 let voltage_window = 1 << 5; 1367 let voltage_window = 1 << 5;
1363 // Initialize card 1368 // Initialize card
1364 match Self::cmd(sd_cmd::sd_send_op_cond(true, false, true, voltage_window), false) { 1369 match self.cmd(sd_cmd::sd_send_op_cond(true, false, true, voltage_window), false) {
1365 // ACMD41 1370 // ACMD41
1366 Ok(_) => (), 1371 Ok(_) => (),
1367 Err(Error::Crc) => (), 1372 Err(Error::Crc) => (),
@@ -1388,7 +1393,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1388 let access_mode = 0b10 << 29; 1393 let access_mode = 0b10 << 29;
1389 let op_cond = high_voltage | access_mode | 0b1_1111_1111 << 15; 1394 let op_cond = high_voltage | access_mode | 0b1_1111_1111 << 15;
1390 // Initialize card 1395 // Initialize card
1391 match Self::cmd(emmc_cmd::send_op_cond(op_cond), false) { 1396 match self.cmd(emmc_cmd::send_op_cond(op_cond), false) {
1392 Ok(_) => (), 1397 Ok(_) => (),
1393 Err(Error::Crc) => (), 1398 Err(Error::Crc) => (),
1394 Err(err) => return Err(err), 1399 Err(err) => return Err(err),
@@ -1410,7 +1415,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1410 } 1415 }
1411 } 1416 }
1412 1417
1413 Self::cmd(common_cmd::all_send_cid(), false)?; // CMD2 1418 self.cmd(common_cmd::all_send_cid(), false)?; // CMD2
1414 let cid0 = regs.respr(0).read().cardstatus() as u128; 1419 let cid0 = regs.respr(0).read().cardstatus() as u128;
1415 let cid1 = regs.respr(1).read().cardstatus() as u128; 1420 let cid1 = regs.respr(1).read().cardstatus() as u128;
1416 let cid2 = regs.respr(2).read().cardstatus() as u128; 1421 let cid2 = regs.respr(2).read().cardstatus() as u128;
@@ -1421,7 +1426,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1421 SdmmcPeripheral::SdCard(ref mut card) => { 1426 SdmmcPeripheral::SdCard(ref mut card) => {
1422 card.cid = cid.into(); 1427 card.cid = cid.into();
1423 1428
1424 Self::cmd(sd_cmd::send_relative_address(), false)?; 1429 self.cmd(sd_cmd::send_relative_address(), false)?;
1425 let rca = RCA::<SD>::from(regs.respr(0).read().cardstatus()); 1430 let rca = RCA::<SD>::from(regs.respr(0).read().cardstatus());
1426 card.rca = rca.address(); 1431 card.rca = rca.address();
1427 } 1432 }
@@ -1429,11 +1434,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1429 emmc.cid = cid.into(); 1434 emmc.cid = cid.into();
1430 1435
1431 emmc.rca = 1u16.into(); 1436 emmc.rca = 1u16.into();
1432 Self::cmd(emmc_cmd::assign_relative_address(emmc.rca), false)?; 1437 self.cmd(emmc_cmd::assign_relative_address(emmc.rca), false)?;
1433 } 1438 }
1434 } 1439 }
1435 1440
1436 Self::cmd(common_cmd::send_csd(card.get_address()), false)?; 1441 self.cmd(common_cmd::send_csd(card.get_address()), false)?;
1437 let csd0 = regs.respr(0).read().cardstatus() as u128; 1442 let csd0 = regs.respr(0).read().cardstatus() as u128;
1438 let csd1 = regs.respr(1).read().cardstatus() as u128; 1443 let csd1 = regs.respr(1).read().cardstatus() as u128;
1439 let csd2 = regs.respr(2).read().cardstatus() as u128; 1444 let csd2 = regs.respr(2).read().cardstatus() as u128;
@@ -1475,12 +1480,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1475 BusWidth::Four if card.scr.bus_width_four() => 2, 1480 BusWidth::Four if card.scr.bus_width_four() => 2,
1476 _ => 0, 1481 _ => 0,
1477 }; 1482 };
1478 Self::cmd(common_cmd::app_cmd(card.rca), false)?; 1483 self.cmd(common_cmd::app_cmd(card.rca), false)?;
1479 Self::cmd(sd_cmd::cmd6(acmd_arg), false)?; 1484 self.cmd(sd_cmd::cmd6(acmd_arg), false)?;
1480 } 1485 }
1481 SdmmcPeripheral::Emmc(_) => { 1486 SdmmcPeripheral::Emmc(_) => {
1482 // Write bus width to ExtCSD byte 183 1487 // Write bus width to ExtCSD byte 183
1483 Self::cmd( 1488 self.cmd(
1484 emmc_cmd::modify_ext_csd(emmc_cmd::AccessMode::WriteByte, 183, widbus), 1489 emmc_cmd::modify_ext_csd(emmc_cmd::AccessMode::WriteByte, 183, widbus),
1485 false, 1490 false,
1486 )?; 1491 )?;
@@ -1497,7 +1502,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1497 } 1502 }
1498 1503
1499 // CPSMACT and DPSMACT must be 0 to set WIDBUS 1504 // CPSMACT and DPSMACT must be 0 to set WIDBUS
1500 Self::wait_idle(); 1505 self.wait_idle();
1501 1506
1502 regs.clkcr().modify(|w| w.set_widbus(widbus)); 1507 regs.clkcr().modify(|w| w.set_widbus(widbus));
1503 1508
@@ -1546,7 +1551,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1546 /// 1551 ///
1547 /// SD only. 1552 /// SD only.
1548 pub async fn init_sd_card(&mut self, freq: Hertz) -> Result<(), Error> { 1553 pub async fn init_sd_card(&mut self, freq: Hertz) -> Result<(), Error> {
1549 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1554 let _scoped_block_stop = self.info.rcc.block_stop();
1550 1555
1551 self.init_internal(freq, SdmmcPeripheral::SdCard(Card::default())).await 1556 self.init_internal(freq, SdmmcPeripheral::SdCard(Card::default())).await
1552 } 1557 }
@@ -1579,9 +1584,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1579 }; 1584 };
1580 1585
1581 // Arm `OnDrop` after the buffer, so it will be dropped first 1586 // Arm `OnDrop` after the buffer, so it will be dropped first
1582 let on_drop = OnDrop::new(|| Self::on_drop()); 1587 let on_drop = OnDrop::new(|| self.on_drop());
1583 1588
1584 let transfer = Self::prepare_datapath_read( 1589 let transfer = self.prepare_datapath_read(
1585 &self.config, 1590 &self.config,
1586 #[cfg(sdmmc_v1)] 1591 #[cfg(sdmmc_v1)]
1587 &mut self.dma, 1592 &mut self.dma,
@@ -1589,10 +1594,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1589 64, 1594 64,
1590 6, 1595 6,
1591 ); 1596 );
1592 InterruptHandler::<T>::enable_interrupts(); 1597 self.enable_interrupts();
1593 Self::cmd(sd_cmd::cmd6(set_function), true)?; // CMD6 1598 self.cmd(sd_cmd::cmd6(set_function), true)?; // CMD6
1594 1599
1595 let res = Self::complete_datapath_transfer(true).await; 1600 let res = self.complete_datapath_transfer(true).await;
1596 1601
1597 // Host is allowed to use the new functions at least 8 1602 // Host is allowed to use the new functions at least 8
1598 // clocks after the end of the switch command 1603 // clocks after the end of the switch command
@@ -1605,7 +1610,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1605 match res { 1610 match res {
1606 Ok(_) => { 1611 Ok(_) => {
1607 on_drop.defuse(); 1612 on_drop.defuse();
1608 Self::stop_datapath(); 1613 self.stop_datapath();
1609 drop(transfer); 1614 drop(transfer);
1610 1615
1611 // Function Selection of Function Group 1 1616 // Function Selection of Function Group 1
@@ -1629,8 +1634,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1629 /// SD only. 1634 /// SD only.
1630 async fn get_scr(&mut self, card: &mut Card) -> Result<(), Error> { 1635 async fn get_scr(&mut self, card: &mut Card) -> Result<(), Error> {
1631 // Read the 64-bit SCR register 1636 // Read the 64-bit SCR register
1632 Self::cmd(common_cmd::set_block_length(8), false)?; // CMD16 1637 self.cmd(common_cmd::set_block_length(8), false)?; // CMD16
1633 Self::cmd(common_cmd::app_cmd(card.rca), false)?; 1638 self.cmd(common_cmd::app_cmd(card.rca), false)?;
1634 1639
1635 let cmd_block = match self.cmd_block.as_deref_mut() { 1640 let cmd_block = match self.cmd_block.as_deref_mut() {
1636 Some(x) => x, 1641 Some(x) => x,
@@ -1639,9 +1644,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1639 let scr = &mut cmd_block.0[..2]; 1644 let scr = &mut cmd_block.0[..2];
1640 1645
1641 // Arm `OnDrop` after the buffer, so it will be dropped first 1646 // Arm `OnDrop` after the buffer, so it will be dropped first
1642 let on_drop = OnDrop::new(|| Self::on_drop()); 1647 let on_drop = OnDrop::new(|| self.on_drop());
1643 1648
1644 let transfer = Self::prepare_datapath_read( 1649 let transfer = self.prepare_datapath_read(
1645 &self.config, 1650 &self.config,
1646 #[cfg(sdmmc_v1)] 1651 #[cfg(sdmmc_v1)]
1647 &mut self.dma, 1652 &mut self.dma,
@@ -1649,14 +1654,14 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1649 8, 1654 8,
1650 3, 1655 3,
1651 ); 1656 );
1652 InterruptHandler::<T>::enable_interrupts(); 1657 self.enable_interrupts();
1653 Self::cmd(sd_cmd::send_scr(), true)?; 1658 self.cmd(sd_cmd::send_scr(), true)?;
1654 1659
1655 let res = Self::complete_datapath_transfer(true).await; 1660 let res = self.complete_datapath_transfer(true).await;
1656 1661
1657 if res.is_ok() { 1662 if res.is_ok() {
1658 on_drop.defuse(); 1663 on_drop.defuse();
1659 Self::stop_datapath(); 1664 self.stop_datapath();
1660 drop(transfer); 1665 drop(transfer);
1661 1666
1662 unsafe { 1667 unsafe {
@@ -1679,15 +1684,15 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1679 None => &mut CmdBlock::new(), 1684 None => &mut CmdBlock::new(),
1680 }; 1685 };
1681 1686
1682 Self::cmd(common_cmd::set_block_length(64), false)?; // CMD16 1687 self.cmd(common_cmd::set_block_length(64), false)?; // CMD16
1683 Self::cmd(common_cmd::app_cmd(rca), false)?; // APP 1688 self.cmd(common_cmd::app_cmd(rca), false)?; // APP
1684 1689
1685 let status = cmd_block; 1690 let status = cmd_block;
1686 1691
1687 // Arm `OnDrop` after the buffer, so it will be dropped first 1692 // Arm `OnDrop` after the buffer, so it will be dropped first
1688 let on_drop = OnDrop::new(|| Self::on_drop()); 1693 let on_drop = OnDrop::new(|| self.on_drop());
1689 1694
1690 let transfer = Self::prepare_datapath_read( 1695 let transfer = self.prepare_datapath_read(
1691 &self.config, 1696 &self.config,
1692 #[cfg(sdmmc_v1)] 1697 #[cfg(sdmmc_v1)]
1693 &mut self.dma, 1698 &mut self.dma,
@@ -1695,14 +1700,14 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1695 64, 1700 64,
1696 6, 1701 6,
1697 ); 1702 );
1698 InterruptHandler::<T>::enable_interrupts(); 1703 self.enable_interrupts();
1699 Self::cmd(sd_cmd::sd_status(), true)?; 1704 self.cmd(sd_cmd::sd_status(), true)?;
1700 1705
1701 let res = Self::complete_datapath_transfer(true).await; 1706 let res = self.complete_datapath_transfer(true).await;
1702 1707
1703 if res.is_ok() { 1708 if res.is_ok() {
1704 on_drop.defuse(); 1709 on_drop.defuse();
1705 Self::stop_datapath(); 1710 self.stop_datapath();
1706 drop(transfer); 1711 drop(transfer);
1707 1712
1708 for byte in status.iter_mut() { 1713 for byte in status.iter_mut() {
@@ -1717,7 +1722,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1717 /// 1722 ///
1718 /// eMMC only. 1723 /// eMMC only.
1719 pub async fn init_emmc(&mut self, freq: Hertz) -> Result<(), Error> { 1724 pub async fn init_emmc(&mut self, freq: Hertz) -> Result<(), Error> {
1720 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1725 let _scoped_block_stop = self.info.rcc.block_stop();
1721 1726
1722 self.init_internal(freq, SdmmcPeripheral::Emmc(Emmc::default())).await 1727 self.init_internal(freq, SdmmcPeripheral::Emmc(Emmc::default())).await
1723 } 1728 }
@@ -1726,7 +1731,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1726 /// 1731 ///
1727 /// eMMC only. 1732 /// eMMC only.
1728 async fn read_ext_csd(&mut self) -> Result<(), Error> { 1733 async fn read_ext_csd(&mut self) -> Result<(), Error> {
1729 let card = self.card.as_mut().ok_or(Error::NoCard)?.get_emmc(); 1734 let mut card = self.card.take().ok_or(Error::NoCard)?;
1735 let emmc = card.get_emmc();
1730 1736
1731 // Note: cmd_block can't be used because ExtCSD is too long to fit. 1737 // Note: cmd_block can't be used because ExtCSD is too long to fit.
1732 let mut data_block = DataBlock([0u8; 512]); 1738 let mut data_block = DataBlock([0u8; 512]);
@@ -1734,12 +1740,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1734 // NOTE(unsafe) DataBlock uses align 4 1740 // NOTE(unsafe) DataBlock uses align 4
1735 let buffer = unsafe { &mut *((&mut data_block.0) as *mut [u8; 512] as *mut [u32; 128]) }; 1741 let buffer = unsafe { &mut *((&mut data_block.0) as *mut [u8; 512] as *mut [u32; 128]) };
1736 1742
1737 Self::cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16 1743 self.cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16
1738 1744
1739 // Arm `OnDrop` after the buffer, so it will be dropped first 1745 let transfer = self.prepare_datapath_read(
1740 let on_drop = OnDrop::new(|| Self::on_drop());
1741
1742 let transfer = Self::prepare_datapath_read(
1743 &self.config, 1746 &self.config,
1744 #[cfg(sdmmc_v1)] 1747 #[cfg(sdmmc_v1)]
1745 &mut self.dma, 1748 &mut self.dma,
@@ -1747,26 +1750,30 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1747 512, 1750 512,
1748 9, 1751 9,
1749 ); 1752 );
1750 InterruptHandler::<T>::enable_interrupts(); 1753 self.enable_interrupts();
1751 Self::cmd(emmc_cmd::send_ext_csd(), true)?; 1754 self.cmd(emmc_cmd::send_ext_csd(), true)?;
1752 1755
1753 let res = Self::complete_datapath_transfer(true).await; 1756 // Arm `OnDrop` after the buffer, so it will be dropped first
1757 let on_drop = OnDrop::new(|| self.on_drop());
1758
1759 let res = self.complete_datapath_transfer(true).await;
1754 1760
1755 if res.is_ok() { 1761 if res.is_ok() {
1756 on_drop.defuse(); 1762 on_drop.defuse();
1757 Self::stop_datapath(); 1763 self.stop_datapath();
1758 drop(transfer); 1764 drop(transfer);
1759 1765
1760 card.ext_csd = unsafe { core::mem::transmute::<_, [u32; 128]>(data_block.0) }.into(); 1766 emmc.ext_csd = unsafe { core::mem::transmute::<_, [u32; 128]>(data_block.0) }.into();
1761 } 1767 }
1768
1762 res 1769 res
1763 } 1770 }
1764} 1771}
1765 1772
1766impl<'d, T: Instance> Drop for Sdmmc<'d, T> { 1773impl<'d> Drop for Sdmmc<'d> {
1767 fn drop(&mut self) { 1774 fn drop(&mut self) {
1768 T::Interrupt::disable(); 1775 // T::Interrupt::disable();
1769 Self::on_drop(); 1776 self.on_drop();
1770 1777
1771 critical_section::with(|_| { 1778 critical_section::with(|_| {
1772 self.clk.set_as_disconnected(); 1779 self.clk.set_as_disconnected();
@@ -1799,9 +1806,28 @@ impl<'d, T: Instance> Drop for Sdmmc<'d, T> {
1799 1806
1800////////////////////////////////////////////////////// 1807//////////////////////////////////////////////////////
1801 1808
1809type Regs = RegBlock;
1810
1811struct Info {
1812 regs: Regs,
1813 rcc: RccInfo,
1814}
1815
1816struct State {
1817 waker: AtomicWaker,
1818}
1819
1820impl State {
1821 const fn new() -> Self {
1822 Self {
1823 waker: AtomicWaker::new(),
1824 }
1825 }
1826}
1827
1802trait SealedInstance { 1828trait SealedInstance {
1803 fn regs() -> RegBlock; 1829 fn info() -> &'static Info;
1804 fn state() -> &'static AtomicWaker; 1830 fn state() -> &'static State;
1805} 1831}
1806 1832
1807/// SDMMC instance trait. 1833/// SDMMC instance trait.
@@ -1828,13 +1854,17 @@ dma_trait!(SdmmcDma, Instance);
1828foreach_peripheral!( 1854foreach_peripheral!(
1829 (sdmmc, $inst:ident) => { 1855 (sdmmc, $inst:ident) => {
1830 impl SealedInstance for peripherals::$inst { 1856 impl SealedInstance for peripherals::$inst {
1831 fn regs() -> RegBlock { 1857 fn info() -> &'static Info {
1832 crate::pac::$inst 1858 static INFO: Info = Info {
1859 regs: unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) },
1860 rcc: crate::peripherals::$inst::RCC_INFO,
1861 };
1862 &INFO
1833 } 1863 }
1834 1864
1835 fn state() -> &'static ::embassy_sync::waitqueue::AtomicWaker { 1865 fn state() -> &'static State {
1836 static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new(); 1866 static STATE: State = State::new();
1837 &WAKER 1867 &STATE
1838 } 1868 }
1839 } 1869 }
1840 1870
@@ -1844,7 +1874,7 @@ foreach_peripheral!(
1844 }; 1874 };
1845); 1875);
1846 1876
1847impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> { 1877impl<'d> block_device_driver::BlockDevice<512> for Sdmmc<'d> {
1848 type Error = Error; 1878 type Error = Error;
1849 type Align = aligned::A4; 1879 type Align = aligned::A4;
1850 1880
@@ -1853,7 +1883,7 @@ impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> {
1853 block_address: u32, 1883 block_address: u32,
1854 buf: &mut [aligned::Aligned<Self::Align, [u8; 512]>], 1884 buf: &mut [aligned::Aligned<Self::Align, [u8; 512]>],
1855 ) -> Result<(), Self::Error> { 1885 ) -> Result<(), Self::Error> {
1856 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1886 let _scoped_block_stop = self.info.rcc.block_stop();
1857 // TODO: I think block_address needs to be adjusted by the partition start offset 1887 // TODO: I think block_address needs to be adjusted by the partition start offset
1858 if buf.len() == 1 { 1888 if buf.len() == 1 {
1859 let block = unsafe { &mut *(&mut buf[0] as *mut _ as *mut crate::sdmmc::DataBlock) }; 1889 let block = unsafe { &mut *(&mut buf[0] as *mut _ as *mut crate::sdmmc::DataBlock) };
@@ -1871,7 +1901,7 @@ impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> {
1871 block_address: u32, 1901 block_address: u32,
1872 buf: &[aligned::Aligned<Self::Align, [u8; 512]>], 1902 buf: &[aligned::Aligned<Self::Align, [u8; 512]>],
1873 ) -> Result<(), Self::Error> { 1903 ) -> Result<(), Self::Error> {
1874 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1904 let _scoped_block_stop = self.info.rcc.block_stop();
1875 // TODO: I think block_address needs to be adjusted by the partition start offset 1905 // TODO: I think block_address needs to be adjusted by the partition start offset
1876 if buf.len() == 1 { 1906 if buf.len() == 1 {
1877 let block = unsafe { &*(&buf[0] as *const _ as *const crate::sdmmc::DataBlock) }; 1907 let block = unsafe { &*(&buf[0] as *const _ as *const crate::sdmmc::DataBlock) };