hi
Dependencies: FreescaleIAP mbed-rtos mbed
cdms_sd.cpp@0:bcbd76c86cde, 2015-12-16 (annotated)
- Committer:
- cholletisaik777
- Date:
- Wed Dec 16 09:06:59 2015 +0000
- Revision:
- 0:bcbd76c86cde
nnb
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cholletisaik777 | 0:bcbd76c86cde | 1 | #include "cdms_sd.h" |
cholletisaik777 | 0:bcbd76c86cde | 2 | |
cholletisaik777 | 0:bcbd76c86cde | 3 | SPI spi_sd(PTE1, PTE3, PTE2); // MOSI,MISO, CLOCK microcontroller(in order) |
cholletisaik777 | 0:bcbd76c86cde | 4 | DigitalOut cs_sd(PTE22); |
cholletisaik777 | 0:bcbd76c86cde | 5 | |
cholletisaik777 | 0:bcbd76c86cde | 6 | Serial sd1(USBTX,USBRX); |
cholletisaik777 | 0:bcbd76c86cde | 7 | |
cholletisaik777 | 0:bcbd76c86cde | 8 | int cdv; |
cholletisaik777 | 0:bcbd76c86cde | 9 | uint64_t sd_sectors(); |
cholletisaik777 | 0:bcbd76c86cde | 10 | uint64_t sectors; |
cholletisaik777 | 0:bcbd76c86cde | 11 | |
cholletisaik777 | 0:bcbd76c86cde | 12 | void FCTN_SD_MNGR() |
cholletisaik777 | 0:bcbd76c86cde | 13 | { |
cholletisaik777 | 0:bcbd76c86cde | 14 | /*Size of block of SD card for 2GB = 512B, 4 , 8 GB SD card. We will prefer 8 GB. |
cholletisaik777 | 0:bcbd76c86cde | 15 | SD allocation. Assuming 8GB |
cholletisaik777 | 0:bcbd76c86cde | 16 | SCP: 600 MB -122880 |
cholletisaik777 | 0:bcbd76c86cde | 17 | SFF-AT: 2 GB -4194304 |
cholletisaik777 | 0:bcbd76c86cde | 18 | SFF-BT: 5 GB -10485760 |
cholletisaik777 | 0:bcbd76c86cde | 19 | HK-ARCH:100 MB -204800 |
cholletisaik777 | 0:bcbd76c86cde | 20 | LOG: 50MB -102400 |
cholletisaik777 | 0:bcbd76c86cde | 21 | SD card management: 50MB - 102400*/ |
cholletisaik777 | 0:bcbd76c86cde | 22 | |
cholletisaik777 | 0:bcbd76c86cde | 23 | } |
cholletisaik777 | 0:bcbd76c86cde | 24 | int initialise_card() |
cholletisaik777 | 0:bcbd76c86cde | 25 | { |
cholletisaik777 | 0:bcbd76c86cde | 26 | // Set to 100kHz for initialisation, and clock card with cs_sd = 1 |
cholletisaik777 | 0:bcbd76c86cde | 27 | spi_sd.frequency(100000); |
cholletisaik777 | 0:bcbd76c86cde | 28 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 29 | for (int i = 0; i < 16; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 30 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 31 | } |
cholletisaik777 | 0:bcbd76c86cde | 32 | |
cholletisaik777 | 0:bcbd76c86cde | 33 | // send CMD0, should return with all zeros except IDLE STATE set (bit 0) |
cholletisaik777 | 0:bcbd76c86cde | 34 | if (cmd(0, 0) != R1_IDLE_STATE) { |
cholletisaik777 | 0:bcbd76c86cde | 35 | debug("No disk, or could not put SD card in to spi_sd idle state\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 36 | return SDCARD_FAIL; |
cholletisaik777 | 0:bcbd76c86cde | 37 | } |
cholletisaik777 | 0:bcbd76c86cde | 38 | |
cholletisaik777 | 0:bcbd76c86cde | 39 | // send CMD8 to determine whther it is ver 2.x |
cholletisaik777 | 0:bcbd76c86cde | 40 | int r = cmd8(); |
cholletisaik777 | 0:bcbd76c86cde | 41 | if (r == R1_IDLE_STATE) { |
cholletisaik777 | 0:bcbd76c86cde | 42 | printf("\rEntering v2\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 43 | return initialise_card_v2(); |
cholletisaik777 | 0:bcbd76c86cde | 44 | |
cholletisaik777 | 0:bcbd76c86cde | 45 | } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { |
cholletisaik777 | 0:bcbd76c86cde | 46 | printf("\rEntering v1\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 47 | return initialise_card_v1(); |
cholletisaik777 | 0:bcbd76c86cde | 48 | |
cholletisaik777 | 0:bcbd76c86cde | 49 | } else { |
cholletisaik777 | 0:bcbd76c86cde | 50 | debug("\rNot in idle state after sending CMD8 (not an SD card?)\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 51 | return SDCARD_FAIL; |
cholletisaik777 | 0:bcbd76c86cde | 52 | } |
cholletisaik777 | 0:bcbd76c86cde | 53 | } |
cholletisaik777 | 0:bcbd76c86cde | 54 | |
cholletisaik777 | 0:bcbd76c86cde | 55 | int initialise_card_v1() |
cholletisaik777 | 0:bcbd76c86cde | 56 | { |
cholletisaik777 | 0:bcbd76c86cde | 57 | for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 58 | cmd(55, 0); |
cholletisaik777 | 0:bcbd76c86cde | 59 | if (cmd(41, 0) == 0) { |
cholletisaik777 | 0:bcbd76c86cde | 60 | printf("\rv1 initialization successfull\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 61 | cdv = 512; |
cholletisaik777 | 0:bcbd76c86cde | 62 | debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r"); |
cholletisaik777 | 0:bcbd76c86cde | 63 | |
cholletisaik777 | 0:bcbd76c86cde | 64 | return SDCARD_V1; |
cholletisaik777 | 0:bcbd76c86cde | 65 | } |
cholletisaik777 | 0:bcbd76c86cde | 66 | } |
cholletisaik777 | 0:bcbd76c86cde | 67 | |
cholletisaik777 | 0:bcbd76c86cde | 68 | debug("\rTimeout waiting for v1.x card\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 69 | return SDCARD_FAIL; |
cholletisaik777 | 0:bcbd76c86cde | 70 | } |
cholletisaik777 | 0:bcbd76c86cde | 71 | |
cholletisaik777 | 0:bcbd76c86cde | 72 | |
cholletisaik777 | 0:bcbd76c86cde | 73 | int initialise_card_v2() |
cholletisaik777 | 0:bcbd76c86cde | 74 | { |
cholletisaik777 | 0:bcbd76c86cde | 75 | for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 76 | wait_ms(50); |
cholletisaik777 | 0:bcbd76c86cde | 77 | cmd58(); |
cholletisaik777 | 0:bcbd76c86cde | 78 | cmd(55, 0); |
cholletisaik777 | 0:bcbd76c86cde | 79 | if (cmd(41, 0x40000000) == 0) { |
cholletisaik777 | 0:bcbd76c86cde | 80 | printf("\rv2 initialization successfull\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 81 | cmd58(); |
cholletisaik777 | 0:bcbd76c86cde | 82 | debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r"); |
cholletisaik777 | 0:bcbd76c86cde | 83 | cdv = 1; |
cholletisaik777 | 0:bcbd76c86cde | 84 | |
cholletisaik777 | 0:bcbd76c86cde | 85 | return SDCARD_V2; |
cholletisaik777 | 0:bcbd76c86cde | 86 | } |
cholletisaik777 | 0:bcbd76c86cde | 87 | } |
cholletisaik777 | 0:bcbd76c86cde | 88 | |
cholletisaik777 | 0:bcbd76c86cde | 89 | debug("\rTimeout waiting for v2.x card\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 90 | return SDCARD_FAIL; |
cholletisaik777 | 0:bcbd76c86cde | 91 | } |
cholletisaik777 | 0:bcbd76c86cde | 92 | |
cholletisaik777 | 0:bcbd76c86cde | 93 | int cmd(int cmd, int arg) |
cholletisaik777 | 0:bcbd76c86cde | 94 | { |
cholletisaik777 | 0:bcbd76c86cde | 95 | cs_sd = 0; |
cholletisaik777 | 0:bcbd76c86cde | 96 | |
cholletisaik777 | 0:bcbd76c86cde | 97 | // send a command |
cholletisaik777 | 0:bcbd76c86cde | 98 | spi_sd.write(0x40 | cmd); |
cholletisaik777 | 0:bcbd76c86cde | 99 | spi_sd.write(arg >> 24); |
cholletisaik777 | 0:bcbd76c86cde | 100 | spi_sd.write(arg >> 16); |
cholletisaik777 | 0:bcbd76c86cde | 101 | spi_sd.write(arg >> 8); |
cholletisaik777 | 0:bcbd76c86cde | 102 | spi_sd.write(arg >> 0); |
cholletisaik777 | 0:bcbd76c86cde | 103 | spi_sd.write(0x95); |
cholletisaik777 | 0:bcbd76c86cde | 104 | |
cholletisaik777 | 0:bcbd76c86cde | 105 | // wait for the repsonse (response[7] == 0) |
cholletisaik777 | 0:bcbd76c86cde | 106 | for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 107 | int response = spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 108 | if (!(response & 0x80)) { |
cholletisaik777 | 0:bcbd76c86cde | 109 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 110 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 111 | return response; |
cholletisaik777 | 0:bcbd76c86cde | 112 | } |
cholletisaik777 | 0:bcbd76c86cde | 113 | } |
cholletisaik777 | 0:bcbd76c86cde | 114 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 115 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 116 | return -1; // timeout |
cholletisaik777 | 0:bcbd76c86cde | 117 | } |
cholletisaik777 | 0:bcbd76c86cde | 118 | |
cholletisaik777 | 0:bcbd76c86cde | 119 | |
cholletisaik777 | 0:bcbd76c86cde | 120 | int cmd58() |
cholletisaik777 | 0:bcbd76c86cde | 121 | { |
cholletisaik777 | 0:bcbd76c86cde | 122 | cs_sd = 0; |
cholletisaik777 | 0:bcbd76c86cde | 123 | int arg = 0; |
cholletisaik777 | 0:bcbd76c86cde | 124 | |
cholletisaik777 | 0:bcbd76c86cde | 125 | // send a command |
cholletisaik777 | 0:bcbd76c86cde | 126 | spi_sd.write(0x40 | 58); |
cholletisaik777 | 0:bcbd76c86cde | 127 | spi_sd.write(arg >> 24); |
cholletisaik777 | 0:bcbd76c86cde | 128 | spi_sd.write(arg >> 16); |
cholletisaik777 | 0:bcbd76c86cde | 129 | spi_sd.write(arg >> 8); |
cholletisaik777 | 0:bcbd76c86cde | 130 | spi_sd.write(arg >> 0); |
cholletisaik777 | 0:bcbd76c86cde | 131 | spi_sd.write(0x95); |
cholletisaik777 | 0:bcbd76c86cde | 132 | |
cholletisaik777 | 0:bcbd76c86cde | 133 | // wait for the repsonse (response[7] == 0) |
cholletisaik777 | 0:bcbd76c86cde | 134 | for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 135 | int response = spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 136 | if (!(response & 0x80)) { |
cholletisaik777 | 0:bcbd76c86cde | 137 | int ocr = spi_sd.write(0xFF) << 24; |
cholletisaik777 | 0:bcbd76c86cde | 138 | ocr |= spi_sd.write(0xFF) << 16; |
cholletisaik777 | 0:bcbd76c86cde | 139 | ocr |= spi_sd.write(0xFF) << 8; |
cholletisaik777 | 0:bcbd76c86cde | 140 | ocr |= spi_sd.write(0xFF) << 0; |
cholletisaik777 | 0:bcbd76c86cde | 141 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 142 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 143 | return response; |
cholletisaik777 | 0:bcbd76c86cde | 144 | } |
cholletisaik777 | 0:bcbd76c86cde | 145 | } |
cholletisaik777 | 0:bcbd76c86cde | 146 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 147 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 148 | return -1; // timeout |
cholletisaik777 | 0:bcbd76c86cde | 149 | } |
cholletisaik777 | 0:bcbd76c86cde | 150 | |
cholletisaik777 | 0:bcbd76c86cde | 151 | |
cholletisaik777 | 0:bcbd76c86cde | 152 | int cmd8() |
cholletisaik777 | 0:bcbd76c86cde | 153 | { |
cholletisaik777 | 0:bcbd76c86cde | 154 | cs_sd = 0; |
cholletisaik777 | 0:bcbd76c86cde | 155 | |
cholletisaik777 | 0:bcbd76c86cde | 156 | // send a command |
cholletisaik777 | 0:bcbd76c86cde | 157 | spi_sd.write(0x40 | 8); // CMD8 |
cholletisaik777 | 0:bcbd76c86cde | 158 | spi_sd.write(0x00); // reserved |
cholletisaik777 | 0:bcbd76c86cde | 159 | spi_sd.write(0x00); // reserved |
cholletisaik777 | 0:bcbd76c86cde | 160 | spi_sd.write(0x01); // 3.3v |
cholletisaik777 | 0:bcbd76c86cde | 161 | spi_sd.write(0xAA); // check pattern |
cholletisaik777 | 0:bcbd76c86cde | 162 | spi_sd.write(0x87); // crc |
cholletisaik777 | 0:bcbd76c86cde | 163 | |
cholletisaik777 | 0:bcbd76c86cde | 164 | // wait for the repsonse (response[7] == 0) |
cholletisaik777 | 0:bcbd76c86cde | 165 | for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 166 | char response[5]; |
cholletisaik777 | 0:bcbd76c86cde | 167 | response[0] = spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 168 | if (!(response[0] & 0x80)) { |
cholletisaik777 | 0:bcbd76c86cde | 169 | for (int j = 1; j < 5; j++) { |
cholletisaik777 | 0:bcbd76c86cde | 170 | response[i] = spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 171 | } |
cholletisaik777 | 0:bcbd76c86cde | 172 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 173 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 174 | return response[0]; |
cholletisaik777 | 0:bcbd76c86cde | 175 | } |
cholletisaik777 | 0:bcbd76c86cde | 176 | } |
cholletisaik777 | 0:bcbd76c86cde | 177 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 178 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 179 | return -1; // timeout |
cholletisaik777 | 0:bcbd76c86cde | 180 | } |
cholletisaik777 | 0:bcbd76c86cde | 181 | |
cholletisaik777 | 0:bcbd76c86cde | 182 | uint64_t sd_sectors() |
cholletisaik777 | 0:bcbd76c86cde | 183 | { |
cholletisaik777 | 0:bcbd76c86cde | 184 | uint32_t c_size, c_size_mult, read_bl_len; |
cholletisaik777 | 0:bcbd76c86cde | 185 | uint32_t block_len, mult, blocknr, capacity; |
cholletisaik777 | 0:bcbd76c86cde | 186 | uint32_t hc_c_size; |
cholletisaik777 | 0:bcbd76c86cde | 187 | uint64_t blocks; |
cholletisaik777 | 0:bcbd76c86cde | 188 | |
cholletisaik777 | 0:bcbd76c86cde | 189 | // CMD9, Response R2 (R1 byte + 16-byte block read) |
cholletisaik777 | 0:bcbd76c86cde | 190 | if (cmdx(9, 0) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 191 | debug("\rDidn't get a response from the disk\n"); |
cholletisaik777 | 0:bcbd76c86cde | 192 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 193 | } |
cholletisaik777 | 0:bcbd76c86cde | 194 | |
cholletisaik777 | 0:bcbd76c86cde | 195 | uint8_t cs_sdd[16]; |
cholletisaik777 | 0:bcbd76c86cde | 196 | if (read(cs_sdd, 16) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 197 | debug("\rCouldn't read cs_sdd response from disk\n"); |
cholletisaik777 | 0:bcbd76c86cde | 198 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 199 | } |
cholletisaik777 | 0:bcbd76c86cde | 200 | |
cholletisaik777 | 0:bcbd76c86cde | 201 | // cs_sdd_structure : cs_sdd[127:126] |
cholletisaik777 | 0:bcbd76c86cde | 202 | // c_size : cs_sdd[73:62] |
cholletisaik777 | 0:bcbd76c86cde | 203 | // c_size_mult : cs_sdd[49:47] |
cholletisaik777 | 0:bcbd76c86cde | 204 | // read_bl_len : cs_sdd[83:80] - the *maximum* read block length |
cholletisaik777 | 0:bcbd76c86cde | 205 | |
cholletisaik777 | 0:bcbd76c86cde | 206 | int cs_sdd_structure = ext_bits(cs_sdd, 127, 126); |
cholletisaik777 | 0:bcbd76c86cde | 207 | |
cholletisaik777 | 0:bcbd76c86cde | 208 | switch (cs_sdd_structure) { |
cholletisaik777 | 0:bcbd76c86cde | 209 | case 0: |
cholletisaik777 | 0:bcbd76c86cde | 210 | cdv = 512; |
cholletisaik777 | 0:bcbd76c86cde | 211 | c_size = ext_bits(cs_sdd, 73, 62); |
cholletisaik777 | 0:bcbd76c86cde | 212 | c_size_mult = ext_bits(cs_sdd, 49, 47); |
cholletisaik777 | 0:bcbd76c86cde | 213 | read_bl_len = ext_bits(cs_sdd, 83, 80); |
cholletisaik777 | 0:bcbd76c86cde | 214 | |
cholletisaik777 | 0:bcbd76c86cde | 215 | block_len = 1 << read_bl_len; |
cholletisaik777 | 0:bcbd76c86cde | 216 | mult = 1 << (c_size_mult + 2); |
cholletisaik777 | 0:bcbd76c86cde | 217 | blocknr = (c_size + 1) * mult; |
cholletisaik777 | 0:bcbd76c86cde | 218 | capacity = blocknr * block_len; |
cholletisaik777 | 0:bcbd76c86cde | 219 | blocks = capacity / 512; |
cholletisaik777 | 0:bcbd76c86cde | 220 | debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks); |
cholletisaik777 | 0:bcbd76c86cde | 221 | break; |
cholletisaik777 | 0:bcbd76c86cde | 222 | |
cholletisaik777 | 0:bcbd76c86cde | 223 | case 1: |
cholletisaik777 | 0:bcbd76c86cde | 224 | cdv = 1; |
cholletisaik777 | 0:bcbd76c86cde | 225 | hc_c_size = ext_bits(cs_sdd, 63, 48); |
cholletisaik777 | 0:bcbd76c86cde | 226 | blocks = (hc_c_size+1)*1024; |
cholletisaik777 | 0:bcbd76c86cde | 227 | debug_if(SD_DBG, "\n\rSDHC Card \n\rhc_c_size: %d\n\rcapacity: %lld \n\rsectors: %lld\n\r", hc_c_size, blocks*512, blocks); |
cholletisaik777 | 0:bcbd76c86cde | 228 | break; |
cholletisaik777 | 0:bcbd76c86cde | 229 | |
cholletisaik777 | 0:bcbd76c86cde | 230 | default: |
cholletisaik777 | 0:bcbd76c86cde | 231 | debug("cs_sdD struct unsupported\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 232 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 233 | }; |
cholletisaik777 | 0:bcbd76c86cde | 234 | return blocks; |
cholletisaik777 | 0:bcbd76c86cde | 235 | } |
cholletisaik777 | 0:bcbd76c86cde | 236 | |
cholletisaik777 | 0:bcbd76c86cde | 237 | int cmdx(int cmd, int arg) |
cholletisaik777 | 0:bcbd76c86cde | 238 | { |
cholletisaik777 | 0:bcbd76c86cde | 239 | cs_sd = 0; |
cholletisaik777 | 0:bcbd76c86cde | 240 | |
cholletisaik777 | 0:bcbd76c86cde | 241 | // send a command |
cholletisaik777 | 0:bcbd76c86cde | 242 | spi_sd.write(0x40 | cmd); |
cholletisaik777 | 0:bcbd76c86cde | 243 | spi_sd.write(arg >> 24); |
cholletisaik777 | 0:bcbd76c86cde | 244 | spi_sd.write(arg >> 16); |
cholletisaik777 | 0:bcbd76c86cde | 245 | spi_sd.write(arg >> 8); |
cholletisaik777 | 0:bcbd76c86cde | 246 | spi_sd.write(arg >> 0); |
cholletisaik777 | 0:bcbd76c86cde | 247 | spi_sd.write(0x95); |
cholletisaik777 | 0:bcbd76c86cde | 248 | |
cholletisaik777 | 0:bcbd76c86cde | 249 | // wait for the repsonse (response[7] == 0) |
cholletisaik777 | 0:bcbd76c86cde | 250 | for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 251 | int response = spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 252 | if (!(response & 0x80)) { |
cholletisaik777 | 0:bcbd76c86cde | 253 | return response; |
cholletisaik777 | 0:bcbd76c86cde | 254 | } |
cholletisaik777 | 0:bcbd76c86cde | 255 | } |
cholletisaik777 | 0:bcbd76c86cde | 256 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 257 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 258 | return -1; // timeout |
cholletisaik777 | 0:bcbd76c86cde | 259 | } |
cholletisaik777 | 0:bcbd76c86cde | 260 | |
cholletisaik777 | 0:bcbd76c86cde | 261 | static uint32_t ext_bits(unsigned char *data, int msb, int lsb) |
cholletisaik777 | 0:bcbd76c86cde | 262 | { |
cholletisaik777 | 0:bcbd76c86cde | 263 | uint32_t bits = 0; |
cholletisaik777 | 0:bcbd76c86cde | 264 | uint32_t size = 1 + msb - lsb; |
cholletisaik777 | 0:bcbd76c86cde | 265 | for (int i = 0; i < size; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 266 | uint32_t position = lsb + i; |
cholletisaik777 | 0:bcbd76c86cde | 267 | uint32_t byte = 15 - (position >> 3); |
cholletisaik777 | 0:bcbd76c86cde | 268 | uint32_t bit = position & 0x7; |
cholletisaik777 | 0:bcbd76c86cde | 269 | uint32_t value = (data[byte] >> bit) & 1; |
cholletisaik777 | 0:bcbd76c86cde | 270 | bits |= value << i; |
cholletisaik777 | 0:bcbd76c86cde | 271 | } |
cholletisaik777 | 0:bcbd76c86cde | 272 | return bits; |
cholletisaik777 | 0:bcbd76c86cde | 273 | } |
cholletisaik777 | 0:bcbd76c86cde | 274 | |
cholletisaik777 | 0:bcbd76c86cde | 275 | int disk_initialize() |
cholletisaik777 | 0:bcbd76c86cde | 276 | { |
cholletisaik777 | 0:bcbd76c86cde | 277 | int i = initialise_card(); |
cholletisaik777 | 0:bcbd76c86cde | 278 | debug_if(SD_DBG, "init card = %d\n", i); |
cholletisaik777 | 0:bcbd76c86cde | 279 | sectors = sd_sectors(); |
cholletisaik777 | 0:bcbd76c86cde | 280 | |
cholletisaik777 | 0:bcbd76c86cde | 281 | // Set block length to 512 (CMD16) |
cholletisaik777 | 0:bcbd76c86cde | 282 | if (cmd(16, 512) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 283 | debug("\rSet 512-byte block timed out\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 284 | return 1; |
cholletisaik777 | 0:bcbd76c86cde | 285 | } else { |
cholletisaik777 | 0:bcbd76c86cde | 286 | printf("\rDisk initialization successfull\r\n"); |
cholletisaik777 | 0:bcbd76c86cde | 287 | } |
cholletisaik777 | 0:bcbd76c86cde | 288 | |
cholletisaik777 | 0:bcbd76c86cde | 289 | spi_sd.frequency(1000000); // Set to 1MHz for data transfer |
cholletisaik777 | 0:bcbd76c86cde | 290 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 291 | } |
cholletisaik777 | 0:bcbd76c86cde | 292 | |
cholletisaik777 | 0:bcbd76c86cde | 293 | int disk_write(const uint8_t *buffer, uint64_t block_number) |
cholletisaik777 | 0:bcbd76c86cde | 294 | |
cholletisaik777 | 0:bcbd76c86cde | 295 | { |
cholletisaik777 | 0:bcbd76c86cde | 296 | // set write address for single block (CMD24) |
cholletisaik777 | 0:bcbd76c86cde | 297 | if (cmd(24, block_number * cdv) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 298 | return 1; |
cholletisaik777 | 0:bcbd76c86cde | 299 | } |
cholletisaik777 | 0:bcbd76c86cde | 300 | |
cholletisaik777 | 0:bcbd76c86cde | 301 | // send the data block |
cholletisaik777 | 0:bcbd76c86cde | 302 | write(buffer, 512); |
cholletisaik777 | 0:bcbd76c86cde | 303 | //printf("Written Successfully bro \n"); |
cholletisaik777 | 0:bcbd76c86cde | 304 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 305 | } |
cholletisaik777 | 0:bcbd76c86cde | 306 | |
cholletisaik777 | 0:bcbd76c86cde | 307 | int write(const uint8_t*buffer, uint32_t length) |
cholletisaik777 | 0:bcbd76c86cde | 308 | { |
cholletisaik777 | 0:bcbd76c86cde | 309 | cs_sd = 0; |
cholletisaik777 | 0:bcbd76c86cde | 310 | |
cholletisaik777 | 0:bcbd76c86cde | 311 | // indicate start of block |
cholletisaik777 | 0:bcbd76c86cde | 312 | spi_sd.write(0xFE); |
cholletisaik777 | 0:bcbd76c86cde | 313 | |
cholletisaik777 | 0:bcbd76c86cde | 314 | // write the data |
cholletisaik777 | 0:bcbd76c86cde | 315 | for (int i = 0; i < length; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 316 | spi_sd.write(buffer[i]); |
cholletisaik777 | 0:bcbd76c86cde | 317 | } |
cholletisaik777 | 0:bcbd76c86cde | 318 | |
cholletisaik777 | 0:bcbd76c86cde | 319 | // write the checksum |
cholletisaik777 | 0:bcbd76c86cde | 320 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 321 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 322 | |
cholletisaik777 | 0:bcbd76c86cde | 323 | // check the response token |
cholletisaik777 | 0:bcbd76c86cde | 324 | if ((spi_sd.write(0xFF) & 0x1F) != 0x05) { |
cholletisaik777 | 0:bcbd76c86cde | 325 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 326 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 327 | return 1; |
cholletisaik777 | 0:bcbd76c86cde | 328 | } |
cholletisaik777 | 0:bcbd76c86cde | 329 | |
cholletisaik777 | 0:bcbd76c86cde | 330 | // wait for write to finish |
cholletisaik777 | 0:bcbd76c86cde | 331 | while (spi_sd.write(0xFF) == 0); |
cholletisaik777 | 0:bcbd76c86cde | 332 | |
cholletisaik777 | 0:bcbd76c86cde | 333 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 334 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 335 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 336 | } |
cholletisaik777 | 0:bcbd76c86cde | 337 | |
cholletisaik777 | 0:bcbd76c86cde | 338 | int disk_read(uint8_t *buffer, uint64_t block_number) |
cholletisaik777 | 0:bcbd76c86cde | 339 | { |
cholletisaik777 | 0:bcbd76c86cde | 340 | // set read address for single block (CMD17) |
cholletisaik777 | 0:bcbd76c86cde | 341 | if (cmd(17, block_number * cdv) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 342 | return 1; |
cholletisaik777 | 0:bcbd76c86cde | 343 | } |
cholletisaik777 | 0:bcbd76c86cde | 344 | |
cholletisaik777 | 0:bcbd76c86cde | 345 | // receive the data |
cholletisaik777 | 0:bcbd76c86cde | 346 | read(buffer, 512); |
cholletisaik777 | 0:bcbd76c86cde | 347 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 348 | } |
cholletisaik777 | 0:bcbd76c86cde | 349 | |
cholletisaik777 | 0:bcbd76c86cde | 350 | int read(uint8_t *buffer, uint32_t length) |
cholletisaik777 | 0:bcbd76c86cde | 351 | { |
cholletisaik777 | 0:bcbd76c86cde | 352 | cs_sd = 0; |
cholletisaik777 | 0:bcbd76c86cde | 353 | |
cholletisaik777 | 0:bcbd76c86cde | 354 | // read until start byte (0xFF) |
cholletisaik777 | 0:bcbd76c86cde | 355 | while (spi_sd.write(0xFF) != 0xFE); |
cholletisaik777 | 0:bcbd76c86cde | 356 | |
cholletisaik777 | 0:bcbd76c86cde | 357 | // read data |
cholletisaik777 | 0:bcbd76c86cde | 358 | for (int i = 0; i < length; i++) { |
cholletisaik777 | 0:bcbd76c86cde | 359 | buffer[i] = spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 360 | } |
cholletisaik777 | 0:bcbd76c86cde | 361 | spi_sd.write(0xFF); // checksum |
cholletisaik777 | 0:bcbd76c86cde | 362 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 363 | |
cholletisaik777 | 0:bcbd76c86cde | 364 | cs_sd = 1; |
cholletisaik777 | 0:bcbd76c86cde | 365 | spi_sd.write(0xFF); |
cholletisaik777 | 0:bcbd76c86cde | 366 | return 0; |
cholletisaik777 | 0:bcbd76c86cde | 367 | } |
cholletisaik777 | 0:bcbd76c86cde | 368 | |
cholletisaik777 | 0:bcbd76c86cde | 369 | int disk_erase(int startBlock, int totalBlocks) |
cholletisaik777 | 0:bcbd76c86cde | 370 | { |
cholletisaik777 | 0:bcbd76c86cde | 371 | if(cmd(32, startBlock * cdv) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 372 | return 1; |
cholletisaik777 | 0:bcbd76c86cde | 373 | } |
cholletisaik777 | 0:bcbd76c86cde | 374 | if (cmd(33, (startBlock+totalBlocks-1) * cdv) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 375 | return 1; |
cholletisaik777 | 0:bcbd76c86cde | 376 | } |
cholletisaik777 | 0:bcbd76c86cde | 377 | if (cmd(38,0) != 0) { |
cholletisaik777 | 0:bcbd76c86cde | 378 | return 1; |
cholletisaik777 | 0:bcbd76c86cde | 379 | } |
cholletisaik777 | 0:bcbd76c86cde | 380 | |
cholletisaik777 | 0:bcbd76c86cde | 381 | return 0; //normal return |
cholletisaik777 | 0:bcbd76c86cde | 382 | } |