Skip to content

Commit 1ba799f

Browse files
committed
start adding argument and response module
1 parent 70c836b commit 1ba799f

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
@@ -77,6 +77,378 @@ 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 super::argument::VoltageSuppliedSelect;
234+
235+
/// SD card state.
236+
#[bitbybit::bitenum(u4, exhaustive = false)]
237+
#[derive(Debug, PartialEq, Eq)]
238+
pub enum State {
239+
/// Idle state.
240+
Idle = 0,
241+
/// Ready state.
242+
Ready = 1,
243+
/// Identification state.
244+
Ident = 2,
245+
/// Standby state.
246+
Stby = 3,
247+
/// Transfer state.
248+
Tran = 4,
249+
/// Data state.
250+
Data = 5,
251+
/// Receive state.
252+
Rcv = 6,
253+
/// Programming state.
254+
Prg = 7,
255+
/// Disconnected state.
256+
Dis = 8,
257+
/// Reserved for IO mode.
258+
ReservedIoMode = 15,
259+
}
260+
261+
/// Card status (R1).
262+
#[bitbybit::bitfield(u32, default = 0x0, debug, forbid_overlaps)]
263+
pub struct CardStatus {
264+
/// The command's argument was out range of the allowed range for this card.
265+
#[bit(31, rw)]
266+
out_of_range: bool,
267+
/// A misaligned address which did not match the block length that was used in the command
268+
#[bit(30, rw)]
269+
address_error: bool,
270+
/// The transferred block length is not allowed for this card, or the number of transferred
271+
/// bytes does not match the block length.
272+
#[bit(29, rw)]
273+
block_len_error: bool,
274+
/// An error in the sequence of erase commands occurred.
275+
#[bit(28, rw)]
276+
erase_seq_error: bool,
277+
/// An invalid selection of write-blocks for erase occurred.
278+
#[bit(27, rw)]
279+
erase_param: bool,
280+
/// Set when the host attempts to write to a protected block or to the temporary write
281+
/// protected card or write protected until power cycle card or permanent write protected
282+
/// card.
283+
#[bit(26, rw)]
284+
wp_violation: bool,
285+
/// When set, signals that the card is locked by the host
286+
#[bit(25, rw)]
287+
card_is_locked: bool,
288+
/// Set when a sequence or password error has been detected in lock/unlock card command.
289+
#[bit(24, rw)]
290+
lock_unlock_failed: bool,
291+
/// The CRC check of the previous command failed.
292+
#[bit(23, rw)]
293+
com_crc_error: bool,
294+
/// Command not legal for the card state
295+
#[bit(22, rw)]
296+
illegal_command: bool,
297+
/// Card internal ECC was applied but failed to correct the data.
298+
#[bit(21, rw)]
299+
card_ecc_failed: bool,
300+
/// Internal card controller error
301+
#[bit(20, rw)]
302+
cc_error: bool,
303+
/// A general or an unknown error occurred during the operation.
304+
#[bit(19, rw)]
305+
error: bool,
306+
/// Can be either one of the following errors:
307+
/// - The read only section of the CSD does not match the card content.
308+
/// - An attempt to reverse the copy (set as original) or permanent WP (unprotected) bits was made.
309+
#[bit(16, rw)]
310+
csd_overwrite: bool,
311+
/// Set when only partial address space was erased due to existing write protected blocks
312+
/// or the temporary write protected or write protected until power cycle or permanent write
313+
/// protected card was erased.
314+
#[bit(15, rw)]
315+
wp_erase_skip: bool,
316+
/// The command has been executed without using the internal ECC.
317+
#[bit(14, rw)]
318+
card_ecc_disabled: bool,
319+
/// An erase sequence was cleared before executing because an out of erase sequence command
320+
/// was received
321+
#[bit(13, rw)]
322+
erase_reset: bool,
323+
/// CURRENT_STATE. The state of the card when receiving the command. If the command
324+
/// execution causes a state change, it will be visible to the host in the response to the
325+
/// next command.
326+
#[bits(9..=12, rw)]
327+
state: Option<State>,
328+
/// Corresponds to buffer empty signaling on the bus
329+
#[bit(8, rw)]
330+
ready_for_data: bool,
331+
/// FX_EVENT. Extension Functions may set this bit to get host to deal with events.
332+
#[bit(6, rw)]
333+
fx_event: bool,
334+
/// '1': Enabled. The card will expect ACMD, or an indiication that the command has been
335+
/// interpreted as ACMD.
336+
#[bit(5, rw)]
337+
app_cmd: bool,
338+
/// Error in the sequence of the authentification process.
339+
#[bit(3, rw)]
340+
ake_seq_error: bool,
341+
}
342+
343+
/// Operation Conditions Register (OCR).
344+
#[bitbybit::bitfield(u32, default = 0x0, debug, forbid_overlaps)]
345+
pub struct Ocr {
346+
/// '0' if not finished yet.
347+
#[bit(31, rw)]
348+
initialization_complete: bool,
349+
/// CCS. Only valid if power up status bit is set.
350+
#[bit(30, rw)]
351+
card_capacity_status: bool,
352+
/// UHS-II Card Status. '1' if card supports UHS-II interface.
353+
#[bit(29, rw)]
354+
uhs_2_card_status: bool,
355+
/// CO2T. Only supported by SDUC cards.
356+
#[bit(27, rw)]
357+
over_2_tb_support_status: bool,
358+
/// Switching to 1.8V accepted. Only supported by UHS-I cards.
359+
#[bit(24, rw)]
360+
s18a: bool,
361+
/// 3.5V-3.6V voltage window supported.
362+
#[bit(23, rw)]
363+
_3_5_to_3_6v: bool,
364+
/// 3.4V-3.5V voltage window supported.
365+
#[bit(22, rw)]
366+
_3_4_to_3_5v: bool,
367+
/// 3.3V-3.4V voltage window supported.
368+
#[bit(21, rw)]
369+
_3_3_to_3_4v: bool,
370+
/// 3.2V-3.3V voltage window supported.
371+
#[bit(20, rw)]
372+
_3_2_to_3_3v: bool,
373+
/// 3.1V-3.2V voltage window supported.
374+
#[bit(19, rw)]
375+
_3_1_to_3_2v: bool,
376+
/// 3.0V-3.1V voltage window supported.
377+
#[bit(18, rw)]
378+
_3_0_to_3_1v: bool,
379+
/// 2.9V-3.0V voltage window supported.
380+
#[bit(17, rw)]
381+
_2_9_to_3_0v: bool,
382+
/// 2.8V-2.9V voltage window supported.
383+
#[bit(16, rw)]
384+
_2_8_to_2_9v: bool,
385+
/// 2.7V-2.8V voltage window supported.
386+
#[bit(15, rw)]
387+
_2_7_to_2_8v: bool,
388+
/// Reserved for low voltage range.
389+
#[bit(7, rw)]
390+
reserved_low_voltage: bool,
391+
}
392+
393+
/// R1 is the card sate.
394+
pub type R1 = CardStatus;
395+
396+
/// R3 is the OCR register.
397+
pub type R3 = Ocr;
398+
399+
/// Published RCA response (R6).
400+
#[bitbybit::bitfield(u32, default = 0x0, debug, forbid_overlaps)]
401+
pub struct R6 {
402+
/// Relative card address.
403+
#[bits(16..=31, rw)]
404+
rca: u16,
405+
/// Status bit 23. The CRC check of the previous command failed.
406+
#[bit(15, rw)]
407+
com_crc_error: bool,
408+
/// Status bit 22. Command not legal for the card state
409+
#[bit(14, rw)]
410+
illegal_command: bool,
411+
/// Status bit 19. A general or an unknown error occurred during the operation.
412+
#[bit(13, rw)]
413+
error: bool,
414+
/// CURRENT_STATE. The state of the card when receiving the command. If the command
415+
/// execution causes a state change, it will be visible to the host in the response to the
416+
/// next command.
417+
#[bits(9..=12, rw)]
418+
state: Option<State>,
419+
/// Corresponds to buffer empty signaling on the bus
420+
#[bit(8, rw)]
421+
ready_for_data: bool,
422+
/// FX_EVENT. Extension Functions may set this bit to get host to deal with events.
423+
#[bit(6, rw)]
424+
fx_event: bool,
425+
/// '1': Enabled. The card will expect ACMD, or an indiication that the command has been
426+
/// interpreted as ACMD.
427+
#[bit(5, rw)]
428+
app_cmd: bool,
429+
/// Error in the sequence of the authentification process.
430+
#[bit(3, rw)]
431+
ake_seq_error: bool,
432+
}
433+
434+
/// Card interface conditions (R7).
435+
#[bitbybit::bitfield(u32, default = 0x0, debug, forbid_overlaps)]
436+
pub struct R7 {
437+
/// PCIe 1.2V support.
438+
#[bit(13, rw)]
439+
pcie_1_2v_support: bool,
440+
/// PCIe response.
441+
#[bit(12, rw)]
442+
pcie_accepted: bool,
443+
/// Voltage accepted.
444+
#[bits(8..=11, rw)]
445+
voltage_accepted: Option<VoltageSuppliedSelect>,
446+
/// Echo-back of check pattern.
447+
#[bits(0..=7, rw)]
448+
echo_check_pattern: u8,
449+
}
450+
}
451+
80452
/// status for card in the ready state
81453
pub const R1_READY_STATE: u8 = 0x00;
82454

0 commit comments

Comments
 (0)