Prechádzať zdrojové kódy

Use PIO mode for synchronous transfers to host

Petteri Aimonen 3 rokov pred
rodič
commit
a65ffefd9b

+ 37 - 37
lib/AzulSCSI_platform_GD32F205/scsiPhy.cpp

@@ -30,6 +30,13 @@ static const char *g_scsi_phy_mode_names[] = {
     "Unknown", "PIO", "DMA_TIMER", "GREENPAK_PIO", "GREENPAK_DMA"
 };
 
+// State of polling write request
+static struct {
+    const uint8_t *data;
+    uint32_t count;
+    bool use_sync_mode;
+} g_scsi_writereq;
+
 static void init_irqs();
 
 /***********************/
@@ -170,6 +177,7 @@ extern "C" void scsiPhyReset(void)
 
     g_scsi_sts_selection = 0;
     g_scsi_ctrl_bsy = 0;
+    g_scsi_writereq.count = 0;
     init_irqs();
 
 #ifdef SCSI_SYNC_MODE_AVAILABLE
@@ -300,21 +308,15 @@ extern "C" void scsiWrite(const uint8_t* data, uint32_t count)
     scsiFinishWrite();
 }
 
-static struct {
-    const uint8_t *data;
-    uint32_t count;
-} g_scsi_writereq;
-
 extern "C" void scsiStartWrite(const uint8_t* data, uint32_t count)
 {
     scsiLogDataIn(data, count);
 
-    if (g_scsi_phase == DATA_IN && scsiDev.target->syncOffset > 0)
-    {
-        // Synchronous data transfer
-        scsi_accel_sync_startWrite(data, count, &scsiDev.resetFlag);
-    }
-    else if (g_scsi_phy_mode == PHY_MODE_PIO || g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO)
+    g_scsi_writereq.use_sync_mode = (g_scsi_phase == DATA_IN && scsiDev.target->syncOffset > 0);
+
+    if (g_scsi_phy_mode == PHY_MODE_PIO
+        || g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO
+        || g_scsi_writereq.use_sync_mode)
     {
         // Software based bit-banging.
         // Write requests are queued and then executed in isWriteFinished() callback.
@@ -356,20 +358,28 @@ static void processPollingWrite(uint32_t count)
     
     const uint8_t *data = g_scsi_writereq.data;
     uint32_t count_words = count / 4;
-    if (count_words * 4 == count)
+
+    if (g_scsi_writereq.use_sync_mode)
+    {
+        // Synchronous mode transfer
+        scsi_accel_sync_send(data, count, &scsiDev.resetFlag);
+    }
+    else if (count_words * 4 == count)
     {
-        // Use accelerated subroutine
         if (g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO)
         {
+            // GreenPAK PIO accelerated asynchronous transfer
             scsi_accel_greenpak_send((const uint32_t*)data, count_words, &scsiDev.resetFlag);
         }
         else
         {
+            // Assembler optimized asynchronous transfer
             scsi_accel_asm_send((const uint32_t*)data, count_words, &scsiDev.resetFlag);
         }
     }
     else
     {
+        // Use simple loop for unaligned transfers
         for (uint32_t i = 0; i < count; i++)
         {
             if (scsiDev.resetFlag) break;
@@ -407,47 +417,37 @@ static bool isPollingWriteFinished(const uint8_t *data)
 
 extern "C" bool scsiIsWriteFinished(const uint8_t *data)
 {
-    if (g_scsi_phase == DATA_IN && scsiDev.target->syncOffset > 0)
+    // Check if there is still a polling transfer in progress
+    if (!isPollingWriteFinished(data))
     {
-        return scsi_accel_sync_isWriteFinished(data);
+        // Process the transfer piece-by-piece while waiting
+        // for SD card to react.
+        processPollingWrite(256);
+        return isPollingWriteFinished(data);
     }
-    else if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
+    
+    if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
     {
         return scsi_accel_dma_isWriteFinished(data);
     }
     else
     {
-        // Check if there is still a polling transfer in progress
-        if (!isPollingWriteFinished(data))
-        {
-            // Process the transfer piece-by-piece while waiting
-            // for SD card to react.
-            processPollingWrite(256);
-            return isPollingWriteFinished(data);
-        }
-
         return true;
     }
 }
 
 extern "C" void scsiFinishWrite()
 {
-    if (g_scsi_phase == DATA_IN && scsiDev.target->syncOffset > 0)
+    if (g_scsi_writereq.count)
     {
-        return scsi_accel_sync_finishWrite(&scsiDev.resetFlag);
+        // Finish previously started polling write request.
+        processPollingWrite(g_scsi_writereq.count);
     }
-    else if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
+
+    if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
     {
         scsi_accel_dma_finishWrite(&scsiDev.resetFlag);
     }
-    else
-    {
-        // Finish previously started polling write request.
-        if (g_scsi_writereq.count)
-        {
-            processPollingWrite(g_scsi_writereq.count);
-        }
-    }
 }
 
 /*********************/
@@ -483,7 +483,7 @@ extern "C" void scsiRead(uint8_t* data, uint32_t count, int* parityError)
     if (g_scsi_phase == DATA_OUT && scsiDev.target->syncOffset > 0)
     {
         // Synchronous data transfer
-        scsi_accel_sync_read(data, count, parityError, &scsiDev.resetFlag);
+        scsi_accel_sync_recv(data, count, parityError, &scsiDev.resetFlag);
     }
     else if (count_words * 4 == count && count_words >= 2 && use_greenpak)
     {

+ 12 - 21
lib/AzulSCSI_platform_GD32F205/scsi_accel_sync.cpp

@@ -23,14 +23,15 @@
 
 void scsi_accel_sync_init() {}
 
-void scsi_accel_sync_read(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag) {}
-void scsi_accel_sync_startWrite(const uint8_t* data, uint32_t count, volatile int *resetFlag) {}
-void scsi_accel_sync_stopWrite() {}
-void scsi_accel_sync_finishWrite(volatile int *resetFlag) {}
-bool scsi_accel_sync_isWriteFinished(const uint8_t* data) { return true; }
+void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag) {}
+void scsi_accel_sync_send(const uint8_t* data, uint32_t count, volatile int *resetFlag) {}
 
 #else
 
+/********************************/
+/* Transfer from host to device */
+/********************************/
+
 #define SYNC_DMA_BUFSIZE 512
 static uint32_t g_sync_dma_buf[SYNC_DMA_BUFSIZE];
 
@@ -91,7 +92,7 @@ void scsi_accel_sync_init()
     gpio_init(SCSI_IN_ACK_EXMC_NWAIT_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_IN_ACK_EXMC_NWAIT_PIN);
 }
 
-void scsi_accel_sync_read(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag)
+void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag)
 {
     // Enable EXMC to drive REQ from EXMC_NOE pin
     EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_SNCTL_NRBKEN;
@@ -137,7 +138,11 @@ void scsi_accel_sync_read(uint8_t *data, uint32_t count, int* parityError, volat
     EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_SNCTL_NRBKEN;
 }
 
-void scsi_accel_sync_startWrite(const uint8_t* data, uint32_t count, volatile int *resetFlag)
+/********************************/
+/* Transfer from device to host */
+/********************************/
+
+void scsi_accel_sync_send(const uint8_t* data, uint32_t count, volatile int *resetFlag)
 {
     for (int i = 0; i < count; i++)
     {
@@ -151,19 +156,5 @@ void scsi_accel_sync_startWrite(const uint8_t* data, uint32_t count, volatile in
     SCSI_RELEASE_DATA_REQ();
 }
 
-void scsi_accel_sync_stopWrite()
-{
-
-}
-
-void scsi_accel_sync_finishWrite(volatile int *resetFlag)
-{
-
-}
-
-bool scsi_accel_sync_isWriteFinished(const uint8_t* data)
-{
-    return true;
-}
 
 #endif

+ 2 - 5
lib/AzulSCSI_platform_GD32F205/scsi_accel_sync.h

@@ -13,8 +13,5 @@
 
 void scsi_accel_sync_init();
 
-void scsi_accel_sync_read(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag);
-void scsi_accel_sync_startWrite(const uint8_t* data, uint32_t count, volatile int *resetFlag);
-void scsi_accel_sync_stopWrite();
-void scsi_accel_sync_finishWrite(volatile int *resetFlag);
-bool scsi_accel_sync_isWriteFinished(const uint8_t* data);
+void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volatile int *resetFlag);
+void scsi_accel_sync_send(const uint8_t* data, uint32_t count, volatile int *resetFlag);