Преглед изворни кода

Implemented multi-sector SD read command.

Michael McMaster пре 12 година
родитељ
комит
4f4b37bb16

+ 2 - 2
lib/SCSI2SD/readme.txt

@@ -43,7 +43,7 @@ Performance
 
 As currently implemented:
 
-Sequential read: 250kb/sec Sequential write: 240kb/sec
+Sequential read: 424kb/sec Sequential write: 414kb/sec
 
 Tested with a 16GB class 10 SD card, via the commands:
 
@@ -53,7 +53,7 @@ Tested with a 16GB class 10 SD card, via the commands:
  # READ TEST
  sudo dd bs=8192 count=100 if=/dev/sdX of=/dev/null
 
-I am working on updating the slow polling SD card communication to use DMA. I expect the performance to reach 1Mb/sec. 
+I am working on updating the SD card communication to use DMA, to allow simultaneous use of the SD and SCSI interfaces. I expect the performance to reach 1Mb/sec. 
 
 
 Compatibility

+ 4 - 12
lib/SCSI2SD/software/SCSI2SD/SCSI2SD.cydsn/disk.c

@@ -140,7 +140,7 @@ static void doRead(uint32 lba, uint32 blocks)
 		transfer.currentBlock = 0;
 		scsiDev.phase = DATA_IN;
 		scsiDev.dataLen = 0; // No data yet
-		sdPrepareRead(0);
+		sdPrepareRead();
 	}
 }
 
@@ -352,15 +352,7 @@ void scsiDiskPoll()
 	{
 		if (scsiDev.dataLen == 0)
 		{
-			if (sdIsReadReady())
-			{
-				sdReadSector();
-				if ((transfer.currentBlock + 1) < transfer.blocks)
-				{
-					sdPrepareRead(1); // Tell SD card to grab data while we send
-									// buffer to SCSI.
-				}
-			}
+			sdReadSector();
 		}
 		else if (scsiDev.dataPtr == scsiDev.dataLen)
 		{
@@ -371,6 +363,7 @@ void scsiDiskPoll()
 			{
 				scsiDev.phase = STATUS;
 				scsiDiskReset();
+				sdCompleteRead();
 			}
 		}
 	}
@@ -383,12 +376,11 @@ void scsiDiskPoll()
 			scsiDev.dataPtr = 0;
 			transfer.currentBlock++;
 			if (transfer.currentBlock >= transfer.blocks)
-				
 			{
 				scsiDev.dataLen = 0;
 				scsiDev.phase = STATUS;
 				scsiDiskReset();
-				
+
 				if (writeOk)
 				{
 					sdCompleteWrite();

+ 31 - 24
lib/SCSI2SD/software/SCSI2SD/SCSI2SD.cydsn/sd.c

@@ -127,14 +127,14 @@ static uint8 sdCRCCommandAndResponse(uint8 cmd, uint32 param)
 }
 
 
-void sdPrepareRead(int nextBlockOffset)
+void sdPrepareRead()
 {
-	uint32 len = (transfer.lba + transfer.currentBlock + nextBlockOffset);
+	uint32 len = (transfer.lba + transfer.currentBlock);
 	if (!sdDev.ccs)
 	{
 		len = len * SCSI_BLOCK_SIZE;
 	}
-	uint8 v = sdCommandAndResponse(17, len);
+	uint8 v = sdCommandAndResponse(SD_READ_MULTIPLE_BLOCK, len);
 	if (v)
 	{
 		scsiDiskReset();
@@ -146,30 +146,15 @@ void sdPrepareRead(int nextBlockOffset)
 	}
 }
 
-int sdIsReadReady()
+void sdReadSector()
 {
-	uint8 v = sdWaitResp();
-	if (v == 0xFF)
-	{
-		return 0;
-	}
-	else if (v == 0xFE)
-	{
-		return 1;
-	}
-	else
+	// Wait for a start-block token.
+	uint8 token;
+	do
 	{
-		scsiDiskReset();
-		scsiDev.status = CHECK_CONDITION;
-		scsiDev.sense.code = HARDWARE_ERROR;
-		scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
-		scsiDev.phase = STATUS;
-		return 0;
-	}
-}
+		token = sdSpiByte(0xFF);
+	} while(token != 0xFE); // TODO don't loop forever here in case of error!
 
-void sdReadSector()
-{
 	int prep = 0;
 	int i = 0;
 	while (i < SCSI_BLOCK_SIZE)
@@ -194,6 +179,28 @@ void sdReadSector()
 	scsiDev.dataPtr = 0;
 }
 
+void sdCompleteRead()
+{
+	//uint8 r1b = sdCommandAndResponse(SD_STOP_TRANSMISSION, 0);
+	sdSendCommand(SD_STOP_TRANSMISSION, 0);
+	sdSpiByte(0xFF); // NEED STUFF BYTE for cmd12
+	uint8 r1b = sdReadResp();
+	if (r1b)
+	{
+		scsiDev.status = CHECK_CONDITION;
+		scsiDev.sense.code = HARDWARE_ERROR;
+		scsiDev.sense.asc = UNRECOVERED_READ_ERROR;
+		scsiDev.phase = STATUS;
+	}
+	
+	// R1b has an optional trailing "busy" signal.
+	uint8 busy;
+	do
+	{
+		busy = sdSpiByte(0xFF);
+	} while (busy == 0);
+}
+
 static void sdWaitWriteBusy()
 {
 	uint8 val;

+ 4 - 2
lib/SCSI2SD/software/SCSI2SD/SCSI2SD.cydsn/sd.h

@@ -23,7 +23,9 @@ typedef enum
 	SD_SEND_OP_COND = 1,
 	SD_SEND_IF_COND = 8, // SD V2
 	SD_SEND_CSD = 9,
+	SD_STOP_TRANSMISSION = 12,
 	SD_SET_BLOCKLEN = 16,
+	SD_READ_MULTIPLE_BLOCK = 18,
 	SD_APP_SET_WR_BLK_ERASE_COUNT = 23,
 	SD_APP_SEND_OP_COND = 41,
 	SD_APP_CMD = 55,
@@ -56,8 +58,8 @@ void sdPrepareWrite();
 int sdWriteSector();
 void sdCompleteWrite();
 
-void sdPrepareRead(int nextBlockOffset);
-int sdIsReadReady();
+void sdPrepareRead();
 void sdReadSector();
+void sdCompleteRead();
 
 #endif