embedded_sdmmc/sdmmc_proto.rs
1//! embedded-sdmmc-rs - Constants from the SD Specifications
2//!
3//! Based on SdFat, under the following terms:
4//!
5//! > Copyright (c) 2011-2018 Bill Greiman
6//! > This file is part of the SdFat library for SD memory cards.
7//! >
8//! > MIT License
9//! >
10//! > Permission is hereby granted, free of charge, to any person obtaining a
11//! > copy of this software and associated documentation files (the "Software"),
12//! > to deal in the Software without restriction, including without limitation
13//! > the rights to use, copy, modify, merge, publish, distribute, sublicense,
14//! > and/or sell copies of the Software, and to permit persons to whom the
15//! > Software is furnished to do so, subject to the following conditions:
16//! >
17//! > The above copyright notice and this permission notice shall be included
18//! > in all copies or substantial portions of the Software.
19//! >
20//! > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21//! > OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22//! > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23//! > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24//! > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25//! > FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26//! > DEALINGS IN THE SOFTWARE.
27
28//==============================================================================
29
30// Possible errors the SD card can return
31
32pub const ERROR_OK: u8 = 0x00;
33
34// Basic commands and switch command.
35pub const ERROR_CMD0: u8 = 0x20;
36pub const ERROR_CMD2: u8 = 0x21;
37pub const ERROR_CMD3: u8 = 0x22;
38pub const ERROR_CMD6: u8 = 0x23;
39pub const ERROR_CMD7: u8 = 0x24;
40pub const ERROR_CMD8: u8 = 0x25;
41pub const ERROR_CMD9: u8 = 0x26;
42pub const ERROR_CMD10: u8 = 0x27;
43pub const ERROR_CMD12: u8 = 0x28;
44pub const ERROR_CMD13: u8 = 0x29;
45
46// Read, write, erase, and extension commands.
47pub const ERROR_CMD17: u8 = 0x30;
48pub const ERROR_CMD18: u8 = 0x31;
49pub const ERROR_CMD24: u8 = 0x32;
50pub const ERROR_CMD25: u8 = 0x33;
51pub const ERROR_CMD32: u8 = 0x34;
52pub const ERROR_CMD33: u8 = 0x35;
53pub const ERROR_CMD38: u8 = 0x36;
54pub const ERROR_CMD58: u8 = 0x37;
55pub const ERROR_CMD59: u8 = 0x38;
56
57// Application specific commands.
58pub const ERROR_ACMD6: u8 = 0x40;
59pub const ERROR_ACMD13: u8 = 0x41;
60pub const ERROR_ACMD23: u8 = 0x42;
61pub const ERROR_ACMD41: u8 = 0x43;
62
63// Read/write errors
64pub const ERROR_READ: u8 = 0x50;
65pub const ERROR_READ_CRC: u8 = 0x51;
66pub const ERROR_READ_FIFO: u8 = 0x52;
67pub const ERROR_READ_REG: u8 = 0x53;
68pub const ERROR_READ_START: u8 = 0x54;
69pub const ERROR_READ_TIMEOUT: u8 = 0x55;
70pub const ERROR_STOP_TRAN: u8 = 0x56;
71pub const ERROR_WRITE: u8 = 0x57;
72pub const ERROR_WRITE_FIFO: u8 = 0x58;
73pub const ERROR_WRITE_START: u8 = 0x59;
74pub const ERROR_WRITE_TIMEOUT: u8 = 0x60;
75
76// Misc errors.
77pub const ERROR_DMA: u8 = 0x60;
78pub const ERROR_ERASE: u8 = 0x61;
79pub const ERROR_ERASE_SINGLE_BLOCK: u8 = 0x61;
80pub const ERROR_ERASE_TIMEOUT: u8 = 0x62;
81pub const ERROR_INIT_NOT_CALLED: u8 = 0x63;
82pub const ERROR_FUNCTION_NOT_SUPPORTED: u8 = 0x64;
83
84//==============================================================================
85
86/// Types of SD card supported
87#[derive(Debug, Copy, Clone)]
88#[repr(u8)]
89pub enum CardType {
90 SD1 = 1,
91 SD2 = 2,
92 SDHC = 3,
93}
94
95//==============================================================================
96
97// SD Card Commands
98
99/// GO_IDLE_STATE - init card in spi mode if CS low
100pub const CMD0: u8 = 0x00;
101/// ALL_SEND_CID - Asks any card to send the CID.
102pub const CMD2: u8 = 0x02;
103/// SEND_RELATIVE_ADDR - Ask the card to publish a new RCA.
104pub const CMD3: u8 = 0x03;
105/// SWITCH_FUNC - Switch Function Command
106pub const CMD6: u8 = 0x06;
107/// SELECT/DESELECT_CARD - toggles between the stand-by and transfer states.
108pub const CMD7: u8 = 0x07;
109/// SEND_IF_COND - verify SD Memory Card interface operating condition.*/
110pub const CMD8: u8 = 0x08;
111/// SEND_CSD - read the Card Specific Data (CSD register)
112pub const CMD9: u8 = 0x09;
113/// SEND_CID - read the card identification information (CID register)
114pub const CMD10: u8 = 0x0A;
115/// STOP_TRANSMISSION - end multiple block read sequence
116pub const CMD12: u8 = 0x0C;
117/// SEND_STATUS - read the card status register
118pub const CMD13: u8 = 0x0D;
119/// READ_SINGLE_BLOCK - read a single data block from the card
120pub const CMD17: u8 = 0x11;
121/// READ_MULTIPLE_BLOCK - read a multiple data blocks from the card
122pub const CMD18: u8 = 0x12;
123/// WRITE_BLOCK - write a single data block to the card
124pub const CMD24: u8 = 0x18;
125/// WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION
126pub const CMD25: u8 = 0x19;
127/// ERASE_WR_BLK_START - sets the address of the first block to be erased
128pub const CMD32: u8 = 0x20;
129/// ERASE_WR_BLK_END - sets the address of the last block of the continuous
130/// range to be erased*/
131pub const CMD33: u8 = 0x21;
132/// ERASE - erase all previously selected blocks
133pub const CMD38: u8 = 0x26;
134/// APP_CMD - escape for application specific command
135pub const CMD55: u8 = 0x37;
136/// READ_OCR - read the OCR register of a card
137pub const CMD58: u8 = 0x3A;
138/// CRC_ON_OFF - enable or disable CRC checking
139pub const CMD59: u8 = 0x3B;
140/// SET_BUS_WIDTH - Defines the data bus width for data transfer.
141pub const ACMD6: u8 = 0x06;
142/// SD_STATUS - Send the SD Status.
143pub const ACMD13: u8 = 0x0D;
144/// SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be pre-erased
145/// before writing
146pub const ACMD23: u8 = 0x17;
147/// SD_SEND_OP_COMD - Sends host capacity support information and activates
148/// the card's initialization process
149pub const ACMD41: u8 = 0x29;
150
151//==============================================================================
152
153// CARD_STATUS
154
155/// The command's argument was out of the allowed range for this card.
156pub const CARD_STATUS_OUT_OF_RANGE: u32 = 1 << 31;
157
158/// A misaligned address which did not match the block length.
159pub const CARD_STATUS_ADDRESS_ERROR: u32 = 1 << 30;
160
161/// The transferred block length is not allowed for this card.
162pub const CARD_STATUS_BLOCK_LEN_ERROR: u32 = 1 << 29;
163
164/// An error in the sequence of erase commands occurred.
165pub const CARD_STATUS_ERASE_SEQ_ERROR: u32 = 1 << 28;
166
167/// An invalid selection of write-blocks for erase occurred.
168pub const CARD_STATUS_ERASE_PARAM: u32 = 1 << 27;
169
170/// Set when the host attempts to write to a protected block.
171pub const CARD_STATUS_WP_VIOLATION: u32 = 1 << 26;
172
173/// When set, signals that the card is locked by the host.
174pub const CARD_STATUS_CARD_IS_LOCKED: u32 = 1 << 25;
175
176/// Set when a sequence or password error has been detected.
177pub const CARD_STATUS_LOCK_UNLOCK_FAILED: u32 = 1 << 24;
178
179/// The CRC check of the previous command failed.
180pub const CARD_STATUS_COM_CRC_ERROR: u32 = 1 << 23;
181
182/// Command not legal for the card state.
183pub const CARD_STATUS_ILLEGAL_COMMAND: u32 = 1 << 22;
184
185/// Card internal ECC was applied but failed to correct the data.
186pub const CARD_STATUS_CARD_ECC_FAILED: u32 = 1 << 21;
187
188/// Internal card controller error
189pub const CARD_STATUS_CC_ERROR: u32 = 1 << 20;
190
191/// A general or an unknown error occurred during the operation.
192pub const CARD_STATUS_ERROR: u32 = 1 << 19;
193
194// bits 19, 18, and 17 reserved.
195/// Permanent WP set or attempt to change read only values of CSD.
196pub const CARD_STATUS_CSD_OVERWRITE: u32 = 1 << 16;
197
198/// partial address space was erased due to write protect.
199pub const CARD_STATUS_WP_ERASE_SKIP: u32 = 1 << 15;
200
201/// The command has been executed without using the internal ECC.
202pub const CARD_STATUS_CARD_ECC_DISABLED: u32 = 1 << 14;
203
204/// out of erase sequence command was received.
205pub const CARD_STATUS_ERASE_RESET: u32 = 1 << 13;
206
207/// The state of the card when receiving the command.
208/// * 0 = idle
209/// * 1 = ready
210/// * 2 = ident
211/// * 3 = stby
212/// * 4 = tran
213/// * 5 = data
214/// * 6 = rcv
215/// * 7 = prg
216/// * 8 = dis
217/// * 9-14 = reserved
218/// * 15 = reserved for I/O mode
219pub const CARD_STATUS_CURRENT_STATE: u32 = 0xF << 9;
220
221/// Shift for current state.
222pub const CARD_STATUS_CURRENT_STATE_SHIFT: u32 = 9;
223
224/// Corresponds to buffer empty signaling on the bus.
225pub const CARD_STATUS_READY_FOR_DATA: u32 = 1 << 8;
226
227// bit 7 reserved.
228
229/// Extension Functions may set this bit to get host to deal with events.
230pub const CARD_STATUS_FX_EVENT: u32 = 1 << 6;
231
232/// The card will expect ACMD, or the command has been interpreted as ACMD
233pub const CARD_STATUS_APP_CMD: u32 = 1 << 5;
234
235// bit 4 reserved.
236
237/// Error in the sequence of the authentication process.
238pub const CARD_STATUS_AKE_SEQ_ERROR: u32 = 1 << 3;
239
240// bits 2,1, and 0 reserved for manufacturer test mode.
241
242//==============================================================================
243
244/// status for card in the ready state
245pub const R1_READY_STATE: u8 = 0x00;
246
247/// status for card in the idle state
248pub const R1_IDLE_STATE: u8 = 0x01;
249
250/// status bit for illegal command
251pub const R1_ILLEGAL_COMMAND: u8 = 0x04;
252
253/// start data token for read or write single block*/
254pub const DATA_START_BLOCK: u8 = 0xFE;
255
256/// stop token for write multiple blocks*/
257pub const STOP_TRAN_TOKEN: u8 = 0xFD;
258
259/// start data token for write multiple blocks*/
260pub const WRITE_MULTIPLE_TOKEN: u8 = 0xFC;
261
262/// mask for data response tokens after a write block operation
263pub const DATA_RES_MASK: u8 = 0x1F;
264
265/// write data accepted token
266pub const DATA_RES_ACCEPTED: u8 = 0x05;
267
268/// Card Identification Register
269#[repr(packed)]
270pub struct Cid {
271 /// Manufacturer ID
272 pub mid: u8,
273 /// OAM/Application ID
274 pub oid: [u8; 2],
275 /// Product Name
276 pub pnm: [u8; 5],
277 /// Product revision
278 pub prv: u8,
279 /// Product Serial Number
280 pub psn: u32,
281 /// Manufacturing date year high digit
282 pub mdt_year_high: u8,
283 /// Manufacturing date month/year low digit
284 pub mdt_year_low_month: u8,
285 /// CRC (top bit always 1)
286 pub crc: u8,
287}
288
289pub struct CsdV1 {
290 pub data: [u8; 16],
291}
292
293pub struct CsdV2 {
294 pub data: [u8; 16],
295}
296
297pub enum Csd {
298 V1(CsdV1),
299 V2(CsdV2),
300}
301
302impl CsdV1 {
303 pub fn new() -> CsdV1 {
304 CsdV1 { data: [0u8; 16] }
305 }
306
307 define_field!(csd_ver, u8, 0, 6, 2);
308 define_field!(data_read_access_time1, u8, 1, 0, 8);
309 define_field!(data_read_access_time2, u8, 2, 0, 8);
310 define_field!(max_data_transfer_rate, u8, 3, 0, 8);
311 define_field!(card_command_classes, u16, [(4, 0, 8), (5, 4, 4)]);
312 define_field!(read_block_length, u8, 5, 0, 4);
313 define_field!(read_partial_blocks, bool, 6, 7);
314 define_field!(write_block_misalignment, bool, 6, 6);
315 define_field!(read_block_misalignment, bool, 6, 5);
316 define_field!(dsr_implemented, bool, 6, 4);
317 define_field!(device_size, u32, [(6, 0, 2), (7, 0, 8), (8, 6, 2)]);
318 define_field!(max_read_current_vdd_max, u8, 8, 0, 3);
319 define_field!(max_read_current_vdd_min, u8, 8, 3, 3);
320 define_field!(max_write_current_vdd_max, u8, 9, 2, 3);
321 define_field!(max_write_current_vdd_min, u8, 9, 5, 3);
322 define_field!(device_size_multiplier, u8, [(9, 0, 2), (10, 7, 1)]);
323 define_field!(erase_single_block_enabled, bool, 10, 6);
324 define_field!(erase_sector_size, u8, [(10, 0, 6), (11, 7, 1)]);
325 define_field!(write_protect_group_size, u8, 11, 0, 7);
326 define_field!(write_protect_group_enable, bool, 12, 7);
327 define_field!(write_speed_factor, u8, 12, 2, 3);
328 define_field!(max_write_data_length, u8, [(12, 0, 2), (13, 6, 2)]);
329 define_field!(write_partial_blocks, bool, 13, 5);
330 define_field!(file_format, u8, 14, 2, 2);
331 define_field!(temporary_write_protection, bool, 14, 4);
332 define_field!(permanent_write_protection, bool, 14, 5);
333 define_field!(copy_flag_set, bool, 14, 6);
334 define_field!(file_format_group_set, bool, 14, 7);
335 define_field!(crc, u8, 15, 0, 8);
336
337 /// Returns the card capacity in bytes
338 pub fn card_capacity_bytes(&self) -> u64 {
339 let multiplier = self.device_size_multiplier() + self.read_block_length() + 2;
340 (u64::from(self.device_size()) + 1) << multiplier
341 }
342
343 /// Returns the card capacity in 512-byte blocks
344 pub fn card_capacity_blocks(&self) -> u32 {
345 let multiplier = self.device_size_multiplier() + self.read_block_length() - 7;
346 (self.device_size() + 1) << multiplier
347 }
348}
349
350impl CsdV2 {
351 pub fn new() -> CsdV2 {
352 CsdV2 { data: [0u8; 16] }
353 }
354
355 define_field!(csd_ver, u8, 0, 6, 2);
356 define_field!(data_read_access_time1, u8, 1, 0, 8);
357 define_field!(data_read_access_time2, u8, 2, 0, 8);
358 define_field!(max_data_transfer_rate, u8, 3, 0, 8);
359 define_field!(card_command_classes, u16, [(4, 0, 8), (5, 4, 4)]);
360 define_field!(read_block_length, u8, 5, 0, 4);
361 define_field!(read_partial_blocks, bool, 6, 7);
362 define_field!(write_block_misalignment, bool, 6, 6);
363 define_field!(read_block_misalignment, bool, 6, 5);
364 define_field!(dsr_implemented, bool, 6, 4);
365 define_field!(device_size, u32, [(7, 0, 6), (8, 0, 8), (9, 0, 8)]);
366 define_field!(erase_single_block_enabled, bool, 10, 6);
367 define_field!(erase_sector_size, u8, [(10, 0, 6), (11, 7, 1)]);
368 define_field!(write_protect_group_size, u8, 11, 0, 7);
369 define_field!(write_protect_group_enable, bool, 12, 7);
370 define_field!(write_speed_factor, u8, 12, 2, 3);
371 define_field!(max_write_data_length, u8, [(12, 0, 2), (13, 6, 2)]);
372 define_field!(write_partial_blocks, bool, 13, 5);
373 define_field!(file_format, u8, 14, 2, 2);
374 define_field!(temporary_write_protection, bool, 14, 4);
375 define_field!(permanent_write_protection, bool, 14, 5);
376 define_field!(copy_flag_set, bool, 14, 6);
377 define_field!(file_format_group_set, bool, 14, 7);
378 define_field!(crc, u8, 15, 0, 8);
379
380 /// Returns the card capacity in bytes
381 pub fn card_capacity_bytes(&self) -> u64 {
382 (u64::from(self.device_size()) + 1) * 512 * 1024
383 }
384
385 /// Returns the card capacity in 512-byte blocks
386 pub fn card_capacity_blocks(&self) -> u32 {
387 (self.device_size() + 1) * 1024
388 }
389}
390
391/// Perform the 7-bit CRC used on the SD card
392pub fn crc7(data: &[u8]) -> u8 {
393 let mut crc = 0u8;
394 for mut d in data.iter().cloned() {
395 for _bit in 0..8 {
396 crc <<= 1;
397 if ((d & 0x80) ^ (crc & 0x80)) != 0 {
398 crc ^= 0x09;
399 }
400 d <<= 1;
401 }
402 }
403 (crc << 1) | 1
404}
405
406/// Perform the X25 CRC calculation, as used for data blocks.
407pub fn crc16(data: &[u8]) -> u16 {
408 let mut crc = 0u16;
409 for &byte in data {
410 crc = ((crc >> 8) & 0xFF) | (crc << 8);
411 crc ^= u16::from(byte);
412 crc ^= (crc & 0xFF) >> 4;
413 crc ^= crc << 12;
414 crc ^= (crc & 0xFF) << 5;
415 }
416 crc
417}
418
419#[cfg(test)]
420mod test {
421 use super::*;
422
423 #[test]
424 fn test_crc7() {
425 const DATA: [u8; 15] = [
426 0x00, 0x26, 0x00, 0x32, 0x5f, 0x59, 0x83, 0xc8, 0xad, 0xdb, 0xcf, 0xff, 0xd2, 0x40,
427 0x40,
428 ];
429 assert_eq!(crc7(&DATA), 0xA5);
430 }
431
432 #[test]
433 fn test_crc16() {
434 // An actual CSD read from an SD card
435 const DATA: [u8; 16] = [
436 0x00, 0x26, 0x00, 0x32, 0x5f, 0x5a, 0x83, 0xae, 0xfe, 0xfb, 0xcf, 0xff, 0x92, 0x80,
437 0x40, 0xdf,
438 ];
439 assert_eq!(crc16(&DATA), 0x9fc5);
440 }
441
442 #[test]
443 fn test_csdv1b() {
444 const EXAMPLE: CsdV1 = CsdV1 {
445 data: [
446 0x00, 0x26, 0x00, 0x32, 0x5f, 0x59, 0x83, 0xc8, 0xad, 0xdb, 0xcf, 0xff, 0xd2, 0x40,
447 0x40, 0xa5,
448 ],
449 };
450
451 // CSD Structure: describes version of CSD structure
452 // 0b00 [Interpreted: Version 1.0]
453 assert_eq!(EXAMPLE.csd_ver(), 0x00);
454
455 // Data Read Access Time 1: defines Asynchronous part of the read
456 // access time 0x26 [Interpreted: 1.5 x 1ms]
457 assert_eq!(EXAMPLE.data_read_access_time1(), 0x26);
458
459 // Data Read Access Time 2: worst case clock dependent factor for data
460 // access time 0x00 [Decimal: 0 x 100 Clocks]
461 assert_eq!(EXAMPLE.data_read_access_time2(), 0x00);
462
463 // Max Data Transfer Rate: sometimes stated as Mhz
464 // 0x32 [Interpreted: 2.5 x 10Mbit/s]
465 assert_eq!(EXAMPLE.max_data_transfer_rate(), 0x32);
466
467 // Card Command Classes: 0x5f5 [Interpreted: Class 0: Yes. Class 1:
468 // No. Class 2: Yes. Class 3: No. Class 4: Yes. Class 5: Yes. Class 6:
469 // Yes. Class 7: Yes. Class 8: Yes. Class 9: No. Class 10: Yes. Class
470 // 11: No. ]
471 assert_eq!(EXAMPLE.card_command_classes(), 0x5f5);
472
473 // Max Read Data Block Length:
474 // 0x9 [Interpreted: 512 Bytes]
475 assert_eq!(EXAMPLE.read_block_length(), 0x09);
476
477 // Partial Blocks for Read Allowed:
478 // 0b1 [Interpreted: Yes]
479 assert_eq!(EXAMPLE.read_partial_blocks(), true);
480
481 // Write Block Misalignment:
482 // 0b0 [Interpreted: No]
483 assert_eq!(EXAMPLE.write_block_misalignment(), false);
484
485 // Read Block Misalignment:
486 // 0b0 [Interpreted: No]
487 assert_eq!(EXAMPLE.read_block_misalignment(), false);
488
489 // DSR Implemented: indicates configurable driver stage integrated on
490 // card 0b0 [Interpreted: No]
491 assert_eq!(EXAMPLE.dsr_implemented(), false);
492
493 // Device Size: to calculate the card capacity excl. security area
494 // ((device size + 1)*device size multiplier*max read data block
495 // length) bytes 0xf22 [Decimal: 3874]
496 assert_eq!(EXAMPLE.device_size(), 3874);
497
498 // Max Read Current @ VDD Min:
499 // 0x5 [Interpreted: 35mA]
500 assert_eq!(EXAMPLE.max_read_current_vdd_min(), 5);
501
502 // Max Read Current @ VDD Max:
503 // 0x5 [Interpreted: 80mA]
504 assert_eq!(EXAMPLE.max_read_current_vdd_max(), 5);
505
506 // Max Write Current @ VDD Min:
507 // 0x6 [Interpreted: 60mA]
508 assert_eq!(EXAMPLE.max_write_current_vdd_min(), 6);
509
510 // Max Write Current @ VDD Max::
511 // 0x6 [Interpreted: 200mA]
512 assert_eq!(EXAMPLE.max_write_current_vdd_max(), 6);
513
514 // Device Size Multiplier:
515 // 0x7 [Interpreted: x512]
516 assert_eq!(EXAMPLE.device_size_multiplier(), 7);
517
518 // Erase Single Block Enabled:
519 // 0x1 [Interpreted: Yes]
520 assert_eq!(EXAMPLE.erase_single_block_enabled(), true);
521
522 // Erase Sector Size: size of erasable sector in write blocks
523 // 0x1f [Interpreted: 32 blocks]
524 assert_eq!(EXAMPLE.erase_sector_size(), 0x1F);
525
526 // Write Protect Group Size:
527 // 0x7f [Interpreted: 128 sectors]
528 assert_eq!(EXAMPLE.write_protect_group_size(), 0x7f);
529
530 // Write Protect Group Enable:
531 // 0x1 [Interpreted: Yes]
532 assert_eq!(EXAMPLE.write_protect_group_enable(), true);
533
534 // Write Speed Factor: block program time as multiple of read access time
535 // 0x4 [Interpreted: x16]
536 assert_eq!(EXAMPLE.write_speed_factor(), 0x4);
537
538 // Max Write Data Block Length:
539 // 0x9 [Interpreted: 512 Bytes]
540 assert_eq!(EXAMPLE.max_write_data_length(), 0x9);
541
542 // Partial Blocks for Write Allowed:
543 // 0x0 [Interpreted: No]
544 assert_eq!(EXAMPLE.write_partial_blocks(), false);
545
546 // File Format Group:
547 // 0b0 [Interpreted: is either Hard Disk with Partition Table/DOS FAT without Partition Table/Universal File Format/Other/Unknown]
548 assert_eq!(EXAMPLE.file_format_group_set(), false);
549
550 // Copy Flag:
551 // 0b1 [Interpreted: Non-Original]
552 assert_eq!(EXAMPLE.copy_flag_set(), true);
553
554 // Permanent Write Protection:
555 // 0b0 [Interpreted: No]
556 assert_eq!(EXAMPLE.permanent_write_protection(), false);
557
558 // Temporary Write Protection:
559 // 0b0 [Interpreted: No]
560 assert_eq!(EXAMPLE.temporary_write_protection(), false);
561
562 // File Format:
563 // 0x0 [Interpreted: Hard Disk with Partition Table]
564 assert_eq!(EXAMPLE.file_format(), 0x00);
565
566 // CRC7 Checksum + always 1 in LSB:
567 // 0xa5
568 assert_eq!(EXAMPLE.crc(), 0xa5);
569
570 assert_eq!(EXAMPLE.card_capacity_bytes(), 1_015_808_000);
571 assert_eq!(EXAMPLE.card_capacity_blocks(), 1_984_000);
572 }
573
574 #[test]
575 fn test_csdv1() {
576 const EXAMPLE: CsdV1 = CsdV1 {
577 data: [
578 0x00, 0x7f, 0x00, 0x32, 0x5b, 0x5a, 0x83, 0xaf, 0x7f, 0xff, 0xcf, 0x80, 0x16, 0x80,
579 0x00, 0x6f,
580 ],
581 };
582 // CSD Structure: describes version of CSD structure
583 // 0b00 [Interpreted: Version 1.0]
584 assert_eq!(EXAMPLE.csd_ver(), 0x00);
585
586 // Data Read Access Time 1: defines Asynchronous part of the read access time
587 // 0x7f [Interpreted: 8.0 x 10ms]
588 assert_eq!(EXAMPLE.data_read_access_time1(), 0x7F);
589
590 // Data Read Access Time 2: worst case clock dependent factor for data access time
591 // 0x00 [Decimal: 0 x 100 Clocks]
592 assert_eq!(EXAMPLE.data_read_access_time2(), 0x00);
593
594 // Max Data Transfer Rate: sometimes stated as Mhz
595 // 0x32 [Interpreted: 2.5 x 10Mbit/s]
596 assert_eq!(EXAMPLE.max_data_transfer_rate(), 0x32);
597
598 // Card Command Classes:
599 // 0x5b5 [Interpreted: Class 0: Yes. Class 1: No. Class 2: Yes. Class 3: No. Class 4: Yes. Class 5: Yes. Class 6: No. Class 7: Yes. Class 8: Yes. Class 9: No. Class 10: Yes. Class 11: No. ]
600 assert_eq!(EXAMPLE.card_command_classes(), 0x5b5);
601
602 // Max Read Data Block Length:
603 // 0xa [Interpreted: 1024 Bytes]
604 assert_eq!(EXAMPLE.read_block_length(), 0x0a);
605
606 // Partial Blocks for Read Allowed:
607 // 0b1 [Interpreted: Yes]
608 assert_eq!(EXAMPLE.read_partial_blocks(), true);
609
610 // Write Block Misalignment:
611 // 0b0 [Interpreted: No]
612 assert_eq!(EXAMPLE.write_block_misalignment(), false);
613
614 // Read Block Misalignment:
615 // 0b0 [Interpreted: No]
616 assert_eq!(EXAMPLE.read_block_misalignment(), false);
617
618 // DSR Implemented: indicates configurable driver stage integrated on card
619 // 0b0 [Interpreted: No]
620 assert_eq!(EXAMPLE.dsr_implemented(), false);
621
622 // Device Size: to calculate the card capacity excl. security area
623 // ((device size + 1)*device size multiplier*max read data block
624 // length) bytes 0xebd [Decimal: 3773]
625 assert_eq!(EXAMPLE.device_size(), 3773);
626
627 // Max Read Current @ VDD Min:
628 // 0x7 [Interpreted: 100mA]
629 assert_eq!(EXAMPLE.max_read_current_vdd_min(), 7);
630
631 // Max Read Current @ VDD Max:
632 // 0x7 [Interpreted: 200mA]
633 assert_eq!(EXAMPLE.max_read_current_vdd_max(), 7);
634
635 // Max Write Current @ VDD Min:
636 // 0x7 [Interpreted: 100mA]
637 assert_eq!(EXAMPLE.max_write_current_vdd_min(), 7);
638
639 // Max Write Current @ VDD Max::
640 // 0x7 [Interpreted: 200mA]
641 assert_eq!(EXAMPLE.max_write_current_vdd_max(), 7);
642
643 // Device Size Multiplier:
644 // 0x7 [Interpreted: x512]
645 assert_eq!(EXAMPLE.device_size_multiplier(), 7);
646
647 // Erase Single Block Enabled:
648 // 0x1 [Interpreted: Yes]
649 assert_eq!(EXAMPLE.erase_single_block_enabled(), true);
650
651 // Erase Sector Size: size of erasable sector in write blocks
652 // 0x1f [Interpreted: 32 blocks]
653 assert_eq!(EXAMPLE.erase_sector_size(), 0x1F);
654
655 // Write Protect Group Size:
656 // 0x00 [Interpreted: 1 sectors]
657 assert_eq!(EXAMPLE.write_protect_group_size(), 0x00);
658
659 // Write Protect Group Enable:
660 // 0x0 [Interpreted: No]
661 assert_eq!(EXAMPLE.write_protect_group_enable(), false);
662
663 // Write Speed Factor: block program time as multiple of read access time
664 // 0x5 [Interpreted: x32]
665 assert_eq!(EXAMPLE.write_speed_factor(), 0x5);
666
667 // Max Write Data Block Length:
668 // 0xa [Interpreted: 1024 Bytes]
669 assert_eq!(EXAMPLE.max_write_data_length(), 0xa);
670
671 // Partial Blocks for Write Allowed:
672 // 0x0 [Interpreted: No]
673 assert_eq!(EXAMPLE.write_partial_blocks(), false);
674
675 // File Format Group:
676 // 0b0 [Interpreted: is either Hard Disk with Partition Table/DOS FAT without Partition Table/Universal File Format/Other/Unknown]
677 assert_eq!(EXAMPLE.file_format_group_set(), false);
678
679 // Copy Flag:
680 // 0b0 [Interpreted: Original]
681 assert_eq!(EXAMPLE.copy_flag_set(), false);
682
683 // Permanent Write Protection:
684 // 0b0 [Interpreted: No]
685 assert_eq!(EXAMPLE.permanent_write_protection(), false);
686
687 // Temporary Write Protection:
688 // 0b0 [Interpreted: No]
689 assert_eq!(EXAMPLE.temporary_write_protection(), false);
690
691 // File Format:
692 // 0x0 [Interpreted: Hard Disk with Partition Table]
693 assert_eq!(EXAMPLE.file_format(), 0x00);
694
695 // CRC7 Checksum + always 1 in LSB:
696 // 0x6f
697 assert_eq!(EXAMPLE.crc(), 0x6F);
698
699 assert_eq!(EXAMPLE.card_capacity_bytes(), 1_978_662_912);
700 assert_eq!(EXAMPLE.card_capacity_blocks(), 3_864_576);
701 }
702
703 #[test]
704 fn test_csdv2() {
705 const EXAMPLE: CsdV2 = CsdV2 {
706 data: [
707 0x40, 0x0e, 0x00, 0x32, 0x5b, 0x59, 0x00, 0x00, 0x1d, 0x69, 0x7f, 0x80, 0x0a, 0x40,
708 0x00, 0x8b,
709 ],
710 };
711 // CSD Structure: describes version of CSD structure
712 // 0b01 [Interpreted: Version 2.0 SDHC]
713 assert_eq!(EXAMPLE.csd_ver(), 0x01);
714
715 // Data Read Access Time 1: defines Asynchronous part of the read access time
716 // 0x0e [Interpreted: 1.0 x 1ms]
717 assert_eq!(EXAMPLE.data_read_access_time1(), 0x0E);
718
719 // Data Read Access Time 2: worst case clock dependent factor for data access time
720 // 0x00 [Decimal: 0 x 100 Clocks]
721 assert_eq!(EXAMPLE.data_read_access_time2(), 0x00);
722
723 // Max Data Transfer Rate: sometimes stated as Mhz
724 // 0x32 [Interpreted: 2.5 x 10Mbit/s]
725 assert_eq!(EXAMPLE.max_data_transfer_rate(), 0x32);
726
727 // Card Command Classes:
728 // 0x5b5 [Interpreted: Class 0: Yes. Class 1: No. Class 2: Yes. Class 3: No. Class 4: Yes. Class 5: Yes. Class 6: No. Class 7: Yes. Class 8: Yes. Class 9: No. Class 10: Yes. Class 11: No. ]
729 assert_eq!(EXAMPLE.card_command_classes(), 0x5b5);
730
731 // Max Read Data Block Length:
732 // 0x9 [Interpreted: 512 Bytes]
733 assert_eq!(EXAMPLE.read_block_length(), 0x09);
734
735 // Partial Blocks for Read Allowed:
736 // 0b0 [Interpreted: Yes]
737 assert_eq!(EXAMPLE.read_partial_blocks(), false);
738
739 // Write Block Misalignment:
740 // 0b0 [Interpreted: No]
741 assert_eq!(EXAMPLE.write_block_misalignment(), false);
742
743 // Read Block Misalignment:
744 // 0b0 [Interpreted: No]
745 assert_eq!(EXAMPLE.read_block_misalignment(), false);
746
747 // DSR Implemented: indicates configurable driver stage integrated on card
748 // 0b0 [Interpreted: No]
749 assert_eq!(EXAMPLE.dsr_implemented(), false);
750
751 // Device Size: to calculate the card capacity excl. security area
752 // ((device size + 1)* 512kbytes
753 // 0x001d69 [Decimal: 7529]
754 assert_eq!(EXAMPLE.device_size(), 7529);
755
756 // Erase Single Block Enabled:
757 // 0x1 [Interpreted: Yes]
758 assert_eq!(EXAMPLE.erase_single_block_enabled(), true);
759
760 // Erase Sector Size: size of erasable sector in write blocks
761 // 0x7f [Interpreted: 128 blocks]
762 assert_eq!(EXAMPLE.erase_sector_size(), 0x7F);
763
764 // Write Protect Group Size:
765 // 0x00 [Interpreted: 1 sectors]
766 assert_eq!(EXAMPLE.write_protect_group_size(), 0x00);
767
768 // Write Protect Group Enable:
769 // 0x0 [Interpreted: No]
770 assert_eq!(EXAMPLE.write_protect_group_enable(), false);
771
772 // Write Speed Factor: block program time as multiple of read access time
773 // 0x2 [Interpreted: x4]
774 assert_eq!(EXAMPLE.write_speed_factor(), 0x2);
775
776 // Max Write Data Block Length:
777 // 0x9 [Interpreted: 512 Bytes]
778 assert_eq!(EXAMPLE.max_write_data_length(), 0x9);
779
780 // Partial Blocks for Write Allowed:
781 // 0x0 [Interpreted: No]
782 assert_eq!(EXAMPLE.write_partial_blocks(), false);
783
784 // File Format Group:
785 // 0b0 [Interpreted: is either Hard Disk with Partition Table/DOS FAT without Partition Table/Universal File Format/Other/Unknown]
786 assert_eq!(EXAMPLE.file_format_group_set(), false);
787
788 // Copy Flag:
789 // 0b0 [Interpreted: Original]
790 assert_eq!(EXAMPLE.copy_flag_set(), false);
791
792 // Permanent Write Protection:
793 // 0b0 [Interpreted: No]
794 assert_eq!(EXAMPLE.permanent_write_protection(), false);
795
796 // Temporary Write Protection:
797 // 0b0 [Interpreted: No]
798 assert_eq!(EXAMPLE.temporary_write_protection(), false);
799
800 // File Format:
801 // 0x0 [Interpreted: Hard Disk with Partition Table]
802 assert_eq!(EXAMPLE.file_format(), 0x00);
803
804 // CRC7 Checksum + always 1 in LSB:
805 // 0x8b
806 assert_eq!(EXAMPLE.crc(), 0x8b);
807
808 assert_eq!(EXAMPLE.card_capacity_bytes(), 3_947_888_640);
809 assert_eq!(EXAMPLE.card_capacity_blocks(), 7_710_720);
810 }
811
812 #[test]
813 fn test_csdv2b() {
814 const EXAMPLE: CsdV2 = CsdV2 {
815 data: [
816 0x40, 0x0e, 0x00, 0x32, 0x5b, 0x59, 0x00, 0x00, 0x3a, 0x91, 0x7f, 0x80, 0x0a, 0x40,
817 0x00, 0x05,
818 ],
819 };
820 // CSD Structure: describes version of CSD structure
821 // 0b01 [Interpreted: Version 2.0 SDHC]
822 assert_eq!(EXAMPLE.csd_ver(), 0x01);
823
824 // Data Read Access Time 1: defines Asynchronous part of the read access time
825 // 0x0e [Interpreted: 1.0 x 1ms]
826 assert_eq!(EXAMPLE.data_read_access_time1(), 0x0E);
827
828 // Data Read Access Time 2: worst case clock dependent factor for data access time
829 // 0x00 [Decimal: 0 x 100 Clocks]
830 assert_eq!(EXAMPLE.data_read_access_time2(), 0x00);
831
832 // Max Data Transfer Rate: sometimes stated as Mhz
833 // 0x32 [Interpreted: 2.5 x 10Mbit/s]
834 assert_eq!(EXAMPLE.max_data_transfer_rate(), 0x32);
835
836 // Card Command Classes:
837 // 0x5b5 [Interpreted: Class 0: Yes. Class 1: No. Class 2: Yes. Class 3: No. Class 4: Yes. Class 5: Yes. Class 6: No. Class 7: Yes. Class 8: Yes. Class 9: No. Class 10: Yes. Class 11: No. ]
838 assert_eq!(EXAMPLE.card_command_classes(), 0x5b5);
839
840 // Max Read Data Block Length:
841 // 0x9 [Interpreted: 512 Bytes]
842 assert_eq!(EXAMPLE.read_block_length(), 0x09);
843
844 // Partial Blocks for Read Allowed:
845 // 0b0 [Interpreted: Yes]
846 assert_eq!(EXAMPLE.read_partial_blocks(), false);
847
848 // Write Block Misalignment:
849 // 0b0 [Interpreted: No]
850 assert_eq!(EXAMPLE.write_block_misalignment(), false);
851
852 // Read Block Misalignment:
853 // 0b0 [Interpreted: No]
854 assert_eq!(EXAMPLE.read_block_misalignment(), false);
855
856 // DSR Implemented: indicates configurable driver stage integrated on card
857 // 0b0 [Interpreted: No]
858 assert_eq!(EXAMPLE.dsr_implemented(), false);
859
860 // Device Size: to calculate the card capacity excl. security area
861 // ((device size + 1)* 512kbytes
862 // 0x003a91 [Decimal: 7529]
863 assert_eq!(EXAMPLE.device_size(), 14993);
864
865 // Erase Single Block Enabled:
866 // 0x1 [Interpreted: Yes]
867 assert_eq!(EXAMPLE.erase_single_block_enabled(), true);
868
869 // Erase Sector Size: size of erasable sector in write blocks
870 // 0x7f [Interpreted: 128 blocks]
871 assert_eq!(EXAMPLE.erase_sector_size(), 0x7F);
872
873 // Write Protect Group Size:
874 // 0x00 [Interpreted: 1 sectors]
875 assert_eq!(EXAMPLE.write_protect_group_size(), 0x00);
876
877 // Write Protect Group Enable:
878 // 0x0 [Interpreted: No]
879 assert_eq!(EXAMPLE.write_protect_group_enable(), false);
880
881 // Write Speed Factor: block program time as multiple of read access time
882 // 0x2 [Interpreted: x4]
883 assert_eq!(EXAMPLE.write_speed_factor(), 0x2);
884
885 // Max Write Data Block Length:
886 // 0x9 [Interpreted: 512 Bytes]
887 assert_eq!(EXAMPLE.max_write_data_length(), 0x9);
888
889 // Partial Blocks for Write Allowed:
890 // 0x0 [Interpreted: No]
891 assert_eq!(EXAMPLE.write_partial_blocks(), false);
892
893 // File Format Group:
894 // 0b0 [Interpreted: is either Hard Disk with Partition Table/DOS FAT without Partition Table/Universal File Format/Other/Unknown]
895 assert_eq!(EXAMPLE.file_format_group_set(), false);
896
897 // Copy Flag:
898 // 0b0 [Interpreted: Original]
899 assert_eq!(EXAMPLE.copy_flag_set(), false);
900
901 // Permanent Write Protection:
902 // 0b0 [Interpreted: No]
903 assert_eq!(EXAMPLE.permanent_write_protection(), false);
904
905 // Temporary Write Protection:
906 // 0b0 [Interpreted: No]
907 assert_eq!(EXAMPLE.temporary_write_protection(), false);
908
909 // File Format:
910 // 0x0 [Interpreted: Hard Disk with Partition Table]
911 assert_eq!(EXAMPLE.file_format(), 0x00);
912
913 // CRC7 Checksum + always 1 in LSB:
914 // 0x05
915 assert_eq!(EXAMPLE.crc(), 0x05);
916
917 assert_eq!(EXAMPLE.card_capacity_bytes(), 7_861_174_272);
918 assert_eq!(EXAMPLE.card_capacity_blocks(), 15_353_856);
919 }
920}
921
922// ****************************************************************************
923//
924// End Of File
925//
926// ****************************************************************************