Skip to content

Commit 2e7bd36

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

1 file changed

Lines changed: 380 additions & 0 deletions

File tree

src/sdcard/mod.rs

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
81461
pub const R1_READY_STATE: u8 = 0x00;
82462

0 commit comments

Comments
 (0)