Forráskód Böngészése

Merge pull request #70 from ZuluSCSI/rp2040_bugfixes

RP2040 platform-specific bugfixes
Alex Perez 3 éve
szülő
commit
5e72afc0da

+ 31 - 5
lib/ZuluSCSI_platform_RP2040/scsi_accel_rp2040.cpp

@@ -432,20 +432,45 @@ bool scsi_accel_rp2040_isWriteFinished(const uint8_t* data)
     return finished;
 }
 
+static bool scsi_accel_rp2040_isWriteDone()
+{
+    // Check if data is still waiting in PIO FIFO
+    if (!pio_sm_is_tx_fifo_empty(SCSI_DMA_PIO, SCSI_DMA_SM))
+        return false;
+
+    if (g_scsi_dma.syncOffset > 0)
+    {
+        // Check if all bytes of synchronous write have been acknowledged
+        if (pio_sm_get_rx_fifo_level(SCSI_DMA_PIO, SCSI_DMA_SM) > g_scsi_dma.syncOffsetPreload)
+            return false;
+    }
+    else
+    {
+        // Check if state machine has written out its OSR
+        if (pio_sm_get_pc(SCSI_DMA_PIO, SCSI_DMA_SM) != g_scsi_dma.pio_offset_async_write)
+            return false;
+    }
+
+    // Check if ACK of the final byte has finished
+    if (SCSI_IN(ACK))
+        return false;
+
+    return true;
+}
+
 void scsi_accel_rp2040_stopWrite(volatile int *resetFlag)
 {
     // Wait for TX fifo to be empty and ACK to go high
     // For synchronous writes wait for all ACKs to be received also
     uint32_t start = millis();
-    while ((!pio_sm_is_tx_fifo_empty(SCSI_DMA_PIO, SCSI_DMA_SM)
-            || pio_sm_get_rx_fifo_level(SCSI_DMA_PIO, SCSI_DMA_SM) > g_scsi_dma.syncOffsetPreload
-            || SCSI_IN(ACK)) && !*resetFlag)
+    while (!scsi_accel_rp2040_isWriteDone() && !*resetFlag)
     {
         if ((uint32_t)(millis() - start) > 5000)
         {
             azlog("scsi_accel_rp2040_stopWrite() timeout, FIFO levels ",
                 (int)pio_sm_get_tx_fifo_level(SCSI_DMA_PIO, SCSI_DMA_SM), " ",
-                (int)pio_sm_get_rx_fifo_level(SCSI_DMA_PIO, SCSI_DMA_SM));
+                (int)pio_sm_get_rx_fifo_level(SCSI_DMA_PIO, SCSI_DMA_SM), " PC ",
+                (int)pio_sm_get_pc(SCSI_DMA_PIO, SCSI_DMA_SM));
             *resetFlag = 1;
             break;
         }
@@ -610,11 +635,12 @@ void scsi_accel_rp2040_init()
     g_scsi_dma.core1_active = false;
     multicore_reset_core1();
     multicore_launch_core1(&enable_irq_second_core);
-    delay(1);
+    delay(5);
 
     if (!g_scsi_dma.core1_active)
     {
         azlog("Failed to offload SCSI DMA interrupts to second core, using first core");
+        multicore_reset_core1();
         irq_set_exclusive_handler(DMA_IRQ_0, scsi_dma_write_irq);
         irq_set_enabled(DMA_IRQ_0, true);
     }

+ 11 - 4
lib/ZuluSCSI_platform_RP2040/sd_card_sdio.cpp

@@ -13,6 +13,7 @@
 static uint32_t g_sdio_ocr; // Operating condition register from card
 static uint32_t g_sdio_rca; // Relative card address
 static cid_t g_sdio_cid;
+static csd_t g_sdio_csd;
 static int g_sdio_error_line;
 static sdio_status_t g_sdio_error;
 static uint32_t g_sdio_dma_buf[128];
@@ -119,6 +120,13 @@ bool SdioCard::begin(SdioConfig sdioConfig)
         return false;
     }
 
+    // Get CSD
+    if (!checkReturnOk(rp2040_sdio_command_R2(CMD9, g_sdio_rca, (uint8_t*)&g_sdio_csd)))
+    {
+        azdbg("SDIO failed to read CSD");
+        return false;
+    }
+
     // Select card
     if (!checkReturnOk(rp2040_sdio_command_R1(CMD7, g_sdio_rca, &reply)))
     {
@@ -173,7 +181,8 @@ bool SdioCard::readCID(cid_t* cid)
 
 bool SdioCard::readCSD(csd_t* csd)
 {
-    return checkReturnOk(rp2040_sdio_command_R2(CMD9, g_sdio_rca, (uint8_t*)csd)); // SEND_CSD
+    *csd = g_sdio_csd;
+    return true;
 }
 
 bool SdioCard::readOCR(uint32_t* ocr)
@@ -203,9 +212,7 @@ bool SdioCard::readStop()
 
 uint32_t SdioCard::sectorCount()
 {
-    csd_t csd;
-    readCSD(&csd);
-    return sdCardCapacity(&csd);
+    return sdCardCapacity(&g_sdio_csd);
 }
 
 uint32_t SdioCard::status()

+ 4 - 2
src/ZuluSCSI_disk.cpp

@@ -85,9 +85,11 @@ public:
             m_israw = true;
             m_blockdev = SD.card();
 
-            if (m_endsector >= SD.card()->sectorCount())
+            uint32_t sectorCount = SD.card()->sectorCount();
+            if (m_endsector >= sectorCount)
             {
-                m_endsector = SD.card()->sectorCount() - 1;
+                azlog("Limiting RAW image mapping to SD card sector count: ", (int)sectorCount);
+                m_endsector = sectorCount - 1;
             }
         }
         else