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

Merge pull request #546 from ZuluSCSI/dev_new_sdio

ZuluSCSI Blaster: Enable new SDIO library
Alex Perez 7 сар өмнө
parent
commit
7ca6c49118

+ 51 - 1
lib/ZuluSCSI_platform_RP2MCU/ZuluSCSI_platform.cpp

@@ -40,6 +40,11 @@
 #include "custom_timings.h"
 #include <ZuluSCSI_settings.h>
 
+#ifdef SD_USE_RP2350_SDIO
+#include <sdio_rp2350.h>
+#else
+#include <sdio.h>
+#endif
 
 #ifndef PIO_FRAMEWORK_ARDUINO_NO_USB
 # include <SerialUSB.h>
@@ -171,7 +176,9 @@ bool platform_reclock(zuluscsi_speed_grade_t speed_grade)
 #endif
             logmsg("Initial Clock set to ", (int) platform_sys_clock_in_hz(), "Hz");
             logmsg("Reclocking the MCU to ",(int) g_zuluscsi_timings->clk_hz, "Hz");
+#ifndef SD_USE_RP2350_SDIO
             logmsg("Setting the SDIO clock to ", (int)((g_zuluscsi_timings->clk_hz / g_zuluscsi_timings->sdio.clk_div_pio + (5 * MHZ / 10)) / MHZ) , "MHz");
+#endif
             usb_log_poll();
             reclock();
             logmsg("After reclocking, system reports clock set to ", (int) platform_sys_clock_in_hz(), "Hz");
@@ -645,6 +652,28 @@ void isr_hardfault(void)
 /* Debug logging and watchdog            */
 /*****************************************/
 
+static bool usb_serial_connected()
+{
+#ifdef PIO_FRAMEWORK_ARDUINO_NO_USB
+    return false;
+#endif
+
+    static bool connected;
+    static uint32_t last_check_time;
+
+#ifdef PLATFORM_MASS_STORAGE
+    if (platform_msc_lock_get()) return connected; // Avoid re-entrant USB events
+#endif
+
+    if (last_check_time == 0 || (uint32_t)(millis() - last_check_time) > 1000)
+    {
+        connected = bool(Serial);
+        last_check_time = millis();
+    }
+
+    return connected;
+}
+
 // Send log data to USB UART if USB is connected.
 // Data is retrieved from the shared log ring buffer and
 // this function sends as much as fits in USB CDC buffer.
@@ -659,6 +688,8 @@ static void usb_log_poll()
 #ifndef PIO_FRAMEWORK_ARDUINO_NO_USB
     static uint32_t logpos = 0;
 
+    if (!usb_serial_connected()) return;
+
 #ifdef PLATFORM_MASS_STORAGE
     if (platform_msc_lock_get()) return; // Avoid re-entrant USB events
 #endif
@@ -686,7 +717,9 @@ static void usb_log_poll()
 // Grab input from USB Serial terminal
 static void usb_input_poll()
 {
-    #ifndef PIO_FRAMEWORK_ARDUINO_NO_USB
+#ifndef PIO_FRAMEWORK_ARDUINO_NO_USB
+
+    if (!usb_serial_connected()) return;
 
 #ifdef PLATFORM_MASS_STORAGE
     if (platform_msc_lock_get()) return; // Avoid re-entrant USB events
@@ -1140,3 +1173,20 @@ const uint16_t g_scsi_parity_check_lookup[512] __attribute__((aligned(1024), sec
 #undef X
 
 } /* extern "C" */
+
+
+#ifdef SD_USE_SDIO
+// These functions are not used for SDIO mode but are needed to avoid build error.
+void sdCsInit(SdCsPin_t pin) {}
+void sdCsWrite(SdCsPin_t pin, bool level) {}
+
+// SDIO configuration for main program
+SdioConfig g_sd_sdio_config(DMA_SDIO);
+
+#ifdef SD_USE_RP2350_SDIO
+void platform_set_sd_callback(sd_callback_t func, const uint8_t *buffer)
+{
+    rp2350_sdio_sdfat_set_callback(func, buffer);
+}
+#endif
+#endif

+ 3 - 0
lib/ZuluSCSI_platform_RP2MCU/rp2040-template.ld

@@ -99,6 +99,9 @@ SECTIONS
          * Uncommenting this line puts all code in flash.
          * You may have to delete "firmware.elf" for the next build
          * to use this linker file's changes
+         *
+         * Alternatively, use "hbreak" in gdb to force hardware
+         * breakpoints instead of RAM breakpoints.
          */
         /* *(.text .text*) */
     } > FLASH

+ 3 - 0
lib/ZuluSCSI_platform_RP2MCU/rp23xx-template.ld

@@ -82,6 +82,9 @@ SECTIONS
     Uncomment the EXCLUDE_FILE line below and comment the EXCLUDE_FILE line above for debug to work properly,
     the initial break point to main seems to get clobbered when everything is in SRAM.
     You may have to delete the "firmware.elf" file so the next build links with newly modified linker script
+
+    Alternatively, use "hbreak" in gdb to force hardware
+    breakpoints instead of RAM breakpoints.
     ------------------------------------------------------------*/
         /* *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) */
 /* =============================================================== */

+ 2 - 9
lib/ZuluSCSI_platform_RP2MCU/sd_card_sdio.cpp

@@ -24,7 +24,7 @@
 
 #include "ZuluSCSI_platform.h"
 
-#ifdef SD_USE_SDIO
+#if defined(SD_USE_SDIO) && !defined(SD_USE_RP2350_SDIO)
 
 #include "ZuluSCSI_log.h"
 #include "sdio.h"
@@ -549,11 +549,4 @@ bool SdioCard::readSectors(uint32_t sector, uint8_t* dst, size_t n)
     }
 }
 
-// These functions are not used for SDIO mode but are needed to avoid build error.
-void sdCsInit(SdCsPin_t pin) {}
-void sdCsWrite(SdCsPin_t pin, bool level) {}
-
-// SDIO configuration for main program
-SdioConfig g_sd_sdio_config(DMA_SDIO);
-
-#endif
+#endif

+ 5 - 1
lib/ZuluSCSI_platform_RP2MCU/sdio.cpp

@@ -30,12 +30,14 @@
 // https://www.sdcard.org/downloads/pls/
 // "SDIO Physical Layer Simplified Specification Version 8.00"
 
+#include <ZuluSCSI_platform.h>
+#if defined(SD_USE_SDIO) && !defined(SD_USE_RP2350_SDIO)
+
 #include "sdio.h"
 #include <hardware/pio.h>
 #include <hardware/dma.h>
 #include <hardware/gpio.h>
 #include <hardware/structs/scb.h>
-#include <ZuluSCSI_platform.h>
 #include <ZuluSCSI_log.h>
 #include "timings_RP2MCU.h"
 
@@ -932,3 +934,5 @@ void rp2040_sdio_init(int clock_divider)
     irq_set_enabled(DMA_IRQ_1, true);
 #endif
 }
+
+#endif

+ 6 - 0
lib/ZuluSCSI_platform_RP2MCU/sdio.h

@@ -24,6 +24,10 @@
 // the PIO peripheral. The high-level commands are in sd_card_sdio.cpp.
 
 #pragma once
+
+#include <ZuluSCSI_platform.h>
+#if defined(SD_USE_SDIO) && !defined(SD_USE_RP2350_SDIO)
+
 #include <stdint.h>
 
 enum sdio_status_t {
@@ -74,3 +78,5 @@ sdio_status_t receive_status_register(uint8_t* sds);
 
 // (Re)initialize the SDIO interface
 void rp2040_sdio_init(int clock_divider = 1);
+
+#endif

+ 49 - 0
lib/ZuluSCSI_platform_RP2MCU/sdio_rp2350_config.h

@@ -0,0 +1,49 @@
+/* Configuration for RP2350_SDIO library */
+
+#pragma once
+
+#include "ZuluSCSI_platform.h"
+#include <ZuluSCSI_log.h>
+
+// #define SDIO_BREAKPOINT_ON_ERROR
+// #define ZULUSCSI_DEBUG_SDIO
+
+// SDIO error messages are logged only to debug log, because normally
+// the problem can be reported through SCSI status.
+#ifdef SDIO_BREAKPOINT_ON_ERROR
+#define SDIO_ERRMSG(txt, arg1, arg2) do{dbgmsg(txt, " ", (uint32_t)(arg1), " ", (uint32_t)(arg2)); asm("bkpt");} while(0)
+#else
+#define SDIO_ERRMSG(txt, arg1, arg2) dbgmsg(txt, " ", (uint32_t)(arg1), " ", (uint32_t)(arg2))
+#endif
+
+// SDIO debug messages are normally disabled because they are very verbose
+#ifdef ZULUSCSI_DEBUG_SDIO
+#define SDIO_DBGMSG(txt, arg1, arg2) dbgmsg(txt, " ", (uint32_t)(arg1), " ", (uint32_t)(arg2))
+#endif
+
+// PIO block to use
+#define SDIO_PIO pio1
+#define SDIO_SM  0
+
+// GPIO configuration
+#define SDIO_GPIO_FUNC GPIO_FUNC_PIO1
+#define SDIO_GPIO_SLEW GPIO_SLEW_RATE_FAST
+#define SDIO_GPIO_DRIVE GPIO_DRIVE_STRENGTH_8MA
+
+// DMA channels to use
+#define SDIO_DMACH_A 4
+#define SDIO_DMACH_B 5
+#define SDIO_DMAIRQ_IDX 1
+#define SDIO_DMAIRQ DMA_IRQ_1
+
+#define SDIO_DEFAULT_SPEED SDIO_HIGHSPEED_OVERCLOCK
+#define SDIO_MAX_CLOCK_RATE_EXCEED_PERCENT 15
+
+// GPIO pins come from platform header
+// #define SDIO_CLK 34
+// #define SDIO_CMD 35
+// #define SDIO_D0  36
+// #define SDIO_D1  37
+// #define SDIO_D2  38
+// #define SDIO_D3  39
+// #define SDIO_PIO_IOBASE 16

+ 4 - 1
platformio.ini

@@ -131,7 +131,7 @@ debug_build_flags =
 build_flags =
     ${env.build_flags}
     -O2 -Isrc -ggdb -g3
-    -Wall -Wno-sign-compare -Wno-ignored-qualifiers
+    -Wall -Wno-sign-compare -Wno-ignored-qualifiers -Wno-overloaded-virtual
     -DSPI_DRIVER_SELECT=3
     -DSD_CHIP_SELECT_MODE=2
     -DENABLE_DEDICATED_SPI=1
@@ -140,6 +140,7 @@ build_flags =
     -DPICO_FLASH_SPI_CLKDIV=2
     -DPLATFORM_MASS_STORAGE
     -DFILE_COPY_CONSTRUCTOR_SELECT=FILE_COPY_CONSTRUCTOR_PUBLIC
+    -DDISABLE_FS_H_WARNING
     -DRECLOCKING_SUPPORTED
 ; build flags mirroring the "framework-arduinopico#x.x.x-DaynaPORT" static library build
     -DPICO_CYW43_ARCH_POLL=1
@@ -317,12 +318,14 @@ ldscript_bootloader = lib/ZuluSCSI_platform_RP2MCU/rp23xx_btldr.ld
 lib_deps =
     ${env:ZuluSCSI_RP2MCU.lib_deps}
     ZuluI2S
+    SDIO_RP2350=https://github.com/rabbitholecomputing/SDIO_RP2350
 build_flags =
     ${env:ZuluSCSI_RP2MCU.build_flags}
     -DZULUSCSI_BLASTER
     -DZULUSCSI_MCU_RP23XX
     -DENABLE_AUDIO_OUTPUT
     -DENABLE_AUDIO_OUTPUT_I2S
+    -DSD_USE_RP2350_SDIO
     -DROMDRIVE_OFFSET=${env:ZuluSCSI_Blaster.program_flash_allocation}
 ; Use the -Wl line below as a "build_flags" entry if you wish to make a map file
 ; to check memory locations of the compiled code.

+ 1 - 1
src/ImageBackingStore.cpp

@@ -136,7 +136,7 @@ bool ImageBackingStore::_internal_open(const char *filename)
 
     uint32_t sectorcount = m_fsfile.size() / SD_SECTOR_SIZE;
     uint32_t begin = 0, end = 0;
-    if (m_fsfile.contiguousRange(&begin, &end) && end >= begin + sectorcount)
+    if (m_fsfile.contiguousRange(&begin, &end) && end >= begin + sectorcount - 1)
     {
         // Convert to raw mapping, this avoids some unnecessary
         // access overhead in SdFat library.

+ 22 - 3
src/ZuluSCSI.cpp

@@ -649,6 +649,16 @@ static bool mountSDCard()
   // Check for the common case, FAT filesystem as first partition
   if (SD.begin(SD_CONFIG))
   {
+#ifdef HAS_SDIO_CLASS
+    int speed = ((SdioCard*)SD.card())->kHzSdClk();
+    if (speed > 0)
+    {
+      logmsg("SD card communication speed: ",
+        (int)((speed + 500) / 1000), " MHz, ",
+        (int)((speed + 1000) / 2000), " MB/s");
+    }
+#endif
+
     reload_ini_cache(CONFIGFILE);
     return true;
   }
@@ -916,6 +926,16 @@ static void firmware_update()
   root.close();
 }
 
+// Checks if SD card is still present
+static bool poll_sd_card()
+{
+#ifdef SD_USE_SDIO
+  return SD.card()->status() != 0 && SD.card()->errorCode() == 0;
+#else
+  uint32_t ocr;
+  return SD.card()->readOCR(&ocr);
+#endif
+}
 
 // Place all the setup code that requires the SD card to be initialized here
 // Which is pretty much everything after platform_init and and platform_late_init
@@ -1123,10 +1143,9 @@ extern "C" void zuluscsi_main_loop(void)
         (uint32_t)(millis() - sd_card_check_time) > SDCARD_POLL_INTERVAL)
     {
       sd_card_check_time = millis();
-      uint32_t ocr;
-      if (!SD.card()->readOCR(&ocr))
+      if (!poll_sd_card())
       {
-        if (!SD.card()->readOCR(&ocr))
+        if (!poll_sd_card())
         {
           g_sdcard_present = false;
           logmsg("SD card removed, trying to reinit");

+ 1 - 1
src/ZuluSCSI_disk.cpp

@@ -417,7 +417,7 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_lun, in
         {
             // ROM is always contiguous, no need to log
         }
-        else if (img.file.contiguousRange(&sector_begin, &sector_end))
+        else if (img.file.isContiguous() && img.file.contiguousRange(&sector_begin, &sector_end))
         {
 #ifdef ZULUSCSI_HARDWARE_CONFIG
             if (g_hw_config.is_active())