sdmmc_core/command/class/class8/acmd53/
arg.rs1use crate::lib_bitfield;
2use crate::result::{Error, Result};
3
4mod sssf;
5
6pub use sssf::*;
7
8lib_bitfield! {
9 pub Argument(u32): u8 {
11 raw_sp: 31, 24;
12 raw_spsp1: 23, 16;
13 raw_spsp0: 15, 8;
14 raw_sssf: 7, 0;
15 }
16}
17
18impl Argument {
19 pub const LEN: usize = 4;
21 pub const DEFAULT: u32 = 1;
23
24 pub const fn new() -> Self {
26 Self(Self::DEFAULT)
27 }
28
29 pub const fn sp(&self) -> u8 {
31 self.raw_sp()
32 }
33
34 pub fn set_sp(&mut self, val: u8) {
36 self.set_raw_sp(val as u32);
37 }
38
39 pub const fn spsp1(&self) -> u8 {
41 self.raw_spsp1()
42 }
43
44 pub fn set_spsp1(&mut self, val: u8) {
46 self.set_raw_spsp1(val as u32);
47 }
48
49 pub const fn spsp0(&self) -> u8 {
51 self.raw_spsp0()
52 }
53
54 pub fn set_spsp0(&mut self, val: u8) {
56 self.set_raw_spsp0(val as u32);
57 }
58
59 pub const fn sssf(&self) -> Result<SdSecuritySpecificField> {
61 SdSecuritySpecificField::from_raw(self.raw_sssf())
62 }
63
64 pub fn set_sssf(&mut self, val: SdSecuritySpecificField) {
66 self.set_raw_sssf(val.into_raw() as u32);
67 }
68
69 pub const fn try_from_bits(val: u32) -> Result<Self> {
71 match Self(val) {
72 acmd if acmd.sssf().is_err() => Err(Error::invalid_field_variant(
73 "command::argument::sssf",
74 acmd.raw_sssf() as usize,
75 )),
76 acmd => Ok(acmd),
77 }
78 }
79
80 pub const fn bytes(&self) -> [u8; Self::LEN] {
82 self.0.to_be_bytes()
83 }
84
85 pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
87 match val.len() {
88 len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
89 _ => Self::try_from_bits(u32::from_be_bytes([val[0], val[1], val[2], val[3]])),
90 }
91 }
92}
93
94impl Default for Argument {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100impl TryFrom<u32> for Argument {
101 type Error = Error;
102
103 fn try_from(val: u32) -> Result<Self> {
104 Self::try_from_bits(val)
105 }
106}
107
108impl From<Argument> for u32 {
109 fn from(val: Argument) -> Self {
110 val.bits()
111 }
112}
113
114impl From<Argument> for [u8; Argument::LEN] {
115 fn from(val: Argument) -> Self {
116 val.bytes()
117 }
118}
119
120impl TryFrom<&[u8]> for Argument {
121 type Error = Error;
122
123 fn try_from(val: &[u8]) -> Result<Self> {
124 Self::try_from_bytes(val)
125 }
126}
127
128impl<const N: usize> TryFrom<&[u8; N]> for Argument {
129 type Error = Error;
130
131 fn try_from(val: &[u8; N]) -> Result<Self> {
132 Self::try_from_bytes(val.as_ref())
133 }
134}
135
136impl<const N: usize> TryFrom<[u8; N]> for Argument {
137 type Error = Error;
138
139 fn try_from(val: [u8; N]) -> Result<Self> {
140 Self::try_from_bytes(val.as_ref())
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147 use crate::test_field;
148
149 #[test]
150 fn test_fields() {
151 let new_sssf = SdSecuritySpecificField::new();
152 let new_sp = 0;
153 let new_spsp1 = 0;
154 let new_spsp0 = 0;
155
156 (8..=u32::BITS)
158 .map(|r| (((1u64 << r) - 1) as u32) | 1)
159 .for_each(|raw_arg| {
160 let raw = raw_arg.to_be_bytes();
161 let exp_sp = ((raw_arg & 0xff00_0000) >> 24) as u8;
162 let exp_spsp1 = ((raw_arg & 0xff_0000) >> 16) as u8;
163 let exp_spsp0 = ((raw_arg & 0xff00) >> 8) as u8;
164 let raw_sssf = (raw_arg & 0xff) as u8;
165
166 match Argument::try_from_bits(raw_arg) {
167 Ok(mut exp_arg) => {
168 let exp_sssf = SdSecuritySpecificField::from_raw(raw_sssf).unwrap();
169
170 assert_eq!(Argument::try_from_bits(raw_arg), Ok(exp_arg));
171 assert_eq!(Argument::try_from_bytes(&raw), Ok(exp_arg));
172 assert_eq!(Argument::try_from(raw_arg), Ok(exp_arg));
173 assert_eq!(Argument::try_from(raw), Ok(exp_arg));
174 assert_eq!(Argument::try_from(&raw), Ok(exp_arg));
175
176 assert_eq!(exp_arg.sp(), exp_sp);
177
178 exp_arg.set_sp(new_sp);
179 assert_eq!(exp_arg.sp(), new_sp);
180
181 exp_arg.set_sp(exp_sp);
182 assert_eq!(exp_arg.sp(), exp_sp);
183
184 assert_eq!(exp_arg.spsp1(), exp_spsp1);
185
186 exp_arg.set_spsp1(new_spsp1);
187 assert_eq!(exp_arg.spsp1(), new_spsp1);
188
189 exp_arg.set_spsp1(exp_spsp1);
190 assert_eq!(exp_arg.spsp1(), exp_spsp1);
191
192 assert_eq!(exp_arg.spsp0(), exp_spsp0);
193
194 exp_arg.set_spsp0(new_spsp0);
195 assert_eq!(exp_arg.spsp0(), new_spsp0);
196
197 exp_arg.set_spsp0(exp_spsp0);
198 assert_eq!(exp_arg.spsp0(), exp_spsp0);
199
200 assert_eq!(exp_arg.spsp0(), exp_spsp0);
201
202 exp_arg.set_sssf(new_sssf);
203 assert_eq!(exp_arg.sssf(), Ok(new_sssf));
204
205 exp_arg.set_sssf(exp_sssf);
206 assert_eq!(exp_arg.sssf(), Ok(exp_sssf));
207 }
208 Err(err) => {
209 let exp_err = Error::invalid_field_variant(
210 "command::argument::sssf",
211 raw_sssf as usize,
212 );
213 assert_eq!(err, exp_err);
214
215 assert_eq!(Argument::try_from_bits(raw_arg), Err(exp_err));
216 assert_eq!(Argument::try_from_bytes(&raw), Err(exp_err));
217 assert_eq!(Argument::try_from(raw_arg), Err(exp_err));
218 assert_eq!(Argument::try_from(raw), Err(exp_err));
219 assert_eq!(Argument::try_from(&raw), Err(exp_err));
220 }
221 }
222 });
223
224 (1..=8u32)
226 .map(|r| ((1u64 << r) - 1) as u32)
227 .for_each(|raw_arg| {
228 let raw = raw_arg.to_be_bytes();
229 let raw_sssf = (raw_arg & 0xff) as u8;
230
231 match Argument::try_from_bits(raw_arg) {
232 Ok(mut exp_arg) => {
233 let exp_sssf = SdSecuritySpecificField::from_raw(raw_sssf).unwrap();
234
235 assert_eq!(Argument::try_from_bits(raw_arg), Ok(exp_arg));
236 assert_eq!(Argument::try_from_bytes(&raw), Ok(exp_arg));
237 assert_eq!(Argument::try_from(raw_arg), Ok(exp_arg));
238 assert_eq!(Argument::try_from(raw), Ok(exp_arg));
239 assert_eq!(Argument::try_from(&raw), Ok(exp_arg));
240
241 exp_arg.set_sssf(new_sssf);
242 assert_eq!(exp_arg.sssf(), Ok(new_sssf));
243
244 exp_arg.set_sssf(exp_sssf);
245 assert_eq!(exp_arg.sssf(), Ok(exp_sssf));
246 }
247 Err(err) => {
248 let exp_err = Error::invalid_field_variant(
249 "command::argument::sssf",
250 raw_sssf as usize,
251 );
252 assert_eq!(err, exp_err);
253
254 assert_eq!(Argument::try_from_bits(raw_arg), Err(exp_err));
255 assert_eq!(Argument::try_from_bytes(&raw), Err(exp_err));
256 assert_eq!(Argument::try_from(raw_arg), Err(exp_err));
257 assert_eq!(Argument::try_from(raw), Err(exp_err));
258 assert_eq!(Argument::try_from(&raw), Err(exp_err));
259 }
260 }
261 });
262 }
263}