Skip to main content

embedded_hal_sdmmc/response/
types.rs

1//! SD/MMC response types.
2
3use super::ResponseMode;
4
5/// Represents the response types used in the SD/MMC protocol.
6#[repr(C)]
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub enum ResponseType {
9    /// No response type.
10    None,
11    /// The standard response sent for most command types.
12    R1,
13    /// The same as the `R1` response, but drives a `BUSY` signal on the `DAT` line(s).
14    R1b,
15    /// 136-bit response that includes the contents of the card `CID` or `CSD` register.
16    R2,
17    /// Returns the contents of the card `OCR` register.
18    R3,
19    /// SDIO response to the `IO_SEND_OP_COND` command.
20    ///
21    /// Returns the card `IO_OCR` register contents, and other operating conditions.
22    R4,
23    /// SDIO response to the `IO_RW_DIRECT` commands.
24    R5,
25    /// Response containing the published RCA information.
26    R6,
27    /// Response containing the card interface condition.
28    R7,
29}
30
31impl ResponseType {
32    /// Represents the byte length for an 8-bit response.
33    pub const LEN_8BIT: usize = 1;
34    /// Represents the byte length for an 16-bit response.
35    pub const LEN_16BIT: usize = 2;
36    /// Represents the byte length for an 40-bit response.
37    pub const LEN_40BIT: usize = 5;
38    /// Represents the byte length for an 48-bit response.
39    pub const LEN_48BIT: usize = 6;
40    /// Represents the byte length for an 136-bit response.
41    pub const LEN_136BIT: usize = 17;
42    /// Represents the byte length for no response.
43    pub const LEN_NONE: usize = 0;
44
45    /// Creates a new [ResponseType].
46    pub const fn new() -> Self {
47        Self::R1
48    }
49
50    /// Gets the byte length of the [ResponseType] based on the operation mode.
51    pub const fn len(&self, mode: ResponseMode) -> usize {
52        match (mode, self) {
53            (
54                ResponseMode::Sd,
55                Self::R1 | Self::R1b | Self::R3 | Self::R4 | Self::R6 | Self::R7,
56            ) => Self::LEN_48BIT,
57            (ResponseMode::Sd | ResponseMode::Sdio, Self::R2) => Self::LEN_136BIT,
58            (ResponseMode::Sdio, Self::R1 | Self::R1b | Self::R4 | Self::R5 | Self::R6) => {
59                Self::LEN_48BIT
60            }
61            (ResponseMode::Spi, Self::R1 | Self::R1b) => Self::LEN_8BIT,
62            (ResponseMode::Spi, Self::R2 | Self::R5) => Self::LEN_16BIT,
63            (ResponseMode::Spi, Self::R3 | Self::R4 | Self::R7) => Self::LEN_40BIT,
64            _ => Self::LEN_NONE,
65        }
66    }
67
68    /// Gets whether the response type includes a `CRC-7` checksum field.
69    pub const fn has_crc(&self, mode: ResponseMode) -> bool {
70        matches!(
71            (mode, self),
72            (
73                ResponseMode::Sd,
74                Self::R1 | Self::R1b | Self::R2 | Self::R4 | Self::R5 | Self::R6 | Self::R7
75            )
76        ) || matches!((mode, self), (ResponseMode::Sdio, Self::R5 | Self::R6))
77    }
78}
79
80impl Default for ResponseType {
81    fn default() -> Self {
82        Self::new()
83    }
84}