sdmmc_core/command/class/class0/cmd1/
arg.rs1use crate::lib_bitfield;
2use crate::register::Ocr;
3use crate::result::{Error, Result};
4
5lib_bitfield! {
6 pub Argument(u32): u32 {
8 raw_ocr: 31, 0;
9 }
10}
11
12impl Argument {
13 pub const LEN: usize = 4;
15 pub const DEFAULT: u32 = 0;
17
18 pub const fn new() -> Self {
20 Self(Self::DEFAULT)
21 }
22
23 pub const fn ocr(&self) -> Ocr {
25 Ocr::from_bits(self.raw_ocr())
26 }
27
28 pub fn set_ocr(&mut self, mut val: Ocr) {
30 val.set_busy(false);
31 self.set_raw_ocr(val.bits())
32 }
33
34 pub const fn try_from_bits(val: u32) -> Result<Self> {
36 match Self(val) {
37 arg if arg.ocr().busy() => Err(Error::invalid_field_variant(
38 "cmd::arg::ocr",
39 arg.raw_ocr() as usize,
40 )),
41 arg => Ok(arg),
42 }
43 }
44
45 pub const fn bytes(&self) -> [u8; Self::LEN] {
47 self.0.to_be_bytes()
48 }
49
50 pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
52 match val.len() {
53 len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
54 _ => Self::try_from_bits(u32::from_be_bytes([val[0], val[1], val[2], val[3]])),
55 }
56 }
57}
58
59impl Default for Argument {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65impl TryFrom<u32> for Argument {
66 type Error = Error;
67
68 fn try_from(val: u32) -> Result<Self> {
69 Self::try_from_bits(val)
70 }
71}
72
73impl From<Argument> for u32 {
74 fn from(val: Argument) -> Self {
75 val.bits()
76 }
77}
78
79impl From<Argument> for [u8; Argument::LEN] {
80 fn from(val: Argument) -> Self {
81 val.bytes()
82 }
83}
84
85impl TryFrom<&[u8]> for Argument {
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 Argument {
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 Argument {
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
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn test_fields() {
115 let mut arg = Argument::new();
116 let new_ocr = Ocr::new();
117
118 assert_eq!(arg.ocr(), new_ocr);
119
120 (1..u32::BITS)
121 .map(|r| ((1u64 << r) - 1) as u32)
122 .for_each(|raw_arg| {
123 let mut exp_arg = Argument(raw_arg);
124 let exp_ocr = Ocr::from_bits(raw_arg);
125 let raw = raw_arg.to_be_bytes();
126
127 if exp_ocr.busy() {
128 let exp_err = Error::invalid_field_variant("cmd::arg::ocr", raw_arg as usize);
129
130 assert_eq!(Argument::try_from_bits(raw_arg), Err(exp_err));
131 assert_eq!(Argument::try_from_bytes(&raw), Err(exp_err));
132 assert_eq!(Argument::try_from(&raw), Err(exp_err));
133 assert_eq!(Argument::try_from(raw), Err(exp_err));
134 } else {
135 assert_eq!(Argument::try_from_bits(raw_arg), Ok(exp_arg));
136 assert_eq!(Argument::try_from_bytes(&raw), Ok(exp_arg));
137 assert_eq!(Argument::try_from(&raw), Ok(exp_arg));
138 assert_eq!(Argument::try_from(raw), Ok(exp_arg));
139
140 assert_eq!(exp_arg.bits(), raw_arg);
141 assert_eq!(exp_arg.bytes(), raw);
142
143 assert_eq!(exp_arg.ocr(), exp_ocr);
144
145 exp_arg.set_ocr(new_ocr);
146 assert_eq!(exp_arg.ocr(), new_ocr);
147
148 exp_arg.set_ocr(exp_ocr);
149 assert_eq!(exp_arg.ocr(), exp_ocr);
150 }
151 });
152 }
153}