Synchronous support 5MB/s and 10MB/s working.
[SCSI2SD-V6.git] / src / firmware / scsiPhy.c
index 2231089d8bdefb3ef317851a0eda745c6e5b76b3..71640f4ff74b47e30f36df43bf735dc7b185e452 100755 (executable)
 \r
 #include <string.h>\r
 \r
+// Assumes a 60MHz fpga clock.\r
+// 7:6 Hold count, 45ns\r
+// 5:3 Assertion count, 90ns\r
+// 2:0 Deskew count, 55ns\r
+#define SCSI_DEFAULT_TIMING ((0x3 << 6) | (0x6 << 3) | 0x4)\r
+\r
+// 7:6 Hold count, 10ns\r
+// 5:3 Assertion count, 30ns\r
+// 2:0 Deskew count, 25ns\r
+#define SCSI_FAST_TIMING ((0x1 << 6) | (0x2 << 3) | 0x2)\r
+\r
 // Private DMA variables.\r
 static int dmaInProgress = 0;\r
 \r
@@ -218,17 +229,21 @@ scsiRead(uint8_t* data, uint32_t count)
                        };\r
                }\r
 \r
-#if FIFODEBUG\r
-               if (!scsiPhyFifoEmpty()) {\r
+\r
+               i += chunk;\r
+               chunk = nextChunk;\r
+       }\r
+#if 1\r
+               if (!scsiPhyFifoEmpty() || !scsiPhyFifoAltEmpty()) {\r
                        int j = 0;\r
                        while (!scsiPhyFifoEmpty()) { scsiPhyRx(); ++j; }\r
+                       scsiPhyFifoFlip();\r
+                       int k = 0;\r
+                       while (!scsiPhyFifoEmpty()) { scsiPhyRx(); ++k; }\r
                        // Force a lock-up.\r
                        assertFail();\r
                }\r
 #endif\r
-               i += chunk;\r
-               chunk = nextChunk;\r
-       }\r
 }\r
 \r
 void\r
@@ -382,12 +397,29 @@ void scsiEnterPhase(int phase)
        int newPhase = phase > 0 ? phase : 0;\r
        int oldPhase = *SCSI_CTRL_PHASE;\r
 \r
-       if (!scsiPhyFifoEmpty() || !scsiPhyFifoAltEmpty()) {\r
+       if (!scsiDev.resetFlag && (!scsiPhyFifoEmpty() || !scsiPhyFifoAltEmpty())) {\r
                // Force a lock-up.\r
                assertFail();\r
        }\r
        if (newPhase != oldPhase)\r
        {\r
+               if ((newPhase == DATA_IN || newPhase == DATA_OUT) &&\r
+                       scsiDev.target->syncOffset)\r
+               {\r
+                       if (scsiDev.target->syncPeriod == 25)\r
+                       {\r
+                               // SCSI2 FAST Timing. 10MB/s.\r
+                               *SCSI_CTRL_TIMING = SCSI_FAST_TIMING;\r
+                       } else {\r
+                               // 5MB/s Timing\r
+                               *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+                       }\r
+                       *SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;\r
+               } else {\r
+                       *SCSI_CTRL_SYNC_OFFSET = 0;\r
+                       *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+               }\r
+\r
                *SCSI_CTRL_PHASE = newPhase;\r
                busSettleDelay();\r
 \r
@@ -446,6 +478,9 @@ void scsiPhyReset()
        *SCSI_FIFO_SEL = 0;\r
        *SCSI_CTRL_DBX = 0;\r
 \r
+       *SCSI_CTRL_SYNC_OFFSET = 0;\r
+       *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+\r
        // DMA Benchmark code\r
        // Currently 10MB/s. Assume 20MB/s is achievable with 16 bits.\r
        #ifdef DMA_BENCHMARK\r
@@ -609,6 +644,9 @@ void scsiPhyInit()
        *SCSI_FIFO_SEL = 0;\r
        *SCSI_CTRL_DBX = 0;\r
 \r
+       *SCSI_CTRL_SYNC_OFFSET = 0;\r
+       *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+\r
 }\r
 \r
 void scsiPhyConfig()\r