Skip to content

Commit 1ec5d6b

Browse files
committed
start adding argument and response module
1 parent 4311956 commit 1ec5d6b

1 file changed

Lines changed: 372 additions & 0 deletions

File tree

src/sdcard/mod.rs

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,378 @@ pub const ACMD41: u8 = 0x29;
9595

9696
//==============================================================================
9797

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

0 commit comments

Comments
 (0)