Ver código fonte

Fix PhyMode=1(PIO) on ZuluSCSI GD32 V1.1 (fix #245)

With the GD32 SDIO driver, check_sd_read_done() was returning true
even when no SD card read was in progress. This is because unlike
the SPI driver, the SDIO driver does not disable the DMA channel.

Also fixed a bug where scsiIsWriteFinished() erroneously returned
true on this early return, causing this to be a data corruption
instead of a hang.

Only affects GD32 V1.1 platform when PhyMode=1 setting is specified
in zuluscsi.ini.
Petteri Aimonen 2 anos atrás
pai
commit
c07a862e43

+ 1 - 0
lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.h

@@ -190,6 +190,7 @@ extern SdioConfig g_sd_sdio_config_crash;
 
 // Check if a DMA request for SD card read has completed.
 // This is used to optimize the timing of data transfers on SCSI bus.
+// When called outside of SD callback processing, always returns false.
 bool check_sd_read_done();
 
 #endif

+ 10 - 1
lib/ZuluSCSI_platform_GD32F205/scsiPhy.cpp

@@ -447,8 +447,17 @@ 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) && !check_sd_read_done())
+    if (!isPollingWriteFinished(data))
     {
+        if (check_sd_read_done())
+        {
+            // Current SD card transfer is finished so return early
+            // to start a new transfer before doing SCSI data transfer.
+            // This is faster because the SD transfer can run on background,
+            // but PIO mode SCSI transfer cannot.
+            return false;
+        }
+
         // Process the transfer piece-by-piece while waiting
         // for SD card to react.
         int max_count = g_scsi_writereq.count / 8;

+ 2 - 0
lib/ZuluSCSI_platform_GD32F205/sd_card_sdio.cpp

@@ -318,6 +318,8 @@ bool SdioCard::readSectors(uint32_t sector, uint8_t* dst, size_t n)
 // This is used to optimize the timing of data transfers on SCSI bus.
 bool check_sd_read_done()
 {
+    if (!m_stream_callback) return false;
+
     return (DMA_CHCTL(DMA1, DMA_CH3) & DMA_CHXCTL_CHEN)
         && (DMA_INTF(DMA1) & DMA_FLAG_ADD(DMA_FLAG_FTF, DMA_CH3));
 }