sdmmc_core/response/spi/
r7.rs1use 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 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 pub const LEN: usize = 5;
25 pub const DEFAULT: [u8; Self::LEN] = [0, 0, 0, 0x1, 0];
27
28 pub const fn new() -> Self {
30 Self(Self::DEFAULT)
31 }
32
33 pub const fn r1(&self) -> Result<R1> {
35 R1::try_from_bits(self.raw_r1())
36 }
37
38 pub fn set_r1(&mut self, r1: R1) {
40 self.set_raw_r1(r1.bits());
41 }
42
43 pub const fn voltage_accepted(&self) -> Result<VoltageAccepted> {
45 VoltageAccepted::from_raw(self.raw_voltage_accepted())
46 }
47
48 pub fn set_voltage_accepted(&mut self, voltage_accepted: VoltageAccepted) {
50 self.set_raw_voltage_accepted(voltage_accepted.into_raw());
51 }
52
53 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}