sdmmc_core/response/spi/
r7.rs

1use crate::response::sd::r7::VoltageAccepted;
2use crate::response::spi::r1::R1;
3use crate::result::{Error, Result};
4use crate::{lib_bitfield, response};
5
6lib_bitfield! {
7    /// Represents the response to the `SEND_IF_COND` command (`CMD8`) in SPI mode.
8    pub R7(MSB0 [u8; 5]): u8 {
9        raw_r1: 39, 32;
10        pub command_version: 31, 28;
11        raw_voltage_accepted: 11, 8;
12        pub echo_check: 7, 0;
13    }
14}
15
16response! {
17    R7 {
18        response_mode: Spi,
19    }
20}
21
22impl R7 {
23    /// Represents the byte length of the [R7] response.
24    pub const LEN: usize = 5;
25    /// Represents the default byte value of the [R7] response.
26    pub const DEFAULT: [u8; Self::LEN] = [0, 0, 0, 0x1, 0];
27
28    /// Creates a new [R7].
29    pub const fn new() -> Self {
30        Self(Self::DEFAULT)
31    }
32
33    /// Gets the [R1] for the [R7].
34    pub const fn r1(&self) -> Result<R1> {
35        R1::try_from_bits(self.raw_r1())
36    }
37
38    /// Sets the [R1] for the [R7].
39    pub fn set_r1(&mut self, r1: R1) {
40        self.set_raw_r1(r1.bits());
41    }
42
43    /// Gets the [VoltageAccepted] value of the [R7] response.
44    pub const fn voltage_accepted(&self) -> Result<VoltageAccepted> {
45        VoltageAccepted::from_raw(self.raw_voltage_accepted())
46    }
47
48    /// Sets the [VoltageAccepted] value of the [R7] response.
49    pub fn set_voltage_accepted(&mut self, voltage_accepted: VoltageAccepted) {
50        self.set_raw_voltage_accepted(voltage_accepted.into_raw());
51    }
52
53    /// Attempts to convert a byte slice into a [R7].
54    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
55        match val.len() {
56            len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
57            _ => match R7([val[0], val[1], val[2], val[3], val[4]]) {
58                r7 if r7.r1().is_err() => {
59                    Err(Error::invalid_field_variant("r7::r1", r7.raw_r1() as usize))
60                }
61                r7 if r7.voltage_accepted().is_err() => Err(Error::invalid_field_variant(
62                    "r7::voltage_accepted",
63                    r7.raw_voltage_accepted() as usize,
64                )),
65                r7 => Ok(r7),
66            },
67        }
68    }
69}
70
71impl Default for R7 {
72    fn default() -> Self {
73        Self::new()
74    }
75}
76
77impl TryFrom<&[u8]> for R7 {
78    type Error = Error;
79
80    fn try_from(val: &[u8]) -> Result<Self> {
81        Self::try_from_bytes(val)
82    }
83}
84
85impl<const N: usize> TryFrom<[u8; N]> for R7 {
86    type Error = Error;
87
88    fn try_from(val: [u8; N]) -> Result<Self> {
89        Self::try_from_bytes(val.as_ref())
90    }
91}
92
93impl<const N: usize> TryFrom<&[u8; N]> for R7 {
94    type Error = Error;
95
96    fn try_from(val: &[u8; N]) -> Result<Self> {
97        Self::try_from_bytes(val.as_ref())
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104
105    #[test]
106    fn test_fields() {
107        let mut r7 = R7::new();
108
109        assert_eq!(r7.r1(), Ok(R1::new()));
110        assert_eq!(r7.command_version(), 0);
111        assert_eq!(r7.voltage_accepted(), Ok(VoltageAccepted::new()));
112        assert_eq!(r7.echo_check(), 0);
113
114        (0..=u8::MAX)
115            .zip(0..=u8::MAX)
116            .map(|(r1, cmd)| (r1, cmd & 0xf))
117            .zip(0..=u8::MAX)
118            .map(|(s, va)| (s, va & 0xf))
119            .zip(0..=u8::MAX)
120            .for_each(|(((r1, cmd), va), echo)| {
121                let raw = [r1, cmd << 4, 0, va, echo];
122
123                match (R1::try_from_bits(r1), VoltageAccepted::from_raw(va)) {
124                    (Ok(r1), Ok(va)) => {
125                        r7 = R7(raw);
126
127                        assert_eq!(R7::try_from_bytes(raw.as_ref()), Ok(r7));
128                        assert_eq!(R7::try_from(raw), Ok(r7));
129
130                        assert_eq!(r7.r1(), Ok(r1));
131                        assert_eq!(r7.command_version(), cmd);
132                        assert_eq!(r7.voltage_accepted(), Ok(va));
133                        assert_eq!(r7.echo_check(), echo);
134
135                        r7.set_r1(R1::new());
136                        assert_eq!(r7.r1(), Ok(R1::new()));
137
138                        r7.set_r1(r1);
139                        assert_eq!(r7.r1(), Ok(r1));
140
141                        r7.set_command_version(0);
142                        assert_eq!(r7.command_version(), 0);
143
144                        r7.set_command_version(cmd);
145                        assert_eq!(r7.command_version(), cmd);
146
147                        r7.set_echo_check(0);
148                        assert_eq!(r7.echo_check(), 0);
149
150                        r7.set_echo_check(echo);
151                        assert_eq!(r7.echo_check(), echo);
152
153                        r7.set_voltage_accepted(VoltageAccepted::new());
154                        assert_eq!(r7.voltage_accepted(), Ok(VoltageAccepted::new()));
155
156                        r7.set_voltage_accepted(va);
157                        assert_eq!(r7.voltage_accepted(), Ok(va));
158                    }
159                    (Err(_), _) => {
160                        assert_eq!(
161                            R7::try_from_bytes(raw.as_ref()),
162                            Err(Error::invalid_field_variant("r7::r1", r1 as usize))
163                        );
164                        assert_eq!(
165                            R7::try_from(raw),
166                            Err(Error::invalid_field_variant("r7::r1", r1 as usize))
167                        );
168                    }
169                    (_, Err(_)) => {
170                        assert_eq!(
171                            R7::try_from_bytes(raw.as_ref()),
172                            Err(Error::invalid_field_variant(
173                                "r7::voltage_accepted",
174                                va as usize
175                            ))
176                        );
177                        assert_eq!(
178                            R7::try_from(raw),
179                            Err(Error::invalid_field_variant(
180                                "r7::voltage_accepted",
181                                va as usize
182                            ))
183                        );
184                    }
185                }
186            });
187    }
188}