sdmmc_core/response/sd/
r3.rs

1//! `R3` response to the `ACMD41` command containing the card `OCR` register.
2
3use crate::register::Ocr;
4use crate::response::{End, Start};
5use crate::result::{Error, Result};
6use crate::{lib_bitfield, response};
7
8lib_bitfield! {
9    /// Represents the `R3` response to the `ACMD41` command in SD mode.
10    pub R3(MSB0 [u8; 6]): u32 {
11        raw_start: 47, 40;
12        raw_ocr: 39, 8;
13        raw_end: 7, 0;
14    }
15}
16
17response! {
18    R3 {
19        response_mode: Sd,
20    }
21}
22
23impl R3 {
24    /// Represents the byte length of [R3].
25    pub const LEN: usize = 6;
26    /// Represents the default byte value of the [R3].
27    pub const DEFAULT: [u8; Self::LEN] = [0x3f, 0, 0, 0, 0, 0xff];
28
29    /// Creates a new [R3].
30    pub const fn new() -> Self {
31        Self(Self::DEFAULT)
32    }
33
34    /// Attempts to get the [Start] fields of the [R3].
35    pub const fn start(&self) -> Result<Start> {
36        Start::try_from_bits(self.raw_start() as u8)
37    }
38
39    /// Gets the [Ocr] field of the [R3].
40    pub const fn ocr(&self) -> Ocr {
41        Ocr::from_bits(self.raw_ocr())
42    }
43
44    /// Sets the [Ocr] field of the [R3].
45    pub fn set_ocr(&mut self, val: Ocr) {
46        self.set_raw_ocr(val.bits());
47    }
48
49    /// Attempts to get the [End] fields of the [R3].
50    pub const fn end(&self) -> Result<End> {
51        End::try_from_bits(self.raw_end() as u8)
52    }
53
54    /// Attempts to convert a byte slice into a [R3].
55    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
56        match val.len() {
57            len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
58            _ => {
59                let r3 = Self([val[0], val[1], val[2], val[3], val[4], val[5]]);
60                let exp_start = Start::from_bits(0x3f);
61                let exp_end = End::from_bits(0xff);
62
63                match (r3.start(), r3.end()) {
64                    (Ok(exp_start), Ok(exp_end)) => Ok(r3),
65                    (_, Ok(exp_end)) => Err(Error::invalid_field_variant(
66                        "r3::start",
67                        r3.raw_start() as usize,
68                    )),
69                    (_, _) => Err(Error::invalid_field_variant(
70                        "r3::end",
71                        r3.raw_end() as usize,
72                    )),
73                }
74            }
75        }
76    }
77}
78
79impl Default for R3 {
80    fn default() -> Self {
81        Self::new()
82    }
83}
84
85impl TryFrom<&[u8]> for R3 {
86    type Error = Error;
87
88    fn try_from(val: &[u8]) -> Result<Self> {
89        Self::try_from_bytes(val)
90    }
91}
92
93impl<const N: usize> TryFrom<&[u8; N]> for R3 {
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
101impl<const N: usize> TryFrom<[u8; N]> for R3 {
102    type Error = Error;
103
104    fn try_from(val: [u8; N]) -> Result<Self> {
105        Self::try_from_bytes(val.as_ref())
106    }
107}
108
109impl From<R3> for [u8; R3::LEN] {
110    fn from(val: R3) -> Self {
111        val.bytes()
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use super::*;
118
119    #[test]
120    fn test_valid() {
121        let exp_start = Start::from_bits(0x3f);
122        let exp_end = End::from_bits(0xff);
123
124        (1..=u32::BITS)
125            .map(|r| ((1u64 << r) - 1) as u32)
126            .for_each(|raw_ocr| {
127                let ocr = Ocr::from_bits(raw_ocr);
128                let [ocr0, ocr1, ocr2, ocr3] = ocr.bytes();
129                let raw = [0x3f, ocr0, ocr1, ocr2, ocr3, 0xff];
130
131                let mut exp_r3 = R3::new();
132                exp_r3.set_ocr(ocr);
133
134                assert_eq!(R3::try_from_bytes(raw.as_ref()), Ok(exp_r3));
135                assert_eq!(exp_r3.start(), Ok(exp_start));
136                assert_eq!(exp_r3.ocr(), ocr);
137                assert_eq!(exp_r3.end(), Ok(exp_end));
138
139                exp_r3.set_ocr(Ocr::new());
140                assert_eq!(exp_r3.ocr(), Ocr::new());
141
142                exp_r3.set_ocr(ocr);
143                assert_eq!(exp_r3.ocr(), ocr);
144            });
145    }
146}