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

ZuluSCSI Blaster: Enable high performance SDIO library

Petteri Aimonen 7 місяців тому
батько
коміт
d3b040043d

+ 24 - 0
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");
@@ -1166,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

+ 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

+ 2 - 0
platformio.ini

@@ -318,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.

+ 10 - 0
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;
   }