Pradeep Kotipalli
/
raw_sd_card_write_raw
efe
Fork of raw_sd_card_disc_init by
Diff: main.cpp
- Revision:
- 0:d4197e4552ea
- Child:
- 1:1843a53b51a8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Jun 06 09:49:36 2015 +0000 @@ -0,0 +1,191 @@ +#include "mbed.h" +#include "mbed_debug.h" + +#define SD_COMMAND_TIMEOUT 5000 + +#define SD_DBG 0 + +#define R1_IDLE_STATE (1 << 0) +#define R1_ERASE_RESET (1 << 1) +#define R1_ILLEGAL_COMMAND (1 << 2) +#define R1_COM_CRC_ERROR (1 << 3) +#define R1_ERASE_SEQUENCE_ERROR (1 << 4) +#define R1_ADDRESS_ERROR (1 << 5) +#define R1_PARAMETER_ERROR (1 << 6) + +int initialise_card(); +int initialise_card_v1(); +int initialise_card_v2(); +int cmd(int, int); +int cmd58(); +int cmd8(); + +int cdv; + +#define SDCARD_FAIL 0 +#define SDCARD_V1 1 +#define SDCARD_V2 2 +#define SDCARD_V2HC 3 + + + +SPI spi(PTD6, PTD7, PTD5); // mosi, miso, sclk +DigitalOut cs(PTD2); + + + +int main() +{ + while(1) + { initialise_card(); + int result= initialise_card(); + printf("%d\n",result); + } +} + + + + +int initialise_card() { + // Set to 100kHz for initialisation, and clock card with cs = 1 + spi.frequency(100000); + cs = 1; + for (int i = 0; i < 16; i++) { + spi.write(0xFF); + } + + // send CMD0, should return with all zeros except IDLE STATE set (bit 0) + if (cmd(0, 0) != R1_IDLE_STATE) { + debug("No disk, or could not put SD card in to SPI idle state\n"); + return SDCARD_FAIL; + } + + // send CMD8 to determine whther it is ver 2.x + int r = cmd8(); + if (r == R1_IDLE_STATE) { + return initialise_card_v2(); + } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { + return initialise_card_v1(); + } else { + debug("Not in idle state after sending CMD8 (not an SD card?)\n"); + return SDCARD_FAIL; + } +} + +int initialise_card_v1() { + for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { + cmd(55, 0); + if (cmd(41, 0) == 0) { + cdv = 512; + debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r"); + return SDCARD_V1; + } + } + + debug("Timeout waiting for v1.x card\n"); + return SDCARD_FAIL; +} + + +int initialise_card_v2() { + for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { + wait_ms(50); + cmd58(); + cmd(55, 0); + if (cmd(41, 0x40000000) == 0) { + cmd58(); + debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r"); + cdv = 1; + return SDCARD_V2; + } + } + + debug("Timeout waiting for v2.x card\n"); + return SDCARD_FAIL; +} + +int cmd(int cmd, int arg) { + cs = 0; + + // send a command + spi.write(0x40 | cmd); + spi.write(arg >> 24); + spi.write(arg >> 16); + spi.write(arg >> 8); + spi.write(arg >> 0); + spi.write(0x95); + + // wait for the repsonse (response[7] == 0) +for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { + int response = spi.write(0xFF); + if (!(response & 0x80)) { + cs = 1; + spi.write(0xFF); + return response; + } + } + cs = 1; + spi.write(0xFF); + return -1; // timeout +} + + +int cmd58() { + cs = 0; + int arg = 0; + + // send a command + spi.write(0x40 | 58); + spi.write(arg >> 24); + spi.write(arg >> 16); + spi.write(arg >> 8); + spi.write(arg >> 0); + spi.write(0x95); + + // wait for the repsonse (response[7] == 0) + for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { + int response = spi.write(0xFF); + if (!(response & 0x80)) { + int ocr = spi.write(0xFF) << 24; + ocr |= spi.write(0xFF) << 16; + ocr |= spi.write(0xFF) << 8; + ocr |= spi.write(0xFF) << 0; + cs = 1; + spi.write(0xFF); + return response; + } + } + cs = 1; + spi.write(0xFF); + return -1; // timeout +} + + +int cmd8() { + cs = 0; + + // send a command + spi.write(0x40 | 8); // CMD8 + spi.write(0x00); // reserved + spi.write(0x00); // reserved + spi.write(0x01); // 3.3v + spi.write(0xAA); // check pattern + spi.write(0x87); // crc + + // wait for the repsonse (response[7] == 0) + for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) { + char response[5]; + response[0] = spi.write(0xFF); + if (!(response[0] & 0x80)) { + for (int j = 1; j < 5; j++) { + response[i] = spi.write(0xFF); + } + cs = 1; + spi.write(0xFF); + return response[0]; + } + } + cs = 1; + spi.write(0xFF); + return -1; // timeout +} \ No newline at end of file