sdmmc_core/response/sd/r5/
flags.rs1use crate::lib_bitfield;
2use crate::result::{Error, Result};
3
4mod io_current_state;
5
6pub use io_current_state::*;
7
8lib_bitfield! {
9 pub Flags(u8): u8 {
11 pub crc_error: 7;
13 pub illegal_command: 6;
15 raw_io_current_state: 5, 4;
16 pub error: 3;
18 pub function_number: 1;
20 pub out_of_range: 0;
22 }
23}
24
25impl Flags {
26 pub const fn new() -> Self {
28 Self(0)
29 }
30
31 pub const fn io_current_state(&self) -> Result<IoCurrentState> {
33 IoCurrentState::from_raw(self.raw_io_current_state())
34 }
35
36 pub fn set_io_current_state(&mut self, val: IoCurrentState) {
38 self.set_raw_io_current_state(val.into_raw())
39 }
40
41 pub const fn try_from_bits(val: u8) -> Result<Self> {
43 let flags = Self(val);
44
45 match flags.io_current_state() {
46 Ok(_) => Ok(flags),
47 Err(_) => Err(Error::invalid_field_variant(
48 "r5::flags::io_current_state",
49 flags.raw_io_current_state() as usize,
50 )),
51 }
52 }
53}
54
55impl Default for Flags {
56 fn default() -> Self {
57 Self::new()
58 }
59}
60
61impl From<Flags> for u8 {
62 fn from(val: Flags) -> Self {
63 val.bits()
64 }
65}
66
67impl TryFrom<u8> for Flags {
68 type Error = Error;
69
70 fn try_from(val: u8) -> Result<Self> {
71 Self::try_from_bits(val)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_valid() {
81 let mut flags = Flags::new();
82
83 test_field!(flags, out_of_range: 0);
84 test_field!(flags, function_number: 1);
85 test_field!(flags, error: 3);
86 test_field!(flags, illegal_command: 6);
87 test_field!(flags, crc_error: 7);
88
89 [
90 IoCurrentState::Disabled,
91 IoCurrentState::Command,
92 IoCurrentState::Transfer,
93 ]
94 .into_iter()
95 .for_each(|io_cs| {
96 let raw_io_cs = io_cs.into_raw();
97 let mut exp_flags = Flags(raw_io_cs << 4);
98 assert_eq!(Flags::try_from_bits(raw_io_cs << 4), Ok(exp_flags));
99 assert_eq!(exp_flags.io_current_state(), Ok(io_cs));
100
101 exp_flags.set_io_current_state(IoCurrentState::new());
102 assert_eq!(exp_flags.io_current_state(), Ok(IoCurrentState::new()));
103 });
104 }
105
106 #[test]
107 fn test_invalid() {
108 let raw_io_cs = [
109 IoCurrentState::Disabled,
110 IoCurrentState::Command,
111 IoCurrentState::Transfer,
112 ]
113 .map(|r| r.into_raw());
114
115 (0..=u8::MAX)
116 .filter(|b| !raw_io_cs.iter().any(|&c| ((b >> 4) & 0x3) == c))
117 .for_each(|invalid_bits| {
118 let invalid_io_cs = (invalid_bits >> 4) & 0x3;
119
120 assert_eq!(
121 Flags::try_from_bits(invalid_bits),
122 Err(Error::invalid_field_variant(
123 "r5::flags::io_current_state",
124 invalid_io_cs as usize
125 )),
126 );
127 });
128 }
129}