Browse Source

Fix pauses during transfer in PIO mode (#70)

Some SCSI hosts expect that a whole sector is transferred without any gaps.
This was previously fixed for DMA modes, but the PIO mode still had some pauses.
Petteri Aimonen 3 years ago
parent
commit
bf78bfd39d

+ 4 - 0
lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.h

@@ -145,4 +145,8 @@ extern SdioConfig g_sd_sdio_config_crash;
 
 #endif
 
+// Check if a DMA request for SD card read has completed.
+// This is used to optimize the timing of data transfers on SCSI bus.
+bool check_sd_read_done();
+
 #endif

+ 11 - 3
lib/ZuluSCSI_platform_GD32F205/scsiPhy.cpp

@@ -418,13 +418,21 @@ static bool isPollingWriteFinished(const uint8_t *data)
 extern "C" bool scsiIsWriteFinished(const uint8_t *data)
 {
     // Check if there is still a polling transfer in progress
-    if (!isPollingWriteFinished(data))
+    if (!isPollingWriteFinished(data) && !check_sd_read_done())
     {
         // Process the transfer piece-by-piece while waiting
         // for SD card to react.
         int max_count = g_scsi_writereq.count / 8;
-        max_count &= ~255;
-        if (max_count < 256) max_count = 256;
+        
+        // Always transfer whole sectors without pause to avoid problems with some SCSI hosts.
+        int bytesPerSector = 512;
+        if (scsiDev.target)
+        {
+            bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+        }
+        if (max_count % bytesPerSector != 0) max_count -= (max_count % bytesPerSector);
+        if (max_count < bytesPerSector) max_count = bytesPerSector;
+        
         processPollingWrite(max_count);
         return isPollingWriteFinished(data);
     }

+ 7 - 0
lib/ZuluSCSI_platform_GD32F205/sd_card_sdio.cpp

@@ -282,6 +282,13 @@ bool SdioCard::readSectors(uint32_t sector, uint8_t* dst, size_t n)
         get_stream_callback(dst, n * 512)));
 }
 
+// Check if a DMA request for SD card read has completed.
+// This is used to optimize the timing of data transfers on SCSI bus.
+bool check_sd_read_done()
+{
+    return (DMA_CHCTL(DMA1, DMA_CH3) & DMA_CHXCTL_CHEN)
+        && (DMA_INTF(DMA1) & DMA_FLAG_ADD(DMA_FLAG_FTF, DMA_CH3));
+}
 
 // These functions are not used for SDIO mode but are needed to avoid build error.
 void sdCsInit(SdCsPin_t pin) {}

+ 8 - 0
lib/ZuluSCSI_platform_GD32F205/sd_card_spi.cpp

@@ -263,4 +263,12 @@ void azplatform_set_sd_callback(sd_callback_t func, const uint8_t *buffer)
     g_sd_spi_port.set_sd_callback(func, buffer);    
 }
 
+// Check if a DMA request for SD card read has completed.
+// This is used to optimize the timing of data transfers on SCSI bus.
+bool check_sd_read_done()
+{
+    return (DMA_CHCTL(DMA0, SD_SPI_RX_DMA_CHANNEL) & DMA_CHXCTL_CHEN)
+        && (DMA_INTF(DMA0) & DMA_FLAG_ADD(DMA_FLAG_FTF, SD_SPI_RX_DMA_CHANNEL));
+}
+
 #endif