nlknlknln

Dependencies:   mbed

Fork of raw_sd_card_readsaswell by Pradeep Kotipalli

Committer:
pradeepvk2208
Date:
Sat Jun 06 11:59:07 2015 +0000
Revision:
4:003e6dfc288d
Parent:
3:d4bb1e13a897
Child:
5:e13062be9e7b
dis is final

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