transfer.currentBlock = 0;\r
scsiDev.phase = DATA_OUT;\r
scsiDev.dataLen = SCSI_BLOCK_SIZE;\r
-\r
+ scsiDev.dataPtr = SCSI_BLOCK_SIZE; // TODO FIX scsiDiskPoll()\r
sdPrepareWrite();\r
}\r
}\r
else if (scsiDev.phase == DATA_OUT &&\r
transfer.currentBlock != transfer.blocks)\r
{\r
- if (scsiDev.dataPtr == SCSI_BLOCK_SIZE)\r
+ int writeOk = sdWriteSector();\r
+ // TODO FIX scsiDiskPoll() scsiDev.dataPtr = 0;\r
+ transfer.currentBlock++;\r
+ if (transfer.currentBlock >= transfer.blocks)\r
{\r
- int writeOk = sdWriteSector();\r
+ scsiDev.dataLen = 0;\r
scsiDev.dataPtr = 0;\r
- transfer.currentBlock++;\r
- if (transfer.currentBlock >= transfer.blocks)\r
- {\r
- scsiDev.dataLen = 0;\r
- scsiDev.phase = STATUS;\r
- scsiDiskReset();\r
+ scsiDev.phase = STATUS;\r
+ scsiDiskReset();\r
\r
- if (writeOk)\r
- {\r
- sdCompleteWrite();\r
- }\r
+ if (writeOk)\r
+ {\r
+ sdCompleteWrite();\r
}\r
}\r
}\r
\r
int sdWriteSector()\r
{\r
- int result, i, maxWait;\r
+ int prep, i, guard; \r
+ int result, maxWait;\r
uint8 dataToken;\r
+\r
+ // Don't do a bus settle delay if we're already in the correct phase.\r
+ if (transfer.currentBlock == 0)\r
+ {\r
+ scsiEnterPhase(DATA_OUT);\r
+ }\r
\r
// Wait for a previously-written sector to complete.\r
sdWaitWriteBusy();\r
-\r
sdSpiByte(0xFC); // MULTIPLE byte start token\r
- for (i = 0; i < SCSI_BLOCK_SIZE; i++)\r
+ \r
+ prep = 0;\r
+ i = 0;\r
+ guard = 0;\r
+\r
+ // This loop is critically important for performance.\r
+ // We stream data straight from the SCSI fifos into the SPIM component\r
+ // FIFO's. If the loop isn't fast enough, the transmit FIFO's will empty,\r
+ // and performance will suffer. Every clock cycle counts. \r
+ while (i < SCSI_BLOCK_SIZE)\r
{\r
- while(!(SDCard_ReadTxStatus() & SDCard_STS_TX_FIFO_NOT_FULL))\r
- {}\r
- SDCard_WriteTxData(scsiDev.data[i]);\r
- }\r
- while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE)) {}\r
- SDCard_ClearFIFO();\r
+ uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);\r
+ uint8_t scsiStatus = CY_GET_REG8(scsiTarget_StatusReg__STATUS_REG);\r
+\r
+ // Read from the SCSI fifo if there is room to stream the byte to the\r
+ // SPIM fifos\r
+ // See sdReadSector for comment on guard (FIFO size is really 5)\r
+ if((guard - i < 4) &&\r
+ (scsiStatus & 2)) // SCSI RX FIFO NOT EMPTY\r
+ {\r
+ uint8_t val = CY_GET_REG8(scsiTarget_datapath__F1_REG);\r
+ CY_SET_REG8(SDCard_TXDATA_PTR, val);\r
+ guard++;\r
+ }\r
+ \r
+ // Byte has been sent out the SPIM interface.\r
+ if (sdRxStatus & SDCard_STS_RX_FIFO_NOT_EMPTY)\r
+ {\r
+ CY_GET_REG8(SDCard_RXDATA_PTR);\r
+ ++i;\r
+ }\r
\r
+ if (prep < SCSI_BLOCK_SIZE &&\r
+ (scsiStatus & 1) // SCSI TX FIFO NOT FULL\r
+ )\r
+ {\r
+ // Trigger the SCSI component to read a byte\r
+ CY_SET_REG8(scsiTarget_datapath__F0_REG, 0xFF);\r
+ prep++;\r
+ } \r
+ }\r
+ \r
sdSpiByte(0x00); // CRC\r
sdSpiByte(0x00); // CRC\r
\r