Simon Ford
/
SDCardTest
Diff: SDFileSystem.cpp
- Revision:
- 2:849162a1207f
- Parent:
- 1:2dec995d53f8
- Child:
- 3:68ef62208d4d
--- a/SDFileSystem.cpp Mon Dec 14 20:31:54 2009 +0000 +++ b/SDFileSystem.cpp Mon Dec 14 22:32:28 2009 +0000 @@ -104,6 +104,14 @@ _cs = 1; } +#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 SDFileSystem::disk_initialize() { _spi.frequency(100000); // Set to 100kHz for initialisation @@ -115,11 +123,20 @@ } // send CMD0, should return with all zeros except IDLE STATE set (bit 0) - if(_cmd(0, 0) != 0x01) { - fprintf(stderr, "Not in idle state\n"); + if(_cmd(0, 0) != R1_IDLE_STATE) { + fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); return 1; } - + + int r = _cmd8(); + if(r == R1_IDLE_STATE) { + printf("SD version 2.x\n"); + } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { + printf("SD version 1.x\n"); + } else { + error("Unknown SD version\n"); + } + // ACMD41 to give host capacity support (repeat until not busy) // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand for(int i=0;; i++) { @@ -133,6 +150,8 @@ } } + printf("OK\n"); + _sectors = _sd_sectors(); // Set block length to 512 (CMD16) @@ -198,6 +217,35 @@ return -1; // timeout } +int SDFileSystem::_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 +} + int SDFileSystem::_read(char *buffer, int length) { _cs = 0;