sdmmc_core/response/spi/
r2.rs

1//! R2 response for SPI mode.
2
3use crate::response::spi::r1::R1;
4use crate::result::{Error, Result};
5use crate::{lib_bitfield, response};
6
7lib_bitfield! {
8    /// Represents the response to the `SEND_STATUS` command in SPI mode.
9    pub R2(u16): u8 {
10        raw_r1: 15, 8;
11        /// An out-of-range access was attempted.
12        pub out_of_range: 7;
13        /// An invalid sector for erase.
14        pub erase_param: 6;
15        /// An attempt was made to write to a write-protected block.
16        pub wp_violation: 5;
17        /// Internal card ECC failed to correct data error.
18        pub card_ecc_failed: 4;
19        /// Internal card control error.
20        pub cc_error: 3;
21        /// A general or unknown error occurred.
22        pub error: 2;
23        /// Card lock/unlock failed, or write-protect erase skip
24        pub lock_failed: 1;
25        /// SD card is locked.
26        pub card_locked: 0;
27    }
28}
29
30response! {
31    R2 {
32        response_mode: Spi,
33    }
34}
35
36impl R2 {
37    /// Represents the byte length of the [R2].
38    pub const LEN: usize = 2;
39    /// Represents the default value of the [R2].
40    pub const DEFAULT: u16 = 0;
41
42    /// Creates a new [R2].
43    pub const fn new() -> Self {
44        Self(Self::DEFAULT)
45    }
46
47    /// Gets the [R1] portion of the [R2] response.
48    pub const fn r1(&self) -> Result<R1> {
49        R1::try_from_bits(self.raw_r1())
50    }
51
52    /// Sets the [R1] portion of the [R2] response.
53    pub fn set_r1(&mut self, r1: R1) {
54        self.set_raw_r1(r1.bits() as u16);
55    }
56
57    /// Builder function that sets the [R1] portion of the [R2] response.
58    pub const fn with_r1(mut self, r1: R1) -> Self {
59        Self(((r1.bits() as u16) << 8) | (self.bits() & 0xff))
60    }
61
62    /// Attempts to convert a [`u16`] into a [R2].
63    pub const fn try_from_bits(val: u16) -> Result<Self> {
64        match Self(val) {
65            r if r.r1().is_ok() => Ok(r),
66            _ => Err(Error::invalid_field_variant("r2", val as usize)),
67        }
68    }
69
70    /// Converts the [R2] into a byte array.
71    pub const fn bytes(&self) -> [u8; Self::LEN] {
72        self.0.to_be_bytes()
73    }
74
75    /// Attempts to convert a byte slice into a [R2].
76    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
77        match val.len() {
78            len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
79            _ => R2::try_from_bits(u16::from_be_bytes([val[0], val[1]])),
80        }
81    }
82}
83
84impl Default for R2 {
85    fn default() -> Self {
86        Self::new()
87    }
88}
89
90impl TryFrom<u16> for R2 {
91    type Error = Error;
92
93    fn try_from(val: u16) -> Result<Self> {
94        Self::try_from_bits(val)
95    }
96}
97
98impl TryFrom<&[u8]> for R2 {
99    type Error = Error;
100
101    fn try_from(val: &[u8]) -> Result<Self> {
102        Self::try_from_bytes(val)
103    }
104}
105
106impl<const N: usize> TryFrom<[u8; N]> for R2 {
107    type Error = Error;
108
109    fn try_from(val: [u8; N]) -> Result<Self> {
110        Self::try_from_bytes(val.as_ref())
111    }
112}
113
114impl<const N: usize> TryFrom<&[u8; N]> for R2 {
115    type Error = Error;
116
117    fn try_from(val: &[u8; N]) -> Result<Self> {
118        Self::try_from_bytes(val.as_ref())
119    }
120}
121
122impl From<R2> for [u8; R2::LEN] {
123    fn from(val: R2) -> Self {
124        val.bytes()
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131    use crate::test_field;
132
133    #[test]
134    fn test_fields() {
135        let mut r2 = R2::new();
136
137        test_field!(r2, card_locked: 0);
138        test_field!(r2, lock_failed: 1);
139        test_field!(r2, error: 2);
140        test_field!(r2, cc_error: 3);
141        test_field!(r2, card_ecc_failed: 4);
142        test_field!(r2, wp_violation: 5);
143        test_field!(r2, erase_param: 6);
144        test_field!(r2, out_of_range: 7);
145
146        assert_eq!(r2.r1(), Ok(R1::new()));
147
148        (0..=u16::MAX).for_each(|v| {
149            let [r1, _] = v.to_be_bytes();
150
151            match v {
152                v if R1::try_from_bits(r1).is_err() => {
153                    assert_eq!(
154                        R2::try_from(v),
155                        Err(Error::invalid_field_variant("r2", v as usize))
156                    )
157                }
158                v => {
159                    let exp_r1 = R1::try_from_bits(r1).unwrap();
160                    assert_eq!(R2::try_from(v), Ok(R2(v)));
161                    assert_eq!(R2(v).r1(), Ok(exp_r1));
162                    assert_eq!(R2::new().with_r1(exp_r1).r1(), Ok(exp_r1));
163                }
164            }
165        });
166    }
167}