Fix timeout issue on entering data-in phase v6.2.4
authorMichael McMaster <michael@codesrc.com>
Thu, 2 May 2019 09:54:15 +0000 (19:54 +1000)
committerMichael McMaster <michael@codesrc.com>
Thu, 2 May 2019 09:54:15 +0000 (19:54 +1000)
CHANGELOG
rtl/fpga_bitmap.o
src/firmware/config.c
src/firmware/disk.c
src/firmware/scsiPhy.c
src/firmware/scsiPhy.h

index a98974e..a30aa5e 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,8 @@
-2019XXXX
+20190502               6.2.4
        - Port XEBEC support from v5 firmware
        - Add Flexible Disk Drive Geometry SCSI MODE page
        - Stability improvements
+       - Fix regression from 6.1.3 firmware for Kurzweil K2000
 
 20181011               6.2.1
        - Fix bug in USB disk interface with disks over 4GB
index 48d78e9..857b042 100644 (file)
Binary files a/rtl/fpga_bitmap.o and b/rtl/fpga_bitmap.o differ
index 503833a..442a9fa 100755 (executable)
@@ -37,7 +37,7 @@
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x0623;\r
+static const uint16_t FIRMWARE_VERSION = 0x0624;\r
 \r
 // 1 flash row\r
 static const uint8_t DEFAULT_CONFIG[128] =\r
index 55eecdc..961387f 100755 (executable)
@@ -543,6 +543,8 @@ void scsiDiskPoll()
        if (scsiDev.phase == DATA_IN &&\r
                transfer.currentBlock != transfer.blocks)\r
        {\r
+               // Take responsibility for waiting for the phase delays\r
+               uint32_t phaseChangeDelayUs = scsiEnterPhaseImmediate(DATA_IN);\r
 \r
                int totalSDSectors =\r
                        transfer.blocks * SDSectorsPerSCSISector(bytesPerSector);\r
@@ -562,7 +564,7 @@ void scsiDiskPoll()
                uint32_t partialScsiChunk = 0;\r
 \r
                // Start reading from the SD card FIRST, because we change state and\r
-               // wai for SCSI signals\r
+               // wait for SCSI signals\r
                int dataInStarted = 0;\r
 \r
                while ((i < totalSDSectors) &&\r
@@ -611,10 +613,14 @@ void scsiDiskPoll()
 \r
                                sdActive = sectors;\r
 \r
-                               if (!dataInStarted)\r
+                               // Wait now that the SD card is busy\r
+                               // Chances are we've probably already waited sufficient time,\r
+                               // but it's hard to measure microseconds cheaply. So just wait\r
+                               // extra just-in-case. Hopefully it's in parallel with dma.\r
+                               if (phaseChangeDelayUs > 0)\r
                                {\r
-                                       dataInStarted = 1;\r
-                                       scsiEnterPhase(DATA_IN); // Will wait a few microseconds.\r
+                                       s2s_delay_us(phaseChangeDelayUs);\r
+                                       phaseChangeDelayUs = 0;\r
                                }\r
                        }\r
 \r
@@ -685,9 +691,10 @@ void scsiDiskPoll()
 #endif\r
                }\r
 \r
-               if (!dataInStarted && !scsiDev.resetFlag) // zero bytes ?\r
+               if (phaseChangeDelayUs > 0 && !scsiDev.resetFlag) // zero bytes ?\r
                {\r
-                       scsiEnterPhase(DATA_IN); // Will wait a few microseconds.\r
+                       s2s_delay_us(phaseChangeDelayUs);\r
+                       phaseChangeDelayUs = 0;\r
                }\r
 \r
                // We've finished transferring the data to the FPGA, now wait until it's\r
index c00b8d5..deb67b2 100755 (executable)
@@ -30,8 +30,8 @@
 static uint8_t asyncTimings[][4] =\r
 {\r
 /* Speed,    Assert,    Deskew,    Hold,    Glitch */\r
-{/*1.5MB/s*/ 28,        18,        13,      6},\r
-{/*3.3MB/s*/ 13,        6,         6,       6},\r
+{/*1.5MB/s*/ 28,        18,        13,      15},\r
+{/*3.3MB/s*/ 13,        6,         6,       13},\r
 {/*5MB/s*/   9,         6,         6,       6}, // 80ns\r
 {/*safe*/    3,         6,         6,       6}, // Probably safe\r
 {/*turbo*/   3,         3,         3,       2}\r
@@ -481,6 +481,16 @@ scsiSetDefaultTiming()
 }\r
 \r
 void scsiEnterPhase(int newPhase)\r
+{\r
+       uint32_t delay = scsiEnterPhaseImmediate(newPhase);\r
+       if (delay > 0)\r
+       {\r
+               s2s_delay_us(delay);\r
+       }\r
+}\r
+\r
+// Returns microsecond delay\r
+uint32_t scsiEnterPhaseImmediate(int newPhase)\r
 {\r
        // ANSI INCITS 362-2002 SPI-3 10.7.1:\r
        // Phase changes are not allowed while REQ or ACK is asserted.\r
@@ -569,22 +579,27 @@ void scsiEnterPhase(int newPhase)
                                asyncTiming[3]);\r
                }\r
 \r
+               uint32_t delayUs = 0;\r
                if (newPhase >= 0)\r
                {\r
                        *SCSI_CTRL_PHASE = newPhase;\r
-                       busSettleDelay();\r
+                       delayUs += 1; // busSettleDelay\r
 \r
                        if (scsiDev.compatMode < COMPAT_SCSI2)\r
                        {\r
                                // EMU EMAX needs 100uS ! 10uS is not enough.\r
-                               s2s_delay_us(100);\r
+                               delayUs += 100;\r
                        }\r
                }\r
                else\r
                {\r
                        *SCSI_CTRL_PHASE = 0;\r
                }\r
+\r
+               return delayUs;\r
        }\r
+\r
+       return 0; // No change\r
 }\r
 \r
 uint32_t s2s_getScsiRateMBs()\r
index a99ed36..19f0aa6 100755 (executable)
@@ -89,6 +89,7 @@ void scsiPhyConfig(void);
 void scsiPhyReset(void);
 
 void scsiEnterPhase(int phase);
+uint32_t scsiEnterPhaseImmediate(int phase);
 void scsiEnterBusFree(void);
 
 void scsiSetDataCount(uint32_t count);