Переглянути джерело

All DIP switches working

The three dip switch on the ZuluSCSI v1.2 board work
- SCSI ID selector
- device type selector
- TERM/DBG/Disable Direct selectors

Direct mode currently works and the normal mode works
when disable direct/raw mode is selected.
Morio 2 роки тому
батько
коміт
0c97c21474

+ 28 - 3
lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.cpp

@@ -34,6 +34,11 @@ extern "C" {
 const char *g_platform_name = PLATFORM_NAME;
 static bool g_enable_apple_quirks = false;
 
+// hw_config.cpp c functions
+#ifdef ZULUSCSI_HARDWARE_CONFIG
+#include "platform_hw_config.h"
+#endif
+
 /*************************/
 /* Timing functions      */
 /*************************/
@@ -212,16 +217,26 @@ void platform_init()
 #endif
 
     // DIP switches
+#ifdef DIPSW1_PIN
     gpio_init(DIP_PORT, GPIO_MODE_IPD, 0, DIPSW1_PIN | DIPSW2_PIN | DIPSW3_PIN);
+#else
+    // Some boards do not have an Apple quirks dip switch
+    gpio_init(DIP_PORT, GPIO_MODE_IPD, 0, DIPSW2_PIN | DIPSW3_PIN);
+#endif
 
     // LED pins
     gpio_bit_set(LED_PORT, LED_PINS);
     gpio_init(LED_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, LED_PINS);
 
     // Ejection buttons
+#ifdef ZULUSCSI_HARDWARE_CONFIG
+    gpio_init(EJECT_BTN_PORT, GPIO_MODE_IPU, 0, EJECT_BTN_PIN);
+    gpio_init(USER_BTN_PORT,  GPIO_MODE_IPU, 0, USER_BTN_PIN);
+    hw_config_init_gpios();
+#else
     gpio_init(EJECT_1_PORT, GPIO_MODE_IPU, 0, EJECT_1_PIN);
     gpio_init(EJECT_2_PORT, GPIO_MODE_IPU, 0, EJECT_2_PIN);
-
+#endif
     // SWO trace pin on PB3
     gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
 }
@@ -254,14 +269,20 @@ void platform_late_init()
     {
         g_log_debug = false;
     }
-
+#ifdef DIPSW1_PIN
     if (gpio_input_bit_get(DIP_PORT, DIPSW1_PIN))
     {
         logmsg("DIPSW1 is ON: enabling Apple quirks by default");
         g_enable_apple_quirks = true;
     }
+#endif
 
+#ifdef ZULUSCSI_HARDWARE_CONFIG
+    hw_config_init_state();
+#else
     greenpak_load_firmware();
+#endif
+
 }
 
 void platform_disable_led(void)
@@ -502,9 +523,13 @@ uint8_t platform_get_buttons()
     // Buttons are active low: internal pull-up is enabled,
     // and when button is pressed the pin goes low.
     uint8_t buttons = 0;
+#ifdef ZULUSCSI_HARDWARE_CONFIG
+    if (!gpio_input_bit_get(EJECT_BTN_PORT, EJECT_BTN_PIN))   buttons |= 1;
+    if (!gpio_input_bit_get(USER_BTN_PORT, USER_BTN_PIN))   buttons |= 4;
+#else
     if (!gpio_input_bit_get(EJECT_1_PORT, EJECT_1_PIN))   buttons |= 1;
     if (!gpio_input_bit_get(EJECT_2_PORT, EJECT_2_PIN))   buttons |= 2;
-
+#endif
     // Simple debouncing logic: handle button releases after 100 ms delay.
     static uint32_t debounce;
     static uint8_t buttons_debounced = 0;

+ 85 - 16
lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_v1_2_gpio.h

@@ -40,7 +40,7 @@
 #define SCSI_OUT_DATA_MASK (SCSI_OUT_DB0 | SCSI_OUT_DB1 | SCSI_OUT_DB2 | SCSI_OUT_DB3 | SCSI_OUT_DB4 | SCSI_OUT_DB5 | SCSI_OUT_DB6 | SCSI_OUT_DB7 | SCSI_OUT_DBP)
 #define SCSI_OUT_REQ_IDX 4
 
-// Control signals to optional PLD device
+// Control signals to optional PLD device (unused for v1.2 - kept for compilation)
 #define SCSI_OUT_PLD1 GPIO_PIN_15
 #define SCSI_OUT_PLD2 GPIO_PIN_3
 #define SCSI_OUT_PLD3 GPIO_PIN_5
@@ -62,7 +62,7 @@
 #define SCSI_TIMER_DMACHB_IRQ DMA1_Channel1_IRQHandler
 #define SCSI_TIMER_DMACHB_IRQn DMA1_Channel1_IRQn
 
-// GreenPAK logic chip pins
+// GreenPAK logic chip pins (unused for v1.2 - kept for compilation)
 #define GREENPAK_I2C_ADDR 0x10
 #define GREENPAK_I2C_PORT GPIOB
 #define GREENPAK_I2C_SCL GPIO_PIN_8
@@ -77,6 +77,11 @@
 #define GREENPAK_IRQ  EXTI3_IRQHandler
 #define GREENPAK_IRQn EXTI3_IRQn
 
+// I2C for v1.2
+#define I2C_PORT GPIOB
+#define I2C_SCL GPIO_PIN_6
+#define I2C_SDA GPIO_PIN_7
+
 // SCSI input data port
 #define SCSI_IN_PORT  GPIOE
 #define SCSI_IN_DB7   GPIO_PIN_15
@@ -128,14 +133,24 @@
 #define SCSI_SYNC_TIMER_RCU RCU_TIMER1
 
 // SEL pin uses EXTI interrupt
-#define SCSI_SEL_PORT GPIOB
-#define SCSI_SEL_PIN  GPIO_PIN_11
-#define SCSI_SEL_EXTI EXTI_11
-#define SCSI_SEL_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB
-#define SCSI_SEL_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_11
+// #define SCSI_SEL_PORT GPIOB
+// #define SCSI_SEL_PIN  GPIO_PIN_11
+// #define SCSI_SEL_EXTI EXTI_11
+// #define SCSI_SEL_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB
+// #define SCSI_SEL_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_11
+// #define SCSI_SEL_IRQ EXTI10_15_IRQHandler
+// #define SCSI_SEL_IRQn EXTI10_15_IRQn
+
+// SEL pin for 1.2
+#define SCSI_SEL_PORT GPIOD
+#define SCSI_SEL_PIN  GPIO_PIN_15
+#define SCSI_SEL_EXTI EXTI_15
+#define SCSI_SEL_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOD
+#define SCSI_SEL_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_15
 #define SCSI_SEL_IRQ EXTI10_15_IRQHandler
 #define SCSI_SEL_IRQn EXTI10_15_IRQn
 
+
 // BSY pin uses EXTI interrupt
 #define SCSI_BSY_PORT GPIOB
 #define SCSI_BSY_PIN  GPIO_PIN_10
@@ -158,6 +173,33 @@
 #define SCSI_TERM_EN_PORT GPIOB
 #define SCSI_TERM_EN_PIN  GPIO_PIN_0
 
+// SPI/I2S Pins
+#define SPI_CS_PORT     GPIOB
+#define SPI_CS_PIN      GPIO_PIN_9
+#define SPI_MISO_PORT   GPIOC
+#define SPI_MISO_PIN    GPIO_PIN_2
+#define SPI_MOSI_PORT   GPIOC
+#define SPI_MOSI_PIN    GPIO_PIN_3
+#define SPI_CK_PORT     GPIOD
+#define SPI_CK_PIN      GPIO_PIN_3
+
+#define I2S_SD_PORT     SPI_MOSI_PORT
+#define I2S_SD_PIN      SPI_MOSI_PIN
+#define I2S_WS_PORT     SPI_CS_PORT
+#define I2S_WS_PIN      SPI_CS_PIN
+#define I2S_CK_PORT     SPI_CK_PORT
+#define I2S_CK_PIN      SPI_CK_PIN
+
+// SPI/I2S DMA
+#define SPI_DMA         DMA0
+#define SPI_DMA_CH      DMA_CH4
+#define SPI_RCU_DMA     RCU_DMA0
+#define SPI_I2S_SPI     SPI1
+#define SPI_RCU_I2S_SPI RCU_SPI1
+#define SPI_IRQHandler  DMA0_Channel4_IRQHandler
+#define SPI_DMA_IRQn    DMA0_Channel4_IRQn
+
+
 // SD card pins
 #define SD_USE_SDIO 1
 #define SD_SDIO_DATA_PORT GPIOC
@@ -171,10 +213,31 @@
 #define SD_SDIO_CMD       GPIO_PIN_2
 
 // DIP switches
+// #define DIP_PORT     GPIOB
+// #define DIPSW1_PIN   GPIO_PIN_4
+// #define DIPSW2_PIN   GPIO_PIN_5
+// #define DIPSW3_PIN   GPIO_PIN_6
+
+// v1.2 DIP switch pins
 #define DIP_PORT     GPIOB
-#define DIPSW1_PIN   GPIO_PIN_4
 #define DIPSW2_PIN   GPIO_PIN_5
-#define DIPSW3_PIN   GPIO_PIN_6
+#define DIPSW3_PIN   GPIO_PIN_4
+// DIPSW DIRECT MODE replaces DIPSW1
+#define DIPSW_DIRECT_MODE_PORT  GPIOB
+#define DIPSW_DIRECT_MODE_PIN   GPIO_PIN_8
+// SCSI ID DIP swtich
+#define DIPSW_SCSI_ID_BIT_PORT  GPIOC
+#define DIPSW_SCSI_ID_BIT1_PIN  GPIO_PIN_13
+#define DIPSW_SCSI_ID_BIT2_PIN  GPIO_PIN_14
+#define DIPSW_SCSI_ID_BIT3_PIN  GPIO_PIN_15
+#define DIPSW_SCSI_ID_BIT_PINS  (DIPSW_SCSI_ID_BIT1_PIN | DIPSW_SCSI_ID_BIT2_PIN | DIPSW_SCSI_ID_BIT3_PIN)
+#define DIPSW_SCSI_ID_BIT_SHIFT 13
+// Rotary DIP switch
+#define DIPROT_DEVICE_SEL_BIT_PORT  GPIOE
+#define DIPROT_DEVICE_SEL_BIT1_PIN  GPIO_PIN_5
+#define DIPROT_DEVICE_SEL_BIT2_PIN  GPIO_PIN_6
+#define DIPROT_DEVICE_SEL_BIT_PINS  (DIPROT_DEVICE_SEL_BIT1_PIN | DIPROT_DEVICE_SEL_BIT2_PIN)
+#define DIPROT_DEVICE_SEL_BIT_SHIFT 5
 
 // Status LED pins
 #define LED_PORT     GPIOC
@@ -183,11 +246,17 @@
 #define LED_PINS     (LED_I_PIN | LED_E_PIN)
 #define LED_ON()     gpio_bit_reset(LED_PORT, LED_PINS)
 #define LED_OFF()    gpio_bit_set(LED_PORT, LED_PINS)
+#define LED_EJECT_PORT  GPIOA
+#define LED_EJECT_PIN   GPIO_PIN_1
+#define LED_EJECT_ON()  gpio_bit_reset(LED_EJECT_PORT, LED_EJECT_PIN)
+#define LED_EJECT_OFF() gpio_bit_set(LED_EJECT_PORT, LED_EJECT_PIN)
+
+// Ejection button is on GPIO PA3 and USER button is on GPIO PA2
+// Eject and user buttons masks
+#define EJECT_BTN_MASK (1|2)
+#define USER_BTN_MASK  (4)
+#define EJECT_BTN_PORT  GPIOA
+#define EJECT_BTN_PIN   GPIO_PIN_3
+#define USER_BTN_PORT   GPIOA
+#define USER_BTN_PIN    GPIO_PIN_2
 
-// Ejection buttons are available on expansion header J303.
-// PE5 = channel 1, PE6 = channel 2
-// Connect button between GPIO and GND pin.
-#define EJECT_1_PORT    GPIOE
-#define EJECT_1_PIN     GPIO_PIN_5
-#define EJECT_2_PORT    GPIOE
-#define EJECT_2_PIN     GPIO_PIN_6

+ 76 - 0
lib/ZuluSCSI_platform_GD32F205/platform_hw_config.cpp

@@ -0,0 +1,76 @@
+#include "platform_hw_config.h"
+#include "ZuluSCSI_platform.h"
+#include "ZuluSCSI_config.h"
+
+HardwareConfig g_hw_config;
+
+S2S_CFG_TYPE hw_config_selected_device()
+{
+    return g_hw_config.device_type();
+};
+
+bool hw_config_is_active()
+{
+    return g_hw_config.is_active();
+}
+
+void hw_config_init_gpios()
+{
+    g_hw_config.init_gpios();
+}
+
+void hw_config_init_state()
+{
+    g_hw_config.init_state();
+}
+
+void HardwareConfig::init_gpios()
+{
+    // SCSI ID dip switch
+    gpio_init(DIPSW_SCSI_ID_BIT_PORT, GPIO_MODE_IPD, 0, DIPSW_SCSI_ID_BIT_PINS);
+    
+    // Device select BCD rotary dip switch
+    gpio_init(DIPROT_DEVICE_SEL_BIT_PORT, GPIO_MODE_IPD, 0, DIPROT_DEVICE_SEL_BIT_PINS);
+
+    // Direct/Raw Mode Select
+    gpio_init(DIPSW_DIRECT_MODE_PORT, GPIO_MODE_IPD, 0, DIPSW_DIRECT_MODE_PIN);
+
+    LED_EJECT_OFF();
+    gpio_init(LED_EJECT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, LED_EJECT_PIN);
+}
+
+void HardwareConfig::init_state()
+{
+    m_is_active = RESET == gpio_input_bit_get(DIPSW_DIRECT_MODE_PORT, DIPSW_DIRECT_MODE_PIN);
+    m_scsi_id = (gpio_input_port_get(DIPSW_SCSI_ID_BIT_PORT) & DIPSW_SCSI_ID_BIT_PINS) >> DIPSW_SCSI_ID_BIT_SHIFT;
+    
+    uint8_t rotary_select = (gpio_input_port_get(DIPROT_DEVICE_SEL_BIT_PORT) & DIPROT_DEVICE_SEL_BIT_PINS) >> DIPROT_DEVICE_SEL_BIT_SHIFT;
+    switch (rotary_select)
+    {
+    case 0:
+        m_device_type = S2S_CFG_FIXED;
+    break;
+    case 1:
+        m_device_type = S2S_CFG_SEQUENTIAL;
+    break;
+    case 2:
+        m_device_type = S2S_CFG_OPTICAL;
+    break;
+    case 3:
+        m_device_type = S2S_CFG_MO;
+    break;
+
+    default:
+        m_device_type = S2S_CFG_FIXED;
+    }
+    
+    if (m_device_type == S2S_CFG_OPTICAL)
+    {
+        m_blocksize = DEFAULT_BLOCKSIZE_OPTICAL;
+    }
+    else
+    {
+        m_blocksize = RAW_FALLBACK_BLOCKSIZE;
+    }
+}
+

+ 73 - 0
lib/ZuluSCSI_platform_GD32F205/platform_hw_config.h

@@ -0,0 +1,73 @@
+/** 
+ * ZuluSCSI™ - Copyright (c) 2023 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/>.
+**/
+
+/**
+ * Configuration of the ZuluSCSI set by hardware rotary and standard DIP switches
+ * Settings include SCSI ID, device type, and if hardware config is active 
+*/
+
+#pragma once
+#include <scsi2sd.h>
+
+// C wrappers
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+    S2S_CFG_TYPE hw_config_selected_device();
+    bool hw_config_is_active();
+    void hw_config_init_gpios();
+    void hw_config_init_state();
+    
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+class HardwareConfig
+{
+public:
+    // Initialize GPIOs
+    void init_gpios();
+
+    // Initialize device state settings
+    void init_state();
+
+    // get the device type
+    // @returns the device type
+    const S2S_CFG_TYPE& device_type() const {return m_device_type;}
+    const uint8_t& scsi_id()    const {return m_scsi_id;}
+    const bool& is_active()     const {return m_is_active;}
+    const int blocksize()       const {return m_blocksize;}
+
+protected:
+    S2S_CFG_TYPE m_device_type;
+    uint8_t m_scsi_id;
+    bool m_is_active;
+    int m_blocksize;
+};
+
+
+// global hardware configuration
+extern HardwareConfig g_hw_config;
+
+#endif // __cplusplus
+

+ 1 - 0
platformio.ini

@@ -87,6 +87,7 @@ build_flags =
      -DENABLE_DEDICATED_SPI=1
      -DHAS_SDIO_CLASS
      -DZULUSCSI_V1_2
+     -DZULUSCSI_HARDWARE_CONFIG
 
 ; ZuluSCSI RP2040 hardware platform, based on the Raspberry Pi foundation RP2040 microcontroller
 [env:ZuluSCSI_RP2040]

+ 31 - 3
src/ZuluSCSI.cpp

@@ -54,7 +54,9 @@
 #include "ZuluSCSI_disk.h"
 #include "ZuluSCSI_initiator.h"
 #include "ROMDrive.h"
-
+#ifdef ZULUSCSI_HARDWARE_CONFIG
+# include "platform_hw_config.h"
+#endif
 SdFs SD;
 FsFile g_logfile;
 static bool g_romdrive_active;
@@ -291,6 +293,12 @@ bool createImage(const char *cmd_filename, char imgname[MAX_FILE_PATH + 1])
 // Iterate over the root path in the SD card looking for candidate image files.
 bool findHDDImages()
 {
+#ifdef ZULUSCSI_HARDWARE_CONFIG
+  if (g_hw_config.is_active())
+  {
+    return false;
+  }
+#endif // ZULUSCSI_HARDWARE_CONFIG
   char imgdir[MAX_FILE_PATH];
   ini_gets("SCSI", "Dir", "/", imgdir, sizeof(imgdir), CONFIGFILE);
   int dirindex = 0;
@@ -393,7 +401,7 @@ bool findHDDImages()
         if (is_cd)
         {
           // Use 2048 as the default sector size for CD-ROMs
-          blk = 2048;
+          blk = DEFAULT_BLOCKSIZE_OPTICAL;
         }
 
         // Parse SCSI device ID
@@ -591,15 +599,35 @@ static void reinitSCSI()
   }
   else
   {
-#if RAW_FALLBACK_ENABLE
+#if defined(ZULUSCSI_HARDWARE_CONFIG)
+  if (g_hw_config.is_active())
+  {
+    bool success;
+    logmsg("Direct/Raw mode enabled, using hardware switches for configuration");
+    success = scsiDiskOpenHDDImage(g_hw_config.scsi_id(), "RAW:0:0xFFFFFFFF", g_hw_config.scsi_id(), 0,
+                                   g_hw_config.blocksize(), g_hw_config.device_type());
+    if (success)
+    {
+      blinkStatus(BLINK_STATUS_OK);
+    }
+  }
+#elif defined(RAW_FALLBACK_ENABLE)
     logmsg("No images found, enabling RAW fallback partition");
     scsiDiskOpenHDDImage(RAW_FALLBACK_SCSI_ID, "RAW:0:0xFFFFFFFF", RAW_FALLBACK_SCSI_ID, 0,
                          RAW_FALLBACK_BLOCKSIZE);
 #else
     logmsg("No valid image files found!");
 #endif
+
+#ifdef ZULUSCSI_HARDWARE_CONFIG
+  if (!g_hw_config.is_active())
+  {
     blinkStatus(BLINK_ERROR_NO_IMAGES);
   }
+#else
+   blinkStatus(BLINK_ERROR_NO_IMAGES);
+#endif
+  }
 
   scsiPhyReset();
   scsiDiskInit();

+ 4 - 1
src/ZuluSCSI_config.h

@@ -81,6 +81,9 @@
 #define DRIVEINFO_MAGOPT    {"ZULUSCSI", "MO_DRIVE",  PLATFORM_REVISION, ""}
 #define DRIVEINFO_TAPE      {"ZULUSCSI", "TAPE",      PLATFORM_REVISION, ""}
 
+// Default optical drive blocksize
+#define DEFAULT_BLOCKSIZE_OPTICAL 2048
+
 // Default SCSI drive information when Apple quirks are enabled
 #define APPLE_DRIVEINFO_FIXED     {"CDC",      "ZuluSCSI HDD",      PLATFORM_REVISION, "1.0"}
 #define APPLE_DRIVEINFO_REMOVABLE {"IOMEGA",   "BETA230",           PLATFORM_REVISION, "2.02"}
@@ -97,4 +100,4 @@
 // Use prefetch buffer in read requests
 #ifndef PREFETCH_BUFFER_SIZE
 #define PREFETCH_BUFFER_SIZE 8192
-#endif
+#endif

+ 12 - 7
src/ZuluSCSI_disk.cpp

@@ -404,29 +404,34 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int
             logmsg("---- WARNING: file ", filename, " is not contiguous. This will increase read latency.");
         }
 
-        if (type == S2S_CFG_OPTICAL)
+        if (type == S2S_CFG_FIXED)
         {
-            logmsg("---- Configuring as CD-ROM drive based on image name");
+            logmsg("---- Configuring as disk drive drive");
+            img.deviceType = S2S_CFG_FIXED;
+        }
+        else if (type == S2S_CFG_OPTICAL)
+        {
+            logmsg("---- Configuring as CD-ROM drive");
             img.deviceType = S2S_CFG_OPTICAL;
         }
         else if (type == S2S_CFG_FLOPPY_14MB)
         {
-            logmsg("---- Configuring as floppy drive based on image name");
+            logmsg("---- Configuring as floppy drive");
             img.deviceType = S2S_CFG_FLOPPY_14MB;
         }
         else if (type == S2S_CFG_MO)
         {
-            logmsg("---- Configuring as magneto-optical based on image name");
+            logmsg("---- Configuring as magneto-optical");
             img.deviceType = S2S_CFG_MO;
         }
         else if (type == S2S_CFG_REMOVEABLE)
         {
-            logmsg("---- Configuring as removable drive based on image name");
+            logmsg("---- Configuring as removable drive");
             img.deviceType = S2S_CFG_REMOVEABLE;
         }
         else if (type == S2S_CFG_SEQUENTIAL)
         {
-            logmsg("---- Configuring as tape drive based on image name");
+            logmsg("---- Configuring as tape drive");
             img.deviceType = S2S_CFG_SEQUENTIAL;
         }
 
@@ -926,7 +931,7 @@ uint8_t diskEjectButtonUpdate(bool immediate)
 {
     // treat '1' to '0' transitions as eject actions
     static uint8_t previous = 0x00;
-    uint8_t bitmask = platform_get_buttons();
+    uint8_t bitmask = platform_get_buttons() & EJECT_BTN_MASK;
     uint8_t ejectors = (previous ^ bitmask) & previous;
     previous = bitmask;