@@ -77,6 +77,386 @@ pub const ACMD41: u8 = 0x29;
7777
7878//==============================================================================
7979
80+ /// Argument module. Arguments are additional command parameters.
81+ pub mod argument {
82+ use arbitrary_int:: u24;
83+
84+ /// Voltage settings supplied in CMD8.
85+ #[ bitbybit:: bitenum( u4, exhaustive = false ) ]
86+ #[ derive( Debug , Default , PartialEq , Eq ) ]
87+ pub enum VoltageSuppliedSelect {
88+ /// Regular voltage range.
89+ #[ default]
90+ _2_7To3_6V = 0b0001 ,
91+ /// Reserved for low voltage.
92+ LowVoltageRange = 0b0010 ,
93+ }
94+
95+ /// CMD8 argument.
96+ #[ bitbybit:: bitfield( u32 , default = 0x0 ) ]
97+ pub struct Cmd8 {
98+ /// PCIe v1.2 support.
99+ #[ bit( 13 , rw) ]
100+ pcie_1_2v_support : bool ,
101+ /// PCIe available.
102+ #[ bit( 12 , rw) ]
103+ pcie_availability : bool ,
104+ /// Voltage settings.
105+ #[ bits( 8 ..=11 , rw) ]
106+ voltage_supplied : Option < VoltageSuppliedSelect > ,
107+ /// Check pattern which is echoed.
108+ #[ bits( 0 ..=7 , rw) ]
109+ check_pattern : u8 ,
110+ }
111+
112+ /// Power control (XPC) settings.
113+ #[ bitbybit:: bitenum( u1, exhaustive = true ) ]
114+ #[ derive( Debug , PartialEq , Eq ) ]
115+ pub enum PowerControl {
116+ /// Power saving.
117+ PowerSaving = 0 ,
118+ /// Maximum performance.
119+ MaximumPerformance = 1 ,
120+ }
121+
122+ /// HPC.
123+ #[ bitbybit:: bitenum( u1, exhaustive = true ) ]
124+ #[ derive( Debug , PartialEq , Eq ) ]
125+ pub enum HostCapacitySupport {
126+ /// SDSC only.
127+ SdscOnly = 0 ,
128+ /// Extended capacity - SDHC or SDXC.
129+ SdhcOrSdxc = 1 ,
130+ }
131+
132+ /// Lower OCR bits used to negotiate voltage capabilities.
133+ #[ bitbybit:: bitfield( u24, default = 0x0 , debug) ]
134+ pub struct OcrLower {
135+ /// 3.5 to 3.6V
136+ #[ bit( 23 , rw) ]
137+ _3_5_to_3_6v : bool ,
138+ /// 3.4 to 3.5V
139+ #[ bit( 22 , rw) ]
140+ _3_4_to_3_5v : bool ,
141+ /// 3.3 to 3.4V
142+ #[ bit( 21 , rw) ]
143+ _3_3_to_3_4v : bool ,
144+ /// 3.2 to 3.3V
145+ #[ bit( 20 , rw) ]
146+ _3_2_to_3_3v : bool ,
147+ /// 3.1 to 3.2V
148+ #[ bit( 19 , rw) ]
149+ _3_1_to_3_2v : bool ,
150+ /// 3.0 to 3.1V
151+ #[ bit( 18 , rw) ]
152+ _3_0_to_3_1v : bool ,
153+ /// 2.9 to 3.0V
154+ #[ bit( 17 , rw) ]
155+ _2_9_to_3_0v : bool ,
156+ /// 2.8 to 2.9V
157+ #[ bit( 16 , rw) ]
158+ _2_8_to_2_9v : bool ,
159+ /// 2.7 to 2.8V
160+ #[ bit( 15 , rw) ]
161+ _2_7_to_2_8v : bool ,
162+ /// Reserved for low voltage
163+ #[ bit( 7 , rw) ]
164+ reserved_low_voltage : bool ,
165+ }
166+
167+ /// Bus width setting.
168+ #[ bitbybit:: bitenum( u2, exhaustive = false ) ]
169+ #[ derive( Debug , PartialEq , Eq ) ]
170+ pub enum BusWidth {
171+ /// 1 bit bus.
172+ _1bit = 0b00 ,
173+ /// 4 bit bus.
174+ _4bits = 0b10 ,
175+ }
176+
177+ /// ACMD6 - Set bus width.
178+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug, forbid_overlaps) ]
179+ pub struct Acmd6 {
180+ /// Bus width.
181+ #[ bits( 0 ..=1 , rw) ]
182+ bus_width : Option < BusWidth > ,
183+ }
184+
185+ /// ACMD41 argument - Capability negotiation.
186+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug, forbid_overlaps) ]
187+ pub struct Acmd41 {
188+ /// HPC.
189+ #[ bit( 30 , rw) ]
190+ host_capacity_support : HostCapacitySupport ,
191+ /// FB.
192+ #[ bit( 29 , rw) ]
193+ fast_boot : bool ,
194+ /// XPC.
195+ #[ bit( 28 , rw) ]
196+ xpc : PowerControl ,
197+ /// Switch to 1.8V signal voltage request.
198+ #[ bit( 24 , rw) ]
199+ s18r : bool ,
200+ /// If this is set to 0. ACMD41 is called "inquire CMD41" that does not start
201+ /// initialization and is used for getting OCR. Bits 24 to 31 are ignored.
202+ #[ bits( 0 ..=23 , rw) ]
203+ ocr : OcrLower ,
204+ }
205+
206+ /// Relative Card Address (RCA) select.
207+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug) ]
208+ pub struct RcaSelect {
209+ /// RCA.
210+ #[ bits( 16 ..=31 , rw) ]
211+ rca : u16 ,
212+ }
213+
214+ /// CMD9 argument.
215+ pub type Cmd9 = RcaSelect ;
216+ /// CMD7 argument.
217+ pub type Cmd7 = RcaSelect ;
218+
219+ /// CMD13 argument.
220+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug, forbid_overlaps) ]
221+ pub struct Cmd13 {
222+ /// RCA.
223+ #[ bits( 16 ..=31 , rw) ]
224+ rca : u16 ,
225+ /// Send task status instead of regular card status.
226+ #[ bit( 15 , rw) ]
227+ send_task_status : bool ,
228+ }
229+ }
230+
231+ /// Card response module.
232+ pub mod response {
233+ use arbitrary_int:: u2;
234+
235+ use super :: argument:: VoltageSuppliedSelect ;
236+
237+ /// SD card state.
238+ #[ bitbybit:: bitenum( u4, exhaustive = false ) ]
239+ #[ derive( Debug , PartialEq , Eq ) ]
240+ pub enum State {
241+ /// Idle state.
242+ Idle = 0 ,
243+ /// Ready state.
244+ Ready = 1 ,
245+ /// Identification state.
246+ Ident = 2 ,
247+ /// Standby state.
248+ Stby = 3 ,
249+ /// Transfer state.
250+ Tran = 4 ,
251+ /// Data state.
252+ Data = 5 ,
253+ /// Receive state.
254+ Rcv = 6 ,
255+ /// Programming state.
256+ Prg = 7 ,
257+ /// Disconnected state.
258+ Dis = 8 ,
259+ /// Reserved for IO mode.
260+ ReservedIoMode = 15 ,
261+ }
262+
263+ /// Card status (R1).
264+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug, forbid_overlaps) ]
265+ pub struct CardStatus {
266+ /// The command's argument was out range of the allowed range for this card.
267+ #[ bit( 31 , rw) ]
268+ out_of_range : bool ,
269+ /// A misaligned address which did not match the block length was used in the command
270+ #[ bit( 30 , rw) ]
271+ address_error : bool ,
272+ /// The transferred block length is not allowed for this card, or the number of transferred
273+ /// bytes does not match the block length.
274+ #[ bit( 29 , rw) ]
275+ block_len_error : bool ,
276+ /// An error in the sequence of erase commands occurred.
277+ #[ bit( 28 , rw) ]
278+ erase_seq_error : bool ,
279+ /// An invalid selection of write-blocks for erase occurred.
280+ #[ bit( 27 , rw) ]
281+ erase_param : bool ,
282+ /// Set when the host attempts to write to a protected block or to the temporary write
283+ /// protected card or write protected until power cycle card or permanent write protected
284+ /// card.
285+ #[ bit( 26 , rw) ]
286+ wp_violation : bool ,
287+ /// When set, signals that the card is locked by the host
288+ #[ bit( 25 , rw) ]
289+ card_is_locked : bool ,
290+ /// Set when a sequence or password error has been detected in lock/unlock card command.
291+ #[ bit( 24 , rw) ]
292+ lock_unlock_failed : bool ,
293+ /// The CRC check of the previous command failed.
294+ #[ bit( 23 , rw) ]
295+ com_crc_error : bool ,
296+ /// Command not legal for the card state
297+ #[ bit( 22 , rw) ]
298+ illegal_command : bool ,
299+ /// Card internal ECC was applied but failed to correct the data.
300+ #[ bit( 21 , rw) ]
301+ card_ecc_failed : bool ,
302+ /// Internal card controller error
303+ #[ bit( 20 , rw) ]
304+ cc_error : bool ,
305+ /// A general or an unknown error occurred during the operation.
306+ #[ bit( 19 , rw) ]
307+ error : bool ,
308+ /// Can be either one of the following errors:
309+ /// - The read only section of the CSD does not match the card content.
310+ /// - An attempt to reverse the copy (set as original) or permanent WP (unprotected) bits was made.
311+ #[ bit( 16 , rw) ]
312+ csd_overwrite : bool ,
313+ /// Set when only partial address space was erased due to existing write protected blocks
314+ /// or the temporary write protected or write protected until power cycle or permanent write
315+ /// protected card was erased.
316+ #[ bit( 15 , rw) ]
317+ wp_erase_skip : bool ,
318+ /// The command has been executed without using the internal ECC.
319+ #[ bit( 14 , rw) ]
320+ card_ecc_disabled : bool ,
321+ /// An erase sequence was cleared before executing because an out of erase sequence command
322+ /// was received
323+ #[ bit( 13 , rw) ]
324+ erase_reset : bool ,
325+ /// CURRENT_STATE. The state of the card when receiving the command. If the command
326+ /// execution causes a state change, it will be visible to the host in the response to the
327+ /// next command.
328+ #[ bits( 9 ..=12 , rw) ]
329+ state : Option < State > ,
330+ /// Corresponds to buffer empty signaling on the bus
331+ #[ bit( 8 , rw) ]
332+ ready_for_data : bool ,
333+ /// FX_EVENT. Extension Functions may set this bit to get host to deal with events.
334+ #[ bit( 6 , rw) ]
335+ fx_event : bool ,
336+ /// '1': Enabled. The card will expect ACMD, or an indiication that the command has been
337+ /// interpreted as ACMD.
338+ #[ bit( 5 , rw) ]
339+ app_cmd : bool ,
340+ /// Error in the sequence of the authentification process.
341+ #[ bit( 3 , rw) ]
342+ ake_seq_error : bool ,
343+ /// Reserved for application specific commands.
344+ #[ bit( 2 , rw) ]
345+ reserved_app_specific_cmd : bool ,
346+ /// Reserved for manufacturer test mode.
347+ #[ bits( 0 ..=1 , rw) ]
348+ reserved_manufactuere_test_mode : u2 ,
349+ }
350+
351+ /// Operation Conditions Register (OCR).
352+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug, forbid_overlaps) ]
353+ pub struct Ocr {
354+ /// '0' if not finished yet.
355+ #[ bit( 31 , rw) ]
356+ initialization_complete : bool ,
357+ /// CCS. Only valid if power up status bit is set.
358+ #[ bit( 30 , rw) ]
359+ card_capacity_status : bool ,
360+ /// UHS-II Card Status. '1' if card supports UHS-II interface.
361+ #[ bit( 29 , rw) ]
362+ uhs_2_card_status : bool ,
363+ /// CO2T. Only supported by SDUC cards.
364+ #[ bit( 27 , rw) ]
365+ over_2_tb_support_status : bool ,
366+ /// Switching to 1.8V accepted. Only supported by UHS-I cards.
367+ #[ bit( 24 , rw) ]
368+ s18a : bool ,
369+ /// 3.5V-3.6V voltage window supported.
370+ #[ bit( 23 , rw) ]
371+ _3_5_to_3_6v : bool ,
372+ /// 3.4V-3.5V voltage window supported.
373+ #[ bit( 22 , rw) ]
374+ _3_4_to_3_5v : bool ,
375+ /// 3.3V-3.4V voltage window supported.
376+ #[ bit( 21 , rw) ]
377+ _3_3_to_3_4v : bool ,
378+ /// 3.2V-3.3V voltage window supported.
379+ #[ bit( 20 , rw) ]
380+ _3_2_to_3_3v : bool ,
381+ /// 3.1V-3.2V voltage window supported.
382+ #[ bit( 19 , rw) ]
383+ _3_1_to_3_2v : bool ,
384+ /// 3.0V-3.1V voltage window supported.
385+ #[ bit( 18 , rw) ]
386+ _3_0_to_3_1v : bool ,
387+ /// 2.9V-3.0V voltage window supported.
388+ #[ bit( 17 , rw) ]
389+ _2_9_to_3_0v : bool ,
390+ /// 2.8V-2.9V voltage window supported.
391+ #[ bit( 16 , rw) ]
392+ _2_8_to_2_9v : bool ,
393+ /// 2.7V-2.8V voltage window supported.
394+ #[ bit( 15 , rw) ]
395+ _2_7_to_2_8v : bool ,
396+ /// Reserved for low voltage range.
397+ #[ bit( 7 , rw) ]
398+ reserved_low_voltage : bool ,
399+ }
400+
401+ /// R1 is the card sate.
402+ pub type R1 = CardStatus ;
403+
404+ /// R3 is the OCR register.
405+ pub type R3 = Ocr ;
406+
407+ /// Published RCA response (R6).
408+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug, forbid_overlaps) ]
409+ pub struct R6 {
410+ /// Relative card address.
411+ #[ bits( 16 ..=31 , rw) ]
412+ rca : u16 ,
413+ /// Status bit 23. The CRC check of the previous command failed.
414+ #[ bit( 15 , rw) ]
415+ com_crc_error : bool ,
416+ /// Status bit 22. Command not legal for the card state
417+ #[ bit( 14 , rw) ]
418+ illegal_command : bool ,
419+ /// Status bit 19. A general or an unknown error occurred during the operation.
420+ #[ bit( 13 , rw) ]
421+ error : bool ,
422+ /// CURRENT_STATE. The state of the card when receiving the command. If the command
423+ /// execution causes a state change, it will be visible to the host in the response to the
424+ /// next command.
425+ #[ bits( 9 ..=12 , rw) ]
426+ state : Option < State > ,
427+ /// Corresponds to buffer empty signaling on the bus
428+ #[ bit( 8 , rw) ]
429+ ready_for_data : bool ,
430+ /// FX_EVENT. Extension Functions may set this bit to get host to deal with events.
431+ #[ bit( 6 , rw) ]
432+ fx_event : bool ,
433+ /// '1': Enabled. The card will expect ACMD, or an indiication that the command has been
434+ /// interpreted as ACMD.
435+ #[ bit( 5 , rw) ]
436+ app_cmd : bool ,
437+ /// Error in the sequence of the authentification process.
438+ #[ bit( 3 , rw) ]
439+ ake_seq_error : bool ,
440+ }
441+
442+ /// Card interface conditions (R7).
443+ #[ bitbybit:: bitfield( u32 , default = 0x0 , debug, forbid_overlaps) ]
444+ pub struct R7 {
445+ /// PCIe 1.2V support.
446+ #[ bit( 13 , rw) ]
447+ pcie_1_2v_support : bool ,
448+ /// PCIe response.
449+ #[ bit( 12 , rw) ]
450+ pcie_accepted : bool ,
451+ /// Voltage accepted.
452+ #[ bits( 8 ..=11 , rw) ]
453+ voltage_accepted : Option < VoltageSuppliedSelect > ,
454+ /// Echo-back of check pattern.
455+ #[ bits( 0 ..=7 , rw) ]
456+ echo_check_pattern : u8 ,
457+ }
458+ }
459+
80460/// status for card in the ready state
81461pub const R1_READY_STATE : u8 = 0x00 ;
82462
0 commit comments