efe

Dependencies:   mbed

Fork of raw_sd_card_disc_init by Pradeep Kotipalli

Committer:
pradeepvk2208
Date:
Sat Jun 06 09:49:36 2015 +0000
Revision:
0:d4197e4552ea
Child:
1:1843a53b51a8
hijghg

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 0:d4197e4552ea 19 int cmd(int, int);
pradeepvk2208 0:d4197e4552ea 20 int cmd58();
pradeepvk2208 0:d4197e4552ea 21 int cmd8();
pradeepvk2208 0:d4197e4552ea 22
pradeepvk2208 0:d4197e4552ea 23 int cdv;
pradeepvk2208 0:d4197e4552ea 24
pradeepvk2208 0:d4197e4552ea 25 #define SDCARD_FAIL 0
pradeepvk2208 0:d4197e4552ea 26 #define SDCARD_V1 1
pradeepvk2208 0:d4197e4552ea 27 #define SDCARD_V2 2
pradeepvk2208 0:d4197e4552ea 28 #define SDCARD_V2HC 3
pradeepvk2208 0:d4197e4552ea 29
pradeepvk2208 0:d4197e4552ea 30
pradeepvk2208 0:d4197e4552ea 31
pradeepvk2208 0:d4197e4552ea 32 SPI spi(PTD6, PTD7, PTD5); // mosi, miso, sclk
pradeepvk2208 0:d4197e4552ea 33 DigitalOut cs(PTD2);
pradeepvk2208 0:d4197e4552ea 34
pradeepvk2208 0:d4197e4552ea 35
pradeepvk2208 0:d4197e4552ea 36
pradeepvk2208 0:d4197e4552ea 37 int main()
pradeepvk2208 0:d4197e4552ea 38 {
pradeepvk2208 0:d4197e4552ea 39 while(1)
pradeepvk2208 0:d4197e4552ea 40 { initialise_card();
pradeepvk2208 0:d4197e4552ea 41 int result= initialise_card();
pradeepvk2208 0:d4197e4552ea 42 printf("%d\n",result);
pradeepvk2208 0:d4197e4552ea 43 }
pradeepvk2208 0:d4197e4552ea 44 }
pradeepvk2208 0:d4197e4552ea 45
pradeepvk2208 0:d4197e4552ea 46
pradeepvk2208 0:d4197e4552ea 47
pradeepvk2208 0:d4197e4552ea 48
pradeepvk2208 0:d4197e4552ea 49 int initialise_card() {
pradeepvk2208 0:d4197e4552ea 50 // Set to 100kHz for initialisation, and clock card with cs = 1
pradeepvk2208 0:d4197e4552ea 51 spi.frequency(100000);
pradeepvk2208 0:d4197e4552ea 52 cs = 1;
pradeepvk2208 0:d4197e4552ea 53 for (int i = 0; i < 16; i++) {
pradeepvk2208 0:d4197e4552ea 54 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 55 }
pradeepvk2208 0:d4197e4552ea 56
pradeepvk2208 0:d4197e4552ea 57 // send CMD0, should return with all zeros except IDLE STATE set (bit 0)
pradeepvk2208 0:d4197e4552ea 58 if (cmd(0, 0) != R1_IDLE_STATE) {
pradeepvk2208 0:d4197e4552ea 59 debug("No disk, or could not put SD card in to SPI idle state\n");
pradeepvk2208 0:d4197e4552ea 60 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 61 }
pradeepvk2208 0:d4197e4552ea 62
pradeepvk2208 0:d4197e4552ea 63 // send CMD8 to determine whther it is ver 2.x
pradeepvk2208 0:d4197e4552ea 64 int r = cmd8();
pradeepvk2208 0:d4197e4552ea 65 if (r == R1_IDLE_STATE) {
pradeepvk2208 0:d4197e4552ea 66 return initialise_card_v2();
pradeepvk2208 0:d4197e4552ea 67 } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
pradeepvk2208 0:d4197e4552ea 68 return initialise_card_v1();
pradeepvk2208 0:d4197e4552ea 69 } else {
pradeepvk2208 0:d4197e4552ea 70 debug("Not in idle state after sending CMD8 (not an SD card?)\n");
pradeepvk2208 0:d4197e4552ea 71 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 72 }
pradeepvk2208 0:d4197e4552ea 73 }
pradeepvk2208 0:d4197e4552ea 74
pradeepvk2208 0:d4197e4552ea 75 int initialise_card_v1() {
pradeepvk2208 0:d4197e4552ea 76 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 77 cmd(55, 0);
pradeepvk2208 0:d4197e4552ea 78 if (cmd(41, 0) == 0) {
pradeepvk2208 0:d4197e4552ea 79 cdv = 512;
pradeepvk2208 0:d4197e4552ea 80 debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r");
pradeepvk2208 0:d4197e4552ea 81 return SDCARD_V1;
pradeepvk2208 0:d4197e4552ea 82 }
pradeepvk2208 0:d4197e4552ea 83 }
pradeepvk2208 0:d4197e4552ea 84
pradeepvk2208 0:d4197e4552ea 85 debug("Timeout waiting for v1.x card\n");
pradeepvk2208 0:d4197e4552ea 86 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 87 }
pradeepvk2208 0:d4197e4552ea 88
pradeepvk2208 0:d4197e4552ea 89
pradeepvk2208 0:d4197e4552ea 90 int initialise_card_v2() {
pradeepvk2208 0:d4197e4552ea 91 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 92 wait_ms(50);
pradeepvk2208 0:d4197e4552ea 93 cmd58();
pradeepvk2208 0:d4197e4552ea 94 cmd(55, 0);
pradeepvk2208 0:d4197e4552ea 95 if (cmd(41, 0x40000000) == 0) {
pradeepvk2208 0:d4197e4552ea 96 cmd58();
pradeepvk2208 0:d4197e4552ea 97 debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r");
pradeepvk2208 0:d4197e4552ea 98 cdv = 1;
pradeepvk2208 0:d4197e4552ea 99 return SDCARD_V2;
pradeepvk2208 0:d4197e4552ea 100 }
pradeepvk2208 0:d4197e4552ea 101 }
pradeepvk2208 0:d4197e4552ea 102
pradeepvk2208 0:d4197e4552ea 103 debug("Timeout waiting for v2.x card\n");
pradeepvk2208 0:d4197e4552ea 104 return SDCARD_FAIL;
pradeepvk2208 0:d4197e4552ea 105 }
pradeepvk2208 0:d4197e4552ea 106
pradeepvk2208 0:d4197e4552ea 107 int cmd(int cmd, int arg) {
pradeepvk2208 0:d4197e4552ea 108 cs = 0;
pradeepvk2208 0:d4197e4552ea 109
pradeepvk2208 0:d4197e4552ea 110 // send a command
pradeepvk2208 0:d4197e4552ea 111 spi.write(0x40 | cmd);
pradeepvk2208 0:d4197e4552ea 112 spi.write(arg >> 24);
pradeepvk2208 0:d4197e4552ea 113 spi.write(arg >> 16);
pradeepvk2208 0:d4197e4552ea 114 spi.write(arg >> 8);
pradeepvk2208 0:d4197e4552ea 115 spi.write(arg >> 0);
pradeepvk2208 0:d4197e4552ea 116 spi.write(0x95);
pradeepvk2208 0:d4197e4552ea 117
pradeepvk2208 0:d4197e4552ea 118 // wait for the repsonse (response[7] == 0)
pradeepvk2208 0:d4197e4552ea 119 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 120 int response = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 121 if (!(response & 0x80)) {
pradeepvk2208 0:d4197e4552ea 122 cs = 1;
pradeepvk2208 0:d4197e4552ea 123 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 124 return response;
pradeepvk2208 0:d4197e4552ea 125 }
pradeepvk2208 0:d4197e4552ea 126 }
pradeepvk2208 0:d4197e4552ea 127 cs = 1;
pradeepvk2208 0:d4197e4552ea 128 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 129 return -1; // timeout
pradeepvk2208 0:d4197e4552ea 130 }
pradeepvk2208 0:d4197e4552ea 131
pradeepvk2208 0:d4197e4552ea 132
pradeepvk2208 0:d4197e4552ea 133 int cmd58() {
pradeepvk2208 0:d4197e4552ea 134 cs = 0;
pradeepvk2208 0:d4197e4552ea 135 int arg = 0;
pradeepvk2208 0:d4197e4552ea 136
pradeepvk2208 0:d4197e4552ea 137 // send a command
pradeepvk2208 0:d4197e4552ea 138 spi.write(0x40 | 58);
pradeepvk2208 0:d4197e4552ea 139 spi.write(arg >> 24);
pradeepvk2208 0:d4197e4552ea 140 spi.write(arg >> 16);
pradeepvk2208 0:d4197e4552ea 141 spi.write(arg >> 8);
pradeepvk2208 0:d4197e4552ea 142 spi.write(arg >> 0);
pradeepvk2208 0:d4197e4552ea 143 spi.write(0x95);
pradeepvk2208 0:d4197e4552ea 144
pradeepvk2208 0:d4197e4552ea 145 // wait for the repsonse (response[7] == 0)
pradeepvk2208 0:d4197e4552ea 146 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
pradeepvk2208 0:d4197e4552ea 147 int response = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 148 if (!(response & 0x80)) {
pradeepvk2208 0:d4197e4552ea 149 int ocr = spi.write(0xFF) << 24;
pradeepvk2208 0:d4197e4552ea 150 ocr |= spi.write(0xFF) << 16;
pradeepvk2208 0:d4197e4552ea 151 ocr |= spi.write(0xFF) << 8;
pradeepvk2208 0:d4197e4552ea 152 ocr |= spi.write(0xFF) << 0;
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 cmd8() {
pradeepvk2208 0:d4197e4552ea 165 cs = 0;
pradeepvk2208 0:d4197e4552ea 166
pradeepvk2208 0:d4197e4552ea 167 // send a command
pradeepvk2208 0:d4197e4552ea 168 spi.write(0x40 | 8); // CMD8
pradeepvk2208 0:d4197e4552ea 169 spi.write(0x00); // reserved
pradeepvk2208 0:d4197e4552ea 170 spi.write(0x00); // reserved
pradeepvk2208 0:d4197e4552ea 171 spi.write(0x01); // 3.3v
pradeepvk2208 0:d4197e4552ea 172 spi.write(0xAA); // check pattern
pradeepvk2208 0:d4197e4552ea 173 spi.write(0x87); // crc
pradeepvk2208 0:d4197e4552ea 174
pradeepvk2208 0:d4197e4552ea 175 // wait for the repsonse (response[7] == 0)
pradeepvk2208 0:d4197e4552ea 176 for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) {
pradeepvk2208 0:d4197e4552ea 177 char response[5];
pradeepvk2208 0:d4197e4552ea 178 response[0] = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 179 if (!(response[0] & 0x80)) {
pradeepvk2208 0:d4197e4552ea 180 for (int j = 1; j < 5; j++) {
pradeepvk2208 0:d4197e4552ea 181 response[i] = spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 182 }
pradeepvk2208 0:d4197e4552ea 183 cs = 1;
pradeepvk2208 0:d4197e4552ea 184 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 185 return response[0];
pradeepvk2208 0:d4197e4552ea 186 }
pradeepvk2208 0:d4197e4552ea 187 }
pradeepvk2208 0:d4197e4552ea 188 cs = 1;
pradeepvk2208 0:d4197e4552ea 189 spi.write(0xFF);
pradeepvk2208 0:d4197e4552ea 190 return -1; // timeout
pradeepvk2208 0:d4197e4552ea 191 }