Fix stop-bit for samsung SD cards.
authorMichael McMaster <michael@codesrc.com>
Mon, 27 Oct 2014 13:27:46 +0000 (23:27 +1000)
committerMichael McMaster <michael@codesrc.com>
Mon, 27 Oct 2014 13:27:46 +0000 (23:27 +1000)
software/SCSI2SD/src/sd.c

index feb4202..df77988 100755 (executable)
@@ -21,6 +21,7 @@
 #include "disk.h"\r
 #include "sd.h"\r
 #include "led.h"\r
+#include "time.h"\r
 \r
 #include "scsiPhy.h"\r
 \r
@@ -111,7 +112,7 @@ static void sdSendCommand(uint8 cmd, uint32 param)
        send[2] = param >> 16;\r
        send[3] = param >> 8;\r
        send[4] = param;\r
-       send[5] = 0;\r
+       send[5] = 1; // 7:1 CRC, 0: Stop bit.\r
 \r
        for(cmd = 0; cmd < sizeof(send); cmd++)\r
        {\r
@@ -187,12 +188,11 @@ static void
 dmaReadSector(uint8_t* outputBuffer)\r
 {\r
        // Wait for a start-block token.\r
-       // Don't wait more than 100ms, which is the timeout recommended\r
-       // in the standard.\r
-       //100ms @ 64Hz = 6400000\r
-       int maxWait = 6400000;\r
+       // Don't wait more than 200ms.\r
+       // The standard recommends 100ms.\r
+       uint32_t start = getTime_ms();\r
        uint8 token = sdSpiByte(0xFF);\r
-       while (token != 0xFE && (maxWait-- > 0))\r
+       while (token != 0xFE && (diffTime_ms(start, getTime_ms()) <= 200))\r
        {\r
                token = sdSpiByte(0xFF);\r
        }\r
@@ -475,6 +475,8 @@ static int sendIfCond()
 \r
        do\r
        {\r
+               // 11:8 Host voltage. 1 = 2.7-3.6V\r
+               // 7:0 Echo bits. Ignore.\r
                uint8 status = sdCRCCommandAndResponse(SD_SEND_IF_COND, 0x000001AA);\r
 \r
                if (status == SD_R1_IDLE)\r
@@ -505,41 +507,50 @@ static int sendIfCond()
 \r
 static int sdOpCond()\r
 {\r
-       int retries = 50;\r
+       uint32_t start = getTime_ms();\r
 \r
        uint8 status;\r
        do\r
        {\r
-               CyDelay(33); // Spec says to retry for 1 second.\r
-\r
                sdCRCCommandAndResponse(SD_APP_CMD, 0);\r
                // Host Capacity Support = 1 (SDHC/SDXC supported)\r
                status = sdCRCCommandAndResponse(SD_APP_SEND_OP_COND, 0x40000000);\r
 \r
                sdClearStatus();\r
-       } while ((status != 0) && (--retries > 0));\r
 \r
-       return retries > 0;\r
+       // Spec says to poll for 1 second.\r
+       } while ((status != 0) && (diffTime_ms(start, getTime_ms()) < 1000));\r
+\r
+       return status == 0;\r
 }\r
 \r
 static int sdReadOCR()\r
 {\r
-       uint8 buf[4];\r
-       int i;\r
+       uint32_t start = getTime_ms();\r
+       int complete;\r
+       uint8 status;\r
        \r
-       uint8 status = sdCRCCommandAndResponse(SD_READ_OCR, 0);\r
-       if(status){goto bad;}\r
-\r
-       for (i = 0; i < 4; ++i)\r
+       do\r
        {\r
-               buf[i] = sdSpiByte(0xFF);\r
-       }\r
+               uint8 buf[4];\r
+               int i;\r
 \r
-       sdDev.ccs = (buf[0] & 0x40) ? 1 : 0;\r
+               status = sdCRCCommandAndResponse(SD_READ_OCR, 0);\r
+               if(status) { break; }\r
 \r
-       return 1;\r
-bad:\r
-       return 0;\r
+               for (i = 0; i < 4; ++i)\r
+               {\r
+                       buf[i] = sdSpiByte(0xFF);\r
+               }\r
+\r
+               sdDev.ccs = (buf[0] & 0x40) ? 1 : 0;\r
+               complete = (buf[0] & 0x80);\r
+\r
+       } while (!status &&\r
+               !complete &&\r
+               (diffTime_ms(start, getTime_ms()) < 1000));\r
+\r
+       return (status == 0) && complete;\r
 }\r
 \r
 static int sdReadCSD()\r
@@ -547,7 +558,7 @@ static int sdReadCSD()
        uint8 startToken;\r
        int maxWait, i;\r
        uint8 buf[16];\r
-       \r
+\r
        uint8 status = sdCRCCommandAndResponse(SD_SEND_CSD, 0);\r
        if(status){goto bad;}\r
 \r
@@ -634,7 +645,7 @@ int sdInit()
        int result = 0;\r
        int i;\r
        uint8 v;\r
-       \r
+\r
        sdDev.version = 0;\r
        sdDev.ccs = 0;\r
        sdDev.capacity = 0;\r
@@ -666,9 +677,9 @@ int sdInit()
        if(v != 1){goto bad;}\r
 \r
        ledOn();\r
-       if (!sendIfCond()) goto bad; // Sets V1 or V2 flag\r
-       if (!sdOpCond()) goto bad;\r
-       if (!sdReadOCR()) goto bad;\r
+       if (!sendIfCond()) goto bad; // Sets V1 or V2 flag  CMD8\r
+       if (!sdOpCond()) goto bad; // ACMD41. Wait for init completes.\r
+       if (!sdReadOCR()) goto bad; // CMD58. Get CCS flag. Only valid after init.\r
 \r
        // This command will be ignored if sdDev.ccs is set.\r
        // SDHC and SDXC are always 512bytes.\r