sdmmc_core/response/sd/
r2.rs

1//! R2 response for SD mode.
2
3use crate::register::{Cid, Csd};
4use crate::response::Start;
5use crate::result::{Error, Result};
6use crate::{lib_bitfield, response};
7
8mod register;
9
10pub use register::Register;
11
12lib_bitfield! {
13    /// Represents the `R2` response in SD mode.
14    ///
15    /// Contains the `CID` or `CSD` register, including internal CRC7.
16    pub R2(MSB0 [u8; 17]): u128 {
17        raw_start: 135, 128;
18        raw_register: 127, 0;
19    }
20}
21
22response! {
23    R2 {
24        response_mode: Sd,
25    }
26}
27
28impl R2 {
29    /// Represents the byte length of the [R2] response in SD mode.
30    pub const LEN: usize = 17;
31    /// Represents the default byte value of the [R2].
32    pub const DEFAULT: [u8; Self::LEN] = [0x3f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x13];
33
34    /// Creates a new [R2].
35    pub const fn new() -> Self {
36        Self(Self::DEFAULT)
37    }
38
39    /// Attempts to get the [Start] field for the [R2].
40    pub const fn start(&self) -> Result<Start> {
41        Start::try_from_bits(self.raw_start() as u8)
42    }
43
44    /// Attempts to get the [Register] field for the [R2].
45    pub const fn register(&self) -> Result<Register> {
46        Register::try_from_bytes(&self.raw_register().to_be_bytes())
47    }
48
49    /// Sets the [Register] field for the [R2].
50    pub fn set_register(&mut self, val: Register) {
51        self.set_raw_register(u128::from_be_bytes(val.bytes()));
52    }
53
54    /// Attempts to convert a byte slice into a [R2].
55    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
56        match val.len() {
57            len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
58            _ => {
59                let r = Self([
60                    val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9],
61                    val[10], val[11], val[12], val[13], val[14], val[15], val[16],
62                ]);
63
64                match (r.start(), r.register()) {
65                    (Ok(_), Ok(_)) => Ok(r),
66                    (Err(_err), _) => Err(Error::invalid_field_variant(
67                        "r2::start",
68                        r.raw_start() as usize,
69                    )),
70                    (_, Err(err)) => Err(err),
71                }
72            }
73        }
74    }
75}
76
77impl Default for R2 {
78    fn default() -> Self {
79        Self::new()
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn test_valid() {
89        let mut r2 = R2::new();
90        let start = Start::from_bits(0x3f);
91        let register = Register::new();
92        let cid = Cid::new();
93        let csd = Csd::new();
94        let r2_bytes = R2::DEFAULT;
95        let raw_crc = r2_bytes[16];
96
97        assert_eq!(
98            r2.register().and_then(|r| r.cid().map(|c| c.crc().bits())),
99            Ok(raw_crc)
100        );
101        assert_eq!(R2::try_from_bytes(r2_bytes.as_ref()), Ok(r2));
102        assert_eq!(r2.bytes(), r2_bytes);
103
104        assert_eq!(r2.start(), Ok(start));
105
106        assert_eq!(r2.register(), Ok(register));
107
108        assert_eq!(r2.register().unwrap().cid(), Ok(&cid));
109
110        r2.set_register(csd.into());
111        assert_eq!(r2.register().unwrap().csd(), Ok(&csd));
112    }
113}