tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/sdcard/csd.go (about)

     1  package sdcard
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  type CSD struct {
     8  	CSD_STRUCTURE      byte   //  2 R  [127:126]   0x01 : CSD Structure
     9  	TAAC               byte   //  8 R  [119:112]   0x0E : Data Read Access-Time-1
    10  	NSAC               byte   //  8 R  [111:104]   0x00 : Data Read Access-Time-2 in CLK Cycles (NSAC*100)
    11  	TRAN_SPEED         byte   //  8 R  [103:96]    0x5A : Max. Data Transfer Rate
    12  	CCC                uint16 // 12 R  [95:84]    0x5B5 : Card Command Classes
    13  	READ_BL_LEN        byte   //  4 R  [83:80]     0x09 : Max. Read Data Block Length
    14  	READ_BL_PARTIAL    byte   //  1 R  [79:79]     0x00 : Partial Blocks for Read Allowed
    15  	WRITE_BLK_MISALIGN byte   //  1 R  [78:78]     0x00 : Write Block Misalignment
    16  	READ_BLK_MISALIGN  byte   //  1 R  [77:77]     0x00 : Read Block Misalignment
    17  	DSR_IMP            byte   //  1 R  [76:76]     0x00 : DSR Implemented
    18  	C_SIZE             uint32 // 22 R  [69:48] 0xXXXXXX : Device Size
    19  	ERASE_BLK_EN       byte   //  1 R  [46:46]     0x01 : Erase Single Block Enable
    20  	SECTOR_SIZE        byte   //  7 R  [45:39]     0x7F : Erase Sector Size
    21  	WP_GRP_SIZE        byte   //  7 R  [38:32]     0x00 : Write Protect Group Size
    22  	WP_GRP_ENABLE      byte   //  1 R  [31:31]     0x00 : Write Protect Group Enable
    23  	R2W_FACTOR         byte   //  3 R  [28:26]     0x02 : Write Speed Factor
    24  	WRITE_BL_LEN       byte   //  4 R  [25:22]     0x09 : Max. Write data Block Length
    25  	WRITE_BL_PARTIAL   byte   //  1 R  [21:21]     0x00 : Partial Blocks for Write Allowed
    26  	FILE_FORMAT_GRP    byte   //  1 R  [15:15]     0x00 : File Format Group
    27  	COPY               byte   //  1 RW [14:14]     0x00 :Copy Flag
    28  	PERM_WRITE_PROTECT byte   //  1 RW [13:13]     0x00 : Permanent Write Protection
    29  	TMP_WRITE_PROTECT  byte   //  1 RW [12:12]     0x00 : Temporary Write Protection
    30  	FILE_FORMAT        byte   //  2 R  [11:10]     0x00 : File Format
    31  	CRC                byte   //  7 RW [7:1]       0xXX : CRC
    32  }
    33  
    34  func NewCSD(buf []byte) *CSD {
    35  	return &CSD{
    36  		CSD_STRUCTURE:      (buf[0] & 0xC0) >> 6,
    37  		TAAC:               buf[1],
    38  		NSAC:               buf[2],
    39  		TRAN_SPEED:         buf[3],
    40  		CCC:                uint16(buf[4])<<4 | uint16(buf[5])>>4,
    41  		READ_BL_LEN:        buf[5] & 0x0F,
    42  		READ_BL_PARTIAL:    (buf[6] & 0x80) >> 7,
    43  		WRITE_BLK_MISALIGN: (buf[6] & 0x40) >> 6,
    44  		READ_BLK_MISALIGN:  (buf[6] & 0x20) >> 5,
    45  		DSR_IMP:            (buf[6] & 0x10) >> 4,
    46  		C_SIZE:             uint32(buf[7]&0x3F)<<16 | uint32(buf[8])<<8 | uint32(buf[9]),
    47  		ERASE_BLK_EN:       (buf[10] & 0x40) >> 6,
    48  		SECTOR_SIZE:        (buf[10]&0x3F)<<1 | (buf[11]&0x80)>>7,
    49  		WP_GRP_SIZE:        buf[11] & 0x7F,
    50  		WP_GRP_ENABLE:      (buf[12] & 0x80) >> 7,
    51  		R2W_FACTOR:         (buf[12] & 0x1C) >> 2,
    52  		WRITE_BL_LEN:       (buf[12]&0x03)<<2 | (buf[13]&0xC0)>>6,
    53  		WRITE_BL_PARTIAL:   (buf[13] & 0x20) >> 5,
    54  		FILE_FORMAT_GRP:    (buf[14] & 0x80) >> 7,
    55  		COPY:               (buf[14] & 0x40) >> 6,
    56  		PERM_WRITE_PROTECT: (buf[14] & 0x20) >> 5,
    57  		TMP_WRITE_PROTECT:  (buf[14] & 0x10) >> 4,
    58  		FILE_FORMAT:        (buf[14] & 0x0C) >> 2,
    59  		CRC:                (buf[15] & 0xFE) >> 1,
    60  	}
    61  }
    62  
    63  func (c *CSD) Dump() {
    64  	fmt.Printf("CSD_STRUCTURE:      %X\r\n", c.CSD_STRUCTURE)
    65  	fmt.Printf("TAAC:               %X\r\n", c.TAAC)
    66  	fmt.Printf("NSAC:               %X\r\n", c.NSAC)
    67  	fmt.Printf("TRAN_SPEED:         %X\r\n", c.TRAN_SPEED)
    68  	fmt.Printf("CCC:                %X\r\n", c.CCC)
    69  	fmt.Printf("READ_BL_LEN:        %X\r\n", c.READ_BL_LEN)
    70  	fmt.Printf("READ_BL_PARTIAL:    %X\r\n", c.READ_BL_PARTIAL)
    71  	fmt.Printf("WRITE_BLK_MISALIGN: %X\r\n", c.WRITE_BLK_MISALIGN)
    72  	fmt.Printf("READ_BLK_MISALIGN:  %X\r\n", c.READ_BLK_MISALIGN)
    73  	fmt.Printf("DSR_IMP:            %X\r\n", c.DSR_IMP)
    74  	fmt.Printf("C_SIZE:             %X\r\n", c.C_SIZE)
    75  	fmt.Printf("ERASE_BLK_EN:       %X\r\n", c.ERASE_BLK_EN)
    76  	fmt.Printf("SECTOR_SIZE:        %X\r\n", c.SECTOR_SIZE)
    77  	fmt.Printf("WP_GRP_SIZE:        %X\r\n", c.WP_GRP_SIZE)
    78  	fmt.Printf("WP_GRP_ENABLE:      %X\r\n", c.WP_GRP_ENABLE)
    79  	fmt.Printf("R2W_FACTOR:         %X\r\n", c.R2W_FACTOR)
    80  	fmt.Printf("WRITE_BL_LEN:       %X\r\n", c.WRITE_BL_LEN)
    81  	fmt.Printf("WRITE_BL_PARTIAL:   %X\r\n", c.WRITE_BL_PARTIAL)
    82  	fmt.Printf("FILE_FORMAT_GRP:    %X\r\n", c.FILE_FORMAT_GRP)
    83  	fmt.Printf("COPY:               %X\r\n", c.COPY)
    84  	fmt.Printf("PERM_WRITE_PROTECT: %X\r\n", c.PERM_WRITE_PROTECT)
    85  	fmt.Printf("TMP_WRITE_PROTECT:  %X\r\n", c.TMP_WRITE_PROTECT)
    86  	fmt.Printf("FILE_FORMAT:        %X\r\n", c.FILE_FORMAT)
    87  	fmt.Printf("CRC:                %X\r\n", c.CRC)
    88  }
    89  
    90  func (c *CSD) Sectors() (int64, error) {
    91  	sectors := int64(0)
    92  	if c.CSD_STRUCTURE == 0x01 {
    93  		// CSD version 2.0
    94  		sectors = (int64(c.C_SIZE) + 1) * 1024
    95  	} else if c.CSD_STRUCTURE == 0x00 {
    96  		// CSD version 1.0 (old, <=2GB)
    97  		return 0, fmt.Errorf("CSD format version 1.0 is not supported")
    98  	} else {
    99  		return 0, fmt.Errorf("unknown CSD format")
   100  	}
   101  	return sectors, nil
   102  }
   103  
   104  func (c *CSD) Size() uint64 {
   105  	return uint64(c.C_SIZE) * 512 * 1024
   106  }