}
else
{
+ /* MM: Prepare for write */
+ /* Set Block Size for Card */
+ sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+ sdio_cmdinitstructure.Argument = (uint32_t)NumberOfBlocks;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCK_COUNT;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCK_COUNT);
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* /MM */
+
/* Send CMD25 WRITE_MULT_BLOCK with argument data address */
sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
}
\r
#include <string.h>\r
\r
-static const uint16_t FIRMWARE_VERSION = 0x0605;\r
+static const uint16_t FIRMWARE_VERSION = 0x0606;\r
\r
// 1 flash row\r
static const uint8_t DEFAULT_CONFIG[128] =\r
likely(scsiDev.phase == DATA_IN) &&\r
likely(!scsiDev.resetFlag))\r
{\r
- // Wait for the next DMA interrupt. It's beneficial to halt the\r
- // processor to give the DMA controller more memory bandwidth to\r
- // work with.\r
- if (sdActive && scsiActive)\r
- {\r
- __WFI();\r
- }\r
-\r
if (sdActive && sdReadDMAPoll())\r
{\r
prep += sdActive;\r
// Start an SD transfer if we have space.\r
uint32_t startBuffer = prep % buffers;\r
uint32_t sectors = totalSDSectors - prep;\r
+#if 0\r
if (!scsiActive && prep == i)\r
{\r
sectors = 1; // We need to get some data to send ASAP !\r
}\r
else\r
+#endif\r
{\r
uint32_t freeBuffers = buffers - (prep - i);\r
uint32_t contiguousBuffers = buffers - startBuffer;\r
likely(scsiDev.phase == DATA_IN) &&\r
likely(!scsiDev.resetFlag))\r
{\r
- __WFI();\r
}\r
\r
\r
}\r
else\r
{\r
+ // TODO this hurts performance significantly! Work out why __WFI()\r
+ // doesn't wake up immediately !\r
+#if 0\r
// Wait for our 1ms timer to save some power.\r
// There's an interrupt on the SEL signal to ensure we respond\r
// quickly to any SCSI commands. The selection abort time is\r
\r
if (!*SCSI_STS_SELECTED)\r
{\r
- __WFI(); // Will wake on interrupt, regardless of mask\r
+ //__WFI(); // Will wake on interrupt, regardless of mask\r
}\r
if (!interruptState)\r
{\r
__enable_irq();\r
}\r
+#endif\r
}\r
}\r
else if (scsiDev.phase >= 0)\r
typedef struct
{
- uint8_t data[MAX_SECTOR_SIZE * 2]; // Must be aligned for DMA
+ // TODO reduce this buffer size and add a proper cache
+ uint8_t data[MAX_SECTOR_SIZE * 8]; // Must be aligned for DMA
TargetState targets[S2S_MAX_TARGETS];
TargetState* target;
scsiRead(uint8_t* data, uint32_t count)\r
{\r
int i = 0;\r
+\r
+\r
+ uint32_t chunk = ((count - i) > SCSI_FIFO_DEPTH)\r
+ ? SCSI_FIFO_DEPTH : (count - i);\r
+ if (chunk >= 16)\r
+ {\r
+ // DMA is doing 32bit transfers.\r
+ chunk = chunk & 0xFFFFFFF8;\r
+ }\r
+ startScsiRx(chunk);\r
+\r
while (i < count && likely(!scsiDev.resetFlag))\r
{\r
- uint32_t chunk = ((count - i) > SCSI_FIFO_DEPTH)\r
- ? SCSI_FIFO_DEPTH : (count - i);\r
+ while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
+ scsiPhyFifoFlip();\r
\r
- if (chunk >= 16)\r
+ uint32_t nextChunk = ((count - i - chunk) > SCSI_FIFO_DEPTH)\r
+ ? SCSI_FIFO_DEPTH : (count - i - chunk);\r
+ if (nextChunk >= 16)\r
{\r
- // DMA is doing 32bit transfers.\r
- chunk = chunk & 0xFFFFFFF8;\r
+ nextChunk = nextChunk & 0xFFFFFFF8;\r
}\r
-\r
-#if FIFODEBUG\r
- if (!scsiPhyFifoAltEmpty()) {\r
- // Force a lock-up.\r
- assertFail();\r
+ if (nextChunk > 0)\r
+ {\r
+ startScsiRx(nextChunk);\r
}\r
-#endif\r
-\r
- startScsiRx(chunk);\r
- // Wait for the next scsi interrupt (or the 1ms systick)\r
- __WFI();\r
-\r
- while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
- scsiPhyFifoFlip();\r
\r
if (chunk < 16)\r
{\r
{\r
scsiReadDMA(data + i, chunk);\r
\r
- // Wait for the next DMA interrupt (or the 1ms systick)\r
- // It's beneficial to halt the processor to\r
- // give the DMA controller more memory bandwidth to work with.\r
- __WFI();\r
trace(trace_spinReadDMAPoll);\r
\r
while (!scsiReadDMAPoll() && likely(!scsiDev.resetFlag))\r
{\r
- __WFI();\r
};\r
}\r
\r
}\r
#endif\r
i += chunk;\r
+ chunk = nextChunk;\r
}\r
}\r
\r
chunk = chunk & 0xFFFFFFF8;\r
scsiWriteDMA(data + i, chunk);\r
\r
- // Wait for the next DMA interrupt (or the 1ms systick)\r
- // It's beneficial to halt the processor to\r
- // give the DMA controller more memory bandwidth to work with.\r
- __WFI();\r
trace(trace_spinReadDMAPoll);\r
\r
while (!scsiWriteDMAPoll() && likely(!scsiDev.resetFlag))\r
{\r
- __WFI();\r
- };\r
+ }\r
}\r
\r
while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
{\r
- __WFI();\r
}\r
\r
#if FIFODEBUG\r
}\r
while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
{\r
- __WFI();\r
}\r
\r
#if FIFODEBUG\r