sdmmc_core/command/class/class8/acmd41/
arg.rs

1use crate::lib_bitfield;
2use crate::result::{Error, Result};
3
4mod xpc;
5
6pub use xpc::*;
7
8lib_bitfield! {
9    /// Argumentument for CMD5.
10    pub Argument(u32): u32 {
11        /// If set, requests the card's [Ocr](crate::register::ocr::Ocr) contents in the response.
12        pub hcs: 30;
13        raw_xpc: 28;
14        /// Switching 1.8V request.
15        pub s18r: 24;
16        /// VDD Volatage Window (VDD1): 3.5-3.6V.
17        pub vdd_3536: 23;
18        /// VDD Volatage Window (VDD1): 3.4-3.5V.
19        pub vdd_3435: 22;
20        /// VDD Volatage Window (VDD1): 3.3-3.4V.
21        pub vdd_3334: 21;
22        /// VDD Volatage Window (VDD1): 3.2-3.3V.
23        pub vdd_3233: 20;
24        /// VDD Volatage Window (VDD1): 3.1-3.2V.
25        pub vdd_3132: 19;
26        /// VDD Volatage Window (VDD1): 3.0-3.1V.
27        pub vdd_3031: 18;
28        /// VDD Volatage Window (VDD1): 2.9-3.0V.
29        pub vdd_2930: 17;
30        /// VDD Volatage Window (VDD1): 2.8-2.9V.
31        pub vdd_2829: 16;
32        /// VDD Volatage Window (VDD1): 2.7-2.8V.
33        pub vdd_2728: 15;
34    }
35}
36
37impl Argument {
38    /// Represents the byte length of the [Argument].
39    pub const LEN: usize = 4;
40    /// Represents the raw default value of the [Argument].
41    pub const DEFAULT: u32 = 0;
42
43    /// Creates a new [Argument].
44    pub const fn new() -> Self {
45        Self(Self::DEFAULT)
46    }
47
48    /// Gets the `xpc` field of the [Argument].
49    pub const fn xpc(&self) -> Xpc {
50        Xpc::from_bool(self.raw_xpc())
51    }
52
53    /// Sets the `xpc` field of the [Argument].
54    pub fn set_xpc(&mut self, val: Xpc) {
55        self.set_raw_xpc(val.into_bool());
56    }
57
58    /// Converts a [`u32`] into an [Argument].
59    pub const fn from_bits(val: u32) -> Self {
60        Self(val)
61    }
62
63    /// Attempts to convert a [`u32`] into an [Argument].
64    pub const fn try_from_bits(val: u32) -> Result<Self> {
65        Ok(Self::from_bits(val))
66    }
67
68    /// Converts the [Argument] into a byte array.
69    pub const fn bytes(&self) -> [u8; Self::LEN] {
70        self.0.to_be_bytes()
71    }
72
73    /// Attempts to convert a byte slice into an [Argument].
74    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
75        match val.len() {
76            len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
77            _ => Ok(Self(u32::from_be_bytes([val[0], val[1], val[2], val[3]]))),
78        }
79    }
80}
81
82impl Default for Argument {
83    fn default() -> Self {
84        Self::new()
85    }
86}
87
88impl From<u32> for Argument {
89    fn from(val: u32) -> Self {
90        Self::from_bits(val)
91    }
92}
93
94impl From<Argument> for u32 {
95    fn from(val: Argument) -> Self {
96        val.bits()
97    }
98}
99
100impl From<Argument> for [u8; Argument::LEN] {
101    fn from(val: Argument) -> Self {
102        val.bytes()
103    }
104}
105
106impl TryFrom<&[u8]> for Argument {
107    type Error = Error;
108
109    fn try_from(val: &[u8]) -> Result<Self> {
110        Self::try_from_bytes(val)
111    }
112}
113
114impl<const N: usize> TryFrom<&[u8; N]> for Argument {
115    type Error = Error;
116
117    fn try_from(val: &[u8; N]) -> Result<Self> {
118        Self::try_from_bytes(val.as_ref())
119    }
120}
121
122impl<const N: usize> TryFrom<[u8; N]> for Argument {
123    type Error = Error;
124
125    fn try_from(val: [u8; N]) -> Result<Self> {
126        Self::try_from_bytes(val.as_ref())
127    }
128}
129
130#[cfg(test)]
131mod tests {
132    use super::*;
133    use crate::test_field;
134
135    #[test]
136    fn test_fields() {
137        let mut arg = Argument::new();
138        let new_xpc = Xpc::new();
139
140        test_field!(arg, hcs: 30);
141        test_field!(arg, s18r: 24);
142        test_field!(arg, vdd_3536: 23);
143        test_field!(arg, vdd_3435: 22);
144        test_field!(arg, vdd_3334: 21);
145        test_field!(arg, vdd_3233: 20);
146        test_field!(arg, vdd_3132: 19);
147        test_field!(arg, vdd_3031: 18);
148        test_field!(arg, vdd_2930: 17);
149        test_field!(arg, vdd_2829: 16);
150        test_field!(arg, vdd_2728: 15);
151
152        (1..=u32::BITS)
153            .map(|r| ((1u64 << r) - 1) as u32)
154            .for_each(|raw_arg| {
155                let raw = raw_arg.to_be_bytes();
156                let mut exp_arg = Argument(raw_arg);
157
158                let exp_hcs = (raw_arg & (1 << 30)) != 0;
159                let exp_xpc = Xpc::from_bool((raw_arg & (1 << 28)) != 0);
160                let exp_s18r = (raw_arg & (1 << 24)) != 0;
161                let exp_vdd_3536 = (raw_arg & (1 << 23)) != 0;
162                let exp_vdd_3435 = (raw_arg & (1 << 22)) != 0;
163                let exp_vdd_3334 = (raw_arg & (1 << 21)) != 0;
164                let exp_vdd_3233 = (raw_arg & (1 << 20)) != 0;
165                let exp_vdd_3132 = (raw_arg & (1 << 19)) != 0;
166                let exp_vdd_3031 = (raw_arg & (1 << 18)) != 0;
167                let exp_vdd_2930 = (raw_arg & (1 << 17)) != 0;
168                let exp_vdd_2829 = (raw_arg & (1 << 16)) != 0;
169                let exp_vdd_2728 = (raw_arg & (1 << 15)) != 0;
170
171                assert_eq!(Argument::try_from_bits(raw_arg), Ok(exp_arg));
172                assert_eq!(Argument::try_from_bytes(&raw), Ok(exp_arg));
173                assert_eq!(Argument::from(raw_arg), exp_arg);
174                assert_eq!(Argument::try_from(raw), Ok(exp_arg));
175                assert_eq!(Argument::try_from(&raw), Ok(exp_arg));
176
177                assert_eq!(exp_arg.hcs(), exp_hcs);
178                assert_eq!(exp_arg.xpc(), exp_xpc);
179                assert_eq!(exp_arg.s18r(), exp_s18r);
180                assert_eq!(exp_arg.vdd_3536(), exp_vdd_3536);
181                assert_eq!(exp_arg.vdd_3435(), exp_vdd_3435);
182                assert_eq!(exp_arg.vdd_3334(), exp_vdd_3334);
183                assert_eq!(exp_arg.vdd_3233(), exp_vdd_3233);
184                assert_eq!(exp_arg.vdd_3132(), exp_vdd_3132);
185                assert_eq!(exp_arg.vdd_3031(), exp_vdd_3031);
186                assert_eq!(exp_arg.vdd_2930(), exp_vdd_2930);
187                assert_eq!(exp_arg.vdd_2829(), exp_vdd_2829);
188                assert_eq!(exp_arg.vdd_2728(), exp_vdd_2728);
189
190                test_field!(exp_arg, hcs: 30);
191                test_field!(exp_arg, s18r: 24);
192                test_field!(exp_arg, vdd_3536: 23);
193                test_field!(exp_arg, vdd_3435: 22);
194                test_field!(exp_arg, vdd_3334: 21);
195                test_field!(exp_arg, vdd_3233: 20);
196                test_field!(exp_arg, vdd_3132: 19);
197                test_field!(exp_arg, vdd_3031: 18);
198                test_field!(exp_arg, vdd_2930: 17);
199                test_field!(exp_arg, vdd_2829: 16);
200                test_field!(exp_arg, vdd_2728: 15);
201
202                exp_arg.set_xpc(new_xpc);
203                assert_eq!(exp_arg.xpc(), new_xpc);
204
205                exp_arg.set_xpc(exp_xpc);
206                assert_eq!(exp_arg.xpc(), exp_xpc);
207            });
208    }
209}