Dependencies:   mbed

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;