sdmmc_core/command/class/class10/cmd6/
arg.rs1use crate::lib_bitfield;
2use crate::result::{Error, Result};
3
4mod access_mode;
5mod command_system;
6mod driver_strength;
7mod mode;
8mod power_limit;
9
10pub use access_mode::*;
11pub use command_system::*;
12pub use driver_strength::*;
13pub use mode::*;
14pub use power_limit::*;
15
16lib_bitfield! {
17 pub Argument(u32): u8 {
19 raw_mode: 31;
20 raw_power_limit: 15, 12;
21 raw_driver_strength: 11, 8;
22 raw_command_system: 7, 4;
23 raw_access_mode: 3, 0;
24 }
25}
26
27impl Argument {
28 pub const LEN: usize = 4;
30 pub const DEFAULT: u32 = 0;
32
33 pub const fn new() -> Self {
35 Self(0)
36 }
37
38 pub const fn access_mode(&self) -> Result<AccessMode> {
40 AccessMode::from_raw(self.raw_access_mode())
41 }
42
43 pub fn set_access_mode(&mut self, val: AccessMode) {
45 self.set_raw_access_mode(val.into_raw() as u32);
46 }
47
48 pub const fn command_system(&self) -> Result<CommandSystem> {
50 CommandSystem::from_raw(self.raw_command_system())
51 }
52
53 pub fn set_command_system(&mut self, val: CommandSystem) {
55 self.set_raw_command_system(val.into_raw() as u32);
56 }
57
58 pub const fn driver_strength(&self) -> Result<DriverStrength> {
60 DriverStrength::from_raw(self.raw_driver_strength())
61 }
62
63 pub fn set_driver_strength(&mut self, val: DriverStrength) {
65 self.set_raw_driver_strength(val.into_raw() as u32);
66 }
67
68 pub const fn power_limit(&self) -> Result<PowerLimit> {
70 PowerLimit::from_raw(self.raw_power_limit())
71 }
72
73 pub fn set_power_limit(&mut self, val: PowerLimit) {
75 self.set_raw_power_limit(val.into_raw() as u32)
76 }
77
78 pub const fn mode(&self) -> Result<Mode> {
80 Mode::from_raw(self.raw_mode() as u8)
81 }
82
83 pub fn set_mode(&mut self, val: Mode) {
85 self.set_raw_mode(val.into_raw() != 0);
86 }
87
88 pub const fn try_from_bits(val: u32) -> Result<Self> {
90 match Self(val) {
91 arg if arg.access_mode().is_err() => Err(Error::invalid_field_variant(
92 "cmd::argument::access_mode",
93 arg.raw_access_mode() as usize,
94 )),
95 arg if arg.command_system().is_err() => Err(Error::invalid_field_variant(
96 "cmd::argument::command_system",
97 arg.raw_command_system() as usize,
98 )),
99 arg if arg.driver_strength().is_err() => Err(Error::invalid_field_variant(
100 "cmd::argument::driver_strength",
101 arg.raw_driver_strength() as usize,
102 )),
103 arg if arg.power_limit().is_err() => Err(Error::invalid_field_variant(
104 "cmd::argument::power_limit",
105 arg.raw_power_limit() as usize,
106 )),
107 arg if arg.mode().is_err() => Err(Error::invalid_field_variant(
108 "cmd::argument::mode",
109 arg.raw_mode() as usize,
110 )),
111 arg => Ok(arg),
112 }
113 }
114
115 pub const fn bytes(&self) -> [u8; Self::LEN] {
117 self.0.to_be_bytes()
118 }
119
120 pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
122 match val.len() {
123 len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
124 _ => Self::try_from_bits(u32::from_be_bytes([val[0], val[1], val[2], val[3]])),
125 }
126 }
127}
128
129impl Default for Argument {
130 fn default() -> Self {
131 Self::new()
132 }
133}
134
135impl TryFrom<u32> for Argument {
136 type Error = Error;
137
138 fn try_from(val: u32) -> Result<Self> {
139 Self::try_from_bits(val)
140 }
141}
142
143impl From<Argument> for u32 {
144 fn from(val: Argument) -> Self {
145 val.bits()
146 }
147}
148
149impl From<Argument> for [u8; Argument::LEN] {
150 fn from(val: Argument) -> Self {
151 val.bytes()
152 }
153}
154
155impl TryFrom<&[u8]> for Argument {
156 type Error = Error;
157
158 fn try_from(val: &[u8]) -> Result<Self> {
159 Self::try_from_bytes(val)
160 }
161}
162
163impl<const N: usize> TryFrom<&[u8; N]> for Argument {
164 type Error = Error;
165
166 fn try_from(val: &[u8; N]) -> Result<Self> {
167 Self::try_from_bytes(val.as_ref())
168 }
169}
170
171impl<const N: usize> TryFrom<[u8; N]> for Argument {
172 type Error = Error;
173
174 fn try_from(val: [u8; N]) -> Result<Self> {
175 Self::try_from_bytes(val.as_ref())
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182
183 #[test]
184 fn test_fields() {
185 let mut arg = Argument::new();
186
187 assert_eq!(arg.access_mode(), Ok(AccessMode::new()));
188 assert_eq!(arg.command_system(), Ok(CommandSystem::new()));
189 assert_eq!(arg.driver_strength(), Ok(DriverStrength::new()));
190 assert_eq!(arg.power_limit(), Ok(PowerLimit::new()));
191
192 [
193 AccessMode::Sdr12,
194 AccessMode::Sdr25,
195 AccessMode::Sdr50,
196 AccessMode::Sdr104,
197 AccessMode::Ddr50,
198 ]
199 .into_iter()
200 .for_each(|exp_access_mode| {
201 arg.set_access_mode(exp_access_mode);
202 assert_eq!(arg.access_mode(), Ok(exp_access_mode));
203 });
204
205 [
206 CommandSystem::SystemDefault,
207 CommandSystem::ForEC,
208 CommandSystem::Otp,
209 CommandSystem::Assd,
210 CommandSystem::Vendor,
211 ]
212 .into_iter()
213 .for_each(|exp_command_system| {
214 arg.set_command_system(exp_command_system);
215 assert_eq!(arg.command_system(), Ok(exp_command_system));
216 });
217
218 [
219 DriverStrength::TypeB,
220 DriverStrength::TypeA,
221 DriverStrength::TypeC,
222 DriverStrength::TypeD,
223 ]
224 .into_iter()
225 .for_each(|exp_driver_strength| {
226 arg.set_driver_strength(exp_driver_strength);
227 assert_eq!(arg.driver_strength(), Ok(exp_driver_strength));
228 });
229
230 [
231 PowerLimit::W072,
232 PowerLimit::W144,
233 PowerLimit::W216,
234 PowerLimit::W288,
235 PowerLimit::W180,
236 ]
237 .into_iter()
238 .for_each(|exp_power_limit| {
239 arg.set_power_limit(exp_power_limit);
240 assert_eq!(arg.power_limit(), Ok(exp_power_limit));
241 });
242
243 [Mode::Check, Mode::Switch]
244 .into_iter()
245 .for_each(|exp_mode| {
246 arg.set_mode(exp_mode);
247 assert_eq!(arg.mode(), Ok(exp_mode));
248 });
249 }
250}