sdmmc_core/response/sdio/
r6.rs1use crate::crc::Crc7;
2use crate::result::{Error, Result};
3use crate::{lib_bitfield, response};
4
5mod card_status;
6
7pub use card_status::*;
8
9pub const COMMAND_INDEX: u8 = 0b11;
10
11lib_bitfield! {
12 pub R6(MSB0 [u8; 6]): u16 {
14 start_bit: 47;
15 direction: 46;
16 raw_command_index: 45, 40;
17 pub rca: 39, 24;
19 raw_card_status: 23, 8;
20 raw_crc: 7, 1;
21 end_bit: 0;
22 }
23}
24
25response! {
26 R6 {
27 response_mode: Sdio,
28 }
29}
30
31impl R6 {
32 pub const LEN: usize = 6;
34 pub const DEFAULT: [u8; Self::LEN] = [COMMAND_INDEX, 0, 0, 0, 0, 0x45];
36
37 pub const fn new() -> Self {
39 Self(Self::DEFAULT)
40 }
41
42 pub const fn command_index(&self) -> u8 {
44 self.raw_command_index() as u8
45 }
46
47 pub const fn card_status(&self) -> CardStatus {
49 CardStatus::from_bits(self.raw_card_status())
50 }
51
52 pub fn set_card_status(&mut self, val: CardStatus) {
54 self.set_raw_card_status(val.bits());
55 }
56
57 pub const fn crc(&self) -> Crc7 {
59 Crc7::from_bits(self.raw_crc() as u8)
60 }
61
62 pub fn calculate_crc(&mut self) -> Crc7 {
64 let crc = Crc7::calculate(self.0[..Self::LEN - 1].as_ref());
65 self.set_raw_crc(crc.bits() as u16);
66 crc
67 }
68
69 pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
71 match val.len() {
72 len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
73 _ => {
74 let crc = Crc7::calculate(&[val[0], val[1], val[2], val[3], val[4]]);
75
76 match R6([val[0], val[1], val[2], val[3], val[4], val[5]]) {
77 r6 if r6.start_bit() => Err(Error::invalid_field_variant("r6::start_bit", 1)),
78 r6 if r6.direction() => Err(Error::invalid_field_variant("r6::direction", 1)),
79 r6 if r6.command_index() != COMMAND_INDEX => Err(Error::invalid_field_variant(
80 "r6::command_index",
81 r6.command_index() as usize,
82 )),
83 r6 if r6.raw_crc() as u8 != crc.bits() => {
84 Err(Error::invalid_crc7(r6.raw_crc() as u8, crc.bits()))
85 }
86 r6 if !r6.end_bit() => Err(Error::invalid_field_variant("r6::end_bit", 0)),
87 r6 => Ok(r6),
88 }
89 }
90 }
91 }
92}
93
94impl Default for R6 {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use crate::test_field;
104 use crate::util::raw_with_crc;
105
106 #[test]
107 fn test_fields() {
108 let mut r6 = R6::new();
109
110 let mut cs = r6.card_status();
111
112 test_field!(cs, error: 13);
113 test_field!(cs, illegal_command: 14);
114 test_field!(cs, crc_error: 15);
115
116 assert_eq!(r6.rca(), 0);
117
118 (1..=u16::BITS)
119 .map(|r| ((1u32 << r) - 1) as u16)
120 .for_each(|rca| {
121 let [rca0, rca1] = rca.to_be_bytes();
122 let (raw, _crc) = raw_with_crc([COMMAND_INDEX, rca0, rca1, 0, 0, 0]);
123
124 let mut exp_r6 = R6(raw);
125
126 assert_eq!(R6::try_from_bytes(raw.as_ref()), Ok(exp_r6));
127 assert_eq!(exp_r6.rca(), rca);
128
129 exp_r6.set_rca(0);
130 assert_eq!(exp_r6.rca(), 0);
131
132 exp_r6.set_rca(rca);
133 assert_eq!(exp_r6.rca(), rca);
134 });
135
136 (1..=u16::BITS)
137 .map(|r| ((1u32 << r) - 1) as u16)
138 .for_each(|cs| {
139 let [cs0, cs1] = cs.to_be_bytes();
140 let (raw, _crc) = raw_with_crc([COMMAND_INDEX, 0, 0, cs0, cs1, 0]);
141
142 let mut exp_r6 = R6(raw);
143 let exp_cs = CardStatus::from_bits(cs);
144
145 assert_eq!(R6::try_from_bytes(raw.as_ref()), Ok(exp_r6));
146 assert_eq!(exp_r6.card_status(), exp_cs);
147
148 exp_r6.set_card_status(CardStatus::new());
149 assert_eq!(exp_r6.card_status(), CardStatus::new());
150
151 exp_r6.set_card_status(exp_cs);
152 assert_eq!(exp_r6.card_status(), exp_cs);
153 });
154 }
155}