1mod bitfield;
4mod command;
5mod enums;
6mod response;
7
8#[macro_export]
10macro_rules! bitflag_is_set {
11 ($ty:ident) => {
12 impl $ty {
13 pub fn is_set(self, oth: Self) -> bool {
15 self & oth != Self::NONE
16 }
17 }
18 };
19}
20
21#[macro_export]
22macro_rules! data_block {
23 (
24 $(#[$block_doc:meta])+
25 $block:ident: $block_len:expr,
26 $(#[$wide_block_doc:meta])+
27 $wide_block:ident: $wide_block_len:expr$(,)?
28 ) => {
29 paste::paste! {
30 $(#[$block_doc])+
31 #[repr(C)]
32 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
33 pub struct $block {
34 data: [u8; $block_len],
35 }
36
37 impl $block {
38 #[doc = "Creates a new [" $block "]."]
39 pub const fn new() -> Self {
40 Self {
41 data: [0u8; $block_len],
42 }
43 }
44
45 #[doc = "Creates a new [" $block "] from line data."]
46 pub const fn from_bytes(data: [u8; $block_len]) -> Self {
47 Self { data }
48 }
49
50 pub const fn data(&self) -> &[u8] {
52 &self.data
53 }
54
55 #[doc = "Converts the [" $block "] into a [" $wide_block "]."]
56 #[doc = ""]
57 #[doc = "This is for using all four `DAT` lines on a SD bus."]
58 pub const fn wide_data(&self) -> $wide_block {
59 use $crate::data::{wide_bus_encode, DataLine};
60
61 let mut wide = $wide_block::new();
62
63 let mut i = 0;
64 let len = self.data.len();
65
66 while i < len {
67 let b = self.data[i];
68 let dat_idx = i.saturating_div(WIDE_BUS_WIDTH);
69
70 wide.dat0[dat_idx] |= wide_bus_encode(b, i, DataLine::Dat0);
71 wide.dat1[dat_idx] |= wide_bus_encode(b, i, DataLine::Dat1);
72 wide.dat2[dat_idx] |= wide_bus_encode(b, i, DataLine::Dat2);
73 wide.dat3[dat_idx] |= wide_bus_encode(b, i, DataLine::Dat3);
74
75 i += 1;
76 }
77
78 wide
79 }
80 }
81
82 impl Default for $block {
83 fn default() -> Self {
84 Self::new()
85 }
86 }
87
88 $(#[$wide_block_doc])+
89 #[repr(C)]
90 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
91 pub struct $wide_block {
92 dat0: [u8; $wide_block_len],
93 dat1: [u8; $wide_block_len],
94 dat2: [u8; $wide_block_len],
95 dat3: [u8; $wide_block_len],
96 }
97
98 impl $wide_block {
99 #[doc = "Creates a new [" $wide_block "]."]
100 pub const fn new() -> Self {
101 Self {
102 dat0: [0u8; $wide_block_len],
103 dat1: [0u8; $wide_block_len],
104 dat2: [0u8; $wide_block_len],
105 dat3: [0u8; $wide_block_len],
106 }
107 }
108
109 #[doc = "Creates a new [" $wide_block "] from `DAT` line data."]
110 pub const fn from_data_lines(
111 dat0: [u8; $wide_block_len],
112 dat1: [u8; $wide_block_len],
113 dat2: [u8; $wide_block_len],
114 dat3: [u8; $wide_block_len],
115 ) -> Self {
116 Self {
117 dat0,
118 dat1,
119 dat2,
120 dat3,
121 }
122 }
123
124 #[doc = "Converts the [" $wide_block "] into a [" $block "]."]
125 #[doc = ""]
126 #[doc = "This is for using all four `DAT` lines on a SD bus."]
127 pub const fn decode(&self) -> $block {
128 use $crate::data::{wide_bus_decode, DataLine, WIDE_BUS_WIDTH};
129
130 let mut block = $block::new();
131
132 let mut i = 0;
133 let len = block.data.len();
134
135 while i < len {
136 let j = i.saturating_div(WIDE_BUS_WIDTH);
137
138 block.data[i] |= wide_bus_decode(self.dat0[j], i, DataLine::Dat0);
139 block.data[i] |= wide_bus_decode(self.dat1[j], i, DataLine::Dat1);
140 block.data[i] |= wide_bus_decode(self.dat2[j], i, DataLine::Dat2);
141 block.data[i] |= wide_bus_decode(self.dat3[j], i, DataLine::Dat3);
142
143 i += 1;
144 }
145
146 block
147 }
148 }
149
150 impl Default for $wide_block {
151 fn default() -> Self {
152 Self::new()
153 }
154 }
155
156 impl From<$block> for $wide_block {
157 fn from(val: $block) -> Self {
158 val.wide_data()
159 }
160 }
161 }
162 };
163}
164
165#[macro_export]
169macro_rules! lib_struct {
170 (
171 $(#[$doc:meta])+
172 $ty:ident {
173 $($field:ident: $field_ty:ident$(,)?)+
174 }
175 ) => {
176 paste::paste! {
177 $(#[$doc])+
178 #[repr(C)]
179 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
180 pub struct $ty {
181 $($field: $field_ty,)+
182 }
183
184 impl $ty {
185 $(
186 #[doc = "Gets the [" $field_ty "] for the [" $ty "]."]
187 pub const fn $field(&self) -> $field_ty {
188 self.$field
189 }
190
191 #[doc = "Sets the [" $field_ty "] for the [" $ty "]."]
192 pub fn [<set_ $field>](&mut self, $field: $field_ty) {
193 self.$field = $field;
194 }
195
196 #[doc = "Builder function that sets the [" $field_ty "] for the [" $ty "]."]
197 pub const fn [<with_ $field>](self, $field: $field_ty) -> Self {
198 Self {
199 $field: $field,
200 ..self
201 }
202 }
203 )+
204 }
205 }
206 }
207}
208
209#[macro_export]
211macro_rules! test_field {
212 ($t:ident, $field:ident) => {
213 paste::paste! {
214 $t.[<set_ $field>](true);
215 assert!($t.$field());
216
217 $t.[<set_ $field>](false);
218 assert!(!$t.$field());
219 }
220 };
221
222 ($t:ident, $field:ident: $bit:expr) => {
223 paste::paste! {
224 $t.[<set_ $field>](true);
225 assert!($t.$field());
226 assert_eq!($t.bits() & (1 << $bit), 1 << $bit);
227
228 $t.[<set_ $field>](false);
229 assert!(!$t.$field());
230 assert_eq!($t.bits() & (1 << $bit), 0);
231 }
232 };
233
234 ($t:ident, $field:ident { bit: $bit:expr, [$base:ty; $N:expr] }) => {
235 paste::paste! {
236 let idx = ($N - (($bit / $base::BITS) as usize) - 1);
237 let bit = $bit % $base::BITS;
238
239 $t.[<set_ $field>](true);
240 assert!($t.$field());
241
242 assert_eq!($t.bytes()[idx] & (1 << bit), 1 << bit);
243
244 $t.[<set_ $field>](false);
245 assert!(!$t.$field());
246 assert_eq!($t.bytes()[idx] & (1 << bit), 0);
247 }
248 };
249}
250
251#[macro_export]
253macro_rules! const_try {
254 ($e:expr) => {
255 match $e {
256 Ok(v) => v,
257 Err(err) => return Err(err),
258 }
259 };
260}