sdmmc_core/response/
end.rs

1use crate::Crc7;
2use crate::lib_bitfield;
3use crate::result::{Error, Result};
4
5lib_bitfield! {
6    /// Represents the ending byte of card responses in SD mode.
7    pub End(u8): u8 {
8        raw_crc: 7, 1;
9        /// The LSB of the response, should always be `1`.
10        pub end_bit: 0;
11    }
12}
13
14impl End {
15    /// Represents the default for the [End].
16    pub const DEFAULT: u8 = 1;
17    const CRC_SHIFT: usize = 1;
18
19    /// Creates a new [End].
20    pub const fn new() -> Self {
21        Self(Self::DEFAULT)
22    }
23
24    /// Gets the [Crc7] for the [End].
25    pub const fn crc(&self) -> Crc7 {
26        Crc7::from_bits(self.raw_crc())
27    }
28
29    /// Sets the [Crc7] for the [End].
30    pub fn set_crc(&mut self, val: Crc7) {
31        self.set_raw_crc(val.bits());
32    }
33
34    /// Converts a [Crc7] into an [End].
35    pub const fn from_crc(crc: Crc7) -> Self {
36        Self((crc.bits() << Self::CRC_SHIFT) | Self::DEFAULT)
37    }
38
39    /// Converts a [`u8`] into an [End].
40    ///
41    /// # Note
42    ///
43    /// Masks the `val` to ensure a valid [End] value.
44    pub const fn from_bits(val: u8) -> Self {
45        Self(val | Self::DEFAULT)
46    }
47
48    /// Attempts to convert a [`u8`] into a [End].
49    pub const fn try_from_bits(val: u8) -> Result<Self> {
50        match Self(val) {
51            e if !e.end_bit() => Err(Error::invalid_field_variant("end", val as usize)),
52            e => Ok(e),
53        }
54    }
55}
56
57impl Default for End {
58    fn default() -> Self {
59        Self::new()
60    }
61}
62
63impl TryFrom<u8> for End {
64    type Error = Error;
65
66    fn try_from(val: u8) -> Result<Self> {
67        Self::try_from_bits(val)
68    }
69}
70
71impl From<End> for u8 {
72    fn from(val: End) -> Self {
73        val.bits()
74    }
75}
76
77impl From<Crc7> for End {
78    fn from(val: Crc7) -> Self {
79        Self::from_crc(val)
80    }
81}
82
83impl From<End> for Crc7 {
84    fn from(val: End) -> Self {
85        val.crc()
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn test_fields() {
95        let mut s = End::new();
96
97        assert_eq!(s.crc(), Crc7::new());
98        assert!(s.end_bit());
99
100        (0..=0xff)
101            .map(|crc| Crc7::from_bits(crc & 0x7f))
102            .for_each(|crc| {
103                let raw_end = (crc.bits() << End::CRC_SHIFT) | End::DEFAULT;
104                let exp_end = End(raw_end);
105
106                assert_eq!(End::try_from_bits(raw_end), Ok(exp_end));
107
108                s.set_crc(crc);
109                assert_eq!(s.crc(), crc);
110
111                // make sure we didn't corrupt other fields
112                assert!(s.end_bit());
113
114                assert_eq!(exp_end.bits(), raw_end);
115            });
116    }
117}