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// ****************************************************************************