Jelajahi Sumber

Fix timeout issue on entering data-in phase

Michael McMaster 6 tahun lalu
induk
melakukan
7506dc64cc

+ 2 - 1
lib/SCSI2SD/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

TEMPAT SAMPAH
lib/SCSI2SD/rtl/fpga_bitmap.o


+ 1 - 1
lib/SCSI2SD/src/firmware/config.c

@@ -37,7 +37,7 @@
 
 #include <string.h>
 
-static const uint16_t FIRMWARE_VERSION = 0x0623;
+static const uint16_t FIRMWARE_VERSION = 0x0624;
 
 // 1 flash row
 static const uint8_t DEFAULT_CONFIG[128] =

+ 13 - 6
lib/SCSI2SD/src/firmware/disk.c

@@ -543,6 +543,8 @@ void scsiDiskPoll()
 	if (scsiDev.phase == DATA_IN &&
 		transfer.currentBlock != transfer.blocks)
 	{
+		// Take responsibility for waiting for the phase delays
+		uint32_t phaseChangeDelayUs = scsiEnterPhaseImmediate(DATA_IN);
 
 		int totalSDSectors =
 			transfer.blocks * SDSectorsPerSCSISector(bytesPerSector);
@@ -562,7 +564,7 @@ void scsiDiskPoll()
 		uint32_t partialScsiChunk = 0;
 
 		// Start reading from the SD card FIRST, because we change state and
-		// wai for SCSI signals
+		// wait for SCSI signals
 		int dataInStarted = 0;
 
 		while ((i < totalSDSectors) &&
@@ -611,10 +613,14 @@ void scsiDiskPoll()
 
 				sdActive = sectors;
 
-				if (!dataInStarted)
+				// Wait now that the SD card is busy
+				// Chances are we've probably already waited sufficient time,
+				// but it's hard to measure microseconds cheaply. So just wait
+				// extra just-in-case. Hopefully it's in parallel with dma.
+				if (phaseChangeDelayUs > 0)
 				{
-					dataInStarted = 1;
-					scsiEnterPhase(DATA_IN); // Will wait a few microseconds.
+					s2s_delay_us(phaseChangeDelayUs);
+					phaseChangeDelayUs = 0;
 				}
 			}
 
@@ -685,9 +691,10 @@ void scsiDiskPoll()
 #endif
 		}
 
-		if (!dataInStarted && !scsiDev.resetFlag) // zero bytes ?
+		if (phaseChangeDelayUs > 0 && !scsiDev.resetFlag) // zero bytes ?
 		{
-			scsiEnterPhase(DATA_IN); // Will wait a few microseconds.
+			s2s_delay_us(phaseChangeDelayUs);
+			phaseChangeDelayUs = 0;
 		}
 
 		// We've finished transferring the data to the FPGA, now wait until it's

+ 19 - 4
lib/SCSI2SD/src/firmware/scsiPhy.c

@@ -30,8 +30,8 @@
 static uint8_t asyncTimings[][4] =
 {
 /* Speed,    Assert,    Deskew,    Hold,    Glitch */
-{/*1.5MB/s*/ 28,        18,        13,      6},
-{/*3.3MB/s*/ 13,        6,         6,       6},
+{/*1.5MB/s*/ 28,        18,        13,      15},
+{/*3.3MB/s*/ 13,        6,         6,       13},
 {/*5MB/s*/   9,         6,         6,       6}, // 80ns
 {/*safe*/    3,         6,         6,       6}, // Probably safe
 {/*turbo*/   3,         3,         3,       2}
@@ -481,6 +481,16 @@ scsiSetDefaultTiming()
 }
 
 void scsiEnterPhase(int newPhase)
+{
+	uint32_t delay = scsiEnterPhaseImmediate(newPhase);
+	if (delay > 0)
+	{
+		s2s_delay_us(delay);
+	}
+}
+
+// Returns microsecond delay
+uint32_t scsiEnterPhaseImmediate(int newPhase)
 {
 	// ANSI INCITS 362-2002 SPI-3 10.7.1:
 	// Phase changes are not allowed while REQ or ACK is asserted.
@@ -569,22 +579,27 @@ void scsiEnterPhase(int newPhase)
 				asyncTiming[3]);
 		}
 
+		uint32_t delayUs = 0;
 		if (newPhase >= 0)
 		{
 			*SCSI_CTRL_PHASE = newPhase;
-			busSettleDelay();
+			delayUs += 1; // busSettleDelay
 
 			if (scsiDev.compatMode < COMPAT_SCSI2)
 			{
 				// EMU EMAX needs 100uS ! 10uS is not enough.
-				s2s_delay_us(100);
+				delayUs += 100;
 			}
 		}
 		else
 		{
 			*SCSI_CTRL_PHASE = 0;
 		}
+
+		return delayUs;
 	}
+
+	return 0; // No change
 }
 
 uint32_t s2s_getScsiRateMBs()

+ 1 - 0
lib/SCSI2SD/src/firmware/scsiPhy.h

@@ -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);