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 }