1use crate::error::{CardError, Error, ErrorContext, Phase};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum ResponseType {
6 None,
8 R1,
10 R1b,
12 R2,
14 R3,
16 R4,
18 R5,
20 R6,
22 R7,
24}
25
26#[derive(Debug, Clone, Copy)]
28pub enum Response {
29 None,
30 R1(R1Response),
31 R1b(R1Response),
32 R2([u8; 16]),
33 R3(OcrResponse),
34 R4(SdioOcrResponse),
35 R5(SdioRwResponse),
36 R6(RcaResponse),
37 R7(IfCondResponse),
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub struct R1Response {
43 pub raw: u32,
44}
45
46impl R1Response {
47 pub fn from_native_raw(raw: u32) -> Result<Self, Error> {
53 let err_bits = ((raw >> 19) & 0x3F) as u8;
54 if err_bits != 0 {
55 return Err(Error::CardError(decode_native_card_error(err_bits)));
56 }
57 Ok(Self { raw })
58 }
59
60 pub fn from_spi_byte(byte: u8) -> Result<Self, Error> {
73 if byte & 0x80 != 0 {
74 return Err(Error::BadResponse(ErrorContext::new(Phase::ResponseWait)));
75 }
76 Ok(Self { raw: byte as u32 })
77 }
78
79 pub fn spi_card_error(&self) -> Option<CardError> {
86 let bits = (self.raw as u8) & 0b0111_1110;
87 if bits == 0 {
88 None
89 } else {
90 Some(decode_spi_card_error(bits))
91 }
92 }
93
94 #[deprecated(note = "use from_native_raw or from_spi_byte instead")]
101 pub fn from_raw(raw: u32) -> Result<Self, Error> {
102 if raw > 0xFF {
103 Self::from_native_raw(raw)
104 } else {
105 Self::from_spi_byte(raw as u8)
106 }
107 }
108
109 pub fn idle(&self) -> bool {
111 self.raw & (1 << 0) != 0
112 }
113
114 pub fn erase_reset(&self) -> bool {
116 self.raw & (1 << 1) != 0
117 }
118
119 pub fn illegal_command(&self) -> bool {
121 self.raw & (1 << 2) != 0
122 }
123
124 pub fn command_crc_failed(&self) -> bool {
126 self.raw & (1 << 3) != 0
127 }
128
129 pub fn current_state(&self) -> CardState {
134 match ((self.raw >> 9) & 0xF) as u8 {
135 0 => CardState::Idle,
136 1 => CardState::Ready,
137 2 => CardState::Identification,
138 3 => CardState::Standby,
139 4 => CardState::Transfer,
140 5 => CardState::SendingData,
141 6 => CardState::ReceiveData,
142 7 => CardState::Programming,
143 8 => CardState::Disconnect,
144 other => CardState::Reserved(other),
145 }
146 }
147
148 pub fn card_is_locked(&self) -> bool {
150 self.raw & (1 << 19) != 0
151 }
152
153 pub fn ready_for_data(&self) -> bool {
159 self.raw & (1 << 8) != 0
160 }
161
162 pub fn switch_error(&self) -> bool {
167 self.raw & (1 << 7) != 0
168 }
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq)]
173pub enum CardState {
174 Idle,
175 Ready,
176 Identification,
177 Standby,
178 Transfer,
179 SendingData,
180 ReceiveData,
181 Programming,
182 Disconnect,
183 Reserved(u8),
184}
185
186#[derive(Debug, Clone, Copy)]
188pub struct OcrResponse {
189 pub raw: u32,
190}
191
192impl OcrResponse {
193 pub fn from_raw(raw: u32) -> Self {
194 Self { raw }
195 }
196
197 pub fn card_powered_up(&self) -> bool {
199 self.raw & (1 << 31) != 0
200 }
201
202 pub fn ccs(&self) -> bool {
204 self.raw & (1 << 30) != 0
205 }
206
207 pub fn voltage_window(&self) -> u32 {
209 self.raw & 0x00FF_FF00
210 }
211
212 pub fn vdd_35_36(&self) -> bool {
214 self.raw & (1 << 23) != 0
215 }
216
217 pub fn vdd_34_35(&self) -> bool {
219 self.raw & (1 << 22) != 0
220 }
221
222 pub fn vdd_33_34(&self) -> bool {
224 self.raw & (1 << 21) != 0
225 }
226
227 pub fn vdd_32_33(&self) -> bool {
229 self.raw & (1 << 20) != 0
230 }
231
232 pub fn supports_2v7_to_3v6(&self) -> bool {
234 self.raw & 0x00FF_8000 != 0
235 }
236
237 pub fn uhs2(&self) -> bool {
239 self.raw & (1 << 29) != 0
240 }
241
242 pub fn s18a(&self) -> bool {
244 self.raw & (1 << 24) != 0
245 }
246}
247
248#[derive(Debug, Clone, Copy)]
250pub struct RcaResponse {
251 pub raw: u32,
252}
253
254impl RcaResponse {
255 pub fn from_raw(raw: u32) -> Self {
256 Self { raw }
257 }
258
259 pub fn rca(&self) -> u16 {
261 ((self.raw >> 16) & 0xFFFF) as u16
262 }
263
264 pub fn status(&self) -> u16 {
266 (self.raw & 0xFFFF) as u16
267 }
268}
269
270#[derive(Debug, Clone, Copy)]
272pub struct IfCondResponse {
273 pub raw: u32,
274}
275
276impl IfCondResponse {
277 pub fn from_raw(raw: u32) -> Self {
278 Self { raw }
279 }
280
281 pub fn voltage(&self) -> u8 {
283 ((self.raw >> 8) & 0xF) as u8
284 }
285
286 pub fn check_pattern(&self) -> u8 {
288 (self.raw & 0xFF) as u8
289 }
290
291 pub fn verify(&self, voltage: u8, pattern: u8) -> bool {
293 self.voltage() == voltage && self.check_pattern() == pattern
294 }
295}
296
297#[derive(Debug, Clone, Copy)]
300pub struct CsdResponse {
301 pub raw: [u8; 16],
302}
303
304impl CsdResponse {
305 pub fn from_raw(raw: [u8; 16]) -> Self {
306 Self { raw }
307 }
308
309 pub fn version(&self) -> u8 {
311 (self.raw[0] >> 6) & 0x03
312 }
313
314 pub fn capacity_blocks(&self) -> Option<u64> {
319 match self.version() {
320 0 => Some(self.csd_v1_capacity_blocks()),
321 1 => Some(self.csd_v2_capacity_blocks()),
322 _ => None,
323 }
324 }
325
326 fn csd_v1_capacity_blocks(&self) -> u64 {
327 let read_bl_len = (self.raw[5] & 0x0F) as u32;
333 let c_size = (((self.raw[6] & 0x03) as u32) << 10)
334 | ((self.raw[7] as u32) << 2)
335 | ((self.raw[8] as u32) >> 6);
336 let c_size_mult = (((self.raw[9] & 0x03) as u32) << 1) | ((self.raw[10] as u32) >> 7);
337 let mult = 1u64 << (c_size_mult + 2);
338 let block_len = 1u64 << read_bl_len;
339 let bytes = (c_size as u64 + 1) * mult * block_len;
340 bytes / 512
341 }
342
343 fn csd_v2_capacity_blocks(&self) -> u64 {
344 let c_size = (((self.raw[7] & 0x3F) as u32) << 16)
349 | ((self.raw[8] as u32) << 8)
350 | (self.raw[9] as u32);
351 (c_size as u64 + 1) * 1024
352 }
353}
354
355#[derive(Debug, Clone, Copy)]
361pub struct CidResponse {
362 pub raw: [u8; 16],
363}
364
365impl CidResponse {
366 pub fn from_raw(raw: [u8; 16]) -> Self {
367 Self { raw }
368 }
369
370 pub fn manufacturer_id(&self) -> u8 {
372 self.raw[0]
373 }
374
375 pub fn oem_id(&self) -> [u8; 2] {
379 [self.raw[1], self.raw[2]]
380 }
381
382 pub fn product_name(&self) -> [u8; 5] {
384 [
385 self.raw[3],
386 self.raw[4],
387 self.raw[5],
388 self.raw[6],
389 self.raw[7],
390 ]
391 }
392
393 pub fn product_revision(&self) -> (u8, u8) {
395 (self.raw[8] >> 4, self.raw[8] & 0x0F)
396 }
397
398 pub fn serial_number(&self) -> u32 {
400 u32::from_be_bytes([self.raw[9], self.raw[10], self.raw[11], self.raw[12]])
401 }
402
403 pub fn manufacture_date(&self) -> (u16, u8) {
409 let year = ((self.raw[13] & 0x0F) << 4) | (self.raw[14] >> 4);
410 let month = self.raw[14] & 0x0F;
411 (2000 + year as u16, month)
412 }
413}
414
415#[derive(Debug, Clone, Copy)]
421pub struct SwitchStatus {
422 pub raw: [u8; 64],
423}
424
425impl SwitchStatus {
426 pub fn from_raw(raw: [u8; 64]) -> Self {
427 Self { raw }
428 }
429
430 pub fn selected_function(&self, group: u8) -> u8 {
437 match group {
438 1 => self.raw[16] & 0x0F,
439 2 => self.raw[16] >> 4,
440 3 => self.raw[15] & 0x0F,
441 4 => self.raw[15] >> 4,
442 5 => self.raw[14] & 0x0F,
443 6 => self.raw[14] >> 4,
444 _ => 0xF,
445 }
446 }
447
448 pub fn high_speed_active(&self) -> bool {
450 self.selected_function(1) == 1
451 }
452
453 pub fn access_mode_supported(&self, function: u8) -> bool {
458 function < 8 && (self.raw[13] & (1 << function)) != 0
459 }
460}
461
462#[derive(Debug, Clone, Copy)]
464pub struct SdioOcrResponse {
465 pub raw: u32,
466}
467
468impl SdioOcrResponse {
469 pub fn from_raw(raw: u32) -> Self {
470 Self { raw }
471 }
472
473 pub fn io_functions(&self) -> u8 {
475 ((self.raw >> 28) & 0x7) as u8
476 }
477
478 pub fn memory_present(&self) -> bool {
480 self.raw & (1 << 27) != 0
481 }
482
483 pub fn io_ready(&self) -> bool {
485 self.raw & (1 << 31) != 0
486 }
487}
488
489#[derive(Debug, Clone, Copy)]
491pub struct SdioRwResponse {
492 pub raw: u32,
493}
494
495impl SdioRwResponse {
496 pub fn from_raw(raw: u32) -> Self {
497 Self { raw }
498 }
499
500 pub fn data(&self) -> u8 {
502 (self.raw & 0xFF) as u8
503 }
504
505 pub fn flags(&self) -> u8 {
507 ((self.raw >> 8) & 0xFF) as u8
508 }
509}
510
511fn decode_spi_card_error(bits: u8) -> CardError {
525 if bits & 0b0000_1000 != 0 {
526 CardError::CommandCrcFailed
527 } else if bits & 0b0000_0100 != 0 {
528 CardError::IllegalCommand
529 } else if bits & 0b0010_0000 != 0 {
530 CardError::AddressError
531 } else if bits & 0b0100_0000 != 0 {
532 CardError::AddressError
534 } else if bits & (0b0001_0000 | 0b0000_0010) != 0 {
535 CardError::EraseSequence
537 } else {
538 CardError::Unknown(bits)
539 }
540}
541
542fn decode_native_card_error(bits: u8) -> CardError {
553 if bits & 0b0001_0000 != 0 {
554 CardError::CommandCrcFailed
555 } else if bits & 0b0000_1000 != 0 {
556 CardError::IllegalCommand
557 } else if bits & 0b0000_0100 != 0 {
558 CardError::CardEccFailed
559 } else if bits & 0b0000_0010 != 0 {
560 CardError::ControllerError
561 } else if bits & 0b0010_0000 != 0 {
562 CardError::ControllerError
564 } else if bits & 0b0000_0001 != 0 {
565 CardError::EraseSequence
567 } else {
568 CardError::Unknown(bits)
569 }
570}
571
572#[cfg(test)]
573mod tests {
574 use super::*;
575
576 #[test]
577 fn spi_r1_idle_uses_bit_zero() {
578 let response = R1Response::from_spi_byte(0x01).unwrap();
579 assert!(response.idle());
580 assert!(!response.illegal_command());
581 assert!(response.spi_card_error().is_none());
582 }
583
584 #[test]
585 fn spi_r1_illegal_command_sets_flag_and_card_error() {
586 let response = R1Response::from_spi_byte(0x04).unwrap();
587 assert!(response.illegal_command());
588 assert_eq!(response.spi_card_error(), Some(CardError::IllegalCommand));
589 }
590
591 #[test]
592 fn spi_r1_idle_plus_illegal_command_preserves_both() {
593 let response = R1Response::from_spi_byte(0x05).unwrap();
594 assert!(response.idle());
595 assert!(response.illegal_command());
596 assert_eq!(response.spi_card_error(), Some(CardError::IllegalCommand));
597 }
598
599 #[test]
600 fn spi_r1_high_bit_is_bus_error() {
601 assert!(matches!(
602 R1Response::from_spi_byte(0x80),
603 Err(Error::BadResponse(_))
604 ));
605 assert!(matches!(
606 R1Response::from_spi_byte(0xFF),
607 Err(Error::BadResponse(_))
608 ));
609 }
610
611 #[test]
612 fn native_r1_status_bits_decoded() {
613 let r1 = R1Response::from_native_raw(4 << 9).unwrap();
615 assert_eq!(r1.current_state(), CardState::Transfer);
616 }
617
618 #[test]
619 fn native_r1_with_illegal_command_returns_error() {
620 let err = R1Response::from_native_raw(1 << 22).unwrap_err();
622 assert_eq!(err, Error::CardError(CardError::IllegalCommand));
623 }
624
625 #[test]
626 fn decode_spi_card_error_priority_handles_multiple_bits() {
627 assert_eq!(
629 decode_spi_card_error(0b0000_1100),
630 CardError::CommandCrcFailed
631 );
632 }
633
634 #[test]
635 fn decode_spi_card_error_unknown_for_unrecognized_bits() {
636 assert_eq!(decode_spi_card_error(0b0000_0000), CardError::Unknown(0));
638 }
639
640 #[test]
641 fn csd_v2_decodes_2gib_capacity() {
642 let mut raw = [0u8; 16];
646 raw[0] = 0x40;
647 raw[7] = 0x00;
648 raw[8] = 0x0F;
649 raw[9] = 0x0F;
650 let csd = CsdResponse::from_raw(raw);
651 assert_eq!(csd.version(), 1);
652 assert_eq!(csd.capacity_blocks(), Some((0x0F0F + 1) * 1024));
653 }
654
655 #[test]
656 fn csd_v1_decodes_known_capacity() {
657 let mut raw = [0u8; 16];
661 raw[0] = 0x00; raw[5] = 0x09; raw[6] = 0b0000_0011; raw[6] = 0b0000_0011;
675 raw[7] = 0xBF;
676 raw[8] = 0b1100_0000;
677 raw[9] = 0b0000_0011;
680 raw[10] = 0b1000_0000;
681 let csd = CsdResponse::from_raw(raw);
682 assert_eq!(csd.version(), 0);
683 let expected = (0x0EFFu64 + 1) * (1 << (7 + 2)) * (1 << 9) / 512;
684 assert_eq!(csd.capacity_blocks(), Some(expected));
685 }
686
687 #[test]
688 fn csd_unknown_version_returns_none() {
689 let mut raw = [0u8; 16];
690 raw[0] = 0x80; let csd = CsdResponse::from_raw(raw);
692 assert_eq!(csd.version(), 2);
693 assert_eq!(csd.capacity_blocks(), None);
694 }
695
696 #[test]
697 fn cid_decodes_manufacturer_oem_product_serial_and_date() {
698 let mut raw = [0u8; 16];
701 raw[0] = 0x03;
702 raw[1] = b'S';
703 raw[2] = b'D';
704 raw[3] = b'A';
705 raw[4] = b'B';
706 raw[5] = b'C';
707 raw[6] = b'1';
708 raw[7] = b'2';
709 raw[8] = (2 << 4) | 7;
710 raw[9] = 0xDE;
711 raw[10] = 0xAD;
712 raw[11] = 0xBE;
713 raw[12] = 0xEF;
714 raw[13] = 0x01; raw[14] = 0xA5; let cid = CidResponse::from_raw(raw);
720 assert_eq!(cid.manufacturer_id(), 0x03);
721 assert_eq!(&cid.oem_id(), b"SD");
722 assert_eq!(&cid.product_name(), b"ABC12");
723 assert_eq!(cid.product_revision(), (2, 7));
724 assert_eq!(cid.serial_number(), 0xDEAD_BEEF);
725 assert_eq!(cid.manufacture_date(), (2026, 5));
726 }
727
728 #[test]
729 fn switch_status_reports_high_speed_when_group_one_function_one() {
730 let mut raw = [0u8; 64];
731 raw[16] = 0x01; let status = SwitchStatus::from_raw(raw);
733 assert_eq!(status.selected_function(1), 1);
734 assert!(status.high_speed_active());
735 }
736
737 #[test]
738 fn switch_status_reports_access_mode_support_bits() {
739 let mut raw = [0u8; 64];
740 raw[13] = (1 << 1) | (1 << 3);
741 let status = SwitchStatus::from_raw(raw);
742
743 assert!(status.access_mode_supported(1));
744 assert!(status.access_mode_supported(3));
745 assert!(!status.access_mode_supported(2));
746 assert!(!status.access_mode_supported(8));
747 }
748
749 #[test]
750 fn switch_status_reports_default_when_group_one_function_zero() {
751 let raw = [0u8; 64];
752 let status = SwitchStatus::from_raw(raw);
753 assert_eq!(status.selected_function(1), 0);
754 assert!(!status.high_speed_active());
755 }
756
757 #[test]
758 fn switch_status_unsupported_group_returns_0xf() {
759 let mut raw = [0u8; 64];
760 raw[16] = 0xF0; let status = SwitchStatus::from_raw(raw);
762 assert_eq!(status.selected_function(2), 0xF);
763 assert_eq!(status.selected_function(7), 0xF); }
765}