mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2024-10-19 17:23:50 +00:00
Write performance improvements. Doubled performance to 900kb/sec.
This commit is contained in:
parent
3e22ca4e6f
commit
0629f76919
@ -43,7 +43,7 @@ Performance
|
||||
|
||||
As currently implemented:
|
||||
|
||||
Sequential read: 930kb/sec Sequential write: 414kb/sec
|
||||
Sequential read: 930kb/sec Sequential write: 900kb/sec
|
||||
|
||||
Tested with a 16GB class 10 SD card, via the commands:
|
||||
|
||||
|
@ -117,7 +117,7 @@ static void doWrite(uint32 lba, uint32 blocks)
|
||||
transfer.currentBlock = 0;
|
||||
scsiDev.phase = DATA_OUT;
|
||||
scsiDev.dataLen = SCSI_BLOCK_SIZE;
|
||||
|
||||
scsiDev.dataPtr = SCSI_BLOCK_SIZE; // TODO FIX scsiDiskPoll()
|
||||
sdPrepareWrite();
|
||||
}
|
||||
}
|
||||
@ -370,21 +370,19 @@ void scsiDiskPoll()
|
||||
else if (scsiDev.phase == DATA_OUT &&
|
||||
transfer.currentBlock != transfer.blocks)
|
||||
{
|
||||
if (scsiDev.dataPtr == SCSI_BLOCK_SIZE)
|
||||
int writeOk = sdWriteSector();
|
||||
// TODO FIX scsiDiskPoll() scsiDev.dataPtr = 0;
|
||||
transfer.currentBlock++;
|
||||
if (transfer.currentBlock >= transfer.blocks)
|
||||
{
|
||||
int writeOk = sdWriteSector();
|
||||
scsiDev.dataLen = 0;
|
||||
scsiDev.dataPtr = 0;
|
||||
transfer.currentBlock++;
|
||||
if (transfer.currentBlock >= transfer.blocks)
|
||||
{
|
||||
scsiDev.dataLen = 0;
|
||||
scsiDev.phase = STATUS;
|
||||
scsiDiskReset();
|
||||
scsiDev.phase = STATUS;
|
||||
scsiDiskReset();
|
||||
|
||||
if (writeOk)
|
||||
{
|
||||
sdCompleteWrite();
|
||||
}
|
||||
if (writeOk)
|
||||
{
|
||||
sdCompleteWrite();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -284,22 +284,61 @@ static void sdWaitWriteBusy()
|
||||
|
||||
int sdWriteSector()
|
||||
{
|
||||
int result, i, maxWait;
|
||||
int prep, i, guard;
|
||||
int result, maxWait;
|
||||
uint8 dataToken;
|
||||
|
||||
// Don't do a bus settle delay if we're already in the correct phase.
|
||||
if (transfer.currentBlock == 0)
|
||||
{
|
||||
scsiEnterPhase(DATA_OUT);
|
||||
}
|
||||
|
||||
// Wait for a previously-written sector to complete.
|
||||
sdWaitWriteBusy();
|
||||
|
||||
sdSpiByte(0xFC); // MULTIPLE byte start token
|
||||
for (i = 0; i < SCSI_BLOCK_SIZE; i++)
|
||||
{
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_TX_FIFO_NOT_FULL))
|
||||
{}
|
||||
SDCard_WriteTxData(scsiDev.data[i]);
|
||||
}
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE)) {}
|
||||
SDCard_ClearFIFO();
|
||||
|
||||
prep = 0;
|
||||
i = 0;
|
||||
guard = 0;
|
||||
|
||||
// This loop is critically important for performance.
|
||||
// We stream data straight from the SCSI fifos into the SPIM component
|
||||
// FIFO's. If the loop isn't fast enough, the transmit FIFO's will empty,
|
||||
// and performance will suffer. Every clock cycle counts.
|
||||
while (i < SCSI_BLOCK_SIZE)
|
||||
{
|
||||
uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);
|
||||
uint8_t scsiStatus = CY_GET_REG8(scsiTarget_StatusReg__STATUS_REG);
|
||||
|
||||
// Read from the SCSI fifo if there is room to stream the byte to the
|
||||
// SPIM fifos
|
||||
// See sdReadSector for comment on guard (FIFO size is really 5)
|
||||
if((guard - i < 4) &&
|
||||
(scsiStatus & 2)) // SCSI RX FIFO NOT EMPTY
|
||||
{
|
||||
uint8_t val = CY_GET_REG8(scsiTarget_datapath__F1_REG);
|
||||
CY_SET_REG8(SDCard_TXDATA_PTR, val);
|
||||
guard++;
|
||||
}
|
||||
|
||||
// Byte has been sent out the SPIM interface.
|
||||
if (sdRxStatus & SDCard_STS_RX_FIFO_NOT_EMPTY)
|
||||
{
|
||||
CY_GET_REG8(SDCard_RXDATA_PTR);
|
||||
++i;
|
||||
}
|
||||
|
||||
if (prep < SCSI_BLOCK_SIZE &&
|
||||
(scsiStatus & 1) // SCSI TX FIFO NOT FULL
|
||||
)
|
||||
{
|
||||
// Trigger the SCSI component to read a byte
|
||||
CY_SET_REG8(scsiTarget_datapath__F0_REG, 0xFF);
|
||||
prep++;
|
||||
}
|
||||
}
|
||||
|
||||
sdSpiByte(0x00); // CRC
|
||||
sdSpiByte(0x00); // CRC
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user