1#![cfg_attr(not(test), no_std)]
11
12use aligned::{A4, Aligned};
13use embedded_hal_async::delay::DelayNs;
14
15use crate::sd::{
16 BlockSize, CardCapacity, CardStatus, OCR, block_size, read_multiple_blocks, read_single_block,
17 stop_transmission, write_multiple_blocks, write_single_block,
18};
19
20pub mod common;
21pub mod emmc;
22pub mod sd;
23pub mod sdio;
24pub mod spi;
25
26const INIT_FREQ: u32 = 400_000;
27
28#[derive(Debug)]
29#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30pub enum MmcError {
31 Timeout,
32 Crc,
33 IllegalCommand,
34 Busy,
35 Io,
36 SignalingSwitchFailed,
37 Unsupported,
38 Other,
39}
40
41#[derive(Debug, Clone, Copy)]
42#[cfg_attr(feature = "defmt", derive(defmt::Format))]
43pub enum BusWidth {
44 W1,
45 W4,
46 W8,
47}
48
49#[derive(Debug, Clone, Copy)]
50#[cfg_attr(feature = "defmt", derive(defmt::Format))]
51pub enum ResponseLen {
52 Zero,
53 R48,
54 R136,
55}
56
57impl ResponseLen {
58 pub const fn words(&self) -> usize {
59 match self {
60 Self::Zero => 0,
61 Self::R48 => 1,
62 Self::R136 => 4,
63 }
64 }
65}
66
67pub trait Response: Sized {
82 const CRC: bool;
84
85 const BUSY: bool;
87
88 const LEN: ResponseLen;
90
91 fn from_words(buf: &[u32; 4]) -> Self;
93}
94
95pub trait Command {
113 const INDEX: u8;
115
116 type Resp<'a>: Response
118 where
119 Self: 'a;
120
121 fn index(&self) -> u8 {
123 Self::INDEX
124 }
125
126 fn arg(&self) -> u32;
128}
129
130pub trait BlockCommand: Command {
132 fn block_size(&self) -> BlockSize;
134
135 fn block_count(&self) -> u32;
137}
138
139pub trait ByteCommand: Command {
141 fn byte_count(&self) -> usize;
143}
144
145pub trait ControlCommand: Command {}
147
148pub trait BlockReadCommand: BlockCommand {
150 fn buf(&mut self) -> &mut Aligned<A4, [u8]>;
152}
153
154pub trait BlockWriteCommand: BlockCommand {
156 fn buf(&self) -> &Aligned<A4, [u8]>;
158}
159
160pub trait ByteReadCommand: ByteCommand {
162 fn buf(&mut self) -> &mut Aligned<A4, [u8]>;
164}
165
166pub trait ByteWriteCommand: ByteCommand {
168 fn buf(&self) -> &Aligned<A4, [u8]>;
170}
171
172pub trait MmcBus {
191 fn send_command<'a, C>(
195 &mut self,
196 cmd: C,
197 ) -> impl Future<Output = Result<C::Resp<'a>, MmcError>>
198 where
199 C: ControlCommand + 'a;
200
201 fn read_blocks<'a, C>(&mut self, cmd: C) -> impl Future<Output = Result<C::Resp<'a>, MmcError>>
203 where
204 C: BlockReadCommand + 'a;
205
206 fn write_blocks<'a, C>(
208 &mut self,
209 cmd: C,
210 ) -> impl Future<Output = Result<C::Resp<'a>, MmcError>>
211 where
212 C: BlockWriteCommand + 'a;
213
214 fn read_bytes<'a, C>(&mut self, cmd: C) -> impl Future<Output = Result<C::Resp<'a>, MmcError>>
216 where
217 C: ByteReadCommand + 'a;
218
219 fn write_bytes<'a, C>(&mut self, cmd: C) -> impl Future<Output = Result<C::Resp<'a>, MmcError>>
221 where
222 C: ByteWriteCommand + 'a;
223
224 fn init_idle(&mut self, hz: u32) -> impl Future<Output = Result<(), MmcError>>;
228
229 #[allow(unused_variables)]
231 fn tune_bus<O>(
232 &mut self,
233 width: BusWidth,
234 hz: u32,
235 op: &mut O,
236 ) -> impl Future<Output = Result<(), MmcError>>
237 where
238 O: TuningOp,
239 {
240 async { Ok(()) }
241 }
242
243 fn wait_for_event(&mut self) -> impl Future<Output = Result<(), MmcError>> {
245 async { Ok(()) }
246 }
247
248 fn set_bus(&mut self, width: BusWidth, hz: u32) -> Result<(), MmcError>;
253
254 fn supports_mmc(&self) -> bool {
256 false
257 }
258
259 fn supports_bus_width(&self) -> BusWidth {
261 BusWidth::W1
262 }
263
264 fn supports_1v8(&self) -> bool {
266 false
267 }
268
269 fn supports_frequency(&self) -> u32 {
271 25_000_000
272 }
273}
274
275impl<T: MmcBus> MmcBus for &mut T {
276 async fn send_command<'a, C>(&mut self, cmd: C) -> Result<C::Resp<'a>, MmcError>
277 where
278 C: ControlCommand + 'a,
279 {
280 T::send_command(self, cmd).await
281 }
282
283 async fn read_blocks<'a, C>(&mut self, cmd: C) -> Result<C::Resp<'a>, MmcError>
284 where
285 C: BlockReadCommand + 'a,
286 {
287 T::read_blocks(self, cmd).await
288 }
289
290 async fn write_blocks<'a, C>(&mut self, cmd: C) -> Result<C::Resp<'a>, MmcError>
291 where
292 C: BlockWriteCommand + 'a,
293 {
294 T::write_blocks(self, cmd).await
295 }
296
297 async fn read_bytes<'a, C>(&mut self, cmd: C) -> Result<C::Resp<'a>, MmcError>
298 where
299 C: ByteReadCommand + 'a,
300 {
301 T::read_bytes(self, cmd).await
302 }
303
304 async fn write_bytes<'a, C>(&mut self, cmd: C) -> Result<C::Resp<'a>, MmcError>
305 where
306 C: ByteWriteCommand + 'a,
307 {
308 T::write_bytes(self, cmd).await
309 }
310
311 async fn tune_bus<O>(&mut self, width: BusWidth, hz: u32, op: &mut O) -> Result<(), MmcError>
312 where
313 O: TuningOp,
314 {
315 T::tune_bus(self, width, hz, op).await
316 }
317
318 async fn wait_for_event(&mut self) -> Result<(), MmcError> {
319 T::wait_for_event(self).await
320 }
321
322 async fn init_idle(&mut self, hz: u32) -> Result<(), MmcError> {
323 T::init_idle(self, hz).await
324 }
325
326 fn set_bus(&mut self, width: BusWidth, hz: u32) -> Result<(), MmcError> {
327 T::set_bus(self, width, hz)
328 }
329
330 fn supports_1v8(&self) -> bool {
331 T::supports_1v8(self)
332 }
333
334 fn supports_bus_width(&self) -> BusWidth {
335 T::supports_bus_width(self)
336 }
337
338 fn supports_frequency(&self) -> u32 {
339 T::supports_frequency(self)
340 }
341
342 fn supports_mmc(&self) -> bool {
343 T::supports_mmc(self)
344 }
345}
346
347pub struct R0;
349
350impl Response for R0 {
351 const CRC: bool = false;
352 const LEN: ResponseLen = ResponseLen::Zero;
353 const BUSY: bool = false;
354
355 fn from_words(_buf: &[u32; 4]) -> Self {
356 Self
357 }
358}
359
360pub struct R1 {
364 pub status: u32,
365}
366
367#[derive(Debug, Clone, Copy, PartialEq, Eq)]
368pub enum CardState {
369 Idle, Ready, Ident, Standby, Transfer, Data, Receive, Programming, Reserved(u8), }
379
380impl R1 {
381 pub const ERR_MASK: u32 = 0xFDF9_8008;
383
384 pub fn to_result(&self) -> Result<(), MmcError> {
385 if self.is_error() {
386 Err(MmcError::Other)
387 } else {
388 Ok(())
389 }
390 }
391
392 pub fn is_error(&self) -> bool {
393 self.status & Self::ERR_MASK != 0
394 }
395
396 pub fn app_cmd(&self) -> bool {
397 self.status & (1 << 5) != 0
398 }
399
400 pub fn ready_for_data(&self) -> bool {
401 self.status & (1 << 8) != 0
402 }
403
404 pub fn current_state(&self) -> CardState {
405 let v = ((self.status >> 9) & 0xF) as u8;
406 match v {
407 0 => CardState::Idle,
408 1 => CardState::Ready,
409 2 => CardState::Ident,
410 3 => CardState::Standby,
411 4 => CardState::Transfer,
412 5 => CardState::Data,
413 6 => CardState::Receive,
414 7 => CardState::Programming,
415 other => CardState::Reserved(other),
416 }
417 }
418}
419
420impl Response for R1 {
421 const CRC: bool = true;
422 const LEN: ResponseLen = ResponseLen::R48;
423 const BUSY: bool = false;
424
425 fn from_words(buf: &[u32; 4]) -> Self {
426 R1 { status: buf[0] }
427 }
428}
429
430pub struct R1b {
435 pub status: u32,
436}
437
438impl R1b {
439 pub const fn to_response(&self) -> R1 {
441 R1 {
442 status: self.status,
443 }
444 }
445}
446
447impl Response for R1b {
448 const CRC: bool = true;
449 const LEN: ResponseLen = ResponseLen::R48;
450 const BUSY: bool = true;
451
452 fn from_words(buf: &[u32; 4]) -> Self {
453 R1b { status: buf[0] }
454 }
455}
456
457pub struct R2 {
461 pub words: [u32; 4],
462}
463
464impl Response for R2 {
465 const CRC: bool = true;
466 const LEN: ResponseLen = ResponseLen::R136;
467 const BUSY: bool = false;
468
469 fn from_words(buf: &[u32; 4]) -> Self {
470 R2 {
471 words: [buf[0], buf[1], buf[2], buf[3]],
472 }
473 }
474}
475
476pub struct R3 {
481 pub ocr: u32,
482}
483
484impl Response for R3 {
485 const CRC: bool = false;
486 const LEN: ResponseLen = ResponseLen::R48;
487 const BUSY: bool = false;
488
489 fn from_words(buf: &[u32; 4]) -> Self {
490 R3 { ocr: buf[0] }
491 }
492}
493
494pub struct R6 {
498 pub rca: u16,
499 pub status: u16,
500}
501
502impl Response for R6 {
503 const CRC: bool = true;
504 const LEN: ResponseLen = ResponseLen::R48;
505 const BUSY: bool = false;
506
507 fn from_words(buf: &[u32; 4]) -> Self {
508 let v = buf[0];
509 R6 {
510 rca: (v >> 16) as u16,
511 status: (v & 0xFFFF) as u16,
512 }
513 }
514}
515
516pub struct R7 {
520 pub voltage: u8,
521 pub check_pattern: u8,
522}
523
524impl Response for R7 {
525 const CRC: bool = true;
526 const LEN: ResponseLen = ResponseLen::R48;
527 const BUSY: bool = false;
528
529 fn from_words(buf: &[u32; 4]) -> Self {
530 let v = buf[0];
531 R7 {
532 voltage: ((v >> 8) & 0xF) as u8,
533 check_pattern: (v & 0xFF) as u8,
534 }
535 }
536}
537
538pub struct R4 {
547 pub ocr: u32,
548}
549
550impl Response for R4 {
551 const CRC: bool = false;
552 const LEN: ResponseLen = ResponseLen::R48;
553 const BUSY: bool = false;
554
555 fn from_words(buf: &[u32; 4]) -> Self {
556 R4 { ocr: buf[0] }
557 }
558}
559
560pub struct R5 {
565 pub flags: u8,
566 pub data: u8,
567}
568
569impl R5 {
570 pub const FLAG_COM_CRC_ERROR: u8 = 1 << 7;
572 pub const FLAG_ILLEGAL_COMMAND: u8 = 1 << 6;
574 pub const FLAG_ERROR: u8 = 1 << 3;
576 pub const FLAG_FUNCTION_NUMBER: u8 = 1 << 1;
578 pub const FLAG_OUT_OF_RANGE: u8 = 1 << 0;
580
581 pub const ERROR_FLAGS: u8 = Self::FLAG_COM_CRC_ERROR
583 | Self::FLAG_ILLEGAL_COMMAND
584 | Self::FLAG_ERROR
585 | Self::FLAG_FUNCTION_NUMBER
586 | Self::FLAG_OUT_OF_RANGE;
587
588 pub fn to_result(&self) -> Result<(), MmcError> {
589 if self.is_error() {
590 Err(MmcError::Other)
591 } else {
592 Ok(())
593 }
594 }
595
596 pub fn is_error(&self) -> bool {
597 self.flags & Self::ERROR_FLAGS != 0
598 }
599}
600
601impl Response for R5 {
602 const CRC: bool = true;
603 const LEN: ResponseLen = ResponseLen::R48;
604 const BUSY: bool = false;
605
606 fn from_words(buf: &[u32; 4]) -> Self {
607 let v = buf[0];
608 R5 {
609 flags: ((v >> 8) & 0xFF) as u8,
610 data: (v & 0xFF) as u8,
611 }
612 }
613}
614
615pub trait TuningOp {
617 fn exec<B: MmcBus>(&mut self, bus: &mut B) -> impl Future<Output = Result<bool, MmcError>>;
623}
624
625impl<T: Command> Command for &T {
627 const INDEX: u8 = T::INDEX;
628
629 type Resp<'a>
630 = T::Resp<'a>
631 where
632 Self: 'a;
633
634 fn arg(&self) -> u32 {
635 T::arg(self)
636 }
637}
638
639impl<T: Command> Command for &mut T {
640 const INDEX: u8 = T::INDEX;
641
642 type Resp<'a>
643 = T::Resp<'a>
644 where
645 Self: 'a;
646
647 fn arg(&self) -> u32 {
648 T::arg(self)
649 }
650}
651
652impl<T: ControlCommand> ControlCommand for &T {}
653
654impl<T: BlockCommand> BlockCommand for &mut T {
655 fn block_count(&self) -> u32 {
656 T::block_count(self)
657 }
658
659 fn block_size(&self) -> BlockSize {
660 T::block_size(self)
661 }
662}
663
664impl<T: BlockReadCommand> BlockReadCommand for &mut T {
665 fn buf(&mut self) -> &mut Aligned<A4, [u8]> {
666 T::buf(self)
667 }
668}
669
670struct BusAdapter<B: MmcBus, D: DelayNs> {
672 pub bus: B,
673 pub delay: D,
674 pub rca: u16,
675}
676
677impl<B: MmcBus, D: DelayNs> BusAdapter<B, D> {
678 async fn app_cmd(&mut self, app_cmd: bool) -> Result<(), MmcError> {
680 if app_cmd {
681 self.bus
682 .send_command(sd::app_cmd(self.rca))
683 .await?
684 .to_result()?
685 }
686
687 Ok(())
688 }
689
690 async fn check_card(&mut self) -> bool {
692 if let Ok(status) = self
693 .bus
694 .send_command(common::card_status(self.rca, false))
695 .await
696 && CardStatus::<()>::from(status).ready_for_data()
697 {
698 true
699 } else {
700 false
701 }
702 }
703
704 async fn wait_if_required<R: Response>(&mut self) -> Result<(), MmcError> {
706 if !R::BUSY {
707 return Ok(());
708 }
709
710 for _ in 0..750 {
713 if self.check_card().await {
714 return Ok(());
715 }
716
717 self.delay.delay_ms(1).await;
718 }
719
720 Err(MmcError::Timeout)
721 }
722
723 pub async fn init_idle(&mut self) -> Result<(), MmcError> {
724 self.bus.init_idle(INIT_FREQ).await?;
727
728 self.delay.delay_us(74_000_000 / INIT_FREQ).await;
730
731 if self.bus.supports_mmc() {
732 self.send_command(common::idle(), false).await?;
733 } else {
734 self.send_command(common::idle_spi(), false).await?;
735 }
736
737 Ok(())
738 }
739
740 pub async fn select_card(&mut self, rca: Option<u16>) -> Result<(), MmcError> {
745 match self
746 .send_command(common::select_card(rca.unwrap_or(0)), false)
747 .await
748 {
749 Err(MmcError::Timeout) if rca.is_none() => Ok(()),
750 result => result.map(|_| ()),
751 }
752 }
753
754 pub async fn get_ocr<'a, C: ControlCommand + 'a, Ext>(
756 &mut self,
757 cmd: &'a C,
758 app_cmd: bool,
759 ) -> Result<OCR<Ext>, MmcError>
760 where
761 OCR<Ext>: From<<C as Command>::Resp<'a>>,
762 {
763 for _ in 0..750 {
766 let ocr: OCR<Ext> = self.send_command(cmd, app_cmd).await?.into();
767
768 if !ocr.is_busy() {
769 return Ok(ocr);
771 }
772
773 self.delay.delay_ms(1).await;
774 }
775
776 Err(MmcError::Timeout)
777 }
778
779 pub async fn send_command<'a, C: ControlCommand + 'a>(
783 &mut self,
784 cmd: C,
785 app_cmd: bool,
786 ) -> Result<C::Resp<'a>, MmcError> {
787 self.app_cmd(app_cmd).await?;
788 let res = self.bus.send_command(cmd).await?;
789 self.wait_if_required::<C::Resp<'a>>().await?;
790
791 Ok(res)
792 }
793
794 pub async fn read_blocks<'a, C: BlockReadCommand + 'a>(
800 &mut self,
801 cmd: C,
802 app_cmd: bool,
803 ) -> Result<C::Resp<'a>, MmcError> {
804 self.app_cmd(app_cmd).await?;
805 let res = self.bus.read_blocks(cmd).await?;
806 self.wait_if_required::<C::Resp<'a>>().await?;
807
808 Ok(res)
809 }
810
811 pub async fn write_blocks<'a, C: BlockWriteCommand + 'a>(
817 &mut self,
818 cmd: C,
819 app_cmd: bool,
820 ) -> Result<C::Resp<'a>, MmcError> {
821 self.app_cmd(app_cmd).await?;
822 let res = self.bus.write_blocks(cmd).await?;
823 self.wait_if_required::<C::Resp<'a>>().await?;
824
825 Ok(res)
826 }
827}
828
829#[non_exhaustive]
831#[allow(missing_docs)]
832#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
833pub enum Signalling {
834 #[default]
835 SDR12,
836 SDR25,
837 SDR50,
838 SDR104,
839 DDR50,
840}
841
842trait Acquirable: Sized + Clone + Default {
844 fn acquire<B: MmcBus, D: DelayNs>(
846 bus: &mut BusAdapter<B, D>,
847 block_size: BlockSize,
848 bus_width: BusWidth,
849 freq: u32,
850 ) -> impl Future<Output = Result<Self, MmcError>>;
851}
852
853#[allow(private_bounds)]
855pub trait Addressable: Acquirable {
856 type Ext;
858
859 fn get_capacity(&self) -> CardCapacity;
861
862 fn block_count(&self) -> u32;
864
865 fn supports_cmd23(&self) -> bool;
867
868 fn supports_acmd23(&self) -> bool;
870}
871
872pub type DefaultBlockDevice<T, B, D> = BlockDevice<T, B, D, 512>;
874
875pub struct BlockDevice<T: Addressable, B: MmcBus, D: DelayNs, const BLOCK_SIZE: usize> {
877 info: T,
878 bus: BusAdapter<B, D>,
879}
880
881impl<A: Addressable, B: MmcBus, D: DelayNs, const BLOCK_SIZE: usize>
883 BlockDevice<A, B, D, BLOCK_SIZE>
884{
885 pub async fn new(bus: B, delay: D, freq: u32) -> Result<Self, MmcError> {
887 let mut this = Self::new_uninit(bus, delay);
888 this.reacquire(freq).await?;
889
890 Ok(this)
891 }
892
893 pub fn new_uninit(bus: B, delay: D) -> Self {
895 Self {
896 info: A::default(),
897 bus: BusAdapter { bus, delay, rca: 0 },
898 }
899 }
900
901 pub async fn reacquire(&mut self, freq: u32) -> Result<(), MmcError> {
903 let freq = freq.clamp(0, self.bus.bus.supports_frequency());
905 let bus_width = self.bus.bus.supports_bus_width();
906
907 self.bus.init_idle().await?;
908 self.info = A::acquire(&mut self.bus, block_size(BLOCK_SIZE), bus_width, freq).await?;
909
910 Ok(())
911 }
912
913 pub fn card(&self) -> A {
915 self.info.clone()
916 }
917
918 fn get_addr(&self, block_idx: u32) -> u32 {
919 match self.info.get_capacity() {
921 CardCapacity::StandardCapacity => block_idx * BLOCK_SIZE as u32,
922 _ => block_idx,
923 }
924 }
925
926 #[inline]
928 async fn read_block(
929 &mut self,
930 block_idx: u32,
931 block: &mut Aligned<A4, [u8; BLOCK_SIZE]>,
932 ) -> Result<(), MmcError> {
933 self.bus
934 .read_blocks(read_single_block(self.get_addr(block_idx), block), false)
935 .await?
936 .to_result()?;
937
938 Ok(())
939 }
940
941 #[inline]
943 async fn read_blocks(
944 &mut self,
945 block_idx: u32,
946 blocks: &mut [Aligned<A4, [u8; BLOCK_SIZE]>],
947 ) -> Result<(), MmcError> {
948 self.bus
949 .read_blocks(
950 read_multiple_blocks(self.get_addr(block_idx), blocks),
951 false,
952 )
953 .await?
954 .to_result()?;
955
956 self.bus.send_command(stop_transmission(), false).await?;
957
958 Ok(())
959 }
960
961 #[inline]
963 async fn write_block(
964 &mut self,
965 block_idx: u32,
966 block: &Aligned<A4, [u8; BLOCK_SIZE]>,
967 ) -> Result<(), MmcError> {
968 self.bus
969 .write_blocks(write_single_block(self.get_addr(block_idx), block), false)
970 .await?
971 .to_response()
972 .to_result()?;
973
974 Ok(())
975 }
976
977 #[inline]
979 async fn write_blocks(
980 &mut self,
981 block_idx: u32,
982 blocks: &[Aligned<A4, [u8; BLOCK_SIZE]>],
983 ) -> Result<(), MmcError> {
984 if self.info.supports_acmd23() {
985 self.bus
986 .send_command(sd::set_wr_blk_erase_count(blocks.len() as u32), true)
987 .await?
988 .to_result()?;
989 }
990
991 let supports_cmd23 = self.info.supports_cmd23();
992
993 if supports_cmd23 {
994 self.bus
995 .send_command(sd::set_block_count(blocks.len() as u32), false)
996 .await?
997 .to_result()?;
998 }
999
1000 self.bus
1001 .write_blocks(
1002 write_multiple_blocks(self.get_addr(block_idx), blocks),
1003 false,
1004 )
1005 .await?
1006 .to_response()
1007 .to_result()?;
1008
1009 if !supports_cmd23 {
1010 self.bus.send_command(stop_transmission(), false).await?;
1011 }
1012
1013 Ok(())
1014 }
1015}
1016
1017impl<A: Addressable, B: MmcBus, D: DelayNs, const BLOCK_SIZE: usize>
1018 block_device_driver::BlockDevice<BLOCK_SIZE> for BlockDevice<A, B, D, BLOCK_SIZE>
1019{
1020 type Align = A4;
1021 type Error = MmcError;
1022
1023 #[inline]
1024 async fn read(
1025 &mut self,
1026 block_address: u32,
1027 blocks: &mut [aligned::Aligned<Self::Align, [u8; BLOCK_SIZE]>],
1028 ) -> Result<(), Self::Error> {
1029 assert_eq!(BLOCK_SIZE % 4, 0);
1030
1031 if blocks.len() == 1 {
1033 self.read_block(block_address, &mut blocks[0]).await?;
1034 } else {
1035 self.read_blocks(block_address, blocks).await?;
1036 }
1037 Ok(())
1038 }
1039
1040 #[inline]
1041 async fn write(
1042 &mut self,
1043 block_address: u32,
1044 blocks: &[aligned::Aligned<Self::Align, [u8; BLOCK_SIZE]>],
1045 ) -> Result<(), Self::Error> {
1046 assert_eq!(BLOCK_SIZE % 4, 0);
1047
1048 if blocks.len() == 1 {
1050 self.write_block(block_address, &blocks[0]).await?;
1051 } else {
1052 self.write_blocks(block_address, blocks).await?;
1053 }
1054 Ok(())
1055 }
1056
1057 async fn size(&mut self) -> Result<u64, Self::Error> {
1058 Ok(self.info.block_count() as u64 * BLOCK_SIZE as u64)
1059 }
1060}