Эх сурвалжийг харах

Merge pull request #208 from ZuluSCSI/dev_2GB_sd_cards

RP2040: Fix support for 2GB SD cards
Alex Perez 2 жил өмнө
parent
commit
fb19e9123c

+ 16 - 4
lib/ZuluSCSI_platform_RP2040/sd_card_sdio.cpp

@@ -344,9 +344,12 @@ bool SdioCard::writeSector(uint32_t sector, const uint8_t* src)
     // If possible, report transfer status to application through callback.
     sd_callback_t callback = get_stream_callback(src, 512, "writeSector", sector);
 
+    // Cards up to 2GB use byte addressing, SDHC cards use sector addressing
+    uint32_t address = (type() == SD_CARD_TYPE_SDHC) ? sector : (sector * 512);
+
     uint32_t reply;
     if (!checkReturnOk(rp2040_sdio_command_R1(16, 512, &reply)) || // SET_BLOCKLEN
-        !checkReturnOk(rp2040_sdio_command_R1(CMD24, sector, &reply)) || // WRITE_BLOCK
+        !checkReturnOk(rp2040_sdio_command_R1(CMD24, address, &reply)) || // WRITE_BLOCK
         !checkReturnOk(rp2040_sdio_tx_start(src, 1))) // Start transmission
     {
         return false;
@@ -387,11 +390,14 @@ bool SdioCard::writeSectors(uint32_t sector, const uint8_t* src, size_t n)
 
     sd_callback_t callback = get_stream_callback(src, n * 512, "writeSectors", sector);
 
+    // Cards up to 2GB use byte addressing, SDHC cards use sector addressing
+    uint32_t address = (type() == SD_CARD_TYPE_SDHC) ? sector : (sector * 512);
+
     uint32_t reply;
     if (!checkReturnOk(rp2040_sdio_command_R1(16, 512, &reply)) || // SET_BLOCKLEN
         !checkReturnOk(rp2040_sdio_command_R1(CMD55, g_sdio_rca, &reply)) || // APP_CMD
         !checkReturnOk(rp2040_sdio_command_R1(ACMD23, n, &reply)) || // SET_WR_CLK_ERASE_COUNT
-        !checkReturnOk(rp2040_sdio_command_R1(CMD25, sector, &reply)) || // WRITE_MULTIPLE_BLOCK
+        !checkReturnOk(rp2040_sdio_command_R1(CMD25, address, &reply)) || // WRITE_MULTIPLE_BLOCK
         !checkReturnOk(rp2040_sdio_tx_start(src, n))) // Start transmission
     {
         return false;
@@ -430,10 +436,13 @@ bool SdioCard::readSector(uint32_t sector, uint8_t* dst)
 
     sd_callback_t callback = get_stream_callback(dst, 512, "readSector", sector);
 
+    // Cards up to 2GB use byte addressing, SDHC cards use sector addressing
+    uint32_t address = (type() == SD_CARD_TYPE_SDHC) ? sector : (sector * 512);
+
     uint32_t reply;
     if (!checkReturnOk(rp2040_sdio_command_R1(16, 512, &reply)) || // SET_BLOCKLEN
         !checkReturnOk(rp2040_sdio_rx_start(dst, 1)) || // Prepare for reception
-        !checkReturnOk(rp2040_sdio_command_R1(CMD17, sector, &reply))) // READ_SINGLE_BLOCK
+        !checkReturnOk(rp2040_sdio_command_R1(CMD17, address, &reply))) // READ_SINGLE_BLOCK
     {
         return false;
     }
@@ -478,10 +487,13 @@ bool SdioCard::readSectors(uint32_t sector, uint8_t* dst, size_t n)
 
     sd_callback_t callback = get_stream_callback(dst, n * 512, "readSectors", sector);
 
+    // Cards up to 2GB use byte addressing, SDHC cards use sector addressing
+    uint32_t address = (type() == SD_CARD_TYPE_SDHC) ? sector : (sector * 512);
+
     uint32_t reply;
     if (!checkReturnOk(rp2040_sdio_command_R1(16, 512, &reply)) || // SET_BLOCKLEN
         !checkReturnOk(rp2040_sdio_rx_start(dst, n)) || // Prepare for reception
-        !checkReturnOk(rp2040_sdio_command_R1(CMD18, sector, &reply))) // READ_MULTIPLE_BLOCK
+        !checkReturnOk(rp2040_sdio_command_R1(CMD18, address, &reply))) // READ_MULTIPLE_BLOCK
     {
         return false;
     }

+ 5 - 0
src/ZuluSCSI.cpp

@@ -564,7 +564,12 @@ void readSCSIDeviceConfig()
 
 static bool mountSDCard()
 {
+  // Prepare for mounting new SD card by closing all old files.
+  // When switching between FAT and exFAT cards the pointers
+  // are invalidated and accessing old files results in crash.
   invalidate_ini_cache();
+  g_logfile.close();
+  scsiDiskCloseSDCardImages();
 
   // Check for the common case, FAT filesystem as first partition
   if (SD.begin(SD_CONFIG))

+ 11 - 0
src/ZuluSCSI_disk.cpp

@@ -166,6 +166,17 @@ void scsiDiskResetImages()
     memset(g_DiskImages, 0, sizeof(g_DiskImages));
 }
 
+void scsiDiskCloseSDCardImages()
+{
+    for (int i = 0; i < S2S_MAX_TARGETS; i++)
+    {
+        if (!g_DiskImages[i].file.isRom())
+        {
+            g_DiskImages[i].file.close();
+        }
+    }
+}
+
 // Verify format conformance to SCSI spec:
 // - Empty bytes filled with 0x20 (space)
 // - Only values 0x20 to 0x7E

+ 5 - 0
src/ZuluSCSI_disk.h

@@ -70,7 +70,12 @@ struct image_config_t: public S2S_TargetCfg
     bool geometrywarningprinted;
 };
 
+// Reset all image configuration to empty reset state, close all images.
 void scsiDiskResetImages();
+
+// Close any files opened from SD card (prepare for remounting SD)
+void scsiDiskCloseSDCardImages();
+
 bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int scsi_lun, int blocksize, S2S_CFG_TYPE type = S2S_CFG_FIXED);
 void scsiDiskLoadConfig(int target_idx);