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