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

Add user based custom timings

Added `zuluscsi_timings.ini` so users can modify their timing values
by themselves. It limits their clock rate to 250MHz as higher clock
rates than 266MHz require a recompile and 250MHz creates a nice
50MHz SDIO clock.
Morio 1 жил өмнө
parent
commit
88718392c8

+ 20 - 4
lib/SCSI2SD/src/firmware/scsi.c

@@ -759,8 +759,16 @@ static void scsiReset()
 
 
 	for (int i = 0; i < S2S_MAX_TARGETS; ++i)
 	for (int i = 0; i < S2S_MAX_TARGETS; ++i)
 	{
 	{
-		scsiDev.targets[i].syncOffset = 0;
-		scsiDev.targets[i].syncPeriod = 0;
+		if (g_force_sync > 0)
+		{
+			scsiDev.targets[i].syncPeriod = g_force_sync;
+			scsiDev.targets[i].syncOffset = g_force_offset;
+		}
+		else
+		{
+			scsiDev.targets[i].syncOffset = 0;
+			scsiDev.targets[i].syncPeriod = 0;
+		}
 	}
 	}
 	scsiDev.minSyncPeriod = 0;
 	scsiDev.minSyncPeriod = 0;
 
 
@@ -1346,8 +1354,16 @@ void scsiInit()
 		scsiDev.targets[i].sense.code = NO_SENSE;
 		scsiDev.targets[i].sense.code = NO_SENSE;
 		scsiDev.targets[i].sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;
 		scsiDev.targets[i].sense.asc = NO_ADDITIONAL_SENSE_INFORMATION;
 
 
-		scsiDev.targets[i].syncOffset = 0;
-		scsiDev.targets[i].syncPeriod = 0;
+		if (g_force_sync > 0)
+		{
+			scsiDev.targets[i].syncPeriod = g_force_sync;
+			scsiDev.targets[i].syncOffset = g_force_offset;
+		}
+		else
+		{
+			scsiDev.targets[i].syncOffset = 0;
+			scsiDev.targets[i].syncPeriod = 0;
+		}
 
 
 		// Always "start" the device. Many systems (eg. Apple System 7)
 		// Always "start" the device. Many systems (eg. Apple System 7)
 		// won't respond properly to
 		// won't respond properly to

+ 2 - 0
lib/SCSI2SD/src/firmware/timings.h

@@ -24,4 +24,6 @@
 extern uint8_t g_max_sync_20_period;
 extern uint8_t g_max_sync_20_period;
 extern uint8_t g_max_sync_10_period;
 extern uint8_t g_max_sync_10_period;
 extern uint8_t g_max_sync_5_period;
 extern uint8_t g_max_sync_5_period;
+extern uint8_t g_force_sync;
+extern uint8_t g_force_offset;
 #endif // ZULUSCSI_SCSI2SD_TIMINGS_H
 #endif // ZULUSCSI_SCSI2SD_TIMINGS_H

+ 11 - 9
lib/ZuluSCSI_platform_GD32F205/scsi2sd_timings.c

@@ -1,24 +1,26 @@
-/** 
+/**
  * ZuluSCSI™ - Copyright (c) 2024 Rabbit Hole Computing™
  * ZuluSCSI™ - Copyright (c) 2024 Rabbit Hole Computing™
- * 
- * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version. 
- * 
+ *
+ * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version.
+ *
  * https://www.gnu.org/licenses/gpl-3.0.html
  * https://www.gnu.org/licenses/gpl-3.0.html
  * ----
  * ----
  * This program is free software: you can redistribute it and/or modify
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version. 
- * 
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details. 
- * 
+ * GNU General Public License for more details.
+ *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 **/
 **/
 #include "timings.h"
 #include "timings.h"
 uint8_t g_max_sync_20_period = 25;
 uint8_t g_max_sync_20_period = 25;
 uint8_t g_max_sync_10_period = 25;
 uint8_t g_max_sync_10_period = 25;
-uint8_t g_max_sync_5_period  = 50; 
+uint8_t g_max_sync_5_period  = 50;
+uint8_t g_force_sync = 0;
+uint8_t g_force_offset = 15;

+ 2 - 0
lib/ZuluSCSI_platform_GD32F450/scsi2sd_timings.c

@@ -22,3 +22,5 @@
 uint8_t g_max_sync_20_period = 25;
 uint8_t g_max_sync_20_period = 25;
 uint8_t g_max_sync_10_period = 25;
 uint8_t g_max_sync_10_period = 25;
 uint8_t g_max_sync_5_period  = 50; 
 uint8_t g_max_sync_5_period  = 50; 
+uint8_t g_force_sync = 0;
+uint8_t g_force_offset = 15;

+ 18 - 2
lib/ZuluSCSI_platform_RP2MCU/ZuluSCSI_platform.cpp

@@ -36,6 +36,7 @@
 #include <hardware/structs/usb.h>
 #include <hardware/structs/usb.h>
 #include <hardware/sync.h>
 #include <hardware/sync.h>
 #include "scsi_accel_target.h"
 #include "scsi_accel_target.h"
+#include "custom_timings.h"
 
 
 #ifndef PIO_FRAMEWORK_ARDUINO_NO_USB
 #ifndef PIO_FRAMEWORK_ARDUINO_NO_USB
 # include <SerialUSB.h>
 # include <SerialUSB.h>
@@ -62,7 +63,6 @@ const char *g_platform_name = PLATFORM_NAME;
 static bool g_scsi_initiator = false;
 static bool g_scsi_initiator = false;
 static uint32_t g_flash_chip_size = 0;
 static uint32_t g_flash_chip_size = 0;
 static bool g_uart_initialized = false;
 static bool g_uart_initialized = false;
-
 /***************/
 /***************/
 /* GPIO init   */
 /* GPIO init   */
 /***************/
 /***************/
@@ -127,13 +127,29 @@ uint32_t platform_sys_clock_in_hz()
 
 
 zuluscsi_reclock_status_t platform_reclock(uint32_t clock_in_khz)
 zuluscsi_reclock_status_t platform_reclock(uint32_t clock_in_khz)
 {
 {
-    if (set_timings(clock_in_khz))
+    CustomTimings ct;
+    if (ct.use_custom_timings())
+    {
+        logmsg("Custom timings found in \"", CUSTOM_TIMINGS_FILE, "\" overriding reclocking");
+        logmsg("Initial Clock set to ", (int) platform_sys_clock_in_hz(), "Hz");
+        if (ct.set_timings_from_file())
+        {
+            reclock();
+            logmsg("SDIO clock set to ", (int)((g_zuluscsi_timings->clk_hz / g_zuluscsi_timings->sdio.clk_div_pio + (5 * MHZ / 10)) / MHZ) , "MHz");
+            return ZULUSCSI_RECLOCK_CUSTOM;
+        }
+        else
+            return ZULUSCSI_RECLOCK_FAILED;
+    }
+    else if (set_timings(clock_in_khz))
     {
     {
         logmsg("Initial Clock set to ", (int) platform_sys_clock_in_hz(), "Hz");
         logmsg("Initial Clock set to ", (int) platform_sys_clock_in_hz(), "Hz");
         reclock();
         reclock();
         logmsg("SDIO clock set to ", (int)((g_zuluscsi_timings->clk_hz / g_zuluscsi_timings->sdio.clk_div_pio + (5 * MHZ / 10)) / MHZ) , "MHz");
         logmsg("SDIO clock set to ", (int)((g_zuluscsi_timings->clk_hz / g_zuluscsi_timings->sdio.clk_div_pio + (5 * MHZ / 10)) / MHZ) , "MHz");
         return ZULUSCSI_RECLOCK_SUCCESS;
         return ZULUSCSI_RECLOCK_SUCCESS;
     }
     }
+    else
+        logmsg("Could not find matching clock rate: ", (int) clock_in_khz, "KHz in presets");
     return ZULUSCSI_RECLOCK_FAILED;
     return ZULUSCSI_RECLOCK_FAILED;
 }
 }
 
 

+ 127 - 0
lib/ZuluSCSI_platform_RP2MCU/custom_timings.cpp

@@ -0,0 +1,127 @@
+/**
+ * ZuluSCSI™ - Copyright (c) 2024 Rabbit Hole Computing™
+ *
+ * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version.
+ *
+ * https://www.gnu.org/licenses/gpl-3.0.html
+ * ----
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+**/
+
+#include "custom_timings.h"
+#include <SdFat.h>
+#include <minIni.h>
+#include <ZuluSCSI_log.h>
+extern SdFs SD;
+
+extern "C"
+{
+    #include <timings.h>
+}
+
+bool CustomTimings::use_custom_timings()
+{
+    return SD.exists(CUSTOM_TIMINGS_FILE) && !ini_getbool("settings", "disable", 0, CUSTOM_TIMINGS_FILE);
+}
+
+bool CustomTimings::set_timings_from_file()
+{
+    const char settings_section[] = "settings";
+    const char pll_section[] = "pll";
+    const char scsi_section[] = "scsi";
+    const char scsi_20_section[] = "scsi_20";
+    const char scsi_10_section[] = "scsi_10";
+    const char scsi_5_section[] = "scsi_5";
+    const char sdio_section[] = "sdio";
+
+
+    zuluscsi_timings_t custom_timings;
+
+
+    // pll
+    int32_t vco = ini_getl(pll_section, "vco_freq_hz", g_zuluscsi_timings->pll.vco_freq, CUSTOM_TIMINGS_FILE);
+    int32_t post_div1 = ini_getl(pll_section, "pd1", g_zuluscsi_timings->pll.post_div1, CUSTOM_TIMINGS_FILE);
+    int32_t post_div2 = ini_getl(pll_section, "pd2", g_zuluscsi_timings->pll.post_div2, CUSTOM_TIMINGS_FILE);
+
+    if (vco > 0 && post_div1 > 0 && post_div2 > 0)
+    {
+        if (vco / post_div1 / post_div2 > 250000000)
+        {
+            logmsg("Reclocking over 250MHz with the PLL settings is not allowed using ", CUSTOM_TIMINGS_FILE);
+            return false;
+        }
+    }
+    else
+    {
+        logmsg("Reclocking failed because 0 or negative PLL settings values");
+        return false;
+    }
+
+    int32_t template_khz = ini_getl(settings_section, "extends_khz", 0, CUSTOM_TIMINGS_FILE);
+    if (template_khz > 0)
+    {
+        if (!set_timings(template_khz))
+        {
+            logmsg("Count not load extends_khz with a value of ", (int) template_khz);
+            return false;
+        }
+    }
+
+    g_zuluscsi_timings->pll.vco_freq = vco;
+    g_zuluscsi_timings->pll.post_div1 = post_div1;
+    g_zuluscsi_timings->pll.post_div2 = post_div2;
+    g_zuluscsi_timings->pll.refdiv =  ini_getl(pll_section, "refdiv", g_zuluscsi_timings->pll.refdiv, CUSTOM_TIMINGS_FILE);
+
+    int32_t number_setting = ini_getl(settings_section, "boot_with_sync_value", 0, CUSTOM_TIMINGS_FILE);
+    if (number_setting > 0)
+    {
+        g_force_sync = number_setting;
+        number_setting = ini_getl(settings_section, "boot_with_offset_value", 15, CUSTOM_TIMINGS_FILE);
+        g_force_offset = number_setting > 15 ? 15 : number_setting;
+        logmsg("Forcing sync of ", (int) g_force_sync, " and offset of ", (int) g_force_offset);
+    }
+    g_zuluscsi_timings->clk_hz = ini_getl(settings_section, "clk_hz", g_zuluscsi_timings->clk_hz, CUSTOM_TIMINGS_FILE);
+
+
+
+    // scsi
+    g_zuluscsi_timings->scsi.clk_period_ps = ini_getl(scsi_section, "clk_period_ps", g_zuluscsi_timings->scsi.clk_period_ps, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi.req_delay = ini_getl(scsi_section, "req_delay_cc", g_zuluscsi_timings->scsi.req_delay, CUSTOM_TIMINGS_FILE);
+
+    // scsi 20
+    g_zuluscsi_timings->scsi_20.delay0 = ini_getl(scsi_20_section, "delay0_cc", g_zuluscsi_timings->scsi_20.delay0, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_20.delay1 = ini_getl(scsi_20_section, "delay1_cc", g_zuluscsi_timings->scsi_20.delay1, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_20.total_delay_adjust = ini_getl(scsi_20_section, "total_delay_adjust_cc", g_zuluscsi_timings->scsi_20.total_delay_adjust, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_20.max_sync = ini_getl(scsi_20_section, "max_sync", g_zuluscsi_timings->scsi_20.max_sync, CUSTOM_TIMINGS_FILE);
+
+    // scsi 10
+    g_zuluscsi_timings->scsi_10.delay0 = ini_getl(scsi_10_section, "delay0_cc", g_zuluscsi_timings->scsi_10.delay0, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_10.delay1 = ini_getl(scsi_10_section, "delay1_cc", g_zuluscsi_timings->scsi_10.delay1, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_10.total_delay_adjust = ini_getl(scsi_10_section, "total_delay_adjust_cc", g_zuluscsi_timings->scsi_10.total_delay_adjust, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_10.max_sync = ini_getl(scsi_10_section, "max_sync", g_zuluscsi_timings->scsi_10.max_sync, CUSTOM_TIMINGS_FILE);
+
+    // scsi 5
+    g_zuluscsi_timings->scsi_5.delay0 = ini_getl(scsi_5_section, "delay0_cc", g_zuluscsi_timings->scsi_5.delay0, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_5.delay1 = ini_getl(scsi_5_section, "delay1_cc", g_zuluscsi_timings->scsi_5.delay1, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_5.total_delay_adjust = ini_getl(scsi_5_section, "total_delay_adjust_cc", g_zuluscsi_timings->scsi_5.total_delay_adjust, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->scsi_5.max_sync = ini_getl(scsi_5_section, "max_sync", g_zuluscsi_timings->scsi_5.max_sync, CUSTOM_TIMINGS_FILE);
+
+    // sdio
+    g_zuluscsi_timings->sdio.clk_div_pio = ini_getl(sdio_section, "clk_div_pio", g_zuluscsi_timings->sdio.clk_div_pio, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->sdio.clk_div_1mhz = ini_getl(sdio_section, "clk_div_1mhz", g_zuluscsi_timings->sdio.clk_div_1mhz, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->sdio.delay0 = ini_getl(sdio_section, "delay0", g_zuluscsi_timings->sdio.delay0, CUSTOM_TIMINGS_FILE);
+    g_zuluscsi_timings->sdio.delay1 = ini_getl(sdio_section, "delay1", g_zuluscsi_timings->sdio.delay1, CUSTOM_TIMINGS_FILE);
+
+    return true;
+}

+ 23 - 15
lib/ZuluSCSI_platform_GD32F205/scsi2sd_timings.h → lib/ZuluSCSI_platform_RP2MCU/custom_timings.h

@@ -1,27 +1,35 @@
-/** 
+/**
  * ZuluSCSI™ - Copyright (c) 2024 Rabbit Hole Computing™
  * ZuluSCSI™ - Copyright (c) 2024 Rabbit Hole Computing™
- * 
- * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version. 
- * 
+ *
+ * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version.
+ *
  * https://www.gnu.org/licenses/gpl-3.0.html
  * https://www.gnu.org/licenses/gpl-3.0.html
  * ----
  * ----
  * This program is free software: you can redistribute it and/or modify
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version. 
- * 
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details. 
- * 
+ * GNU General Public License for more details.
+ *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 **/
 **/
-#ifndef ZULUSCSI_PLATFORM_TIMINGS_H
-#define ZULUSCSI_PLATFORM_TIMINGS_H
-#include <stdint.h>
-extern uint8_t g_max_sync_20_period;
-extern uint8_t g_max_sync_10_period;
-extern uint8_t g_max_sync_5_period;
-#endif // ZULUSCSI_RP2MCU_TIMINGS_H
+#pragma once
+
+#define CUSTOM_TIMINGS_FILE "zuluscsi_timings.ini"
+
+extern "C"
+{
+    #include "timings_RP2MCU.h"
+}
+
+class CustomTimings
+{
+    public:
+        bool use_custom_timings();
+        bool set_timings_from_file();
+};

+ 3 - 1
lib/ZuluSCSI_platform_RP2MCU/scsi2sd_timings.c

@@ -28,4 +28,6 @@ uint8_t g_max_sync_5_period  = 50;
 uint8_t g_max_sync_20_period = 25;
 uint8_t g_max_sync_20_period = 25;
 uint8_t g_max_sync_10_period = 25;
 uint8_t g_max_sync_10_period = 25;
 uint8_t g_max_sync_5_period  = 50; 
 uint8_t g_max_sync_5_period  = 50; 
-#endif
+#endif
+uint8_t g_force_sync = 0;
+uint8_t g_force_offset = 15;

+ 0 - 31
lib/ZuluSCSI_platform_RP2MCU/scsi2sd_timings.h

@@ -1,31 +0,0 @@
-/** 
- * ZuluSCSI™ - Copyright (c) 2024 Rabbit Hole Computing™
- * 
- * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version. 
- * 
- * https://www.gnu.org/licenses/gpl-3.0.html
- * ----
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version. 
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details. 
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
-**/
-#ifndef ZULUSCSI_PLATFORM_TIMINGS_H
-#define ZULUSCSI_PLATFORM_TIMINGS_H
-#include <stdint.h>
-
-// This is actually a minimum number
-// 1/4 of the lowest sync period
-// that keeps the scsi interface stable
-extern uint8_t g_max_sync_20_period;
-extern uint8_t g_max_sync_10_period;
-extern uint8_t g_max_sync_5_period;
-#endif // ZULUSCSI_RP2MCU_TIMINGS_H

+ 1 - 1
lib/ZuluSCSI_platform_RP2MCU/timings_RP2MCU.c

@@ -316,4 +316,4 @@ bool set_timings(uint32_t target_clk_in_khz)
         }
         }
     }
     }
     return false;
     return false;
-}
+}

+ 5 - 1
src/ZuluSCSI.cpp

@@ -860,10 +860,14 @@ static void zuluscsi_setup_sd_card()
           logmsg("Reclocking this board is not supported");
           logmsg("Reclocking this board is not supported");
           break;
           break;
         case ZULUSCSI_RECLOCK_FAILED:
         case ZULUSCSI_RECLOCK_FAILED:
-          logmsg("Reclocking at ", (int) clock_khz , " KHz is not supported");
+          logmsg("Reclocking failed");
           break;
           break;
         case ZULUSCSI_RECLOCK_SUCCESS:
         case ZULUSCSI_RECLOCK_SUCCESS:
           logmsg("Reclocking at ", (int) clock_khz , " KHz was successful");
           logmsg("Reclocking at ", (int) clock_khz , " KHz was successful");
+          break;
+        case ZULUSCSI_RECLOCK_CUSTOM:
+          logmsg("Custom reclocking timings used");
+          break;
       }
       }
       g_sdcard_present = mountSDCard();
       g_sdcard_present = mountSDCard();
       reinitSCSI();
       reinitSCSI();

+ 1 - 0
src/ZuluSCSI_config.h

@@ -129,6 +129,7 @@
 typedef enum
 typedef enum
 {
 {
     ZULUSCSI_RECLOCK_SUCCESS,
     ZULUSCSI_RECLOCK_SUCCESS,
+    ZULUSCSI_RECLOCK_CUSTOM,
     ZULUSCSI_RECLOCK_NOT_SUPPORTED,
     ZULUSCSI_RECLOCK_NOT_SUPPORTED,
     ZULUSCSI_RECLOCK_FAILED
     ZULUSCSI_RECLOCK_FAILED
 } zuluscsi_reclock_status_t;
 } zuluscsi_reclock_status_t;

+ 1 - 1
zuluscsi.ini

@@ -43,7 +43,7 @@
 #Initiator settings
 #Initiator settings
 #InitiatorID = 7 # SCSI ID, 0-7, when the device is in initiator mode, default is 7
 #InitiatorID = 7 # SCSI ID, 0-7, when the device is in initiator mode, default is 7
 #InitiatorMaxRetry = 5 #  number of retries on failed reads 0-255, default is 5
 #InitiatorMaxRetry = 5 #  number of retries on failed reads 0-255, default is 5
-#InitiatorImageHandling = 0 # 0: skip exisitng images, 1: create new image with incrementing suffix, 2: overwrite exising image
+#InitiatorImageHandling = 0 # 0: skip existing images, 1: create new image with incrementing suffix, 2: overwrite existing image
 
 
 #EnableCDAudio = 0 # 1: Enable CD audio - an external I2S DAC on the v1.2 is required
 #EnableCDAudio = 0 # 1: Enable CD audio - an external I2S DAC on the v1.2 is required
 
 

+ 96 - 0
zuluscsi_timings.ini

@@ -0,0 +1,96 @@
+[settings]
+disable = False # True: disable custom settings - default false: use the settings of this file
+
+# extends_khz lets you choose a built in timing setting as a template
+# this is the same value as would be set in ReclockInKHz in zuluscsi.ini
+# this allows the ability to use a minimum of below settings in your zuluscsi_timings.ini file
+extends_khz = 125000 # default value is 0 - meaning using the base settings of the board
+
+# boot_with_sync value setting starts the board at an assumed sync value
+# boot_with_offset value setting starts the board at an assumed offset value
+# these are values are usually requested by the host to negotiate sync transfers
+# this is for users who are restarting their boards while the system is running
+# to test their settings and don't want to reboot their computers to renegotiate sync
+# ** hot swapping like this is not recommended **
+# the sync value is explained below
+boot_with_sync_value = 0 # default value is 0 meaning this feature is off
+boot_with_offset_value = 15 # default value and max value is 15, if boot_with_sync_value is 0 this value is
+
+
+clk_hz = 250000000 # reclock target system frequency in Hz
+
+[pll]
+# These values can be found by using the script from the Pico-SDK:
+# pico-sdk/src/rp2_common/hardware_clocks/scripts/vcocalc.py
+refdiv =  1 # reference divider
+vco_freq_hz = 1500000000 # vco frequency in Hz
+pd1 = 6 # Post divider 1
+pd2 = 1 # Post divider 2
+
+[scsi]
+# Period of the system clock in picoseconds
+clk_period_ps = 4000 # 1 / clk_hz * 10^12
+# Delay from data setup to REQ assertion.
+# deskew delay + cable skew delay = 55 ns minimum
+req_delay_cc = 14 # 55ns / clk_period_ps * 1000 rounded up
+
+# The next settings are for different SCSI synchronous clock speeds
+    # delay0: Data Setup Time - Delay from data write to REQ assertion
+    # delay1: Transmit Assertion time from REQ assert to REQ deassert (req pulse)
+    # delay2: Negation period - this value is calculated by the firmware: (total_delay - d0 - d1)
+    # total_delay spec is the sync value * 4 in ns
+
+    # Delay0 and Delay1 values are in clock cycles minus 1 for the pio instruction delay
+    #  SCSI clock:  Ultra(20)     Fast(10)  SCSI-1(5)
+    # delay0 spec:     11.5ns         23ns       23ns
+    # delay1 spec:     16.5ns         33ns       53ns
+    # delay2 spec:   min 15ns     min 30ns   min 80ns
+    # total_delay_adjust is manual adjustment value, when checked with a scope
+
+    # sync value is what the SCSI controller sends to the device to negotiate it' sync speed
+    # These are the fastest sync values for each synchronous clock speed
+    #   12 (48ns)  is for Fast20 21MB/s
+    #   25 (100ns) is for Fast10 10MB/s
+    #   50 (200ns) is for Fast5   5MB/s
+    # max_sync - the minimum sync period ("max" meaning fastest throughput) that
+    # is supported at this clock rate, the throughput is 1/4 the actual value in ns
+    # the max transfer speed is 1 / (4 * max_sync) in MB/s
+    # Though the ZuluSCSI generally isn't able to achieve that, it can get close on reads
+
+# the maximum value that delay0_cc and delay1_cc can be set to is 15
+    # due to the way the Programmable IO on the RP2 series chips work
+[scsi_20]
+# These are the Ultra (Fast 20) synchronous SCSI settings, SCSI running at 20MHz
+delay0_cc = 2 # 3 - 1 - delay 0 in clock cycles minus 1
+delay1_cc = 4 # 5 - 1 - delay 1 in clock cycles minus 1
+total_delay_adjust_cc = 1 # adjustment to the total sync period in clock cylces
+max_sync = 12 # the max sync supported by the board in Fast20, total sync periods in ns / 4
+
+[scsi_10]
+# These are the Fast (Fast 10) synchronous SCSI settings, SCSI runnings at 10MHz
+delay0_cc = 5 # 6 - 1
+delay1_cc = 8 # 9 - 1
+total_delay_adjust_cc = 1
+max_sync = 25
+
+[scsi_5]
+# These are the SCSI-1 (Fast 5) synchronous SCSI settings, SCSI runnings at 5MHz
+delay0_cc = 15 # maxed out, should probably be around 16
+delay1_cc = 15 # maxed out, should probably be around be 30
+total_delay_adjust_cc = 1
+max_sync = 50
+
+
+[sdio]
+# These settings determine the clock setting and duty cycle of the SDIO clock
+clk_div_pio = 5 # clk_hz / clk_div_pio should be between 25MHz and 50MHz
+# SDIO first communicates to the SD card at 1MHz, clk_div_1mhz divides the SDIO clock down to 1MHz
+clk_div_1mhz = 50 # this should be the SDIO clock speed in MHz, but for some SDIO clockspeeds using a smaller value worked
+# delay0 and delay1 determine the duty cycle of the SDIO clock
+# their total should equal clk_div_pio. but they both have 1 subtracted from
+# them to accommodate the clock cycle a PIO instruction takes
+# their max value is 15
+delay0 = 3 # 4 - 1
+delay1 = 0 # 1 - 1
+
+# Please post your findings to https://github.com/ZuluSCSI/ZuluSCSI-firmware/discussions