nlknlknln

Dependencies:   mbed

Fork of raw_sd_card_readsaswell by Pradeep Kotipalli

Committer:
pradeepvk2208
Date:
Mon Jun 15 13:37:24 2015 +0000
Revision:
6:09923c817679
Parent:
5:e13062be9e7b
sd_card_raw

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pradeepvk2208 0:d4197e4552ea 1 #include "mbed.h"
pradeepvk2208 0:d4197e4552ea 2 #include "mbed_debug.h"
pradeepvk2208 0:d4197e4552ea 3
pradeepvk2208 0:d4197e4552ea 4 #define SD_COMMAND_TIMEOUT 5000
pradeepvk2208 0:d4197e4552ea 5
pradeepvk2208 0:d4197e4552ea 6 #define SD_DBG 0
pradeepvk2208 0:d4197e4552ea 7
pradeepvk2208 0:d4197e4552ea 8 #define R1_IDLE_STATE (1 << 0)
pradeepvk2208 0:d4197e4552ea 9 #define R1_ERASE_RESET (1 << 1)
pradeepvk2208 0:d4197e4552ea 10 #define R1_ILLEGAL_COMMAND (1 << 2)
pradeepvk2208 0:d4197e4552ea 11 #define R1_COM_CRC_ERROR (1 << 3)
pradeepvk2208 0:d4197e4552ea 12 #define R1_ERASE_SEQUENCE_ERROR (1 << 4)
pradeepvk2208 0:d4197e4552ea 13 #define R1_ADDRESS_ERROR (1 << 5)
pradeepvk2208 0:d4197e4552ea 14 #define R1_PARAMETER_ERROR (1 << 6)
pradeepvk2208 0:d4197e4552ea 15
pradeepvk2208 0:d4197e4552ea 16 int initialise_card();
pradeepvk2208 0:d4197e4552ea 17 int initialise_card_v1();
pradeepvk2208 0:d4197e4552ea 18 int initialise_card_v2();
pradeepvk2208 2:aea18e9b89d8 19 int disk_initialize();
pradeepvk2208 3:d4bb1e13a897 20 int disk_write(const uint8_t *, uint64_t);
pradeepvk2208 4:003e6dfc288d 21 int disk_read(uint8_t *, uint64_t);
pradeepvk2208 3:d4bb1e13a897 22
pradeepvk2208 2:aea18e9b89d8 23 uint64_t sd_sectors();
pradeepvk2208 2:aea18e9b89d8 24 uint64_t sectors;
pradeepvk2208 2:aea18e9b89d8 25
pradeepvk2208 0:d4197e4552ea 26 int cmd(int, int);
pradeepvk2208 0:d4197e4552ea 27 int cmd58();
pradeepvk2208 2:aea18e9b89d8 28 int cmdx(int, int);
pradeepvk2208 0:d4197e4552ea 29 int cmd8();
pradeepvk2208 2:aea18e9b89d8 30 int read(uint8_t*, uint32_t );
pradeepvk2208 3:d4bb1e13a897 31 int write(const uint8_t*, uint32_t );
pradeepvk2208 2:aea18e9b89d8 32 static uint32_t ext_bits(unsigned char *, int , int );
pradeepvk2208 0:d4197e4552ea 33
pradeepvk2208 0:d4197e4552ea 34 int cdv;
pradeepvk2208 0:d4197e4552ea 35
pradeepvk2208 0:d4197e4552ea 36 #define SDCARD_FAIL 0
pradeepvk2208 0:d4197e4552ea 37 #define SDCARD_V1 1
pradeepvk2208 0:d4197e4552ea 38 #define SDCARD_V2 2
pradeepvk2208 0:d4197e4552ea 39 #define SDCARD_V2HC 3
pradeepvk2208 0:d4197e4552ea 40
pradeepvk2208 0:d4197e4552ea 41
pradeepvk2208 0:d4197e4552ea 42
pradeepvk2208 0:d4197e4552ea 43 SPI spi(PTD6, PTD7, PTD5); // mosi, miso, sclk
pradeepvk2208 0:d4197e4552ea 44 DigitalOut cs(PTD2);
pradeepvk2208 3:d4bb1e13a897 45 int count_bro;
pradeepvk2208 6:09923c817679 46 char alpha[26]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y',' '};
pradeepvk2208 5:e13062be9e7b 47 int block_number;
pradeepvk2208 0:d4197e4552ea 48
pradeepvk2208 0:d4197e4552ea 49
pradeepvk2208 0:d4197e4552ea 50 int main()
pradeepvk2208 0:d4197e4552ea 51 {
pradeepvk2208 6:09923c817679 52 Timer t;
pradeepvk2208 3:d4bb1e13a897 53
pradeepvk2208 3:d4bb1e13a897 54 initialise_card();
pradeepvk2208 0:d4197e4552ea 55 int result= initialise_card();
pradeepvk2208 6:09923c817679 56 printf("initialise card result=%d \r\n",result);
pradeepvk2208 2:aea18e9b89d8 57 disk_initialize();
pradeepvk2208 3:d4bb1e13a897 58 uint8_t buffer[512];
pradeepvk2208 6:09923c817679 59
pradeepvk2208 5:e13062be9e7b 60 for(block_number=0;block_number<100;block_number++)
pradeepvk2208 5:e13062be9e7b 61 { for(count_bro=0;count_bro<512;count_bro++)
pradeepvk2208 5:e13062be9e7b 62 {buffer[count_bro]= alpha[rand () % 26];}
pradeepvk2208 6:09923c817679 63 t.start();
pradeepvk2208 6:09923c817679 64 disk_write(buffer, block_number);
pradeepvk2208 6:09923c817679 65 t.stop();
pradeepvk2208 6:09923c817679 66 printf("Time taken to write 1 block is %f \r\n",t.read());
pradeepvk2208 6:09923c817679 67 t.reset();}
pradeepvk2208 4:003e6dfc288d 68 uint8_t read_data[512];
pradeepvk2208 5:e13062be9e7b 69 for(block_number=0;block_number<100;block_number++)
pradeepvk2208 6:09923c817679 70 {t.start();
pradeepvk2208 6:09923c817679 71 disk_read(read_data, block_number);
pradeepvk2208 6:09923c817679 72 t.stop();
pradeepvk2208 6:09923c817679 73 printf("Time taken to read 1 block is %f \r\n",t.read());
pradeepvk2208 6:09923c817679 74 t.reset();
pradeepvk2208 4:003e6dfc288d 75 for(count_bro=0;count_bro<512;count_bro++)
pradeepvk2208 5:e13062be9e7b 76 {printf("%c",read_data[count_bro]);}
pradeepvk2208 6:09923c817679 77 printf("\r\n");}
pradeepvk2208 3:d4bb1e13a897 78
pradeepvk2208 3:d4bb1e13a897 79
pradeepvk2208 3:d4bb1e13a897 80
pradeepvk2208 0:d4197e4552ea 81 }
pradeepvk2208 0:d4197e4552ea 82
pradeepvk2208 0:d4197e4552ea 83
pradeepvk2208 0:d4197e4552ea 84
pradeepvk2208 0:d4197e4552ea 85
pradeepvk2208 0:d4197e4552ea 86 int initialise_card() {
pradeepvk2208 0:d4197e4552ea 87 // Set to 100kHz for initialisation, and clock card with cs = 1
pradeepvk2208 0:d4197e4552ea 88 spi.frequency(100000);
pradeepvk2208 0:d4197e4552ea 89 cs = 1;
pradeepvk2208 0:d4197e4552ea 90 for (int i = 0; i < 16; i++) {
pradeepvk2208 0:d4197e4552ea 91 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 92 }
pradeepvk2208 0:d4197e4552ea 93
pradeepvk2208 0:d4197e4552ea 94 // send CMD0, should return with all zeros except IDLE STATE set (bit 0)
pradeepvk2208 0:d4197e4552ea 95 if (cmd(0, 0) != R1_IDLE_STATE) {
pradeepvk2208 0:d4197e4552ea 96 debug("No disk, or could not put SD card in to SPI idle state\n");
pradeepvk2208 0:d4197e4552ea 97 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 98 }
pradeepvk2208 0:d4197e4552ea 99
pradeepvk2208 0:d4197e4552ea 100 // send CMD8 to determine whther it is ver 2.x
pradeepvk2208 0:d4197e4552ea 101 int r = cmd8();
pradeepvk2208 0:d4197e4552ea 102 if (r == R1_IDLE_STATE) {
pradeepvk2208 6:09923c817679 103 //printf("Entering v2 bro\n");
pradeepvk2208 0:d4197e4552ea 104 return initialise_card_v2();
pradeepvk2208 2:aea18e9b89d8 105
pradeepvk2208 0:d4197e4552ea 106 } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
pradeepvk2208 6:09923c817679 107 // printf("Entering v1 bro\n");
pradeepvk2208 0:d4197e4552ea 108 return initialise_card_v1();
pradeepvk2208 2:aea18e9b89d8 109
pradeepvk2208 0:d4197e4552ea 110 } else {
pradeepvk2208 0:d4197e4552ea 111 debug("Not in idle state after sending CMD8 (not an SD card?)\n");
pradeepvk2208 0:d4197e4552ea 112 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 113 }
pradeepvk2208 0:d4197e4552ea 114 }
pradeepvk2208 0:d4197e4552ea 115
pradeepvk2208 0:d4197e4552ea 116 int initialise_card_v1() {
pradeepvk2208 0:d4197e4552ea 117 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 118 cmd(55, 0);
pradeepvk2208 0:d4197e4552ea 119 if (cmd(41, 0) == 0) {
pradeepvk2208 3:d4bb1e13a897 120 printf("Yuppie v1 successful\n");
pradeepvk2208 0:d4197e4552ea 121 cdv = 512;
pradeepvk2208 0:d4197e4552ea 122 debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r");
pradeepvk2208 1:1843a53b51a8 123
pradeepvk2208 0:d4197e4552ea 124 return SDCARD_V1;
pradeepvk2208 0:d4197e4552ea 125 }
pradeepvk2208 0:d4197e4552ea 126 }
pradeepvk2208 0:d4197e4552ea 127
pradeepvk2208 0:d4197e4552ea 128 debug("Timeout waiting for v1.x card\n");
pradeepvk2208 0:d4197e4552ea 129 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 130 }
pradeepvk2208 0:d4197e4552ea 131
pradeepvk2208 0:d4197e4552ea 132
pradeepvk2208 0:d4197e4552ea 133 int initialise_card_v2() {
pradeepvk2208 0:d4197e4552ea 134 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 135 wait_ms(50);
pradeepvk2208 0:d4197e4552ea 136 cmd58();
pradeepvk2208 0:d4197e4552ea 137 cmd(55, 0);
pradeepvk2208 0:d4197e4552ea 138 if (cmd(41, 0x40000000) == 0) {
pradeepvk2208 3:d4bb1e13a897 139 printf("Yuppie,v2 successful\n");
pradeepvk2208 0:d4197e4552ea 140 cmd58();
pradeepvk2208 0:d4197e4552ea 141 debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r");
pradeepvk2208 0:d4197e4552ea 142 cdv = 1;
pradeepvk2208 1:1843a53b51a8 143
pradeepvk2208 0:d4197e4552ea 144 return SDCARD_V2;
pradeepvk2208 0:d4197e4552ea 145 }
pradeepvk2208 0:d4197e4552ea 146 }
pradeepvk2208 0:d4197e4552ea 147
pradeepvk2208 0:d4197e4552ea 148 debug("Timeout waiting for v2.x card\n");
pradeepvk2208 0:d4197e4552ea 149 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 150 }
pradeepvk2208 0:d4197e4552ea 151
pradeepvk2208 0:d4197e4552ea 152 int cmd(int cmd, int arg) {
pradeepvk2208 0:d4197e4552ea 153 cs = 0;
pradeepvk2208 0:d4197e4552ea 154
pradeepvk2208 0:d4197e4552ea 155 // send a command
pradeepvk2208 0:d4197e4552ea 156 spi.write(0x40 | cmd);
pradeepvk2208 0:d4197e4552ea 157 spi.write(arg >> 24);
pradeepvk2208 0:d4197e4552ea 158 spi.write(arg >> 16);
pradeepvk2208 0:d4197e4552ea 159 spi.write(arg >> 8);
pradeepvk2208 0:d4197e4552ea 160 spi.write(arg >> 0);
pradeepvk2208 0:d4197e4552ea 161 spi.write(0x95);
pradeepvk2208 0:d4197e4552ea 162
pradeepvk2208 0:d4197e4552ea 163 // wait for the repsonse (response[7] == 0)
pradeepvk2208 0:d4197e4552ea 164 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 165 int response = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 166 if (!(response & 0x80)) {
pradeepvk2208 0:d4197e4552ea 167 cs = 1;
pradeepvk2208 0:d4197e4552ea 168 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 169 return response;
pradeepvk2208 0:d4197e4552ea 170 }
pradeepvk2208 0:d4197e4552ea 171 }
pradeepvk2208 0:d4197e4552ea 172 cs = 1;
pradeepvk2208 0:d4197e4552ea 173 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 174 return -1; // timeout
pradeepvk2208 0:d4197e4552ea 175 }
pradeepvk2208 0:d4197e4552ea 176
pradeepvk2208 0:d4197e4552ea 177
pradeepvk2208 0:d4197e4552ea 178 int cmd58() {
pradeepvk2208 0:d4197e4552ea 179 cs = 0;
pradeepvk2208 0:d4197e4552ea 180 int arg = 0;
pradeepvk2208 0:d4197e4552ea 181
pradeepvk2208 0:d4197e4552ea 182 // send a command
pradeepvk2208 0:d4197e4552ea 183 spi.write(0x40 | 58);
pradeepvk2208 0:d4197e4552ea 184 spi.write(arg >> 24);
pradeepvk2208 0:d4197e4552ea 185 spi.write(arg >> 16);
pradeepvk2208 0:d4197e4552ea 186 spi.write(arg >> 8);
pradeepvk2208 0:d4197e4552ea 187 spi.write(arg >> 0);
pradeepvk2208 0:d4197e4552ea 188 spi.write(0x95);
pradeepvk2208 0:d4197e4552ea 189
pradeepvk2208 0:d4197e4552ea 190 // wait for the repsonse (response[7] == 0)
pradeepvk2208 0:d4197e4552ea 191 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 192 int response = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 193 if (!(response & 0x80)) {
pradeepvk2208 0:d4197e4552ea 194 int ocr = spi.write(0xFF) << 24;
pradeepvk2208 0:d4197e4552ea 195 ocr |= spi.write(0xFF) << 16;
pradeepvk2208 0:d4197e4552ea 196 ocr |= spi.write(0xFF) << 8;
pradeepvk2208 0:d4197e4552ea 197 ocr |= spi.write(0xFF) << 0;
pradeepvk2208 0:d4197e4552ea 198 cs = 1;
pradeepvk2208 0:d4197e4552ea 199 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 200 return response;
pradeepvk2208 0:d4197e4552ea 201 }
pradeepvk2208 0:d4197e4552ea 202 }
pradeepvk2208 0:d4197e4552ea 203 cs = 1;
pradeepvk2208 0:d4197e4552ea 204 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 205 return -1; // timeout
pradeepvk2208 0:d4197e4552ea 206 }
pradeepvk2208 0:d4197e4552ea 207
pradeepvk2208 0:d4197e4552ea 208
pradeepvk2208 0:d4197e4552ea 209 int cmd8() {
pradeepvk2208 0:d4197e4552ea 210 cs = 0;
pradeepvk2208 0:d4197e4552ea 211
pradeepvk2208 0:d4197e4552ea 212 // send a command
pradeepvk2208 0:d4197e4552ea 213 spi.write(0x40 | 8); // CMD8
pradeepvk2208 0:d4197e4552ea 214 spi.write(0x00); // reserved
pradeepvk2208 0:d4197e4552ea 215 spi.write(0x00); // reserved
pradeepvk2208 0:d4197e4552ea 216 spi.write(0x01); // 3.3v
pradeepvk2208 0:d4197e4552ea 217 spi.write(0xAA); // check pattern
pradeepvk2208 0:d4197e4552ea 218 spi.write(0x87); // crc
pradeepvk2208 0:d4197e4552ea 219
pradeepvk2208 0:d4197e4552ea 220 // wait for the repsonse (response[7] == 0)
pradeepvk2208 0:d4197e4552ea 221 for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) {
pradeepvk2208 0:d4197e4552ea 222 char response[5];
pradeepvk2208 0:d4197e4552ea 223 response[0] = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 224 if (!(response[0] & 0x80)) {
pradeepvk2208 0:d4197e4552ea 225 for (int j = 1; j < 5; j++) {
pradeepvk2208 0:d4197e4552ea 226 response[i] = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 227 }
pradeepvk2208 0:d4197e4552ea 228 cs = 1;
pradeepvk2208 0:d4197e4552ea 229 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 230 return response[0];
pradeepvk2208 0:d4197e4552ea 231 }
pradeepvk2208 0:d4197e4552ea 232 }
pradeepvk2208 0:d4197e4552ea 233 cs = 1;
pradeepvk2208 0:d4197e4552ea 234 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 235 return -1; // timeout
pradeepvk2208 2:aea18e9b89d8 236 }
pradeepvk2208 2:aea18e9b89d8 237
pradeepvk2208 2:aea18e9b89d8 238 uint64_t sd_sectors() {
pradeepvk2208 2:aea18e9b89d8 239 uint32_t c_size, c_size_mult, read_bl_len;
pradeepvk2208 2:aea18e9b89d8 240 uint32_t block_len, mult, blocknr, capacity;
pradeepvk2208 2:aea18e9b89d8 241 uint32_t hc_c_size;
pradeepvk2208 2:aea18e9b89d8 242 uint64_t blocks;
pradeepvk2208 2:aea18e9b89d8 243
pradeepvk2208 2:aea18e9b89d8 244 // CMD9, Response R2 (R1 byte + 16-byte block read)
pradeepvk2208 2:aea18e9b89d8 245 if (cmdx(9, 0) != 0) {
pradeepvk2208 2:aea18e9b89d8 246 debug("Didn't get a response from the disk\n");
pradeepvk2208 2:aea18e9b89d8 247 return 0;
pradeepvk2208 2:aea18e9b89d8 248 }
pradeepvk2208 2:aea18e9b89d8 249
pradeepvk2208 2:aea18e9b89d8 250 uint8_t csd[16];
pradeepvk2208 2:aea18e9b89d8 251 if (read(csd, 16) != 0) {
pradeepvk2208 2:aea18e9b89d8 252 debug("Couldn't read csd response from disk\n");
pradeepvk2208 2:aea18e9b89d8 253 return 0;
pradeepvk2208 2:aea18e9b89d8 254 }
pradeepvk2208 2:aea18e9b89d8 255
pradeepvk2208 2:aea18e9b89d8 256 // csd_structure : csd[127:126]
pradeepvk2208 2:aea18e9b89d8 257 // c_size : csd[73:62]
pradeepvk2208 2:aea18e9b89d8 258 // c_size_mult : csd[49:47]
pradeepvk2208 2:aea18e9b89d8 259 // read_bl_len : csd[83:80] - the *maximum* read block length
pradeepvk2208 2:aea18e9b89d8 260
pradeepvk2208 2:aea18e9b89d8 261 int csd_structure = ext_bits(csd, 127, 126);
pradeepvk2208 2:aea18e9b89d8 262
pradeepvk2208 2:aea18e9b89d8 263 switch (csd_structure) {
pradeepvk2208 2:aea18e9b89d8 264 case 0:
pradeepvk2208 2:aea18e9b89d8 265 cdv = 512;
pradeepvk2208 2:aea18e9b89d8 266 c_size = ext_bits(csd, 73, 62);
pradeepvk2208 2:aea18e9b89d8 267 c_size_mult = ext_bits(csd, 49, 47);
pradeepvk2208 2:aea18e9b89d8 268 read_bl_len = ext_bits(csd, 83, 80);
pradeepvk2208 2:aea18e9b89d8 269
pradeepvk2208 2:aea18e9b89d8 270 block_len = 1 << read_bl_len;
pradeepvk2208 2:aea18e9b89d8 271 mult = 1 << (c_size_mult + 2);
pradeepvk2208 2:aea18e9b89d8 272 blocknr = (c_size + 1) * mult;
pradeepvk2208 2:aea18e9b89d8 273 capacity = blocknr * block_len;
pradeepvk2208 2:aea18e9b89d8 274 blocks = capacity / 512;
pradeepvk2208 2:aea18e9b89d8 275 debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks);
pradeepvk2208 2:aea18e9b89d8 276 break;
pradeepvk2208 2:aea18e9b89d8 277
pradeepvk2208 2:aea18e9b89d8 278 case 1:
pradeepvk2208 2:aea18e9b89d8 279 cdv = 1;
pradeepvk2208 2:aea18e9b89d8 280 hc_c_size = ext_bits(csd, 63, 48);
pradeepvk2208 2:aea18e9b89d8 281 blocks = (hc_c_size+1)*1024;
pradeepvk2208 2:aea18e9b89d8 282 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);
pradeepvk2208 2:aea18e9b89d8 283 break;
pradeepvk2208 2:aea18e9b89d8 284
pradeepvk2208 2:aea18e9b89d8 285 default:
pradeepvk2208 2:aea18e9b89d8 286 debug("CSD struct unsupported\r\n");
pradeepvk2208 2:aea18e9b89d8 287 return 0;
pradeepvk2208 2:aea18e9b89d8 288 };
pradeepvk2208 2:aea18e9b89d8 289 return blocks;
pradeepvk2208 2:aea18e9b89d8 290 }
pradeepvk2208 2:aea18e9b89d8 291
pradeepvk2208 2:aea18e9b89d8 292 int cmdx(int cmd, int arg) {
pradeepvk2208 2:aea18e9b89d8 293 cs = 0;
pradeepvk2208 2:aea18e9b89d8 294
pradeepvk2208 2:aea18e9b89d8 295 // send a command
pradeepvk2208 2:aea18e9b89d8 296 spi.write(0x40 | cmd);
pradeepvk2208 2:aea18e9b89d8 297 spi.write(arg >> 24);
pradeepvk2208 2:aea18e9b89d8 298 spi.write(arg >> 16);
pradeepvk2208 2:aea18e9b89d8 299 spi.write(arg >> 8);
pradeepvk2208 2:aea18e9b89d8 300 spi.write(arg >> 0);
pradeepvk2208 2:aea18e9b89d8 301 spi.write(0x95);
pradeepvk2208 2:aea18e9b89d8 302
pradeepvk2208 2:aea18e9b89d8 303 // wait for the repsonse (response[7] == 0)
pradeepvk2208 2:aea18e9b89d8 304 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 2:aea18e9b89d8 305 int response = spi.write(0xFF);
pradeepvk2208 2:aea18e9b89d8 306 if (!(response & 0x80)) {
pradeepvk2208 2:aea18e9b89d8 307 return response;
pradeepvk2208 2:aea18e9b89d8 308 }
pradeepvk2208 2:aea18e9b89d8 309 }
pradeepvk2208 2:aea18e9b89d8 310 cs = 1;
pradeepvk2208 2:aea18e9b89d8 311 spi.write(0xFF);
pradeepvk2208 2:aea18e9b89d8 312 return -1; // timeout
pradeepvk2208 2:aea18e9b89d8 313 }
pradeepvk2208 2:aea18e9b89d8 314
pradeepvk2208 2:aea18e9b89d8 315
pradeepvk2208 2:aea18e9b89d8 316 int read(uint8_t *buffer, uint32_t length) {
pradeepvk2208 2:aea18e9b89d8 317 cs = 0;
pradeepvk2208 2:aea18e9b89d8 318
pradeepvk2208 2:aea18e9b89d8 319 // read until start byte (0xFF)
pradeepvk2208 2:aea18e9b89d8 320 while (spi.write(0xFF) != 0xFE);
pradeepvk2208 2:aea18e9b89d8 321
pradeepvk2208 2:aea18e9b89d8 322 // read data
pradeepvk2208 2:aea18e9b89d8 323 for (int i = 0; i < length; i++) {
pradeepvk2208 2:aea18e9b89d8 324 buffer[i] = spi.write(0xFF);
pradeepvk2208 2:aea18e9b89d8 325 }
pradeepvk2208 2:aea18e9b89d8 326 spi.write(0xFF); // checksum
pradeepvk2208 2:aea18e9b89d8 327 spi.write(0xFF);
pradeepvk2208 2:aea18e9b89d8 328
pradeepvk2208 2:aea18e9b89d8 329 cs = 1;
pradeepvk2208 2:aea18e9b89d8 330 spi.write(0xFF);
pradeepvk2208 2:aea18e9b89d8 331 return 0;
pradeepvk2208 2:aea18e9b89d8 332 }
pradeepvk2208 2:aea18e9b89d8 333
pradeepvk2208 2:aea18e9b89d8 334 static uint32_t ext_bits(unsigned char *data, int msb, int lsb) {
pradeepvk2208 2:aea18e9b89d8 335 uint32_t bits = 0;
pradeepvk2208 2:aea18e9b89d8 336 uint32_t size = 1 + msb - lsb;
pradeepvk2208 2:aea18e9b89d8 337 for (int i = 0; i < size; i++) {
pradeepvk2208 2:aea18e9b89d8 338 uint32_t position = lsb + i;
pradeepvk2208 2:aea18e9b89d8 339 uint32_t byte = 15 - (position >> 3);
pradeepvk2208 2:aea18e9b89d8 340 uint32_t bit = position & 0x7;
pradeepvk2208 2:aea18e9b89d8 341 uint32_t value = (data[byte] >> bit) & 1;
pradeepvk2208 2:aea18e9b89d8 342 bits |= value << i;
pradeepvk2208 2:aea18e9b89d8 343 }
pradeepvk2208 2:aea18e9b89d8 344 return bits;
pradeepvk2208 2:aea18e9b89d8 345 }
pradeepvk2208 2:aea18e9b89d8 346
pradeepvk2208 2:aea18e9b89d8 347 int disk_initialize() {
pradeepvk2208 2:aea18e9b89d8 348 int i = initialise_card();
pradeepvk2208 2:aea18e9b89d8 349 debug_if(SD_DBG, "init card = %d\n", i);
pradeepvk2208 2:aea18e9b89d8 350 sectors = sd_sectors();
pradeepvk2208 2:aea18e9b89d8 351
pradeepvk2208 2:aea18e9b89d8 352 // Set block length to 512 (CMD16)
pradeepvk2208 2:aea18e9b89d8 353 if (cmd(16, 512) != 0) {
pradeepvk2208 2:aea18e9b89d8 354 debug("Set 512-byte block timed out\n");
pradeepvk2208 2:aea18e9b89d8 355 return 1;
pradeepvk2208 2:aea18e9b89d8 356 }
pradeepvk2208 2:aea18e9b89d8 357 else
pradeepvk2208 2:aea18e9b89d8 358 {
pradeepvk2208 6:09923c817679 359 // printf("Hey,block init succesful\n");
pradeepvk2208 2:aea18e9b89d8 360 }
pradeepvk2208 2:aea18e9b89d8 361
pradeepvk2208 2:aea18e9b89d8 362 spi.frequency(1000000); // Set to 1MHz for data transfer
pradeepvk2208 2:aea18e9b89d8 363 return 0;
pradeepvk2208 2:aea18e9b89d8 364 }
pradeepvk2208 2:aea18e9b89d8 365
pradeepvk2208 3:d4bb1e13a897 366 int disk_write(const uint8_t *buffer, uint64_t block_number)
pradeepvk2208 3:d4bb1e13a897 367
pradeepvk2208 3:d4bb1e13a897 368 {
pradeepvk2208 3:d4bb1e13a897 369 // set write address for single block (CMD24)
pradeepvk2208 3:d4bb1e13a897 370 if (cmd(24, block_number * cdv) != 0) {
pradeepvk2208 3:d4bb1e13a897 371 return 1;
pradeepvk2208 3:d4bb1e13a897 372 }
pradeepvk2208 3:d4bb1e13a897 373
pradeepvk2208 3:d4bb1e13a897 374 // send the data block
pradeepvk2208 3:d4bb1e13a897 375 write(buffer, 512);
pradeepvk2208 3:d4bb1e13a897 376 return 0;
pradeepvk2208 3:d4bb1e13a897 377 }
pradeepvk2208 3:d4bb1e13a897 378
pradeepvk2208 3:d4bb1e13a897 379 int write(const uint8_t*buffer, uint32_t length) {
pradeepvk2208 3:d4bb1e13a897 380 cs = 0;
pradeepvk2208 3:d4bb1e13a897 381
pradeepvk2208 3:d4bb1e13a897 382 // indicate start of block
pradeepvk2208 3:d4bb1e13a897 383 spi.write(0xFE);
pradeepvk2208 3:d4bb1e13a897 384
pradeepvk2208 3:d4bb1e13a897 385 // write the data
pradeepvk2208 3:d4bb1e13a897 386 for (int i = 0; i < length; i++) {
pradeepvk2208 3:d4bb1e13a897 387 spi.write(buffer[i]);
pradeepvk2208 3:d4bb1e13a897 388 }
pradeepvk2208 3:d4bb1e13a897 389
pradeepvk2208 3:d4bb1e13a897 390 // write the checksum
pradeepvk2208 3:d4bb1e13a897 391 spi.write(0xFF);
pradeepvk2208 3:d4bb1e13a897 392 spi.write(0xFF);
pradeepvk2208 3:d4bb1e13a897 393
pradeepvk2208 3:d4bb1e13a897 394 // check the response token
pradeepvk2208 3:d4bb1e13a897 395 if ((spi.write(0xFF) & 0x1F) != 0x05) {
pradeepvk2208 3:d4bb1e13a897 396 cs = 1;
pradeepvk2208 3:d4bb1e13a897 397 spi.write(0xFF);
pradeepvk2208 3:d4bb1e13a897 398 return 1;
pradeepvk2208 3:d4bb1e13a897 399 }
pradeepvk2208 3:d4bb1e13a897 400
pradeepvk2208 3:d4bb1e13a897 401 // wait for write to finish
pradeepvk2208 3:d4bb1e13a897 402 while (spi.write(0xFF) == 0);
pradeepvk2208 3:d4bb1e13a897 403
pradeepvk2208 3:d4bb1e13a897 404 cs = 1;
pradeepvk2208 3:d4bb1e13a897 405 spi.write(0xFF);
pradeepvk2208 3:d4bb1e13a897 406 return 0;
pradeepvk2208 3:d4bb1e13a897 407 }
pradeepvk2208 3:d4bb1e13a897 408
pradeepvk2208 4:003e6dfc288d 409 int disk_read(uint8_t *buffer, uint64_t block_number) {
pradeepvk2208 4:003e6dfc288d 410 // set read address for single block (CMD17)
pradeepvk2208 4:003e6dfc288d 411 if (cmd(17, block_number * cdv) != 0) {
pradeepvk2208 4:003e6dfc288d 412 return 1;
pradeepvk2208 4:003e6dfc288d 413 }
pradeepvk2208 4:003e6dfc288d 414
pradeepvk2208 4:003e6dfc288d 415 // receive the data
pradeepvk2208 4:003e6dfc288d 416 read(buffer, 512);
pradeepvk2208 4:003e6dfc288d 417 return 0;
pradeepvk2208 4:003e6dfc288d 418 }
pradeepvk2208 4:003e6dfc288d 419