mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2024-12-28 19:32:39 +00:00
Implemented multi-sector SD read command.
This commit is contained in:
parent
b9ed365266
commit
ad91a39f77
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
{
|
||||
uint8 v = sdWaitResp();
|
||||
if (v == 0xFF)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (v == 0xFE)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
scsiDiskReset();
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sdReadSector()
|
||||
{
|
||||
// Wait for a start-block token.
|
||||
uint8 token;
|
||||
do
|
||||
{
|
||||
token = sdSpiByte(0xFF);
|
||||
} while(token != 0xFE); // TODO don't loop forever here in case of error!
|
||||
|
||||
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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user