Просмотр исходного кода

Bugfixes for SCSI2SD integration

Petteri Aimonen 3 лет назад
Родитель
Сommit
19e1250b8b

+ 1 - 0
.github/workflows/firmware_build.yml

@@ -39,6 +39,7 @@ jobs:
       - name: Remove old binaries from release
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        if: github.ref == 'refs/heads/main'
         run: |
           gh api repos/${GITHUB_REPOSITORY}/releases/tags/latest | jq -r '.assets[] | [.url] | @tsv' | xargs -n 1 gh api -X DELETE || true
 

+ 2 - 0
lib/AzulSCSI_platform_GD32F205/AzulSCSI_platform.h

@@ -20,9 +20,11 @@ extern const char *g_azplatform_name;
 
 #if defined(AZULSCSI_V1_0)
 #   define PLATFORM_NAME "AzulSCSI v1.0"
+#   define PLATFORM_MAX_SCSI_SPEED S2S_CFG_SPEED_ASYNC_50
 #   include "AzulSCSI_v1_0_gpio.h"
 #elif defined(AZULSCSI_V1_1)
 #   define PLATFORM_NAME "AzulSCSI v1.1"
+#   define PLATFORM_MAX_SCSI_SPEED S2S_CFG_SPEED_ASYNC_50
 #   include "AzulSCSI_v1_1_gpio.h"
 #endif
 

+ 10 - 1
lib/AzulSCSI_platform_GD32F205/sd_card_spi.cpp

@@ -7,6 +7,8 @@
 #include "gd32f20x_dma.h"
 #include <SdFat.h>
 
+#ifndef SD_USE_SDIO
+
 class GD32SPIDriver : public SdSpiBaseClass
 {
 public:
@@ -238,4 +240,11 @@ void sdCsWrite(SdCsPin_t pin, bool level)
 }
 
 GD32SPIDriver g_sd_spi_port;
-SdSpiConfig g_sd_spi_config(0, DEDICATED_SPI, SD_SCK_MHZ(30), &g_sd_spi_port);
+SdSpiConfig g_sd_spi_config(0, DEDICATED_SPI, SD_SCK_MHZ(30), &g_sd_spi_port);
+
+void azplatform_set_sd_callback(sd_callback_t func, const uint8_t *buffer)
+{
+    g_sd_spi_port.set_sd_callback(func, buffer);    
+}
+
+#endif

+ 35 - 23
src/AzulSCSI.cpp

@@ -239,10 +239,12 @@ bool findHDDImages()
     
     if (cfg && cfg->scsiId & S2S_CFG_TARGET_ENABLED)
     {
+      int capacity_kB = ((uint64_t)cfg->scsiSectors * cfg->bytesPerSector) / 1024;
       azlog("SCSI ID:", (int)(cfg->scsiId & 7),
             " BlockSize:", (int)cfg->bytesPerSector,
             " Type:", (int)cfg->deviceType,
-            " Quirks:", (int)cfg->quirks);
+            " Quirks:", (int)cfg->quirks,
+            " ImageSize:", capacity_kB, "kB");
     }
   }
 
@@ -272,6 +274,23 @@ void readSCSIDeviceConfig()
 /* Main SCSI handling loop       */
 /*********************************/
 
+static void reinitSCSI()
+{
+  readSCSIDeviceConfig();
+  bool foundImage = findHDDImages();
+
+  if (foundImage)
+  {
+    // Ok, there is an image
+    blinkStatus(1);
+  }
+
+  scsiPhyReset();
+  scsiDiskInit();
+  scsiInit();
+  
+}
+
 int main(void)
 {
   azplatform_init();
@@ -290,34 +309,33 @@ int main(void)
   }
 
   print_sd_info();
-
-  readSCSIDeviceConfig();
-  bool foundImage = findHDDImages();
+  
+  reinitSCSI();
 
   azlog("Initialization complete!");
   azlog("Platform: ", g_azplatform_name);
   azlog("FW Version: ", g_azlog_firmwareversion);
 
   init_logfile();
-
-  if (foundImage)
-  {
-    // Ok, there is an image
-    blinkStatus(1);
-  }
-
-  scsiInit();
-
+  
   uint32_t sd_card_check_time = 0;
 
   while (1)
   {
-    azplatform_reset_watchdog(30000);
+    azplatform_reset_watchdog(15000);
     scsiPoll();
+    scsiDiskPoll();
     scsiLogPhaseChange(scsiDev.phase);
 
+    // Save log periodically during status phase if there are new messages.
+    if (scsiDev.phase == STATUS)
+    {
+      save_logfile();
+    }
+
     // Check SD card status for hotplug
-    if ((uint32_t)(millis() - sd_card_check_time) > 5000)
+    if (scsiDev.phase == BUS_FREE &&
+        (uint32_t)(millis() - sd_card_check_time) > 5000)
     {
       sd_card_check_time = millis();
       uint32_t ocr;
@@ -333,15 +351,9 @@ int main(void)
           } while (!SD.begin(SD_CONFIG));
           azlog("SD card reinit succeeded");
           print_sd_info();
-          readSCSIDeviceConfig();
-          foundImage = findHDDImages();
-          init_logfile();
-          scsiInit();
           
-          if (foundImage)
-          {
-            blinkStatus(1);
-          }
+          reinitSCSI();
+          init_logfile();
         }
       }
     }

+ 41 - 17
src/AzulSCSI_disk.cpp

@@ -65,12 +65,9 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int
     return false;
 }
 
-void scsiDiskLoadConfig(int target_idx)
+static void scsiDiskLoadConfig(int target_idx, const char *section)
 {
     image_config_t &img = g_DiskImages[target_idx];
-    char section[6] = "SCSI0";
-    section[4] = '0' + target_idx;
-
     img.deviceType = ini_getl(section, "Type", S2S_CFG_FIXED, CONFIGFILE);
     img.deviceTypeModifier = ini_getl(section, "TypeModifier", 0, CONFIGFILE);
     img.sectorsPerTrack = ini_getl(section, "SectorsPerTrack", 18, CONFIGFILE);
@@ -95,6 +92,18 @@ void scsiDiskLoadConfig(int target_idx)
     memcpy(img.serial, tmp, 16);
 }
 
+void scsiDiskLoadConfig(int target_idx)
+{
+    char section[6] = "SCSI0";
+    section[4] = '0' + target_idx;
+
+    // First load global settings
+    scsiDiskLoadConfig(target_idx, "SCSI");
+
+    // Then settings specific to target ID
+    scsiDiskLoadConfig(target_idx, section);
+}
+
 /*******************************/
 /* Config handling for SCSI2SD */
 /*******************************/
@@ -108,7 +117,12 @@ void s2s_configInit(S2S_BoardCfg* config)
     config->startupDelay = 0;
     config->selectionDelay = ini_getl("SCSI", "SelectionDelay", 255, CONFIGFILE);
     config->flags6 = ini_getl("SCSI", "Flags6", 0, CONFIGFILE);
-    config->scsiSpeed = ini_getl("SCSI", "SCSISpeed", S2S_CFG_SPEED_ASYNC_50, CONFIGFILE);
+    config->scsiSpeed = ini_getl("SCSI", "SCSISpeed", PLATFORM_MAX_SCSI_SPEED, CONFIGFILE);
+
+    if (config->scsiSpeed > PLATFORM_MAX_SCSI_SPEED)
+    {
+        config->scsiSpeed = PLATFORM_MAX_SCSI_SPEED;
+    }
 }
 
 extern "C"
@@ -354,7 +368,7 @@ static void doSeek(uint32_t lba)
 /* Transfer state for read / write commands */
 /********************************************/
 
-BlockDevice blockDev;
+BlockDevice blockDev = {DISK_PRESENT | DISK_INITIALISED};
 Transfer transfer;
 
 /*****************/
@@ -400,11 +414,13 @@ static void doWrite(uint32_t lba, uint32_t blocks)
         transfer.blocks = blocks;
         transfer.currentBlock = 0;
         scsiDev.phase = DATA_OUT;
-        scsiDev.dataLen = bytesPerSector;
-        scsiDev.dataPtr = bytesPerSector;
+        scsiDev.dataLen = 0;
+        scsiDev.dataPtr = 0;
+
+        azdbg("------ Write ", (int)blocks, "x", (int)bytesPerSector, " starting at ", (int)lba);
 
         image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
-        if (!img.file.seek(transfer.lba * img.bytesPerSector))
+        if (!img.file.seek(transfer.lba * bytesPerSector))
         {
             azlog("Seek to ", transfer.lba, " failed for ", scsiDev.target->targetId);
             scsiDev.status = CHECK_CONDITION;
@@ -447,18 +463,21 @@ void diskDataOut()
     uint32_t maxblocks = sizeof(scsiDev.data) / scsiDev.target->liveCfg.bytesPerSector;
     if (blockcount > maxblocks) blockcount = maxblocks;
     uint32_t transferlen = blockcount * scsiDev.target->liveCfg.bytesPerSector;
-
-    // Read first block from SCSI bus
     scsiDev.dataLen = transferlen;
     scsiDev.dataPtr = 0;
-    diskDataOut_callback(0);
     
-    // Start writing blocks to SD card.
-    // The callback will simultaneously read the next block from SCSI bus.
     image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
     uint32_t written = 0;
     while (written < transferlen)
     {
+        // Read next block from SCSI bus
+        if (scsiDev.dataPtr == written)
+        {
+            diskDataOut_callback(0);
+        }
+
+        // Start writing blocks to SD card.
+        // The callback will simultaneously read the next block from SCSI bus.    
         uint8_t *buf = scsiDev.data + written;
         uint32_t buflen = scsiDev.dataPtr - written;
         azplatform_set_sd_callback(&diskDataOut_callback, buf);
@@ -475,8 +494,8 @@ void diskDataOut()
     }
 
     azplatform_set_sd_callback(NULL, NULL);
-
     transfer.currentBlock += blockcount;
+    scsiDev.dataPtr = scsiDev.dataLen = 0;
 }
 
 /*****************/
@@ -512,8 +531,11 @@ static void doRead(uint32_t lba, uint32_t blocks)
         scsiDev.dataLen = 0;
         scsiDev.dataPtr = 0;
 
+        uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+        azdbg("------ Read ", (int)blocks, "x", (int)bytesPerSector, " starting at ", (int)lba);
+
         image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
-        if (!img.file.seek(transfer.lba * img.bytesPerSector))
+        if (!img.file.seek(transfer.lba * bytesPerSector))
         {
             azlog("Seek to ", transfer.lba, " failed for ", scsiDev.target->targetId);
             scsiDev.status = CHECK_CONDITION;
@@ -564,8 +586,11 @@ static void diskDataIn()
         scsiDev.phase = STATUS;
     }
 
+    diskDataIn_callback(transferlen);
+
     azplatform_set_sd_callback(NULL, NULL);
     transfer.currentBlock += blockcount;
+    scsiDev.dataPtr = scsiDev.dataLen = 0;
 }
 
 
@@ -595,7 +620,6 @@ int scsiDiskCommand()
         else if (start)
         {
             scsiDev.target->started = 1;
-            blockDev.state = DISK_INITIALISED;
         }
         else
         {

+ 2 - 2
src/AzulSCSI_log.cpp

@@ -78,9 +78,9 @@ void azlog_raw(bytearray array)
     {
         azlog_raw(array.data[i]);
         azlog_raw(" ");
-        if (i > 64)
+        if (i > 32)
         {
-            azlog_raw("...");
+            azlog_raw("... (total ", (int)array.len, ")");
             break;
         }
     }

+ 36 - 24
src/AzulSCSI_log_trace.cpp

@@ -13,29 +13,40 @@ static bool g_LogData = false;
 
 static const char *getCommandName(uint8_t cmd)
 {
-    if (cmd == 0x00) return "TestUnitReady";
-    if (cmd == 0x1A) return "ModeSense";
-    if (cmd == 0x5A) return "ModeSense10";
-    if (cmd == 0x0A) return "Write6";
-    if (cmd == 0x2A) return "Write10";
-    if (cmd == 0x08) return "Read6";
-    if (cmd == 0x28) return "Read10";
-    if (cmd == 0x12) return "Inquiry";
-    if (cmd == 0x25) return "ReadCapacity";
-    return "";
-}
-
-static void printCommand()
-{
-    uint8_t cmd = scsiDev.cdb[0];
-    const char *cmdname = getCommandName(cmd);
-
-    azdbg("---- COMMAND: ", cmdname, " ", bytearray(scsiDev.cdb, scsiDev.cdbLen));
+    switch (cmd)
+    {
+        case 0x00: return "TestUnitReady";
+        case 0x1A: return "ModeSense";
+        case 0x5A: return "ModeSense10";
+        case 0x0A: return "Write6";
+        case 0x2A: return "Write10";
+        case 0x08: return "Read6";
+        case 0x28: return "Read10";
+        case 0x12: return "Inquiry";
+        case 0x25: return "ReadCapacity";
+        case 0x43: return "CDROM Read TOC";
+        case 0x44: return "CDROM Read Header";
+        case 0x2C: return "Erase10";
+        case 0xAC: return "Erase12";
+        case 0x15: return "ModeSelect6";
+        case 0x55: return "ModeSelect10";
+        case 0x03: return "RequestSense";
+        case 0x16: return "Reserve";
+        case 0x17: return "Release";
+        case 0x1C: return "ReceiveDiagnostic";
+        case 0x1D: return "SendDiagnostic";
+        case 0x3B: return "WriteBuffer";
+        case 0x0F: return "WriteSectorBuffer";
+        case 0x3C: return "ReadBuffer";
+        case 0xC0: return "OMTI-5204 DefineFlexibleDiskFormat";
+        case 0xC2: return "OMTI-5204 AssignDiskParameters";
+        default:   return "Unknown";
+    }
 }
 
 static void printNewPhase(int phase)
 {
-    g_LogData = true; //false;
+    g_LogData = false;
     if (!g_azlog_debug)
     {
         return;
@@ -79,6 +90,7 @@ static void printNewPhase(int phase)
             break;
         
         case COMMAND:
+            g_LogData = true;
             break;
         
         case DATA_IN:
@@ -111,11 +123,6 @@ void scsiLogPhaseChange(int new_phase)
 
     if (new_phase != old_phase)
     {
-        if (old_phase == COMMAND && scsiDev.cdbLen > 0)
-        {
-            printCommand();
-        }
-
         printNewPhase(new_phase);
         old_phase = new_phase;
     }
@@ -131,6 +138,11 @@ void scsiLogDataIn(const uint8_t *buf, uint32_t length)
 
 void scsiLogDataOut(const uint8_t *buf, uint32_t length)
 {
+    if (buf == scsiDev.cdb)
+    {
+        azdbg("---- COMMAND: ", getCommandName(buf[0]));
+    }
+    
     if (g_LogData)
     {
         azdbg("------ OUT: ", bytearray(buf, length));