sdmmc_core/response/spi/
r4.rs1use crate::register::IoOcr;
2use crate::response::sdio::r1::R1;
3use crate::result::{Error, Result};
4use crate::{lib_bitfield, response};
5
6lib_bitfield! {
7 pub R4(MSB0 [u8; 5]): u32 {
9 raw_r1: 39, 32;
11 raw_c: 31;
13 raw_num_io_functions: 30, 28;
15 raw_memory_present: 27;
17 raw_stuff: 26, 24;
19 raw_io_ocr: 23, 0;
21 }
22}
23
24response! {
25 R4 {
26 response_mode: Spi,
27 }
28}
29
30impl R4 {
31 pub const LEN: usize = 5;
33 pub const DEFAULT: [u8; Self::LEN] = [0u8; Self::LEN];
35
36 pub const fn new() -> Self {
38 Self(Self::DEFAULT)
39 }
40
41 pub const fn r1(&self) -> Result<R1> {
43 R1::try_from_bits(self.raw_r1() as u8)
44 }
45
46 pub fn set_r1(&mut self, r1: R1) {
48 self.set_raw_r1(r1.bits() as u32);
49 }
50
51 pub const fn is_card_ready(&self) -> bool {
53 self.raw_c()
54 }
55
56 pub fn set_is_card_ready(&mut self, val: bool) {
58 self.set_raw_c(val);
59 }
60
61 pub const fn is_memory_present(&self) -> bool {
63 self.raw_memory_present()
64 }
65
66 pub fn set_is_memory_present(&mut self, val: bool) {
68 self.set_raw_memory_present(val)
69 }
70
71 pub const fn num_io_functions(&self) -> usize {
73 self.raw_num_io_functions() as usize
74 }
75
76 pub fn set_num_io_functions(&mut self, val: usize) {
80 self.set_raw_num_io_functions((val & 0x7) as u32)
81 }
82
83 pub const fn io_ocr(&self) -> IoOcr {
85 IoOcr::from_bits(self.raw_io_ocr())
86 }
87
88 pub fn set_io_ocr(&mut self, io_ocr: IoOcr) {
90 self.set_raw_io_ocr(io_ocr.bits());
91 }
92
93 pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
95 match val.len() {
96 len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
97 _ if R1::try_from_bits(val[0]).is_err() => {
98 Err(Error::invalid_field_variant("r4::r1", val[0] as usize))
99 }
100 _ => Ok(Self([val[0], val[1], val[2], val[3], val[4]])),
101 }
102 }
103}
104
105impl Default for R4 {
106 fn default() -> Self {
107 Self::new()
108 }
109}
110
111impl TryFrom<&[u8]> for R4 {
112 type Error = Error;
113
114 fn try_from(val: &[u8]) -> Result<Self> {
115 Self::try_from_bytes(val)
116 }
117}
118
119impl<const N: usize> TryFrom<[u8; N]> for R4 {
120 type Error = Error;
121
122 fn try_from(val: [u8; N]) -> Result<Self> {
123 Self::try_from_bytes(val.as_ref())
124 }
125}
126
127impl<const N: usize> TryFrom<&[u8; N]> for R4 {
128 type Error = Error;
129
130 fn try_from(val: &[u8; N]) -> Result<Self> {
131 Self::try_from_bytes(val.as_ref())
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn test_valid() {
141 (1..=40u64)
142 .map(|r| (1u64 << r) - 1)
143 .for_each(|raw_bitfield| {
144 let [_, _, _, b0, b1, b2, b3, b4] = raw_bitfield.to_be_bytes();
145
146 let b0 = b0 & !R1::MASK;
147 let raw_bytes = [b0, b1, b2, b3, b4];
148
149 let exp_r1 = R1::try_from_bits(b0).unwrap();
150 let exp_card_ready = (b1 & 0x80) != 0;
151 let exp_num_io = ((b1 & 0x70) >> 4) as usize;
152 let exp_mem = (b1 & 0x8) != 0;
153 let exp_io_ocr = IoOcr::try_from_bytes(&[b2, b3, b4]).unwrap();
154
155 let mut exp_r4 = R4(raw_bytes);
156
157 assert_eq!(R4::try_from_bytes(raw_bytes.as_ref()), Ok(exp_r4));
158
159 assert_eq!(exp_r4.r1(), Ok(exp_r1));
160
161 exp_r4.set_r1(R1::new());
162 assert_eq!(exp_r4.r1(), Ok(R1::new()));
163
164 exp_r4.set_r1(exp_r1);
165 assert_eq!(exp_r4.r1(), Ok(exp_r1));
166
167 assert_eq!(exp_r4.is_card_ready(), exp_card_ready);
168
169 exp_r4.set_is_card_ready(!exp_card_ready);
170 assert_eq!(exp_r4.is_card_ready(), !exp_card_ready);
171
172 exp_r4.set_is_card_ready(exp_card_ready);
173 assert_eq!(exp_r4.is_card_ready(), exp_card_ready);
174
175 assert_eq!(exp_r4.num_io_functions(), exp_num_io, "{:#x}", raw_bitfield);
176
177 exp_r4.set_num_io_functions(0);
178 assert_eq!(exp_r4.num_io_functions(), 0);
179
180 exp_r4.set_num_io_functions(exp_num_io);
181 assert_eq!(exp_r4.num_io_functions(), exp_num_io);
182
183 assert_eq!(exp_r4.is_memory_present(), exp_mem);
184
185 exp_r4.set_is_memory_present(!exp_mem);
186 assert_eq!(exp_r4.is_memory_present(), !exp_mem);
187
188 exp_r4.set_is_memory_present(exp_mem);
189 assert_eq!(exp_r4.is_memory_present(), exp_mem);
190
191 assert_eq!(exp_r4.io_ocr(), exp_io_ocr);
192
193 exp_r4.set_io_ocr(IoOcr::new());
194 assert_eq!(exp_r4.io_ocr(), IoOcr::new());
195
196 exp_r4.set_io_ocr(exp_io_ocr);
197 assert_eq!(exp_r4.io_ocr(), exp_io_ocr);
198 });
199 }
200}