Fix stop-bit for samsung SD cards.

This commit is contained in:
Michael McMaster 2014-10-27 23:27:46 +10:00
parent 0c53240659
commit f2ce3c3c6b

View File

@ -21,6 +21,7 @@
#include "disk.h"
#include "sd.h"
#include "led.h"
#include "time.h"
#include "scsiPhy.h"
@ -111,7 +112,7 @@ static void sdSendCommand(uint8 cmd, uint32 param)
send[2] = param >> 16;
send[3] = param >> 8;
send[4] = param;
send[5] = 0;
send[5] = 1; // 7:1 CRC, 0: Stop bit.
for(cmd = 0; cmd < sizeof(send); cmd++)
{
@ -187,12 +188,11 @@ static void
dmaReadSector(uint8_t* outputBuffer)
{
// 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);
while (token != 0xFE && (maxWait-- > 0))
while (token != 0xFE && (diffTime_ms(start, getTime_ms()) <= 200))
{
token = sdSpiByte(0xFF);
}
@ -475,6 +475,8 @@ static int sendIfCond()
do
{
// 11:8 Host voltage. 1 = 2.7-3.6V
// 7:0 Echo bits. Ignore.
uint8 status = sdCRCCommandAndResponse(SD_SEND_IF_COND, 0x000001AA);
if (status == SD_R1_IDLE)
@ -505,41 +507,50 @@ static int sendIfCond()
static int sdOpCond()
{
int retries = 50;
uint32_t start = getTime_ms();
uint8 status;
do
{
CyDelay(33); // Spec says to retry for 1 second.
sdCRCCommandAndResponse(SD_APP_CMD, 0);
// Host Capacity Support = 1 (SDHC/SDXC supported)
status = sdCRCCommandAndResponse(SD_APP_SEND_OP_COND, 0x40000000);
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()
{
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()
@ -547,7 +558,7 @@ static int sdReadCSD()
uint8 startToken;
int maxWait, i;
uint8 buf[16];
uint8 status = sdCRCCommandAndResponse(SD_SEND_CSD, 0);
if(status){goto bad;}
@ -634,7 +645,7 @@ int sdInit()
int result = 0;
int i;
uint8 v;
sdDev.version = 0;
sdDev.ccs = 0;
sdDev.capacity = 0;
@ -666,9 +677,9 @@ int sdInit()
if(v != 1){goto bad;}
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.
// SDHC and SDXC are always 512bytes.