sdmmc_core/response/sdio/
r6.rs

1use crate::crc::Crc7;
2use crate::result::{Error, Result};
3use crate::{lib_bitfield, response};
4
5mod card_status;
6
7pub use card_status::*;
8
9pub const COMMAND_INDEX: u8 = 0b11;
10
11lib_bitfield! {
12    /// Represents the Published RCA response in SDIO mode.
13    pub R6(MSB0 [u8; 6]): u16 {
14        start_bit: 47;
15        direction: 46;
16        raw_command_index: 45, 40;
17        /// The new published RCA number of the card.
18        pub rca: 39, 24;
19        raw_card_status: 23, 8;
20        raw_crc: 7, 1;
21        end_bit: 0;
22    }
23}
24
25response! {
26    R6 {
27        response_mode: Sdio,
28    }
29}
30
31impl R6 {
32    /// Represents the byte length of the [R6] response in SDIO mode.
33    pub const LEN: usize = 6;
34    /// Represents the default byte value of [R6].
35    pub const DEFAULT: [u8; Self::LEN] = [COMMAND_INDEX, 0, 0, 0, 0, 0x45];
36
37    /// Creates a new [R6].
38    pub const fn new() -> Self {
39        Self(Self::DEFAULT)
40    }
41
42    /// Gets the command index field of the [R6].
43    pub const fn command_index(&self) -> u8 {
44        self.raw_command_index() as u8
45    }
46
47    /// Gets the [CardStatus] field of the [R6].
48    pub const fn card_status(&self) -> CardStatus {
49        CardStatus::from_bits(self.raw_card_status())
50    }
51
52    /// Sets the [CardStatus] field of the [R6].
53    pub fn set_card_status(&mut self, val: CardStatus) {
54        self.set_raw_card_status(val.bits());
55    }
56
57    /// Gets the [Crc7] field of the [R6].
58    pub const fn crc(&self) -> Crc7 {
59        Crc7::from_bits(self.raw_crc() as u8)
60    }
61
62    /// Calculates and sets the [Crc7] field of the [R6].
63    pub fn calculate_crc(&mut self) -> Crc7 {
64        let crc = Crc7::calculate(self.0[..Self::LEN - 1].as_ref());
65        self.set_raw_crc(crc.bits() as u16);
66        crc
67    }
68
69    /// Attempts to convert a byte slice into a [R6].
70    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
71        match val.len() {
72            len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
73            _ => {
74                let crc = Crc7::calculate(&[val[0], val[1], val[2], val[3], val[4]]);
75
76                match R6([val[0], val[1], val[2], val[3], val[4], val[5]]) {
77                    r6 if r6.start_bit() => Err(Error::invalid_field_variant("r6::start_bit", 1)),
78                    r6 if r6.direction() => Err(Error::invalid_field_variant("r6::direction", 1)),
79                    r6 if r6.command_index() != COMMAND_INDEX => Err(Error::invalid_field_variant(
80                        "r6::command_index",
81                        r6.command_index() as usize,
82                    )),
83                    r6 if r6.raw_crc() as u8 != crc.bits() => {
84                        Err(Error::invalid_crc7(r6.raw_crc() as u8, crc.bits()))
85                    }
86                    r6 if !r6.end_bit() => Err(Error::invalid_field_variant("r6::end_bit", 0)),
87                    r6 => Ok(r6),
88                }
89            }
90        }
91    }
92}
93
94impl Default for R6 {
95    fn default() -> Self {
96        Self::new()
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103    use crate::test_field;
104    use crate::util::raw_with_crc;
105
106    #[test]
107    fn test_fields() {
108        let mut r6 = R6::new();
109
110        let mut cs = r6.card_status();
111
112        test_field!(cs, error: 13);
113        test_field!(cs, illegal_command: 14);
114        test_field!(cs, crc_error: 15);
115
116        assert_eq!(r6.rca(), 0);
117
118        (1..=u16::BITS)
119            .map(|r| ((1u32 << r) - 1) as u16)
120            .for_each(|rca| {
121                let [rca0, rca1] = rca.to_be_bytes();
122                let (raw, _crc) = raw_with_crc([COMMAND_INDEX, rca0, rca1, 0, 0, 0]);
123
124                let mut exp_r6 = R6(raw);
125
126                assert_eq!(R6::try_from_bytes(raw.as_ref()), Ok(exp_r6));
127                assert_eq!(exp_r6.rca(), rca);
128
129                exp_r6.set_rca(0);
130                assert_eq!(exp_r6.rca(), 0);
131
132                exp_r6.set_rca(rca);
133                assert_eq!(exp_r6.rca(), rca);
134            });
135
136        (1..=u16::BITS)
137            .map(|r| ((1u32 << r) - 1) as u16)
138            .for_each(|cs| {
139                let [cs0, cs1] = cs.to_be_bytes();
140                let (raw, _crc) = raw_with_crc([COMMAND_INDEX, 0, 0, cs0, cs1, 0]);
141
142                let mut exp_r6 = R6(raw);
143                let exp_cs = CardStatus::from_bits(cs);
144
145                assert_eq!(R6::try_from_bytes(raw.as_ref()), Ok(exp_r6));
146                assert_eq!(exp_r6.card_status(), exp_cs);
147
148                exp_r6.set_card_status(CardStatus::new());
149                assert_eq!(exp_r6.card_status(), CardStatus::new());
150
151                exp_r6.set_card_status(exp_cs);
152                assert_eq!(exp_r6.card_status(), exp_cs);
153            });
154    }
155}