瀏覽代碼

Fix stop-bit for samsung SD cards.

Michael McMaster 11 年之前
父節點
當前提交
3e347f42ba
共有 1 個文件被更改,包括 39 次插入28 次删除
  1. 39 28
      lib/SCSI2SD/software/SCSI2SD/src/sd.c

+ 39 - 28
lib/SCSI2SD/software/SCSI2SD/src/sd.c

@@ -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.