1#![macro_use]
3
4use core::default::Default;
5use core::future::poll_fn;
6use core::marker::PhantomData;
7use core::ops::{Deref, DerefMut};
8use core::task::Poll;
9
10use embassy_hal_internal::drop::OnDrop;
11use embassy_hal_internal::{Peri, PeripheralType};
12use embassy_sync::waitqueue::AtomicWaker;
13use sdio_host::common_cmd::{self, Resp, ResponseLen};
14use sdio_host::emmc::{ExtCSD, EMMC};
15use sdio_host::sd::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CIC, CID, CSD, OCR, RCA, SCR, SD};
16use sdio_host::{emmc_cmd, sd_cmd, Cmd};
17
18#[cfg(sdmmc_v1)]
19use crate::dma::ChannelAndRequest;
20#[cfg(gpio_v2)]
21use crate::gpio::Pull;
22use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
23use crate::interrupt::typelevel::Interrupt;
24use crate::pac::sdmmc::Sdmmc as RegBlock;
25use crate::rcc::{self, RccPeripheral};
26use crate::time::Hertz;
27use crate::{interrupt, peripherals};
28
29pub struct InterruptHandler<T: Instance> {
31 _phantom: PhantomData<T>,
32}
33
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> {
52 unsafe fn on_interrupt() {
53 T::state().wake();
54 let status = T::regs().star().read();
55 T::regs().maskr().modify(|w| {
56 if status.dcrcfail() {
57 w.set_dcrcfailie(false)
58 }
59 if status.dtimeout() {
60 w.set_dtimeoutie(false)
61 }
62 if status.dataend() {
63 w.set_dataendie(false)
64 }
65 if status.dbckend() {
66 w.set_dbckendie(false)
67 }
68 #[cfg(sdmmc_v1)]
69 if status.stbiterr() {
70 w.set_stbiterre(false)
71 }
72 #[cfg(sdmmc_v2)]
73 if status.dabort() {
74 w.set_dabortie(false)
75 }
76 });
77 }
78}
79
80const SD_INIT_FREQ: Hertz = Hertz(400_000);
82
83#[non_exhaustive]
85#[allow(missing_docs)]
86#[derive(Debug, Copy, Clone, PartialEq, Eq)]
87#[cfg_attr(feature = "defmt", derive(defmt::Format))]
88pub enum Signalling {
89 SDR12,
90 SDR25,
91 SDR50,
92 SDR104,
93 DDR50,
94}
95
96impl Default for Signalling {
97 fn default() -> Self {
98 Signalling::SDR12
99 }
100}
101
102#[repr(align(4))]
106#[derive(Debug, Clone, PartialEq, Eq)]
107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
108pub struct DataBlock(pub [u8; 512]);
109
110impl Deref for DataBlock {
111 type Target = [u8; 512];
112
113 fn deref(&self) -> &Self::Target {
114 &self.0
115 }
116}
117
118impl DerefMut for DataBlock {
119 fn deref_mut(&mut self) -> &mut Self::Target {
120 &mut self.0
121 }
122}
123
124#[derive(Debug, Clone, PartialEq, Eq)]
128#[cfg_attr(feature = "defmt", derive(defmt::Format))]
129pub struct CmdBlock(pub [u32; 16]);
130
131impl CmdBlock {
132 pub const fn new() -> Self {
134 Self([0u32; 16])
135 }
136}
137
138impl Deref for CmdBlock {
139 type Target = [u32; 16];
140
141 fn deref(&self) -> &Self::Target {
142 &self.0
143 }
144}
145
146impl DerefMut for CmdBlock {
147 fn deref_mut(&mut self) -> &mut Self::Target {
148 &mut self.0
149 }
150}
151
152#[non_exhaustive]
154#[derive(Debug, Copy, Clone, PartialEq, Eq)]
155#[cfg_attr(feature = "defmt", derive(defmt::Format))]
156pub enum Error {
157 Timeout,
159 SoftwareTimeout,
161 UnsupportedCardVersion,
163 UnsupportedCardType,
165 UnsupportedVoltage,
167 Crc,
169 NoCard,
171 BusWidth,
173 BadClock,
175 SignalingSwitchFailed,
177 Underrun,
179 #[cfg(sdmmc_v1)]
181 StBitErr,
182}
183
184#[derive(Clone, Copy, Debug, Default)]
185pub struct Card {
187 pub card_type: CardCapacity,
189 pub ocr: OCR<SD>,
191 pub rca: u16,
193 pub cid: CID<SD>,
195 pub csd: CSD<SD>,
197 pub scr: SCR,
199 pub status: SDStatus,
201}
202
203#[derive(Clone, Copy, Debug, Default)]
204pub struct Emmc {
206 pub capacity: CardCapacity,
208 pub ocr: OCR<EMMC>,
210 pub rca: u16,
212 pub cid: CID<EMMC>,
214 pub csd: CSD<EMMC>,
216 pub ext_csd: ExtCSD,
218}
219
220#[repr(u8)]
221enum PowerCtrl {
222 Off = 0b00,
223 On = 0b11,
224}
225
226fn get_waitresp_val(rlen: ResponseLen) -> u8 {
227 match rlen {
228 common_cmd::ResponseLen::Zero => 0,
229 common_cmd::ResponseLen::R48 => 1,
230 common_cmd::ResponseLen::R136 => 3,
231 }
232}
233
234#[cfg(sdmmc_v1)]
240fn clk_div(ker_ck: Hertz, sdmmc_ck: u32) -> Result<(bool, u8, Hertz), Error> {
241 if sdmmc_ck > 50_000_000 {
243 return Err(Error::BadClock);
244 }
245
246 if ker_ck.0 <= sdmmc_ck {
248 return Ok((true, 0, ker_ck));
249 }
250
251 let clk_div = match ker_ck.0.div_ceil(sdmmc_ck) {
252 0 | 1 => Ok(0),
253 x @ 2..=258 => Ok((x - 2) as u8),
254 _ => Err(Error::BadClock),
255 }?;
256
257 let clk_f = Hertz(ker_ck.0 / (clk_div as u32 + 2));
259 Ok((false, clk_div, clk_f))
260}
261
262#[cfg(sdmmc_v2)]
268fn clk_div(ker_ck: Hertz, sdmmc_ck: u32) -> Result<(bool, u16, Hertz), Error> {
269 match ker_ck.0.div_ceil(sdmmc_ck) {
270 0 | 1 => Ok((false, 0, ker_ck)),
271 x @ 2..=2046 => {
272 let clk_div = x.div_ceil(2) as u16;
274 let clk = Hertz(ker_ck.0 / (clk_div as u32 * 2));
275
276 Ok((false, clk_div, clk))
277 }
278 _ => Err(Error::BadClock),
279 }
280}
281
282#[cfg(sdmmc_v1)]
283type Transfer<'a> = crate::dma::Transfer<'a>;
284#[cfg(sdmmc_v2)]
285struct Transfer<'a> {
286 _dummy: PhantomData<&'a ()>,
287}
288
289#[cfg(all(sdmmc_v1, dma))]
290const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions {
291 pburst: crate::dma::Burst::Incr4,
292 mburst: crate::dma::Burst::Incr4,
293 flow_ctrl: crate::dma::FlowControl::Peripheral,
294 fifo_threshold: Some(crate::dma::FifoThreshold::Full),
295 priority: crate::dma::Priority::VeryHigh,
296 circular: false,
297 half_transfer_ir: false,
298 complete_transfer_ir: true,
299};
300#[cfg(all(sdmmc_v1, not(dma)))]
301const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions {
302 priority: crate::dma::Priority::VeryHigh,
303 circular: false,
304 half_transfer_ir: false,
305 complete_transfer_ir: true,
306};
307
308#[non_exhaustive]
313pub struct Config {
314 pub data_transfer_timeout: u32,
316}
317
318impl Default for Config {
319 fn default() -> Self {
320 Self {
321 data_transfer_timeout: 5_000_000,
322 }
323 }
324}
325
326#[derive(Clone, Copy, Debug)]
328pub enum SdmmcPeripheral {
329 SdCard(Card),
331 Emmc(Emmc),
333}
334
335impl SdmmcPeripheral {
336 fn get_address(&self) -> u16 {
338 match self {
339 Self::SdCard(c) => c.rca,
340 Self::Emmc(e) => e.rca,
341 }
342 }
343 fn get_capacity(&self) -> CardCapacity {
345 match self {
346 Self::SdCard(c) => c.card_type,
347 Self::Emmc(e) => e.capacity,
348 }
349 }
350 fn size(&self) -> u64 {
352 match self {
353 Self::SdCard(c) => u64::from(c.csd.block_count()) * 512,
355 Self::Emmc(e) => u64::from(e.ext_csd.sector_count()) * 512,
357 }
358 }
359
360 fn get_sd_card(&mut self) -> &mut Card {
364 match *self {
365 Self::SdCard(ref mut c) => c,
366 _ => unreachable!("SD only"),
367 }
368 }
369
370 fn get_emmc(&mut self) -> &mut Emmc {
374 match *self {
375 Self::Emmc(ref mut e) => e,
376 _ => unreachable!("eMMC only"),
377 }
378 }
379}
380
381pub struct Sdmmc<'d, T: Instance> {
383 _peri: Peri<'d, T>,
384 #[cfg(sdmmc_v1)]
385 dma: ChannelAndRequest<'d>,
386
387 clk: Peri<'d, AnyPin>,
388 cmd: Peri<'d, AnyPin>,
389 d0: Peri<'d, AnyPin>,
390 d1: Option<Peri<'d, AnyPin>>,
391 d2: Option<Peri<'d, AnyPin>>,
392 d3: Option<Peri<'d, AnyPin>>,
393 d4: Option<Peri<'d, AnyPin>>,
394 d5: Option<Peri<'d, AnyPin>>,
395 d6: Option<Peri<'d, AnyPin>>,
396 d7: Option<Peri<'d, AnyPin>>,
397
398 config: Config,
399 clock: Hertz,
401 signalling: Signalling,
403 card: Option<SdmmcPeripheral>,
405
406 cmd_block: Option<&'d mut CmdBlock>,
409}
410
411const CLK_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh);
412#[cfg(gpio_v1)]
413const CMD_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh);
414#[cfg(gpio_v2)]
415const CMD_AF: AfType = AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up);
416const DATA_AF: AfType = CMD_AF;
417
418#[cfg(sdmmc_v1)]
419impl<'d, T: Instance> Sdmmc<'d, T> {
420 pub fn new_1bit(
422 sdmmc: Peri<'d, T>,
423 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
424 dma: Peri<'d, impl SdmmcDma<T>>,
425 clk: Peri<'d, impl CkPin<T>>,
426 cmd: Peri<'d, impl CmdPin<T>>,
427 d0: Peri<'d, impl D0Pin<T>>,
428 config: Config,
429 ) -> Self {
430 critical_section::with(|_| {
431 clk.set_as_af(clk.af_num(), CLK_AF);
432 cmd.set_as_af(cmd.af_num(), CMD_AF);
433 d0.set_as_af(d0.af_num(), DATA_AF);
434 });
435
436 Self::new_inner(
437 sdmmc,
438 new_dma_nonopt!(dma),
439 clk.into(),
440 cmd.into(),
441 d0.into(),
442 None,
443 None,
444 None,
445 None,
446 None,
447 None,
448 None,
449 config,
450 )
451 }
452
453 pub fn new_4bit(
455 sdmmc: Peri<'d, T>,
456 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
457 dma: Peri<'d, impl SdmmcDma<T>>,
458 clk: Peri<'d, impl CkPin<T>>,
459 cmd: Peri<'d, impl CmdPin<T>>,
460 d0: Peri<'d, impl D0Pin<T>>,
461 d1: Peri<'d, impl D1Pin<T>>,
462 d2: Peri<'d, impl D2Pin<T>>,
463 d3: Peri<'d, impl D3Pin<T>>,
464 config: Config,
465 ) -> Self {
466 critical_section::with(|_| {
467 clk.set_as_af(clk.af_num(), CLK_AF);
468 cmd.set_as_af(cmd.af_num(), CMD_AF);
469 d0.set_as_af(d0.af_num(), DATA_AF);
470 d1.set_as_af(d1.af_num(), DATA_AF);
471 d2.set_as_af(d2.af_num(), DATA_AF);
472 d3.set_as_af(d3.af_num(), DATA_AF);
473 });
474
475 Self::new_inner(
476 sdmmc,
477 new_dma_nonopt!(dma),
478 clk.into(),
479 cmd.into(),
480 d0.into(),
481 Some(d1.into()),
482 Some(d2.into()),
483 Some(d3.into()),
484 None,
485 None,
486 None,
487 None,
488 config,
489 )
490 }
491}
492
493#[cfg(sdmmc_v1)]
494impl<'d, T: Instance> Sdmmc<'d, T> {
495 pub fn new_8bit(
497 sdmmc: Peri<'d, T>,
498 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
499 dma: Peri<'d, impl SdmmcDma<T>>,
500 clk: Peri<'d, impl CkPin<T>>,
501 cmd: Peri<'d, impl CmdPin<T>>,
502 d0: Peri<'d, impl D0Pin<T>>,
503 d1: Peri<'d, impl D1Pin<T>>,
504 d2: Peri<'d, impl D2Pin<T>>,
505 d3: Peri<'d, impl D3Pin<T>>,
506 d4: Peri<'d, impl D4Pin<T>>,
507 d5: Peri<'d, impl D5Pin<T>>,
508 d6: Peri<'d, impl D6Pin<T>>,
509 d7: Peri<'d, impl D7Pin<T>>,
510 config: Config,
511 ) -> Self {
512 critical_section::with(|_| {
513 clk.set_as_af(clk.af_num(), CLK_AF);
514 cmd.set_as_af(cmd.af_num(), CMD_AF);
515 d0.set_as_af(d0.af_num(), DATA_AF);
516 d1.set_as_af(d1.af_num(), DATA_AF);
517 d2.set_as_af(d2.af_num(), DATA_AF);
518 d3.set_as_af(d3.af_num(), DATA_AF);
519 d4.set_as_af(d4.af_num(), DATA_AF);
520 d5.set_as_af(d5.af_num(), DATA_AF);
521 d6.set_as_af(d6.af_num(), DATA_AF);
522 d7.set_as_af(d7.af_num(), DATA_AF);
523 });
524
525 Self::new_inner(
526 sdmmc,
527 new_dma_nonopt!(dma),
528 clk.into(),
529 cmd.into(),
530 d0.into(),
531 Some(d1.into()),
532 Some(d2.into()),
533 Some(d3.into()),
534 Some(d4.into()),
535 Some(d5.into()),
536 Some(d6.into()),
537 Some(d7.into()),
538 config,
539 )
540 }
541}
542
543#[cfg(sdmmc_v2)]
544impl<'d, T: Instance> Sdmmc<'d, T> {
545 pub fn new_1bit(
547 sdmmc: Peri<'d, T>,
548 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
549 clk: Peri<'d, impl CkPin<T>>,
550 cmd: Peri<'d, impl CmdPin<T>>,
551 d0: Peri<'d, impl D0Pin<T>>,
552 config: Config,
553 ) -> Self {
554 critical_section::with(|_| {
555 clk.set_as_af(clk.af_num(), CLK_AF);
556 cmd.set_as_af(cmd.af_num(), CMD_AF);
557 d0.set_as_af(d0.af_num(), DATA_AF);
558 });
559
560 Self::new_inner(
561 sdmmc,
562 clk.into(),
563 cmd.into(),
564 d0.into(),
565 None,
566 None,
567 None,
568 None,
569 None,
570 None,
571 None,
572 config,
573 )
574 }
575
576 pub fn new_4bit(
578 sdmmc: Peri<'d, T>,
579 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
580 clk: Peri<'d, impl CkPin<T>>,
581 cmd: Peri<'d, impl CmdPin<T>>,
582 d0: Peri<'d, impl D0Pin<T>>,
583 d1: Peri<'d, impl D1Pin<T>>,
584 d2: Peri<'d, impl D2Pin<T>>,
585 d3: Peri<'d, impl D3Pin<T>>,
586 config: Config,
587 ) -> Self {
588 critical_section::with(|_| {
589 clk.set_as_af(clk.af_num(), CLK_AF);
590 cmd.set_as_af(cmd.af_num(), CMD_AF);
591 d0.set_as_af(d0.af_num(), DATA_AF);
592 d1.set_as_af(d1.af_num(), DATA_AF);
593 d2.set_as_af(d2.af_num(), DATA_AF);
594 d3.set_as_af(d3.af_num(), DATA_AF);
595 });
596
597 Self::new_inner(
598 sdmmc,
599 clk.into(),
600 cmd.into(),
601 d0.into(),
602 Some(d1.into()),
603 Some(d2.into()),
604 Some(d3.into()),
605 None,
606 None,
607 None,
608 None,
609 config,
610 )
611 }
612}
613
614#[cfg(sdmmc_v2)]
615impl<'d, T: Instance> Sdmmc<'d, T> {
616 pub fn new_8bit(
618 sdmmc: Peri<'d, T>,
619 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
620 clk: Peri<'d, impl CkPin<T>>,
621 cmd: Peri<'d, impl CmdPin<T>>,
622 d0: Peri<'d, impl D0Pin<T>>,
623 d1: Peri<'d, impl D1Pin<T>>,
624 d2: Peri<'d, impl D2Pin<T>>,
625 d3: Peri<'d, impl D3Pin<T>>,
626 d4: Peri<'d, impl D4Pin<T>>,
627 d5: Peri<'d, impl D5Pin<T>>,
628 d6: Peri<'d, impl D6Pin<T>>,
629 d7: Peri<'d, impl D7Pin<T>>,
630 config: Config,
631 ) -> Self {
632 critical_section::with(|_| {
633 clk.set_as_af(clk.af_num(), CLK_AF);
634 cmd.set_as_af(cmd.af_num(), CMD_AF);
635 d0.set_as_af(d0.af_num(), DATA_AF);
636 d1.set_as_af(d1.af_num(), DATA_AF);
637 d2.set_as_af(d2.af_num(), DATA_AF);
638 d3.set_as_af(d3.af_num(), DATA_AF);
639 d4.set_as_af(d4.af_num(), DATA_AF);
640 d5.set_as_af(d5.af_num(), DATA_AF);
641 d6.set_as_af(d6.af_num(), DATA_AF);
642 d7.set_as_af(d7.af_num(), DATA_AF);
643 });
644
645 Self::new_inner(
646 sdmmc,
647 clk.into(),
648 cmd.into(),
649 d0.into(),
650 Some(d1.into()),
651 Some(d2.into()),
652 Some(d3.into()),
653 Some(d4.into()),
654 Some(d5.into()),
655 Some(d6.into()),
656 Some(d7.into()),
657 config,
658 )
659 }
660}
661
662impl<'d, T: Instance> Sdmmc<'d, T> {
663 fn new_inner(
664 sdmmc: Peri<'d, T>,
665 #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>,
666 clk: Peri<'d, AnyPin>,
667 cmd: Peri<'d, AnyPin>,
668 d0: Peri<'d, AnyPin>,
669 d1: Option<Peri<'d, AnyPin>>,
670 d2: Option<Peri<'d, AnyPin>>,
671 d3: Option<Peri<'d, AnyPin>>,
672 d4: Option<Peri<'d, AnyPin>>,
673 d5: Option<Peri<'d, AnyPin>>,
674 d6: Option<Peri<'d, AnyPin>>,
675 d7: Option<Peri<'d, AnyPin>>,
676 config: Config,
677 ) -> Self {
678 rcc::enable_and_reset::<T>();
679
680 T::Interrupt::unpend();
681 unsafe { T::Interrupt::enable() };
682
683 let regs = T::regs();
684 regs.clkcr().write(|w| {
685 w.set_pwrsav(false);
686 w.set_negedge(false);
687
688 #[cfg(sdmmc_v1)]
691 w.set_hwfc_en(false);
692 #[cfg(sdmmc_v2)]
693 w.set_hwfc_en(true);
694
695 #[cfg(sdmmc_v1)]
696 w.set_clken(true);
697 });
698
699 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::Off as u8));
702
703 Self {
704 _peri: sdmmc,
705 #[cfg(sdmmc_v1)]
706 dma,
707
708 clk,
709 cmd,
710 d0,
711 d1,
712 d2,
713 d3,
714 d4,
715 d5,
716 d6,
717 d7,
718
719 config,
720 clock: SD_INIT_FREQ,
721 signalling: Default::default(),
722 card: None,
723 cmd_block: None,
724 }
725 }
726
727 #[inline]
729 fn data_active() -> bool {
730 let regs = T::regs();
731
732 let status = regs.star().read();
733 #[cfg(sdmmc_v1)]
734 return status.rxact() || status.txact();
735 #[cfg(sdmmc_v2)]
736 return status.dpsmact();
737 }
738
739 #[inline]
741 fn cmd_active() -> bool {
742 let regs = T::regs();
743
744 let status = regs.star().read();
745 #[cfg(sdmmc_v1)]
746 return status.cmdact();
747 #[cfg(sdmmc_v2)]
748 return status.cpsmact();
749 }
750
751 #[inline]
753 fn wait_idle() {
754 while Self::data_active() || Self::cmd_active() {}
755 }
756
757 #[allow(unused_variables)]
761 fn prepare_datapath_read<'a>(
762 config: &Config,
763 #[cfg(sdmmc_v1)] dma: &'a mut ChannelAndRequest<'d>,
764 buffer: &'a mut [u32],
765 length_bytes: u32,
766 block_size: u8,
767 ) -> Transfer<'a> {
768 assert!(block_size <= 14, "Block size up to 2^14 bytes");
769 let regs = T::regs();
770
771 Self::wait_idle();
773 Self::clear_interrupt_flags();
774
775 regs.dlenr().write(|w| w.set_datalength(length_bytes));
776
777 #[cfg(sdmmc_v1)]
778 let transfer = unsafe { dma.read(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS) };
779 #[cfg(sdmmc_v2)]
780 let transfer = {
781 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32));
782 regs.idmactrlr().modify(|w| w.set_idmaen(true));
783 Transfer {
784 _dummy: core::marker::PhantomData,
785 }
786 };
787
788 regs.dctrl().modify(|w| {
789 w.set_dblocksize(block_size);
790 w.set_dtdir(true);
791 #[cfg(sdmmc_v1)]
792 {
793 w.set_dmaen(true);
794 w.set_dten(true);
795 }
796 });
797
798 transfer
799 }
800
801 fn prepare_datapath_write<'a>(&'a mut self, buffer: &'a [u32], length_bytes: u32, block_size: u8) -> Transfer<'a> {
805 assert!(block_size <= 14, "Block size up to 2^14 bytes");
806 let regs = T::regs();
807
808 Self::wait_idle();
810 Self::clear_interrupt_flags();
811
812 regs.dlenr().write(|w| w.set_datalength(length_bytes));
813
814 #[cfg(sdmmc_v1)]
815 let transfer = unsafe {
816 self.dma
817 .write(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS)
818 };
819 #[cfg(sdmmc_v2)]
820 let transfer = {
821 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_ptr() as u32));
822 regs.idmactrlr().modify(|w| w.set_idmaen(true));
823 Transfer {
824 _dummy: core::marker::PhantomData,
825 }
826 };
827
828 regs.dctrl().modify(|w| {
829 w.set_dblocksize(block_size);
830 w.set_dtdir(false);
831 #[cfg(sdmmc_v1)]
832 {
833 w.set_dmaen(true);
834 w.set_dten(true);
835 }
836 });
837
838 transfer
839 }
840
841 fn stop_datapath() {
843 let regs = T::regs();
844
845 #[cfg(sdmmc_v1)]
846 regs.dctrl().modify(|w| {
847 w.set_dmaen(false);
848 w.set_dten(false);
849 });
850 #[cfg(sdmmc_v2)]
851 regs.idmactrlr().modify(|w| w.set_idmaen(false));
852 }
853
854 fn clkcr_set_clkdiv(&mut self, freq: u32, width: BusWidth) -> Result<(), Error> {
856 let regs = T::regs();
857
858 let width_u32 = match width {
859 BusWidth::One => 1u32,
860 BusWidth::Four => 4u32,
861 BusWidth::Eight => 8u32,
862 _ => panic!("Invalid Bus Width"),
863 };
864
865 let ker_ck = T::frequency();
866 let (_bypass, clkdiv, new_clock) = clk_div(ker_ck, freq)?;
867
868 let sdmmc_bus_bandwidth = new_clock.0 * width_u32;
871 assert!(ker_ck.0 > 3 * sdmmc_bus_bandwidth / 32);
872 self.clock = new_clock;
873
874 Self::wait_idle();
876 regs.clkcr().modify(|w| {
877 w.set_clkdiv(clkdiv);
878 #[cfg(sdmmc_v1)]
879 w.set_bypass(_bypass);
880 });
881
882 Ok(())
883 }
884
885 fn read_status<Ext>(&self, card: &SdmmcPeripheral) -> Result<CardStatus<Ext>, Error>
887 where
888 CardStatus<Ext>: From<u32>,
889 {
890 let regs = T::regs();
891 let rca = card.get_address();
892
893 Self::cmd(common_cmd::card_status(rca, false), false)?; let r1 = regs.respr(0).read().cardstatus();
896 Ok(r1.into())
897 }
898
899 fn select_card(&self, rca: Option<u16>) -> Result<(), Error> {
904 let rca = rca.unwrap_or(0);
906
907 let r = Self::cmd(common_cmd::select_card(rca), false);
908 match (r, rca) {
909 (Err(Error::Timeout), 0) => Ok(()),
910 _ => r,
911 }
912 }
913
914 #[inline]
916 fn clear_interrupt_flags() {
917 let regs = T::regs();
918 regs.icr().write(|w| {
919 w.set_ccrcfailc(true);
920 w.set_dcrcfailc(true);
921 w.set_ctimeoutc(true);
922 w.set_dtimeoutc(true);
923 w.set_txunderrc(true);
924 w.set_rxoverrc(true);
925 w.set_cmdrendc(true);
926 w.set_cmdsentc(true);
927 w.set_dataendc(true);
928 w.set_dbckendc(true);
929 w.set_sdioitc(true);
930 #[cfg(sdmmc_v1)]
931 w.set_stbiterrc(true);
932
933 #[cfg(sdmmc_v2)]
934 {
935 w.set_dholdc(true);
936 w.set_dabortc(true);
937 w.set_busyd0endc(true);
938 w.set_ackfailc(true);
939 w.set_acktimeoutc(true);
940 w.set_vswendc(true);
941 w.set_ckstopc(true);
942 w.set_idmatec(true);
943 w.set_idmabtcc(true);
944 }
945 });
946 }
947
948 #[allow(unused_variables)]
950 fn cmd<R: Resp>(cmd: Cmd<R>, data: bool) -> Result<(), Error> {
951 let regs = T::regs();
952
953 Self::clear_interrupt_flags();
954 while Self::cmd_active() {}
956
957 regs.argr().write(|w| w.set_cmdarg(cmd.arg));
959
960 regs.cmdr().write(|w| {
962 w.set_waitint(false);
963 w.set_waitresp(get_waitresp_val(cmd.response_len()));
964 w.set_cmdindex(cmd.cmd);
965 w.set_cpsmen(true);
966
967 #[cfg(sdmmc_v2)]
968 {
969 let cpsm_stop_transmission = cmd.cmd == 12;
972 w.set_cmdstop(cpsm_stop_transmission);
973 w.set_cmdtrans(data);
974 }
975 });
976
977 let mut status;
978 if cmd.response_len() == ResponseLen::Zero {
979 while {
981 status = regs.star().read();
982 !(status.ctimeout() || status.cmdsent())
983 } {}
984 } else {
985 while {
987 status = regs.star().read();
988 !(status.ctimeout() || status.cmdrend() || status.ccrcfail())
989 } {}
990 }
991
992 if status.ctimeout() {
993 return Err(Error::Timeout);
994 } else if status.ccrcfail() {
995 return Err(Error::Crc);
996 }
997 Ok(())
998 }
999
1000 fn on_drop() {
1001 let regs = T::regs();
1002 if Self::data_active() {
1003 Self::clear_interrupt_flags();
1004 while Self::cmd_active() {}
1007
1008 regs.argr().write(|w| w.set_cmdarg(0));
1010
1011 regs.cmdr().write(|w| {
1013 w.set_waitint(false);
1014 w.set_waitresp(get_waitresp_val(ResponseLen::R48));
1015 w.set_cmdindex(12);
1016 w.set_cpsmen(true);
1017
1018 #[cfg(sdmmc_v2)]
1019 {
1020 w.set_cmdstop(true);
1021 w.set_cmdtrans(false);
1022 }
1023 });
1024
1025 while Self::data_active() {}
1027 }
1028 regs.maskr().write(|_| ()); Self::clear_interrupt_flags();
1030 Self::stop_datapath();
1031 }
1032
1033 #[inline]
1035 async fn complete_datapath_transfer(block: bool) -> Result<(), Error> {
1036 let regs = T::regs();
1037
1038 let res = poll_fn(|cx| {
1039 T::state().register(cx.waker());
1040 let status = regs.star().read();
1041
1042 if status.dcrcfail() {
1043 return Poll::Ready(Err(Error::Crc));
1044 }
1045 if status.dtimeout() {
1046 return Poll::Ready(Err(Error::Timeout));
1047 }
1048 if status.txunderr() {
1049 return Poll::Ready(Err(Error::Underrun));
1050 }
1051 #[cfg(sdmmc_v1)]
1052 if status.stbiterr() {
1053 return Poll::Ready(Err(Error::StBitErr));
1054 }
1055 let done = match block {
1056 true => status.dbckend(),
1057 false => status.dataend(),
1058 };
1059 if done {
1060 return Poll::Ready(Ok(()));
1061 }
1062 Poll::Pending
1063 })
1064 .await;
1065
1066 Self::clear_interrupt_flags();
1067
1068 res
1069 }
1070
1071 #[inline]
1073 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> {
1074 let card_capacity = self.card()?.get_capacity();
1075
1076 let buffer = unsafe { &mut *((&mut buffer.0) as *mut [u8; 512] as *mut [u32; 128]) };
1078
1079 let address = match card_capacity {
1082 CardCapacity::StandardCapacity => block_idx * 512,
1083 _ => block_idx,
1084 };
1085 Self::cmd(common_cmd::set_block_length(512), false)?; let on_drop = OnDrop::new(|| Self::on_drop());
1088
1089 let transfer = Self::prepare_datapath_read(
1090 &self.config,
1091 #[cfg(sdmmc_v1)]
1092 &mut self.dma,
1093 buffer,
1094 512,
1095 9,
1096 );
1097 InterruptHandler::<T>::enable_interrupts();
1098 Self::cmd(common_cmd::read_single_block(address), true)?;
1099
1100 let res = Self::complete_datapath_transfer(true).await;
1101
1102 if res.is_ok() {
1103 on_drop.defuse();
1104 Self::stop_datapath();
1105 drop(transfer);
1106 }
1107 res
1108 }
1109
1110 #[inline]
1112 pub async fn read_blocks(&mut self, block_idx: u32, blocks: &mut [DataBlock]) -> Result<(), Error> {
1113 let card_capacity = self.card()?.get_capacity();
1114
1115 let buffer = unsafe {
1117 let ptr = blocks.as_mut_ptr() as *mut u32;
1118 let len = blocks.len() * 128;
1119 core::slice::from_raw_parts_mut(ptr, len)
1120 };
1121
1122 let address = match card_capacity {
1125 CardCapacity::StandardCapacity => block_idx * 512,
1126 _ => block_idx,
1127 };
1128 Self::cmd(common_cmd::set_block_length(512), false)?; let on_drop = OnDrop::new(|| Self::on_drop());
1131
1132 let transfer = Self::prepare_datapath_read(
1133 &self.config,
1134 #[cfg(sdmmc_v1)]
1135 &mut self.dma,
1136 buffer,
1137 512 * blocks.len() as u32,
1138 9,
1139 );
1140 InterruptHandler::<T>::enable_interrupts();
1141
1142 Self::cmd(common_cmd::read_multiple_blocks(address), true)?;
1143
1144 let res = Self::complete_datapath_transfer(false).await;
1145
1146 Self::cmd(common_cmd::stop_transmission(), false)?; Self::clear_interrupt_flags();
1148
1149 if res.is_ok() {
1150 on_drop.defuse();
1151 Self::stop_datapath();
1152 drop(transfer);
1153 }
1154 res
1155 }
1156
1157 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> {
1159 let card = self.card.as_mut().ok_or(Error::NoCard)?;
1160
1161 let buffer = unsafe { &*((&buffer.0) as *const [u8; 512] as *const [u32; 128]) };
1163
1164 let address = match card.get_capacity() {
1167 CardCapacity::StandardCapacity => block_idx * 512,
1168 _ => block_idx,
1169 };
1170 Self::cmd(common_cmd::set_block_length(512), false)?; let on_drop = OnDrop::new(|| Self::on_drop());
1173
1174 #[cfg(sdmmc_v1)]
1176 Self::cmd(common_cmd::write_single_block(address), true)?;
1177
1178 let transfer = self.prepare_datapath_write(buffer, 512, 9);
1179 InterruptHandler::<T>::enable_interrupts();
1180
1181 #[cfg(sdmmc_v2)]
1182 Self::cmd(common_cmd::write_single_block(address), true)?;
1183
1184 let res = Self::complete_datapath_transfer(true).await;
1185
1186 match res {
1187 Ok(_) => {
1188 on_drop.defuse();
1189 Self::stop_datapath();
1190 drop(transfer);
1191
1192 let mut timeout: u32 = 0x00FF_FFFF;
1194
1195 let card = self.card.as_ref().unwrap();
1196 while timeout > 0 {
1197 let ready_for_data = match card {
1198 SdmmcPeripheral::Emmc(_) => self.read_status::<EMMC>(card)?.ready_for_data(),
1199 SdmmcPeripheral::SdCard(_) => self.read_status::<SD>(card)?.ready_for_data(),
1200 };
1201
1202 if ready_for_data {
1203 return Ok(());
1204 }
1205 timeout -= 1;
1206 }
1207 Err(Error::SoftwareTimeout)
1208 }
1209 Err(e) => Err(e),
1210 }
1211 }
1212
1213 pub async fn write_blocks(&mut self, block_idx: u32, blocks: &[DataBlock]) -> Result<(), Error> {
1215 let card = self.card.as_mut().ok_or(Error::NoCard)?;
1216
1217 let buffer = unsafe {
1219 let ptr = blocks.as_ptr() as *const u32;
1220 let len = blocks.len() * 128;
1221 core::slice::from_raw_parts(ptr, len)
1222 };
1223
1224 let address = match card.get_capacity() {
1227 CardCapacity::StandardCapacity => block_idx * 512,
1228 _ => block_idx,
1229 };
1230
1231 Self::cmd(common_cmd::set_block_length(512), false)?; let block_count = blocks.len();
1234
1235 let on_drop = OnDrop::new(|| Self::on_drop());
1236
1237 #[cfg(sdmmc_v1)]
1238 Self::cmd(common_cmd::write_multiple_blocks(address), true)?; let transfer = self.prepare_datapath_write(buffer, 512 * block_count as u32, 9);
1242 InterruptHandler::<T>::enable_interrupts();
1243
1244 #[cfg(sdmmc_v2)]
1245 Self::cmd(common_cmd::write_multiple_blocks(address), true)?; let res = Self::complete_datapath_transfer(false).await;
1248
1249 Self::cmd(common_cmd::stop_transmission(), false)?; Self::clear_interrupt_flags();
1251
1252 match res {
1253 Ok(_) => {
1254 on_drop.defuse();
1255 Self::stop_datapath();
1256 drop(transfer);
1257
1258 let mut timeout: u32 = 0x00FF_FFFF;
1260
1261 while timeout > 0 {
1263 match self.read_sd_status().await {
1264 Ok(_) => return Ok(()),
1265 Err(Error::Timeout) => (), Err(e) => return Err(e),
1267 }
1268 timeout -= 1;
1269 }
1270 Err(Error::SoftwareTimeout)
1271 }
1272 Err(e) => Err(e),
1273 }
1274 }
1275
1276 #[inline]
1283 pub fn card(&self) -> Result<&SdmmcPeripheral, Error> {
1284 self.card.as_ref().ok_or(Error::NoCard)
1285 }
1286
1287 pub fn clock(&self) -> Hertz {
1289 self.clock
1290 }
1291
1292 pub fn set_cmd_block(&mut self, cmd_block: &'d mut CmdBlock) {
1297 self.cmd_block = Some(cmd_block)
1298 }
1299
1300 async fn init_internal(&mut self, freq: Hertz, mut card: SdmmcPeripheral) -> Result<(), Error> {
1301 let regs = T::regs();
1302 let ker_ck = T::frequency();
1303
1304 let bus_width = match (self.d3.is_some(), self.d7.is_some()) {
1305 (true, true) => {
1306 if matches!(card, SdmmcPeripheral::SdCard(_)) {
1307 return Err(Error::BusWidth);
1308 }
1309 BusWidth::Eight
1310 }
1311 (true, false) => BusWidth::Four,
1312 _ => BusWidth::One,
1313 };
1314
1315 let (_bypass, clkdiv, init_clock) = unwrap!(clk_div(ker_ck, SD_INIT_FREQ.0));
1318 self.clock = init_clock;
1319
1320 Self::wait_idle();
1322
1323 regs.clkcr().modify(|w| {
1324 w.set_widbus(0);
1325 w.set_clkdiv(clkdiv);
1326 #[cfg(sdmmc_v1)]
1327 w.set_bypass(_bypass);
1328 });
1329 regs.dtimer()
1330 .write(|w| w.set_datatime(self.config.data_transfer_timeout));
1331
1332 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8));
1333 Self::cmd(common_cmd::idle(), false)?;
1334
1335 match card {
1336 SdmmcPeripheral::SdCard(ref mut card) => {
1337 Self::cmd(sd_cmd::send_if_cond(1, 0xAA), false)?;
1339 let cic = CIC::from(regs.respr(0).read().cardstatus());
1340
1341 if cic.pattern() != 0xAA {
1342 return Err(Error::UnsupportedCardVersion);
1343 }
1344
1345 if cic.voltage_accepted() & 1 == 0 {
1346 return Err(Error::UnsupportedVoltage);
1347 }
1348
1349 let ocr = loop {
1350 Self::cmd(common_cmd::app_cmd(0), false)?; let voltage_window = 1 << 5;
1355 match Self::cmd(sd_cmd::sd_send_op_cond(true, false, true, voltage_window), false) {
1357 Ok(_) => (),
1359 Err(Error::Crc) => (),
1360 Err(err) => return Err(err),
1361 }
1362 let ocr: OCR<SD> = regs.respr(0).read().cardstatus().into();
1363 if !ocr.is_busy() {
1364 break ocr;
1366 }
1367 };
1368
1369 if ocr.high_capacity() {
1370 card.card_type = CardCapacity::HighCapacity;
1372 } else {
1373 card.card_type = CardCapacity::StandardCapacity;
1374 }
1375 card.ocr = ocr;
1376 }
1377 SdmmcPeripheral::Emmc(ref mut emmc) => {
1378 let ocr = loop {
1379 let high_voltage = 0b0 << 7;
1380 let access_mode = 0b10 << 29;
1381 let op_cond = high_voltage | access_mode | 0b1_1111_1111 << 15;
1382 match Self::cmd(emmc_cmd::send_op_cond(op_cond), false) {
1384 Ok(_) => (),
1385 Err(Error::Crc) => (),
1386 Err(err) => return Err(err),
1387 }
1388 let ocr: OCR<EMMC> = regs.respr(0).read().cardstatus().into();
1389 if !ocr.is_busy() {
1390 break ocr;
1392 }
1393 };
1394
1395 emmc.capacity = if ocr.access_mode() == 0b10 {
1396 CardCapacity::HighCapacity
1398 } else {
1399 CardCapacity::StandardCapacity
1400 };
1401 emmc.ocr = ocr;
1402 }
1403 }
1404
1405 Self::cmd(common_cmd::all_send_cid(), false)?; let cid0 = regs.respr(0).read().cardstatus() as u128;
1407 let cid1 = regs.respr(1).read().cardstatus() as u128;
1408 let cid2 = regs.respr(2).read().cardstatus() as u128;
1409 let cid3 = regs.respr(3).read().cardstatus() as u128;
1410 let cid = (cid0 << 96) | (cid1 << 64) | (cid2 << 32) | (cid3);
1411
1412 match card {
1413 SdmmcPeripheral::SdCard(ref mut card) => {
1414 card.cid = cid.into();
1415
1416 Self::cmd(sd_cmd::send_relative_address(), false)?;
1417 let rca = RCA::<SD>::from(regs.respr(0).read().cardstatus());
1418 card.rca = rca.address();
1419 }
1420 SdmmcPeripheral::Emmc(ref mut emmc) => {
1421 emmc.cid = cid.into();
1422
1423 emmc.rca = 1u16.into();
1424 Self::cmd(emmc_cmd::assign_relative_address(emmc.rca), false)?;
1425 }
1426 }
1427
1428 Self::cmd(common_cmd::send_csd(card.get_address()), false)?;
1429 let csd0 = regs.respr(0).read().cardstatus() as u128;
1430 let csd1 = regs.respr(1).read().cardstatus() as u128;
1431 let csd2 = regs.respr(2).read().cardstatus() as u128;
1432 let csd3 = regs.respr(3).read().cardstatus() as u128;
1433 let csd = (csd0 << 96) | (csd1 << 64) | (csd2 << 32) | (csd3);
1434
1435 self.select_card(Some(card.get_address()))?;
1436
1437 let bus_width = match card {
1438 SdmmcPeripheral::SdCard(ref mut card) => {
1439 card.csd = csd.into();
1440
1441 self.get_scr(card).await?;
1442
1443 if !card.scr.bus_width_four() {
1444 BusWidth::One
1445 } else {
1446 BusWidth::Four
1447 }
1448 }
1449 SdmmcPeripheral::Emmc(ref mut emmc) => {
1450 emmc.csd = csd.into();
1451
1452 bus_width
1453 }
1454 };
1455
1456 let widbus = match bus_width {
1458 BusWidth::Eight => 2,
1459 BusWidth::Four => 1,
1460 BusWidth::One => 0,
1461 _ => unreachable!(),
1462 };
1463
1464 match card {
1465 SdmmcPeripheral::SdCard(ref mut card) => {
1466 let acmd_arg = match bus_width {
1467 BusWidth::Four if card.scr.bus_width_four() => 2,
1468 _ => 0,
1469 };
1470 Self::cmd(common_cmd::app_cmd(card.rca), false)?;
1471 Self::cmd(sd_cmd::cmd6(acmd_arg), false)?;
1472 }
1473 SdmmcPeripheral::Emmc(_) => {
1474 Self::cmd(
1476 emmc_cmd::modify_ext_csd(emmc_cmd::AccessMode::WriteByte, 183, widbus),
1477 false,
1478 )?;
1479
1480 loop {
1482 let status = self.read_status::<EMMC>(&card)?;
1483
1484 if status.ready_for_data() {
1485 break;
1486 }
1487 }
1488 }
1489 }
1490
1491 Self::wait_idle();
1493
1494 regs.clkcr().modify(|w| w.set_widbus(widbus));
1495
1496 if freq.0 <= 25_000_000 {
1498 self.clkcr_set_clkdiv(freq.0, bus_width)?;
1500 } else {
1501 self.clkcr_set_clkdiv(25_000_000, bus_width)?;
1503 }
1504
1505 self.card = Some(card);
1506
1507 match card {
1508 SdmmcPeripheral::SdCard(_) => {
1509 self.read_sd_status().await?;
1511
1512 if freq.0 > 25_000_000 {
1513 self.signalling = self.switch_signalling_mode(Signalling::SDR25).await?;
1515
1516 if self.signalling == Signalling::SDR25 {
1517 self.clkcr_set_clkdiv(freq.0, bus_width)?;
1519
1520 if self.read_status::<SD>(self.card.as_ref().unwrap())?.state() != CurrentState::Transfer {
1521 return Err(Error::SignalingSwitchFailed);
1522 }
1523 }
1524 }
1525
1526 self.read_sd_status().await?;
1528 }
1529 SdmmcPeripheral::Emmc(_) => {
1530 self.read_ext_csd().await?;
1531 }
1532 }
1533
1534 Ok(())
1535 }
1536
1537 pub async fn init_sd_card(&mut self, freq: Hertz) -> Result<(), Error> {
1541 self.init_internal(freq, SdmmcPeripheral::SdCard(Card::default())).await
1542 }
1543
1544 async fn switch_signalling_mode(&mut self, signalling: Signalling) -> Result<Signalling, Error> {
1552 let _ = self.card.as_mut().ok_or(Error::NoCard)?.get_sd_card();
1553 let set_function = 0x8000_0000
1557 | match signalling {
1558 Signalling::DDR50 => 0xFF_FF04,
1560 Signalling::SDR104 => 0xFF_1F03,
1561 Signalling::SDR50 => 0xFF_1F02,
1562 Signalling::SDR25 => 0xFF_FF01,
1563 Signalling::SDR12 => 0xFF_FF00,
1564 };
1565
1566 let status = match self.cmd_block.as_deref_mut() {
1567 Some(x) => x,
1568 None => &mut CmdBlock::new(),
1569 };
1570
1571 let on_drop = OnDrop::new(|| Self::on_drop());
1573
1574 let transfer = Self::prepare_datapath_read(
1575 &self.config,
1576 #[cfg(sdmmc_v1)]
1577 &mut self.dma,
1578 status.as_mut(),
1579 64,
1580 6,
1581 );
1582 InterruptHandler::<T>::enable_interrupts();
1583 Self::cmd(sd_cmd::cmd6(set_function), true)?; let res = Self::complete_datapath_transfer(true).await;
1586
1587 for _ in 0..300 {
1592 cortex_m::asm::nop();
1593 }
1594
1595 match res {
1596 Ok(_) => {
1597 on_drop.defuse();
1598 Self::stop_datapath();
1599 drop(transfer);
1600
1601 let selection = (u32::from_be(status[4]) >> 24) & 0xF;
1603
1604 match selection {
1605 0 => Ok(Signalling::SDR12),
1606 1 => Ok(Signalling::SDR25),
1607 2 => Ok(Signalling::SDR50),
1608 3 => Ok(Signalling::SDR104),
1609 4 => Ok(Signalling::DDR50),
1610 _ => Err(Error::UnsupportedCardType),
1611 }
1612 }
1613 Err(e) => Err(e),
1614 }
1615 }
1616
1617 async fn get_scr(&mut self, card: &mut Card) -> Result<(), Error> {
1621 Self::cmd(common_cmd::set_block_length(8), false)?; Self::cmd(common_cmd::app_cmd(card.rca), false)?;
1624
1625 let cmd_block = match self.cmd_block.as_deref_mut() {
1626 Some(x) => x,
1627 None => &mut CmdBlock::new(),
1628 };
1629 let scr = &mut cmd_block.0[..2];
1630
1631 let on_drop = OnDrop::new(|| Self::on_drop());
1633
1634 let transfer = Self::prepare_datapath_read(
1635 &self.config,
1636 #[cfg(sdmmc_v1)]
1637 &mut self.dma,
1638 scr,
1639 8,
1640 3,
1641 );
1642 InterruptHandler::<T>::enable_interrupts();
1643 Self::cmd(sd_cmd::send_scr(), true)?;
1644
1645 let res = Self::complete_datapath_transfer(true).await;
1646
1647 if res.is_ok() {
1648 on_drop.defuse();
1649 Self::stop_datapath();
1650 drop(transfer);
1651
1652 unsafe {
1653 let scr_bytes = &*(&scr as *const _ as *const [u8; 8]);
1654 card.scr = SCR(u64::from_be_bytes(*scr_bytes));
1655 }
1656 }
1657 res
1658 }
1659
1660 async fn read_sd_status(&mut self) -> Result<(), Error> {
1664 let card = self.card.as_mut().ok_or(Error::NoCard)?.get_sd_card();
1665 let rca = card.rca;
1666
1667 let cmd_block = match self.cmd_block.as_deref_mut() {
1668 Some(x) => x,
1669 None => &mut CmdBlock::new(),
1670 };
1671
1672 Self::cmd(common_cmd::set_block_length(64), false)?; Self::cmd(common_cmd::app_cmd(rca), false)?; let status = cmd_block;
1676
1677 let on_drop = OnDrop::new(|| Self::on_drop());
1679
1680 let transfer = Self::prepare_datapath_read(
1681 &self.config,
1682 #[cfg(sdmmc_v1)]
1683 &mut self.dma,
1684 status.as_mut(),
1685 64,
1686 6,
1687 );
1688 InterruptHandler::<T>::enable_interrupts();
1689 Self::cmd(sd_cmd::sd_status(), true)?;
1690
1691 let res = Self::complete_datapath_transfer(true).await;
1692
1693 if res.is_ok() {
1694 on_drop.defuse();
1695 Self::stop_datapath();
1696 drop(transfer);
1697
1698 for byte in status.iter_mut() {
1699 *byte = u32::from_be(*byte);
1700 }
1701 card.status = status.0.into();
1702 }
1703 res
1704 }
1705
1706 pub async fn init_emmc(&mut self, freq: Hertz) -> Result<(), Error> {
1710 self.init_internal(freq, SdmmcPeripheral::Emmc(Emmc::default())).await
1711 }
1712
1713 async fn read_ext_csd(&mut self) -> Result<(), Error> {
1717 let card = self.card.as_mut().ok_or(Error::NoCard)?.get_emmc();
1718
1719 let mut data_block = DataBlock([0u8; 512]);
1721
1722 let buffer = unsafe { &mut *((&mut data_block.0) as *mut [u8; 512] as *mut [u32; 128]) };
1724
1725 Self::cmd(common_cmd::set_block_length(512), false).unwrap(); let on_drop = OnDrop::new(|| Self::on_drop());
1729
1730 let transfer = Self::prepare_datapath_read(
1731 &self.config,
1732 #[cfg(sdmmc_v1)]
1733 &mut self.dma,
1734 buffer,
1735 512,
1736 9,
1737 );
1738 InterruptHandler::<T>::enable_interrupts();
1739 Self::cmd(emmc_cmd::send_ext_csd(), true)?;
1740
1741 let res = Self::complete_datapath_transfer(true).await;
1742
1743 if res.is_ok() {
1744 on_drop.defuse();
1745 Self::stop_datapath();
1746 drop(transfer);
1747
1748 card.ext_csd = unsafe { core::mem::transmute::<_, [u32; 128]>(data_block.0) }.into();
1749 }
1750 res
1751 }
1752}
1753
1754impl<'d, T: Instance> Drop for Sdmmc<'d, T> {
1755 fn drop(&mut self) {
1756 T::Interrupt::disable();
1757 Self::on_drop();
1758
1759 critical_section::with(|_| {
1760 self.clk.set_as_disconnected();
1761 self.cmd.set_as_disconnected();
1762 self.d0.set_as_disconnected();
1763 if let Some(x) = &mut self.d1 {
1764 x.set_as_disconnected();
1765 }
1766 if let Some(x) = &mut self.d2 {
1767 x.set_as_disconnected();
1768 }
1769 if let Some(x) = &mut self.d3 {
1770 x.set_as_disconnected();
1771 }
1772 if let Some(x) = &mut self.d4 {
1773 x.set_as_disconnected();
1774 }
1775 if let Some(x) = &mut self.d5 {
1776 x.set_as_disconnected();
1777 }
1778 if let Some(x) = &mut self.d6 {
1779 x.set_as_disconnected();
1780 }
1781 if let Some(x) = &mut self.d7 {
1782 x.set_as_disconnected();
1783 }
1784 });
1785 }
1786}
1787
1788trait SealedInstance {
1791 fn regs() -> RegBlock;
1792 fn state() -> &'static AtomicWaker;
1793}
1794
1795#[allow(private_bounds)]
1797pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
1798 type Interrupt: interrupt::typelevel::Interrupt;
1800}
1801
1802pin_trait!(CkPin, Instance);
1803pin_trait!(CmdPin, Instance);
1804pin_trait!(D0Pin, Instance);
1805pin_trait!(D1Pin, Instance);
1806pin_trait!(D2Pin, Instance);
1807pin_trait!(D3Pin, Instance);
1808pin_trait!(D4Pin, Instance);
1809pin_trait!(D5Pin, Instance);
1810pin_trait!(D6Pin, Instance);
1811pin_trait!(D7Pin, Instance);
1812
1813#[cfg(sdmmc_v1)]
1814dma_trait!(SdmmcDma, Instance);
1815
1816foreach_peripheral!(
1817 (sdmmc, $inst:ident) => {
1818 impl SealedInstance for peripherals::$inst {
1819 fn regs() -> RegBlock {
1820 crate::pac::$inst
1821 }
1822
1823 fn state() -> &'static ::embassy_sync::waitqueue::AtomicWaker {
1824 static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new();
1825 &WAKER
1826 }
1827 }
1828
1829 impl Instance for peripherals::$inst {
1830 type Interrupt = crate::interrupt::typelevel::$inst;
1831 }
1832 };
1833);
1834
1835impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> {
1836 type Error = Error;
1837 type Align = aligned::A4;
1838
1839 async fn read(
1840 &mut self,
1841 block_address: u32,
1842 buf: &mut [aligned::Aligned<Self::Align, [u8; 512]>],
1843 ) -> Result<(), Self::Error> {
1844 if buf.len() == 1 {
1846 let block = unsafe { &mut *(&mut buf[0] as *mut _ as *mut crate::sdmmc::DataBlock) };
1847 self.read_block(block_address, block).await?;
1848 } else {
1849 let blocks: &mut [DataBlock] =
1850 unsafe { core::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut DataBlock, buf.len()) };
1851 self.read_blocks(block_address, blocks).await?;
1852 }
1853 Ok(())
1854 }
1855
1856 async fn write(
1857 &mut self,
1858 block_address: u32,
1859 buf: &[aligned::Aligned<Self::Align, [u8; 512]>],
1860 ) -> Result<(), Self::Error> {
1861 if buf.len() == 1 {
1863 let block = unsafe { &*(&buf[0] as *const _ as *const crate::sdmmc::DataBlock) };
1864 self.write_block(block_address, block).await?;
1865 } else {
1866 let blocks: &[DataBlock] =
1867 unsafe { core::slice::from_raw_parts(buf.as_ptr() as *const DataBlock, buf.len()) };
1868 self.write_blocks(block_address, blocks).await?;
1869 }
1870 Ok(())
1871 }
1872
1873 async fn size(&mut self) -> Result<u64, Self::Error> {
1874 Ok(self.card()?.size())
1875 }
1876}