Fix terrible performance
[SCSI2SD-V6.git] / src / firmware / scsiPhy.c
index cb9c206..2231089 100755 (executable)
@@ -176,30 +176,32 @@ void
 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
@@ -209,20 +211,10 @@ scsiRead(uint8_t* data, uint32_t count)
                {\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
-#if 0\r
-                       __WFI();\r
-#endif\r
                        trace(trace_spinReadDMAPoll);\r
 \r
                        while (!scsiReadDMAPoll() && likely(!scsiDev.resetFlag))\r
                        {\r
-#if 0\r
-// TODO NEED SCSI DMA IRQs\r
-                       __WFI();\r
-#endif\r
                        };\r
                }\r
 \r
@@ -235,6 +227,7 @@ scsiRead(uint8_t* data, uint32_t count)
                }\r
 #endif\r
                i += chunk;\r
+               chunk = nextChunk;\r
        }\r
 }\r
 \r
@@ -333,24 +326,16 @@ scsiWrite(const uint8_t* data, uint32_t count)
                        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
-#if 0\r
-                       __WFI();\r
-#endif\r
                        trace(trace_spinReadDMAPoll);\r
 \r
                        while (!scsiWriteDMAPoll() && likely(!scsiDev.resetFlag))\r
                        {\r
-#if 0\r
-// TODO NEED SCSI DMA IRQs\r
-                       __WFI();\r
-#endif\r
-                       };\r
+                       }\r
                }\r
 \r
-               while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
+               while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
+               {\r
+               }\r
 \r
 #if FIFODEBUG\r
                if (!scsiPhyFifoAltEmpty()) {\r
@@ -360,14 +345,11 @@ scsiWrite(const uint8_t* data, uint32_t count)
 #endif\r
 \r
                scsiPhyFifoFlip();\r
-#if 0\r
-// TODO NEED SCSI IRQs\r
-                       __WFI();\r
-#endif\r
-\r
                i += chunk;\r
        }\r
-       while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
+       while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
+       {\r
+       }\r
 \r
 #if FIFODEBUG\r
        if (!scsiPhyFifoAltEmpty()) {\r
@@ -462,6 +444,7 @@ void scsiPhyReset()
 \r
        scsiPhyFifoSel = 0;\r
        *SCSI_FIFO_SEL = 0;\r
+       *SCSI_CTRL_DBX = 0;\r
 \r
        // DMA Benchmark code\r
        // Currently 10MB/s. Assume 20MB/s is achievable with 16 bits.\r
@@ -493,7 +476,6 @@ void scsiPhyReset()
 \r
        // FPGA comms test code\r
        #ifdef FPGA_TEST\r
-\r
        while(1)\r
        {\r
                for (int j = 0; j < SCSI_FIFO_DEPTH; ++j)\r
@@ -501,6 +483,11 @@ void scsiPhyReset()
                        scsiDev.data[j] = j;\r
                }\r
 \r
+               if (!scsiPhyFifoEmpty())\r
+               {\r
+                       assertFail();\r
+               }\r
+\r
                *SCSI_CTRL_PHASE = DATA_IN;\r
                HAL_DMA_Start(\r
                        &memToFSMC,\r
@@ -513,6 +500,11 @@ void scsiPhyReset()
                        HAL_DMA_FULL_TRANSFER,\r
                        0xffffffff);\r
 \r
+               if (!scsiPhyFifoFull())\r
+               {\r
+                       assertFail();\r
+               }\r
+\r
                memset(&scsiDev.data[0], 0, SCSI_FIFO_DEPTH);\r
 \r
                *SCSI_CTRL_PHASE = DATA_OUT;\r
@@ -527,6 +519,12 @@ void scsiPhyReset()
                        HAL_DMA_FULL_TRANSFER,\r
                        0xffffffff);\r
 \r
+               if (!scsiPhyFifoEmpty())\r
+               {\r
+                       assertFail();\r
+               }\r
+\r
+\r
                for (int j = 0; j < SCSI_FIFO_DEPTH; ++j)\r
                {\r
                        if (scsiDev.data[j] != (uint8_t) j)\r
@@ -609,6 +607,7 @@ void scsiPhyInit()
        *SCSI_CTRL_BSY = 0x00;\r
        scsiPhyFifoSel = 0;\r
        *SCSI_FIFO_SEL = 0;\r
+       *SCSI_CTRL_DBX = 0;\r
 \r
 }\r
 \r
@@ -645,30 +644,55 @@ void scsiPhyConfig()
 // 32 = other error\r
 int scsiSelfTest()\r
 {\r
-       return 0;\r
-#if 0\r
+       if (scsiDev.phase != BUS_FREE)\r
+       {\r
+               return 32;\r
+       }\r
+\r
+       // Acquire the SCSI bus.\r
+       for (int i = 0; i < 100; ++i)\r
+       {\r
+               if (scsiStatusBSY())\r
+               {\r
+                       s2s_delay_ms(1);\r
+               }\r
+       }\r
+       if (scsiStatusBSY())\r
+       {\r
+               // Error, couldn't acquire scsi bus\r
+               return 32;\r
+       }\r
+       *SCSI_CTRL_BSY = 1;\r
+       if (! scsiStatusBSY())\r
+       {\r
+               // Error, BSY doesn't work.\r
+               return 32;\r
+       }\r
+\r
+       // Should be safe to use the bus now.\r
+\r
        int result = 0;\r
 \r
-       // TEST DBx and DBp\r
+       // TEST DBx\r
+       // TODO test DBp\r
        int i;\r
-       SCSI_Out_Ctl_Write(1); // Write bits manually.\r
-       SCSI_CTL_PHASE_Write(__scsiphase_io); // Needed for parity generation\r
        for (i = 0; i < 256; ++i)\r
        {\r
-               SCSI_Out_Bits_Write(i);\r
-               scsiDeskewDelay();\r
-               if (scsiReadDBxPins() != (i & 0xff))\r
+               *SCSI_CTRL_DBX = i;\r
+               busSettleDelay();\r
+               if (*SCSI_STS_DBX != (i & 0xff))\r
                {\r
                        result |= 1;\r
                }\r
-               if (Lookup_OddParity[i & 0xff] != SCSI_ReadPin(SCSI_In_DBP))\r
+               /*if (Lookup_OddParity[i & 0xff] != SCSI_ReadPin(SCSI_In_DBP))\r
                {\r
                        result |= 2;\r
-               }\r
+               }*/\r
        }\r
-       SCSI_Out_Ctl_Write(0); // Write bits normally.\r
+       *SCSI_CTRL_DBX = 0;\r
 \r
        // TEST MSG, CD, IO\r
+       /* TODO\r
        for (i = 0; i < 8; ++i)\r
        {\r
                SCSI_CTL_PHASE_Write(i);\r
@@ -717,7 +741,9 @@ int scsiSelfTest()
                }\r
                SCSI_ClearPin(signalsOut[i]);\r
        }\r
+       */\r
+\r
+       *SCSI_CTRL_BSY = 0;\r
        return result;\r
-#endif\r
 }\r
 \r