#include "disk.h"\r
#include "sd.h"\r
#include "led.h"\r
+#include "time.h"\r
\r
#include "scsiPhy.h"\r
\r
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
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
\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
\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
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
int result = 0;\r
int i;\r
uint8 v;\r
- \r
+\r
sdDev.version = 0;\r
sdDev.ccs = 0;\r
sdDev.capacity = 0;\r
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