浏览代码

Reclocking works across the ZuluSCSI RP line

In `lib/ZuluSCSI_platform_RP2MCU/timings.c` are the three clock settings
for the product line. With a special setting for the SD clock rate of
the Pico 2 as it could not do 50MHz SDIO clock at a 250MHz system clock.
Was able to consolidate all the sdio pio and scsi_accel_target pio
assembly files into one file for each function by setting the gpio
waits dynamically via rewriting the the command in code.

There are 3 things left to do.
 - Consolidate the scsi_accel_host pio files
 - Turn the Audio Build back on
 - See about DaynaPORT compatibility at high clock rates
Morio 1 年之前
父节点
当前提交
d7e67aca1a

+ 14 - 8
lib/ZuluSCSI_platform_RP2MCU/ZuluSCSI_platform.cpp

@@ -105,6 +105,12 @@ static void gpio_conf(uint gpio, gpio_function_t fn, bool pullup, bool pulldown,
 
 
 static void reclock() {
+    gpio_set_drive_strength(SDIO_CLK,  GPIO_DRIVE_STRENGTH_12MA);
+    gpio_set_drive_strength(SDIO_CMD,  GPIO_DRIVE_STRENGTH_12MA);
+    gpio_set_drive_strength(SDIO_D0,  GPIO_DRIVE_STRENGTH_12MA);
+    gpio_set_drive_strength(SDIO_D1,  GPIO_DRIVE_STRENGTH_12MA);
+    gpio_set_drive_strength(SDIO_D2,  GPIO_DRIVE_STRENGTH_12MA);
+    gpio_set_drive_strength(SDIO_D3,  GPIO_DRIVE_STRENGTH_12MA);
     // ensure UART is fully drained before we mess up its clock
     uart_tx_wait_blocking(uart0);
     // switch clk_sys and clk_peri to pll_usb
@@ -121,22 +127,22 @@ static void reclock() {
             48 * MHZ);
     // reset PLL
     pll_init(pll_sys,
-        g_zuluscsi_timings.pll.refdiv,
-        g_zuluscsi_timings.pll.vco_freq,
-        g_zuluscsi_timings.pll.post_div1,
-        g_zuluscsi_timings.pll.post_div2);
+        g_zuluscsi_timings->pll.refdiv,
+        g_zuluscsi_timings->pll.vco_freq,
+        g_zuluscsi_timings->pll.post_div1,
+        g_zuluscsi_timings->pll.post_div2);
 
     // switch clocks back to pll_sys
     clock_configure(clk_sys,
             CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
             CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
-            g_zuluscsi_timings.clk_hz,
-            g_zuluscsi_timings.clk_hz);
+            g_zuluscsi_timings->clk_hz,
+            g_zuluscsi_timings->clk_hz);
     clock_configure(clk_peri,
             0,
             CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
-            g_zuluscsi_timings.clk_hz,
-            g_zuluscsi_timings.clk_hz);
+            g_zuluscsi_timings->clk_hz,
+            g_zuluscsi_timings->clk_hz);
     // reset UART for the new clock speed
     uart_init(uart0, 1000000);
 }

+ 17 - 26
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target.cpp

@@ -45,15 +45,7 @@
 #include <audio.h>
 #endif // ENABLE_AUDIO_OUTPUT
 
-#if defined(ZULUSCSI_PICO) || defined(ZULUSCSI_BS2)
-# include "scsi_accel_target_Pico.pio.h"
-#elif defined(ZULUSCSI_PICO_2)
-# include "scsi_accel_target_Pico_2.pio.h"
-#elif defined(ZULUSCSI_RP2350A)
-# include "scsi_accel_target_RP2350A.pio.h"
-#else
-# include "scsi_accel_target_RP2040.pio.h"
-#endif
+#include "scsi_accel_target_RP2MCU.pio.h"
 
 // SCSI bus write acceleration uses up to 3 PIO state machines:
 // SM0: Convert data bytes to lookup addresses to add parity
@@ -806,7 +798,7 @@ static int pio_add_scsi_accel_async_write_program()
         sizeof(scsi_accel_async_write_program_instructions));
 
     // out null, 23         side 1  [0] ;[REQ_DLY-2]      ; Discard unused bits, wait for data preset time
-    uint8_t delay = g_zuluscsi_timings.scsi.req_delay - 2;
+    uint8_t delay = g_zuluscsi_timings->scsi.req_delay - 2;
     assert( delay <= 0xF);
     rewrote_instructions[2] |= pio_encode_delay(delay);
     // wait 1 gpio ACK      side 1      ; Wait for ACK to be inactive
@@ -1235,22 +1227,23 @@ bool scsi_accel_rp2040_setSyncMode(int syncOffset, int syncPeriod)
             // The delays are in clock cycles, each taking 6.66 ns. (@150 MHz)
             // delay0: Delay from data write to REQ assertion (data setup)
             // delay1: Delay from REQ assert to REQ deassert (req pulse width)
-            // delay2: Delay from REQ deassert to data write (data hold)
-            int delay0, delay1, delay2, initialDelay, remainderDelay;
-            uint32_t up_rounder = g_zuluscsi_timings.scsi.clk_period_ps / 2 + 1;
+            // delay2: Delay from REQ deassert to data write (negation period)
+            // see timings.c for delay periods in clock cycles
+            int delay0, delay1, delay2;
+            uint32_t up_rounder = g_zuluscsi_timings->scsi.clk_period_ps / 2 + 1;
             uint32_t delay_in_ps = (syncPeriod * 4) * 1000;
             // This is the delay in clock cycles rounded up
-            int totalDelay = (delay_in_ps + up_rounder) / g_zuluscsi_timings.scsi.clk_period_ps;
+            int totalDelay = (delay_in_ps + up_rounder) / g_zuluscsi_timings->scsi.clk_period_ps;
 
             if (syncPeriod < 25)
             {
                 // Fast-20 SCSI timing: 15 ns assertion period
                 // The hardware rise and fall time require some extra delay,
                 // These delays are in addition to the 1 cycle that the PIO takes to execute the instruction
-                totalDelay += g_zuluscsi_timings.scsi_20.total_delay_adjust;
-                delay0 = g_zuluscsi_timings.scsi_20.delay0; //Data setup time, should be min 11.5ns according to the spec for FAST-20
-                delay1 = g_zuluscsi_timings.scsi_20.delay1; //Data hold time, should be min 16.5ns according to the spec for FAST-20
-                delay2 = totalDelay - delay0 - delay1 - 3; //pulse width, should be min 15ns according to the spec for FAST-20
+                totalDelay += g_zuluscsi_timings->scsi_20.total_delay_adjust;
+                delay0 = g_zuluscsi_timings->scsi_20.delay0; //Data setup time, should be min 11.5ns according to the spec for FAST-20
+                delay1 = g_zuluscsi_timings->scsi_20.delay1; //pulse width, should be min 15ns according to the spec for FAST-20
+                delay2 = totalDelay - delay0 - delay1 - 3;  //Data hold time, should be min 16.5ns according to the spec for FAST-20
                 if (delay2 < 0) delay2 = 0;
                 if (delay2 > 15) delay2 = 15;
             }
@@ -1258,21 +1251,19 @@ bool scsi_accel_rp2040_setSyncMode(int syncOffset, int syncPeriod)
             {
                 // Fast-10 SCSI timing: 30 ns assertion period, 25 ns skew delay
                 // The hardware rise and fall time require some extra delay,
-                totalDelay += g_zuluscsi_timings.scsi_10.total_delay_adjust;
-                delay0 = g_zuluscsi_timings.scsi_10.delay0; // 4;
-                delay1 = g_zuluscsi_timings.scsi_10.delay1; // 6;
+                totalDelay += g_zuluscsi_timings->scsi_10.total_delay_adjust;
+                delay0 = g_zuluscsi_timings->scsi_10.delay0; // 4;
+                delay1 = g_zuluscsi_timings->scsi_10.delay1; // 6;
                 delay2 = totalDelay - delay0 - delay1 - 3;
                 if (delay2 < 0) delay2 = 0;
                 if (delay2 > 15) delay2 = 15;
             }
             else
             {
-                // \TODO set RP23XX timings here
-
                 // Slow SCSI timing: 90 ns assertion period, 55 ns skew delay
-                totalDelay += g_zuluscsi_timings.scsi_5.total_delay_adjust;
-                delay0 = g_zuluscsi_timings.scsi_5.delay0;
-                delay1 = g_zuluscsi_timings.scsi_5.delay1;
+                totalDelay += g_zuluscsi_timings->scsi_5.total_delay_adjust;
+                delay0 = g_zuluscsi_timings->scsi_5.delay0;
+                delay1 = g_zuluscsi_timings->scsi_5.delay1;
                 delay2 = totalDelay - delay0 - delay1 - 3;
                 if (delay2 < 0) delay2 = 0;
                 if (delay2 > 15) delay2 = 15;

+ 0 - 124
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_Pico.pio

@@ -1,124 +0,0 @@
-; ZuluSCSI™ - Copyright (c) 2022 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/>.
-
-
-; RP2040 PIO program for accelerating SCSI communication
-; Run "pioasm scsi_accel.pio scsi_accel.pio.h" to regenerate the C header from this.
-; GPIO mapping:
-; - 0-7: DB0-DB7
-; -   8: DBP
-; Side set is REQ pin
-
-.define REQ 17
-.define ACK 26
-
-; Delay from data setup to REQ assertion.
-; deskew delay + cable skew delay = 55 ns minimum
-; One clock cycle is 8 ns => delay 7 clocks
-.define REQ_DLY 7
-
-; Adds parity to data that is to be written to SCSI
-; This works by generating addresses for DMA to fetch data from.
-; Register X should be initialized to the base address of the lookup table.
-.program scsi_parity
-    pull block
-    in NULL, 1
-    in OSR, 8
-    in X, 23
-
-; Write to SCSI bus using asynchronous handshake.
-; Data is written as 32-bit words that contain the 8 data bits + 1 parity bit.
-; 23 bits in each word are discarded.
-; Number of bytes to send must be multiple of 2.
-.program scsi_accel_async_write
-    .side_set 1
-
-    pull ifempty block          side 1  ; Get data from TX FIFO
-    out pins, 9                 side 1  ; Write data and parity bit
-    out null, 23 [REQ_DLY-2]    side 1  ; Discard unused bits, wait for data preset time
-    wait 1 gpio ACK             side 1  ; Wait for ACK to be inactive
-    wait 0 gpio ACK             side 0  ; Assert REQ, wait for ACK low
-
-; Read from SCSI bus using sync or async handshake.
-; Data is returned as 32-bit words:
-; - bit  0: always zero
-; - bits 1-8: data byte
-; - bit  9: parity bit
-; - bits 10-31: lookup table address
-; Lookup table address should be loaded into register Y.
-; One dummy word should be written to TX fifo for every byte to receive.
-.program scsi_accel_read
-    .side_set 1
-
-    pull block                  side 1  ; Pull from TX fifo for counting bytes and pacing sync mode
-    wait 1 gpio ACK             side 1  ; Wait for ACK high
-    in null, 1                  side 0  ; Zero bit because lookup table entries are 16-bit
-    wait 0 gpio ACK             side 0  ; Assert REQ, wait for ACK low
-    in pins, 9                  side 1  ; Deassert REQ, read GPIO
-    in y, 22                    side 1  ; Copy parity lookup table address
-
-; Data state machine for synchronous writes.
-; Takes the lowest 9 bits of each 32 bit word and writes them to bus with REQ pulse.
-; The delay times will be rewritten by C code to match the negotiated SCSI sync speed.
-;
-; Shifts one bit to ISR per every byte transmitted. This is used to control the transfer
-; pace, the RX fifo acts as a counter to keep track of unacknowledged bytes. The C code
-; can set the syncOffset by changing autopush threshold, e.g. threshold 3 = 12 bytes offset.
-.program scsi_sync_write
-    .side_set 1
-
-    out pins, 9      [0]        side 1  ; Write data and parity bit, wait for deskew delay
-    out null, 23     [0]        side 0  ; Assert REQ, wait for assert time
-    in null, 1       [0]        side 1  ; Deassert REQ, wait for transfer period, wait for space in ACK buffer
-
-; Data pacing state machine for synchronous writes.
-; Takes one bit from ISR on every falling edge of ACK.
-; The C code should set autopull threshold to match scsi_sync_write autopush threshold.
-; System DMA will then move words from scsi_sync_write RX fifo to scsi_sync_write_pacer TX fifo.
-.program scsi_sync_write_pacer
-    wait 1 gpio ACK
-    wait 0 gpio ACK   ; Wait for falling edge on ACK
-    out null, 1       ; Let scsi_sync_write send one more byte
-
-; Data pacing state machine for synchronous reads.
-; The delay times will be rewritten by C code to match the negotiated SCSI sync speed.
-; Number of bytes to receive minus one should be loaded into register X.
-; In synchronous mode this generates the REQ pulses and dummy words.
-; In asynchronous mode it just generates dummy words to feed to scsi_accel_read.
-.program scsi_sync_read_pacer
-    .side_set 1
-
-start:
-    push block      [0]      side 1  ; Send dummy word to scsi_accel_read, wait for transfer period
-    jmp x-- start   [0]      side 0  ; Assert REQ, wait for assert time
-
-finish:
-    jmp finish      [0]      side 1
-
-; Parity checker for reads from SCSI bus.
-; Receives 16-bit words from g_scsi_parity_check_lookup
-; Bottom 8 bits are the data byte, which is passed to output FIFO
-; The 9th bit is parity valid bit, which is 1 for valid and 0 for parity error.
-.program scsi_read_parity
-parity_valid:
-    out isr, 8                ; Take the 8 data bits for passing to RX fifo
-    push block                ; Push the data to RX fifo
-    out x, 24                 ; Take the parity valid bit, and the rest of 32-bit word
-    jmp x-- parity_valid      ; If parity valid bit is 1, repeat from start
-    irq set 0                 ; Parity error, set interrupt flag

+ 0 - 225
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_Pico.pio.h

@@ -1,225 +0,0 @@
-// -------------------------------------------------- //
-// This file is autogenerated by pioasm; do not edit! //
-// -------------------------------------------------- //
-
-#pragma once
-
-#if !PICO_NO_HARDWARE
-#include "hardware/pio.h"
-#endif
-
-// ----------- //
-// scsi_parity //
-// ----------- //
-
-#define scsi_parity_wrap_target 0
-#define scsi_parity_wrap 3
-
-static const uint16_t scsi_parity_program_instructions[] = {
-            //     .wrap_target
-    0x80a0, //  0: pull   block                      
-    0x4061, //  1: in     null, 1                    
-    0x40e8, //  2: in     osr, 8                     
-    0x4037, //  3: in     x, 23                      
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_parity_program = {
-    .instructions = scsi_parity_program_instructions,
-    .length = 4,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_parity_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_parity_wrap_target, offset + scsi_parity_wrap);
-    return c;
-}
-#endif
-
-// ---------------------- //
-// scsi_accel_async_write //
-// ---------------------- //
-
-#define scsi_accel_async_write_wrap_target 0
-#define scsi_accel_async_write_wrap 4
-
-static const uint16_t scsi_accel_async_write_program_instructions[] = {
-            //     .wrap_target
-    0x90e0, //  0: pull   ifempty block   side 1     
-    0x7009, //  1: out    pins, 9         side 1     
-    0x7577, //  2: out    null, 23        side 1 [5] 
-    0x309a, //  3: wait   1 gpio, 26      side 1     
-    0x201a, //  4: wait   0 gpio, 26      side 0     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_accel_async_write_program = {
-    .instructions = scsi_accel_async_write_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_accel_async_write_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_accel_async_write_wrap_target, offset + scsi_accel_async_write_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------- //
-// scsi_accel_read //
-// --------------- //
-
-#define scsi_accel_read_wrap_target 0
-#define scsi_accel_read_wrap 5
-
-static const uint16_t scsi_accel_read_program_instructions[] = {
-            //     .wrap_target
-    0x90a0, //  0: pull   block           side 1     
-    0x309a, //  1: wait   1 gpio, 26      side 1     
-    0x4061, //  2: in     null, 1         side 0     
-    0x201a, //  3: wait   0 gpio, 26      side 0     
-    0x5009, //  4: in     pins, 9         side 1     
-    0x5056, //  5: in     y, 22           side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_accel_read_program = {
-    .instructions = scsi_accel_read_program_instructions,
-    .length = 6,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_accel_read_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_accel_read_wrap_target, offset + scsi_accel_read_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------- //
-// scsi_sync_write //
-// --------------- //
-
-#define scsi_sync_write_wrap_target 0
-#define scsi_sync_write_wrap 2
-
-static const uint16_t scsi_sync_write_program_instructions[] = {
-            //     .wrap_target
-    0x7009, //  0: out    pins, 9         side 1     
-    0x6077, //  1: out    null, 23        side 0     
-    0x5061, //  2: in     null, 1         side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_write_program = {
-    .instructions = scsi_sync_write_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_write_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_write_wrap_target, offset + scsi_sync_write_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------------- //
-// scsi_sync_write_pacer //
-// --------------------- //
-
-#define scsi_sync_write_pacer_wrap_target 0
-#define scsi_sync_write_pacer_wrap 2
-
-static const uint16_t scsi_sync_write_pacer_program_instructions[] = {
-            //     .wrap_target
-    0x209a, //  0: wait   1 gpio, 26                 
-    0x201a, //  1: wait   0 gpio, 26                 
-    0x6061, //  2: out    null, 1                    
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_write_pacer_program = {
-    .instructions = scsi_sync_write_pacer_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_write_pacer_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_write_pacer_wrap_target, offset + scsi_sync_write_pacer_wrap);
-    return c;
-}
-#endif
-
-// -------------------- //
-// scsi_sync_read_pacer //
-// -------------------- //
-
-#define scsi_sync_read_pacer_wrap_target 0
-#define scsi_sync_read_pacer_wrap 2
-
-static const uint16_t scsi_sync_read_pacer_program_instructions[] = {
-            //     .wrap_target
-    0x9020, //  0: push   block           side 1     
-    0x0040, //  1: jmp    x--, 0          side 0     
-    0x1002, //  2: jmp    2               side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_read_pacer_program = {
-    .instructions = scsi_sync_read_pacer_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_read_pacer_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_read_pacer_wrap_target, offset + scsi_sync_read_pacer_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// ---------------- //
-// scsi_read_parity //
-// ---------------- //
-
-#define scsi_read_parity_wrap_target 0
-#define scsi_read_parity_wrap 4
-
-static const uint16_t scsi_read_parity_program_instructions[] = {
-            //     .wrap_target
-    0x60c8, //  0: out    isr, 8                     
-    0x8020, //  1: push   block                      
-    0x6038, //  2: out    x, 24                      
-    0x0040, //  3: jmp    x--, 0                     
-    0xc000, //  4: irq    nowait 0                   
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_read_parity_program = {
-    .instructions = scsi_read_parity_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_read_parity_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_read_parity_wrap_target, offset + scsi_read_parity_wrap);
-    return c;
-}
-#endif
-

+ 0 - 124
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_Pico_2.pio

@@ -1,124 +0,0 @@
-; ZuluSCSI™ - Copyright (c) 2022 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/>.
-
-
-; RP2040 PIO program for accelerating SCSI communication
-; Run "pioasm scsi_accel.pio scsi_accel.pio.h" to regenerate the C header from this.
-; GPIO mapping:
-; - 0-7: DB0-DB7
-; -   8: DBP
-; Side set is REQ pin
-
-.define REQ 17
-.define ACK 26
-
-; Delay from data setup to REQ assertion.
-; deskew delay + cable skew delay = 55 ns minimum
-; One clock cycle is 6.67 ns (150MHz) => delay 8.25 clocks or 9 clocks
-.define REQ_DLY 9
-
-; Adds parity to data that is to be written to SCSI
-; This works by generating addresses for DMA to fetch data from.
-; Register X should be initialized to the base address of the lookup table.
-.program scsi_parity
-    pull block
-    in NULL, 1
-    in OSR, 8
-    in X, 23
-
-; Write to SCSI bus using asynchronous handshake.
-; Data is written as 32-bit words that contain the 8 data bits + 1 parity bit.
-; 23 bits in each word are discarded.
-; Number of bytes to send must be multiple of 2.
-.program scsi_accel_async_write
-    .side_set 1
-
-    pull ifempty block          side 1  ; Get data from TX FIFO
-    out pins, 9                 side 1  ; Write data and parity bit
-    out null, 23 [REQ_DLY-2]    side 1  ; Discard unused bits, wait for data preset time
-    wait 1 gpio ACK             side 1  ; Wait for ACK to be inactive
-    wait 0 gpio ACK             side 0  ; Assert REQ, wait for ACK low
-
-; Read from SCSI bus using sync or async handshake.
-; Data is returned as 32-bit words:
-; - bit  0: always zero
-; - bits 1-8: data byte
-; - bit  9: parity bit
-; - bits 10-31: lookup table address
-; Lookup table address should be loaded into register Y.
-; One dummy word should be written to TX fifo for every byte to receive.
-.program scsi_accel_read
-    .side_set 1
-
-    pull block                  side 1  ; Pull from TX fifo for counting bytes and pacing sync mode
-    wait 1 gpio ACK             side 1  ; Wait for ACK high
-    in null, 1                  side 0  ; Zero bit because lookup table entries are 16-bit
-    wait 0 gpio ACK             side 0  ; Assert REQ, wait for ACK low
-    in pins, 9                  side 1  ; Deassert REQ, read GPIO
-    in y, 22                    side 1  ; Copy parity lookup table address
-
-; Data state machine for synchronous writes.
-; Takes the lowest 9 bits of each 32 bit word and writes them to bus with REQ pulse.
-; The delay times will be rewritten by C code to match the negotiated SCSI sync speed.
-;
-; Shifts one bit to ISR per every byte transmitted. This is used to control the transfer
-; pace, the RX fifo acts as a counter to keep track of unacknowledged bytes. The C code
-; can set the syncOffset by changing autopush threshold, e.g. threshold 3 = 12 bytes offset.
-.program scsi_sync_write
-    .side_set 1
-
-    out pins, 9      [0]        side 1  ; Write data and parity bit, wait for deskew delay
-    out null, 23     [0]        side 0  ; Assert REQ, wait for assert time
-    in null, 1       [0]        side 1  ; Deassert REQ, wait for transfer period, wait for space in ACK buffer
-
-; Data pacing state machine for synchronous writes.
-; Takes one bit from ISR on every falling edge of ACK.
-; The C code should set autopull threshold to match scsi_sync_write autopush threshold.
-; System DMA will then move words from scsi_sync_write RX fifo to scsi_sync_write_pacer TX fifo.
-.program scsi_sync_write_pacer
-    wait 1 gpio ACK
-    wait 0 gpio ACK   ; Wait for falling edge on ACK
-    out null, 1       ; Let scsi_sync_write send one more byte
-
-; Data pacing state machine for synchronous reads.
-; The delay times will be rewritten by C code to match the negotiated SCSI sync speed.
-; Number of bytes to receive minus one should be loaded into register X.
-; In synchronous mode this generates the REQ pulses and dummy words.
-; In asynchronous mode it just generates dummy words to feed to scsi_accel_read.
-.program scsi_sync_read_pacer
-    .side_set 1
-
-start:
-    push block      [0]      side 1  ; Send dummy word to scsi_accel_read, wait for transfer period
-    jmp x-- start   [0]      side 0  ; Assert REQ, wait for assert time
-
-finish:
-    jmp finish      [0]      side 1
-
-; Parity checker for reads from SCSI bus.
-; Receives 16-bit words from g_scsi_parity_check_lookup
-; Bottom 8 bits are the data byte, which is passed to output FIFO
-; The 9th bit is parity valid bit, which is 1 for valid and 0 for parity error.
-.program scsi_read_parity
-parity_valid:
-    out isr, 8                ; Take the 8 data bits for passing to RX fifo
-    push block                ; Push the data to RX fifo
-    out x, 24                 ; Take the parity valid bit, and the rest of 32-bit word
-    jmp x-- parity_valid      ; If parity valid bit is 1, repeat from start
-    irq set 0                 ; Parity error, set interrupt flag

+ 0 - 224
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_Pico_2.pio.h

@@ -1,224 +0,0 @@
-// -------------------------------------------------- //
-// This file is autogenerated by pioasm; do not edit! //
-// -------------------------------------------------- //
-
-#pragma once
-
-#if !PICO_NO_HARDWARE
-#include "hardware/pio.h"
-#endif
-
-// ----------- //
-// scsi_parity //
-// ----------- //
-
-#define scsi_parity_wrap_target 0
-#define scsi_parity_wrap 3
-
-static const uint16_t scsi_parity_program_instructions[] = {
-            //     .wrap_target
-    0x80a0, //  0: pull   block                      
-    0x4061, //  1: in     null, 1                    
-    0x40e8, //  2: in     osr, 8                     
-    0x4037, //  3: in     x, 23                      
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_parity_program = {
-    .instructions = scsi_parity_program_instructions,
-    .length = 4,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_parity_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_parity_wrap_target, offset + scsi_parity_wrap);
-    return c;
-}
-#endif
-
-// ---------------------- //
-// scsi_accel_async_write //
-// ---------------------- //
-
-#define scsi_accel_async_write_wrap_target 0
-#define scsi_accel_async_write_wrap 4
-
-static const uint16_t scsi_accel_async_write_program_instructions[] = {
-            //     .wrap_target
-    0x90e0, //  0: pull   ifempty block   side 1     
-    0x7009, //  1: out    pins, 9         side 1     
-    0x7777, //  2: out    null, 23        side 1 [7] 
-    0x309a, //  3: wait   1 gpio, 26      side 1     
-    0x201a, //  4: wait   0 gpio, 26      side 0     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_accel_async_write_program = {
-    .instructions = scsi_accel_async_write_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_accel_async_write_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_accel_async_write_wrap_target, offset + scsi_accel_async_write_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------- //
-// scsi_accel_read //
-// --------------- //
-
-#define scsi_accel_read_wrap_target 0
-#define scsi_accel_read_wrap 5
-
-static const uint16_t scsi_accel_read_program_instructions[] = {
-            //     .wrap_target
-    0x90a0, //  0: pull   block           side 1     
-    0x309a, //  1: wait   1 gpio, 26      side 1     
-    0x4061, //  2: in     null, 1         side 0     
-    0x201a, //  3: wait   0 gpio, 26      side 0     
-    0x5009, //  4: in     pins, 9         side 1     
-    0x5056, //  5: in     y, 22           side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_accel_read_program = {
-    .instructions = scsi_accel_read_program_instructions,
-    .length = 6,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_accel_read_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_accel_read_wrap_target, offset + scsi_accel_read_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------- //
-// scsi_sync_write //
-// --------------- //
-
-#define scsi_sync_write_wrap_target 0
-#define scsi_sync_write_wrap 2
-
-static const uint16_t scsi_sync_write_program_instructions[] = {
-            //     .wrap_target
-    0x7009, //  0: out    pins, 9         side 1     
-    0x6077, //  1: out    null, 23        side 0     
-    0x5061, //  2: in     null, 1         side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_write_program = {
-    .instructions = scsi_sync_write_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_write_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_write_wrap_target, offset + scsi_sync_write_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------------- //
-// scsi_sync_write_pacer //
-// --------------------- //
-
-#define scsi_sync_write_pacer_wrap_target 0
-#define scsi_sync_write_pacer_wrap 2
-
-static const uint16_t scsi_sync_write_pacer_program_instructions[] = {
-            //     .wrap_target
-    0x209a, //  0: wait   1 gpio, 26                 
-    0x201a, //  1: wait   0 gpio, 26                 
-    0x6061, //  2: out    null, 1                    
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_write_pacer_program = {
-    .instructions = scsi_sync_write_pacer_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_write_pacer_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_write_pacer_wrap_target, offset + scsi_sync_write_pacer_wrap);
-    return c;
-}
-#endif
-
-// -------------------- //
-// scsi_sync_read_pacer //
-// -------------------- //
-
-#define scsi_sync_read_pacer_wrap_target 0
-#define scsi_sync_read_pacer_wrap 2
-
-static const uint16_t scsi_sync_read_pacer_program_instructions[] = {
-            //     .wrap_target
-    0x9020, //  0: push   block           side 1     
-    0x0040, //  1: jmp    x--, 0          side 0     
-    0x1002, //  2: jmp    2               side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_read_pacer_program = {
-    .instructions = scsi_sync_read_pacer_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_read_pacer_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_read_pacer_wrap_target, offset + scsi_sync_read_pacer_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// ---------------- //
-// scsi_read_parity //
-// ---------------- //
-
-#define scsi_read_parity_wrap_target 0
-#define scsi_read_parity_wrap 4
-
-static const uint16_t scsi_read_parity_program_instructions[] = {
-            //     .wrap_target
-    0x60c8, //  0: out    isr, 8                     
-    0x8020, //  1: push   block                      
-    0x6038, //  2: out    x, 24                      
-    0x0040, //  3: jmp    x--, 0                     
-    0xc000, //  4: irq    nowait 0                   
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_read_parity_program = {
-    .instructions = scsi_read_parity_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_read_parity_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_read_parity_wrap_target, offset + scsi_read_parity_wrap);
-    return c;
-}
-#endif

+ 0 - 125
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_RP2350A.pio

@@ -1,125 +0,0 @@
-; ZuluSCSI™ - Copyright (c) 2022 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/>.
-
-
-; RP2040 PIO program for accelerating SCSI communication
-; Run "pioasm scsi_accel.pio scsi_accel.pio.h" to regenerate the C header from this.
-; GPIO mapping:
-; - 0-7: DB0-DB7
-; -   8: DBP
-; Side set is REQ pin
-
-.define REQ 9
-.define ACK 10
-
-; Delay from data setup to REQ assertion.
-; deskew delay + cable skew delay = 55 ns minimum
-; One clock cycle is 6.67 ns (150MHz) => delay 8.25 clocks or 9 clocks
-.define REQ_DLY 9
-
-
-; Adds parity to data that is to be written to SCSI
-; This works by generating addresses for DMA to fetch data from.
-; Register X should be initialized to the base address of the lookup table.
-.program scsi_parity
-    pull block
-    in NULL, 1
-    in OSR, 8
-    in X, 23
-
-; Write to SCSI bus using asynchronous handshake.
-; Data is written as 32-bit words that contain the 8 data bits + 1 parity bit.
-; 23 bits in each word are discarded.
-; Number of bytes to send must be multiple of 2.
-.program scsi_accel_async_write
-    .side_set 1
-
-    pull ifempty block          side 1  ; Get data from TX FIFO
-    out pins, 9                 side 1  ; Write data and parity bit
-    out null, 23 [REQ_DLY-2]    side 1  ; Discard unused bits, wait for data preset time
-    wait 1 gpio ACK             side 1  ; Wait for ACK to be inactive
-    wait 0 gpio ACK             side 0  ; Assert REQ, wait for ACK low
-
-; Read from SCSI bus using sync or async handshake.
-; Data is returned as 32-bit words:
-; - bit  0: always zero
-; - bits 1-8: data byte
-; - bit  9: parity bit
-; - bits 10-31: lookup table address
-; Lookup table address should be loaded into register Y.
-; One dummy word should be written to TX fifo for every byte to receive.
-.program scsi_accel_read
-    .side_set 1
-
-    pull block                  side 1  ; Pull from TX fifo for counting bytes and pacing sync mode
-    wait 1 gpio ACK             side 1  ; Wait for ACK high
-    in null, 1                  side 0  ; Zero bit because lookup table entries are 16-bit
-    wait 0 gpio ACK             side 0  ; Assert REQ, wait for ACK low
-    in pins, 9                  side 1  ; Deassert REQ, read GPIO
-    in y, 22                    side 1  ; Copy parity lookup table address
-
-; Data state machine for synchronous writes.
-; Takes the lowest 9 bits of each 32 bit word and writes them to bus with REQ pulse.
-; The delay times will be rewritten by C code to match the negotiated SCSI sync speed.
-;
-; Shifts one bit to ISR per every byte transmitted. This is used to control the transfer
-; pace, the RX fifo acts as a counter to keep track of unacknowledged bytes. The C code
-; can set the syncOffset by changing autopush threshold, e.g. threshold 3 = 12 bytes offset.
-.program scsi_sync_write
-    .side_set 1
-
-    out pins, 9      [0]        side 1  ; Write data and parity bit, wait for deskew delay
-    out null, 23     [0]        side 0  ; Assert REQ, wait for assert time
-    in null, 1       [0]        side 1  ; Deassert REQ, wait for transfer period, wait for space in ACK buffer
-
-; Data pacing state machine for synchronous writes.
-; Takes one bit from ISR on every falling edge of ACK.
-; The C code should set autopull threshold to match scsi_sync_write autopush threshold.
-; System DMA will then move words from scsi_sync_write RX fifo to scsi_sync_write_pacer TX fifo.
-.program scsi_sync_write_pacer
-    wait 1 gpio ACK
-    wait 0 gpio ACK   ; Wait for falling edge on ACK
-    out null, 1       ; Let scsi_sync_write send one more byte
-
-; Data pacing state machine for synchronous reads.
-; The delay times will be rewritten by C code to match the negotiated SCSI sync speed.
-; Number of bytes to receive minus one should be loaded into register X.
-; In synchronous mode this generates the REQ pulses and dummy words.
-; In asynchronous mode it just generates dummy words to feed to scsi_accel_read.
-.program scsi_sync_read_pacer
-    .side_set 1
-
-start:
-    push block      [0]      side 1  ; Send dummy word to scsi_accel_read, wait for transfer period
-    jmp x-- start   [0]      side 0  ; Assert REQ, wait for assert time
-
-finish:
-    jmp finish      [0]      side 1
-
-; Parity checker for reads from SCSI bus.
-; Receives 16-bit words from g_scsi_parity_check_lookup
-; Bottom 8 bits are the data byte, which is passed to output FIFO
-; The 9th bit is parity valid bit, which is 1 for valid and 0 for parity error.
-.program scsi_read_parity
-parity_valid:
-    out isr, 8                ; Take the 8 data bits for passing to RX fifo
-    push block                ; Push the data to RX fifo
-    out x, 24                 ; Take the parity valid bit, and the rest of 32-bit word
-    jmp x-- parity_valid      ; If parity valid bit is 1, repeat from start
-    irq set 0                 ; Parity error, set interrupt flag

+ 0 - 224
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_RP2350A.pio.h

@@ -1,224 +0,0 @@
-// -------------------------------------------------- //
-// This file is autogenerated by pioasm; do not edit! //
-// -------------------------------------------------- //
-
-#pragma once
-
-#if !PICO_NO_HARDWARE
-#include "hardware/pio.h"
-#endif
-
-// ----------- //
-// scsi_parity //
-// ----------- //
-
-#define scsi_parity_wrap_target 0
-#define scsi_parity_wrap 3
-
-static const uint16_t scsi_parity_program_instructions[] = {
-            //     .wrap_target
-    0x80a0, //  0: pull   block                      
-    0x4061, //  1: in     null, 1                    
-    0x40e8, //  2: in     osr, 8                     
-    0x4037, //  3: in     x, 23                      
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_parity_program = {
-    .instructions = scsi_parity_program_instructions,
-    .length = 4,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_parity_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_parity_wrap_target, offset + scsi_parity_wrap);
-    return c;
-}
-#endif
-
-// ---------------------- //
-// scsi_accel_async_write //
-// ---------------------- //
-
-#define scsi_accel_async_write_wrap_target 0
-#define scsi_accel_async_write_wrap 4
-
-static const uint16_t scsi_accel_async_write_program_instructions[] = {
-            //     .wrap_target
-    0x90e0, //  0: pull   ifempty block   side 1     
-    0x7009, //  1: out    pins, 9         side 1     
-    0x7777, //  2: out    null, 23        side 1 [7] 
-    0x308a, //  3: wait   1 gpio, 10      side 1     
-    0x200a, //  4: wait   0 gpio, 10      side 0     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_accel_async_write_program = {
-    .instructions = scsi_accel_async_write_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_accel_async_write_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_accel_async_write_wrap_target, offset + scsi_accel_async_write_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------- //
-// scsi_accel_read //
-// --------------- //
-
-#define scsi_accel_read_wrap_target 0
-#define scsi_accel_read_wrap 5
-
-static const uint16_t scsi_accel_read_program_instructions[] = {
-            //     .wrap_target
-    0x90a0, //  0: pull   block           side 1     
-    0x308a, //  1: wait   1 gpio, 10      side 1     
-    0x4061, //  2: in     null, 1         side 0     
-    0x200a, //  3: wait   0 gpio, 10      side 0     
-    0x5009, //  4: in     pins, 9         side 1     
-    0x5056, //  5: in     y, 22           side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_accel_read_program = {
-    .instructions = scsi_accel_read_program_instructions,
-    .length = 6,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_accel_read_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_accel_read_wrap_target, offset + scsi_accel_read_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------- //
-// scsi_sync_write //
-// --------------- //
-
-#define scsi_sync_write_wrap_target 0
-#define scsi_sync_write_wrap 2
-
-static const uint16_t scsi_sync_write_program_instructions[] = {
-            //     .wrap_target
-    0x7009, //  0: out    pins, 9         side 1     
-    0x6077, //  1: out    null, 23        side 0     
-    0x5061, //  2: in     null, 1         side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_write_program = {
-    .instructions = scsi_sync_write_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_write_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_write_wrap_target, offset + scsi_sync_write_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// --------------------- //
-// scsi_sync_write_pacer //
-// --------------------- //
-
-#define scsi_sync_write_pacer_wrap_target 0
-#define scsi_sync_write_pacer_wrap 2
-
-static const uint16_t scsi_sync_write_pacer_program_instructions[] = {
-            //     .wrap_target
-    0x208a, //  0: wait   1 gpio, 10                 
-    0x200a, //  1: wait   0 gpio, 10                 
-    0x6061, //  2: out    null, 1                    
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_write_pacer_program = {
-    .instructions = scsi_sync_write_pacer_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_write_pacer_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_write_pacer_wrap_target, offset + scsi_sync_write_pacer_wrap);
-    return c;
-}
-#endif
-
-// -------------------- //
-// scsi_sync_read_pacer //
-// -------------------- //
-
-#define scsi_sync_read_pacer_wrap_target 0
-#define scsi_sync_read_pacer_wrap 2
-
-static const uint16_t scsi_sync_read_pacer_program_instructions[] = {
-            //     .wrap_target
-    0x9020, //  0: push   block           side 1     
-    0x0040, //  1: jmp    x--, 0          side 0     
-    0x1002, //  2: jmp    2               side 1     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_sync_read_pacer_program = {
-    .instructions = scsi_sync_read_pacer_program_instructions,
-    .length = 3,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_sync_read_pacer_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_sync_read_pacer_wrap_target, offset + scsi_sync_read_pacer_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// ---------------- //
-// scsi_read_parity //
-// ---------------- //
-
-#define scsi_read_parity_wrap_target 0
-#define scsi_read_parity_wrap 4
-
-static const uint16_t scsi_read_parity_program_instructions[] = {
-            //     .wrap_target
-    0x60c8, //  0: out    isr, 8                     
-    0x8020, //  1: push   block                      
-    0x6038, //  2: out    x, 24                      
-    0x0040, //  3: jmp    x--, 0                     
-    0xc000, //  4: irq    nowait 0                   
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program scsi_read_parity_program = {
-    .instructions = scsi_read_parity_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config scsi_read_parity_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + scsi_read_parity_wrap_target, offset + scsi_read_parity_wrap);
-    return c;
-}
-#endif

+ 0 - 0
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_RP2040.pio → lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_RP2MCU.pio


+ 0 - 0
lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_RP2040.pio.h → lib/ZuluSCSI_platform_RP2MCU/scsi_accel_target_RP2MCU.pio.h


+ 1 - 1
lib/ZuluSCSI_platform_RP2MCU/sd_card_sdio.cpp

@@ -93,7 +93,7 @@ bool SdioCard::begin(SdioConfig sdioConfig)
     sdio_status_t status;
     
     // Initialize at 1 MHz clock speed
-    rp2040_sdio_init(g_zuluscsi_timings.sdio.clk_div_1mhz);
+    rp2040_sdio_init(g_zuluscsi_timings->sdio.clk_div_1mhz);
 
     // Establish initial connection with the card
     for (int retries = 0; retries < 5; retries++)

+ 27 - 18
lib/ZuluSCSI_platform_RP2MCU/sdio.cpp

@@ -39,15 +39,7 @@
 #include <ZuluSCSI_log.h>
 #include "timings.h"
 
-#if defined(ZULUSCSI_PICO) || defined(ZULUSCSI_BS2)
-# include "sdio_Pico.pio.h"
-#elif defined(ZULUSCSI_PICO_2)
-# include "sdio_Pico_2.pio.h"
-#elif defined(ZULUSCSI_RP2350A)
-# include "sdio_RP2350A.pio.h"
-#else
-# include "sdio_RP2040.pio.h"
-#endif
+# include "sdio_RP2MCU.pio.h"
 
 #define SDIO_PIO pio1
 #define SDIO_CMD_SM 0
@@ -816,13 +808,17 @@ void rp2040_sdio_init(int clock_divider)
 
     // Command & clock state machine
     uint16_t temp_program_instr[32];
-    pio_program rewrite_sdio_cmd_clk_program = { temp_program_instr, sdio_cmd_clk_program.length,  sdio_cmd_clk_program.origin, sdio_cmd_clk_program.pio_version };
+    pio_program rewrite_sdio_cmd_clk_program = {
+        temp_program_instr,
+        sdio_cmd_clk_program.length,
+        sdio_cmd_clk_program.origin,
+        sdio_cmd_clk_program.pio_version };
     memcpy(temp_program_instr, sdio_cmd_clk_program_instructions, sizeof(sdio_cmd_clk_program_instructions));
     // Set the delays for the sdio_cmd_clk SDIO state machine
     for (uint8_t i = 0; i < sizeof(sdio_cmd_clk_program_instructions) / sizeof(sdio_cmd_clk_program_instructions[0]); i++)
     {
         uint16_t instr = sdio_cmd_clk_program_instructions[i]
-            | ((i & 1) ? pio_encode_delay(g_zuluscsi_timings.sdio.delay0) : pio_encode_delay(g_zuluscsi_timings.sdio.delay1));
+            | ((i & 1) ? pio_encode_delay(g_zuluscsi_timings->sdio.delay0) : pio_encode_delay(g_zuluscsi_timings->sdio.delay1));
         temp_program_instr[i] = instr;
     }
     g_sdio.pio_cmd_clk_offset = pio_add_program(SDIO_PIO, &rewrite_sdio_cmd_clk_program);
@@ -844,11 +840,17 @@ void rp2040_sdio_init(int clock_divider)
     // Data reception program
 
     // Set delays for sdio_data_rx PIO state machine
-    pio_program rewrite_sdio_data_rx_program = { temp_program_instr, sdio_data_rx_program.length,  sdio_data_rx_program.origin, sdio_data_rx_program.pio_version };
+    pio_program rewrite_sdio_data_rx_program = {
+        temp_program_instr,
+        sdio_data_rx_program.length,
+        sdio_data_rx_program.origin,
+        sdio_data_rx_program.pio_version };
     memcpy(temp_program_instr, sdio_data_rx_program_instructions, sizeof(sdio_data_rx_program_instructions));
-    uint16_t instr = sdio_data_rx_program_instructions[2] | pio_encode_delay(g_zuluscsi_timings.sdio.clk_div_pio - 1);
+    // wait 1 gpio SDIO_CLK_GPIO  [0]; [CLKDIV-1]
+    uint16_t instr = pio_encode_wait_gpio(true, SDIO_CLK) | pio_encode_delay(g_zuluscsi_timings->sdio.clk_div_pio - 1);
     temp_program_instr[2] = instr;
-    instr = sdio_data_rx_program_instructions[3] | pio_encode_delay(g_zuluscsi_timings.sdio.clk_div_pio - 2);
+    // in PINS, 4                 [0]; [CLKDIV-2]
+    instr = sdio_data_rx_program_instructions[3] | pio_encode_delay(g_zuluscsi_timings->sdio.clk_div_pio - 2);
     temp_program_instr[3] = instr;
 
     g_sdio.pio_data_rx_offset = pio_add_program(SDIO_PIO, &rewrite_sdio_data_rx_program);
@@ -861,16 +863,23 @@ void rp2040_sdio_init(int clock_divider)
     // Data transmission program
 
     // Set delays for sdio_data_tx PIO state machine
-    pio_program rewrite_sdio_data_tx_program = { temp_program_instr, sdio_data_tx_program.length,  sdio_data_tx_program.origin, sdio_data_tx_program.pio_version };
+    pio_program rewrite_sdio_data_tx_program = {
+        temp_program_instr,
+        sdio_data_tx_program.length,
+        sdio_data_tx_program.origin,
+        sdio_data_tx_program.pio_version };
     memcpy(temp_program_instr, sdio_data_tx_program_instructions, sizeof(sdio_data_tx_program_instructions));
-
-    instr = sdio_data_tx_program_instructions[1] | pio_encode_delay(g_zuluscsi_timings.sdio.clk_div_pio + g_zuluscsi_timings.sdio.delay1 - 1);
+    // wait 0 gpio SDIO_CLK_GPIO  
+    instr = pio_encode_wait_gpio(false, SDIO_CLK);
+    temp_program_instr[0] = instr;
+    // wait 1 gpio SDIO_CLK_GPIO;  [0]; [CLKDIV + D1 - 1];
+    instr = pio_encode_wait_gpio(true, SDIO_CLK) | pio_encode_delay(g_zuluscsi_timings->sdio.clk_div_pio + g_zuluscsi_timings->sdio.delay1 - 1);
     temp_program_instr[1] = instr;
     
     for (uint8_t i = 2; i < sizeof(sdio_data_tx_program_instructions) / sizeof(sdio_data_tx_program_instructions[0]); i++)
     {    
         uint16_t instr = sdio_data_tx_program_instructions[i]
-            | ((i & 1) ? pio_encode_delay(g_zuluscsi_timings.sdio.delay1) : pio_encode_delay(g_zuluscsi_timings.sdio.delay0));
+            | ((i & 1) ? pio_encode_delay(g_zuluscsi_timings->sdio.delay1) : pio_encode_delay(g_zuluscsi_timings->sdio.delay0));
         temp_program_instr[i] = instr;
     }
     g_sdio.pio_data_tx_offset = pio_add_program(SDIO_PIO, &rewrite_sdio_data_tx_program);

+ 0 - 164
lib/ZuluSCSI_platform_RP2MCU/sdio_Pico.pio

@@ -1,164 +0,0 @@
-; ZuluSCSI™ - Copyright (c) 2022 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/>.
-
-; RP2040 PIO program for implementing SD card access in SDIO mode
-; Run "pioasm rp2040_sdio.pio rp2040_sdio.pio.h" to regenerate the C header from this.
-
-; The RP2040 official work-in-progress code at
-; https://github.com/raspberrypi/pico-extras/tree/master/src/rp2_common/pico_sd_card
-; may be useful reference, but this is independent implementation.
-;
-; For official SDIO specifications, refer to:
-; https://www.sdcard.org/downloads/pls/
-; "SDIO Physical Layer Simplified Specification Version 8.00"
-
-; Clock settings
-; For 3.3V communication the available speeds are:
-; - Default speed: max. 25 MHz clock
-; - High speed:    max. 50 MHz clock
-;
-; From the default RP2040 clock speed of 125 MHz, the closest dividers
-; are 3 for 41.7 MHz and 5 for 25 MHz. The CPU can apply further divider
-; through state machine registers for the initial handshake.
-;
-; Because data is written on the falling edge and read on the rising
-; edge, it is preferrable to have a long 0 state and short 1 state.
-;.define CLKDIV 3
-.define CLKDIV 5
-.define D0 ((CLKDIV + 1) / 2 - 1)
-.define D1 (CLKDIV/2 - 1)
-.define SDIO_CLK_GPIO 10
-
-; State machine 0 is used to:
-; - generate continuous clock on SDIO_CLK
-; - send CMD packets
-; - receive response packets
-;
-; Pin mapping for this state machine:
-; - Sideset    : CLK
-; - IN/OUT/SET : CMD
-; - JMP_PIN    : CMD
-;
-; The commands to send are put on TX fifo and must have two words:
-; Word 0 bits 31-24: Number of bits in command minus one (usually 47)
-; Word 0 bits 23-00: First 24 bits of the command packet, shifted out MSB first
-; Word 1 bits 31-08: Last 24 bits of the command packet, shifted out MSB first
-; Word 1 bits 07-00: Number of bits in response minus one (usually 47), or 0 if no response
-;
-; The response is put on RX fifo, starting with the MSB.
-; Partial last word will be padded with zero bits at the top.
-;
-; The state machine EXECCTRL should be set so that STATUS indicates TX FIFO < 2
-; and that AUTOPULL and AUTOPUSH are enabled.
-
-.program sdio_cmd_clk
-    .side_set 1
-
-    mov OSR, NULL       side 1 [D1]    ; Make sure OSR is full of zeros to prevent autopull
-
-wait_cmd:
-    mov Y, !STATUS      side 0 [D0]    ; Check if TX FIFO has data
-    jmp !Y wait_cmd     side 1 [D1]
-
-load_cmd:
-    out NULL, 32        side 0 [D0]    ; Load first word (trigger autopull)
-    out X, 8            side 1 [D1]    ; Number of bits to send
-    set pins, 1         side 0 [D0]    ; Initial state of CMD is high
-    set pindirs, 1      side 1 [D1]    ; Set SDIO_CMD as output
-
-send_cmd:
-    out pins, 1         side 0 [D0]    ; Write output on falling edge of CLK
-    jmp X-- send_cmd    side 1 [D1]
-
-prep_resp:
-    set pindirs, 0      side 0 [D0]    ; Set SDIO_CMD as input
-    out X, 8            side 1 [D1]    ; Get number of bits in response
-    nop                 side 0 [D0]    ; For clock alignment
-    jmp !X resp_done    side 1 [D1]    ; Check if we expect a response
-
-wait_resp:
-    nop                  side 0 [D0]
-    jmp PIN wait_resp    side 1 [D1]    ; Loop until SDIO_CMD = 0
-
-    ; Note: input bits are read at the same time as we write CLK=0.
-    ; Because the host controls the clock, the read happens before
-    ; the card sees the falling clock edge. This gives maximum time
-    ; for the data bit to settle.
-read_resp:
-    in PINS, 1          side 0 [D0]    ; Read input data bit
-    jmp X-- read_resp   side 1 [D1]    ; Loop to receive all data bits
-
-resp_done:
-    push                side 0 [D0]    ; Push the remaining part of response
-
-; State machine 1 is used to send and receive data blocks.
-; Pin mapping for this state machine:
-; - IN / OUT: SDIO_D0-D3
-; - GPIO defined at beginning of this file: SDIO_CLK
-
-; Data reception program
-; This program will wait for initial start of block token and then
-; receive a data block. The application must set number of nibbles
-; to receive minus 1 to Y register before running this program.
-.program sdio_data_rx
-
-wait_start:
-    mov X, Y                               ; Reinitialize number of nibbles to receive
-    wait 0 pin 0                           ; Wait for zero state on D0
-    wait 1 gpio SDIO_CLK_GPIO  [CLKDIV-1]  ; Wait for rising edge and then whole clock cycle
-
-rx_data:
-    in PINS, 4                 [CLKDIV-2]  ; Read nibble
-    jmp X--, rx_data
-
-; Data transmission program
-;
-; Before running this program, pindirs should be set as output
-; and register X should be initialized with the number of nibbles
-; to send minus 1 (typically 8 + 1024 + 16 + 1 - 1 = 1048)
-; and register Y with the number of response bits minus 1 (typically 31).
-;
-; Words written to TX FIFO must be:
-; - Word 0: start token 0xFFFFFFF0
-; - Word 1-128: transmitted data (512 bytes)
-; - Word 129-130: CRC checksum
-; - Word 131: end token 0xFFFFFFFF
-;
-; After the card reports idle status, RX FIFO will get a word that
-; contains the D0 line response from card.
-
-.program sdio_data_tx
-    wait 0 gpio SDIO_CLK_GPIO  
-    wait 1 gpio SDIO_CLK_GPIO  [CLKDIV + D1 - 1]; Synchronize so that write occurs on falling edge
-
-tx_loop:
-    out PINS, 4                [D0]    ; Write nibble and wait for whole clock cycle
-    jmp X-- tx_loop            [D1]
-
-    set pindirs, 0x00          [D0]    ; Set data bus as input
-
-.wrap_target
-response_loop:
-    in PINS, 1                 [D1]    ; Read D0 on rising edge
-    jmp Y--, response_loop     [D0]
-
-wait_idle:
-    wait 1 pin 0               [D1]    ; Wait for card to indicate idle condition
-    push                       [D0]    ; Push the response token
-.wrap

+ 0 - 121
lib/ZuluSCSI_platform_RP2MCU/sdio_Pico.pio.h

@@ -1,121 +0,0 @@
-// -------------------------------------------------- //
-// This file is autogenerated by pioasm; do not edit! //
-// -------------------------------------------------- //
-
-#pragma once
-
-#if !PICO_NO_HARDWARE
-#include "hardware/pio.h"
-#endif
-
-// ------------ //
-// sdio_cmd_clk //
-// ------------ //
-
-#define sdio_cmd_clk_wrap_target 0
-#define sdio_cmd_clk_wrap 17
-
-static const uint16_t sdio_cmd_clk_program_instructions[] = {
-            //     .wrap_target
-    0xb1e3, //  0: mov    osr, null       side 1 [1] 
-    0xa24d, //  1: mov    y, !status      side 0 [2] 
-    0x1161, //  2: jmp    !y, 1           side 1 [1] 
-    0x6260, //  3: out    null, 32        side 0 [2] 
-    0x7128, //  4: out    x, 8            side 1 [1] 
-    0xe201, //  5: set    pins, 1         side 0 [2] 
-    0xf181, //  6: set    pindirs, 1      side 1 [1] 
-    0x6201, //  7: out    pins, 1         side 0 [2] 
-    0x1147, //  8: jmp    x--, 7          side 1 [1] 
-    0xe280, //  9: set    pindirs, 0      side 0 [2] 
-    0x7128, // 10: out    x, 8            side 1 [1] 
-    0xa242, // 11: nop                    side 0 [2] 
-    0x1131, // 12: jmp    !x, 17          side 1 [1] 
-    0xa242, // 13: nop                    side 0 [2] 
-    0x11cd, // 14: jmp    pin, 13         side 1 [1] 
-    0x4201, // 15: in     pins, 1         side 0 [2] 
-    0x114f, // 16: jmp    x--, 15         side 1 [1] 
-    0x8220, // 17: push   block           side 0 [2] 
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_cmd_clk_program = {
-    .instructions = sdio_cmd_clk_program_instructions,
-    .length = 18,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_cmd_clk_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_cmd_clk_wrap_target, offset + sdio_cmd_clk_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// ------------ //
-// sdio_data_rx //
-// ------------ //
-
-#define sdio_data_rx_wrap_target 0
-#define sdio_data_rx_wrap 4
-
-static const uint16_t sdio_data_rx_program_instructions[] = {
-            //     .wrap_target
-    0xa022, //  0: mov    x, y                       
-    0x2020, //  1: wait   0 pin, 0                   
-    0x248A, //  2: wait   1 gpio, 10             [4] 
-    0x4304, //  3: in     pins, 4                [3] 
-    0x0043, //  4: jmp    x--, 3                     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_data_rx_program = {
-    .instructions = sdio_data_rx_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_data_rx_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_data_rx_wrap_target, offset + sdio_data_rx_wrap);
-    return c;
-}
-#endif
-
-// ------------ //
-// sdio_data_tx //
-// ------------ //
-
-#define sdio_data_tx_wrap_target 5
-#define sdio_data_tx_wrap 8
-
-static const uint16_t sdio_data_tx_program_instructions[] = {
-    0x200A, //  0: wait   0 gpio, 10                 
-    0x258A, //  1: wait   1 gpio, 10             [5] 
-    0x6204, //  2: out    pins, 4                [2] 
-    0x0142, //  3: jmp    x--, 2                 [1] 
-    0xe280, //  4: set    pindirs, 0             [2] 
-            //     .wrap_target
-    0x4101, //  5: in     pins, 1                [1] 
-    0x0285, //  6: jmp    y--, 5                 [2] 
-    0x21a0, //  7: wait   1 pin, 0               [1] 
-    0x8220, //  8: push   block                  [2] 
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_data_tx_program = {
-    .instructions = sdio_data_tx_program_instructions,
-    .length = 9,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_data_tx_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_data_tx_wrap_target, offset + sdio_data_tx_wrap);
-    return c;
-}
-#endif
-

+ 0 - 164
lib/ZuluSCSI_platform_RP2MCU/sdio_Pico_2.pio

@@ -1,164 +0,0 @@
-; ZuluSCSI™ - Copyright (c) 2022 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/>.
-
-; RP2040 PIO program for implementing SD card access in SDIO mode
-; Run "pioasm rp2040_sdio.pio rp2040_sdio.pio.h" to regenerate the C header from this.
-
-; The RP2040 official work-in-progress code at
-; https://github.com/raspberrypi/pico-extras/tree/master/src/rp2_common/pico_sd_card
-; may be useful reference, but this is independent implementation.
-;
-; For official SDIO specifications, refer to:
-; https://www.sdcard.org/downloads/pls/
-; "SDIO Physical Layer Simplified Specification Version 8.00"
-
-; Clock settings
-; For 3.3V communication the available speeds are:
-; - Default speed: max. 25 MHz clock
-; - High speed:    max. 50 MHz clock
-;
-; From the default RP2040 clock speed of 125 MHz, the closest dividers
-; are 3 for 41.7 MHz and 5 for 25 MHz. The CPU can apply further divider
-; through state machine registers for the initial handshake.
-;
-; Because data is written on the falling edge and read on the rising
-; edge, it is preferrable to have a long 0 state and short 1 state.
-;.define CLKDIV 3
-.define CLKDIV 5
-.define D0 ((CLKDIV + 1) / 2 - 1)
-.define D1 (CLKDIV/2 - 1)
-.define SDIO_CLK_GPIO 10
-
-; State machine 0 is used to:
-; - generate continuous clock on SDIO_CLK
-; - send CMD packets
-; - receive response packets
-;
-; Pin mapping for this state machine:
-; - Sideset    : CLK
-; - IN/OUT/SET : CMD
-; - JMP_PIN    : CMD
-;
-; The commands to send are put on TX fifo and must have two words:
-; Word 0 bits 31-24: Number of bits in command minus one (usually 47)
-; Word 0 bits 23-00: First 24 bits of the command packet, shifted out MSB first
-; Word 1 bits 31-08: Last 24 bits of the command packet, shifted out MSB first
-; Word 1 bits 07-00: Number of bits in response minus one (usually 47), or 0 if no response
-;
-; The response is put on RX fifo, starting with the MSB.
-; Partial last word will be padded with zero bits at the top.
-;
-; The state machine EXECCTRL should be set so that STATUS indicates TX FIFO < 2
-; and that AUTOPULL and AUTOPUSH are enabled.
-
-.program sdio_cmd_clk
-    .side_set 1
-
-    mov OSR, NULL       side 1 [D1]    ; Make sure OSR is full of zeros to prevent autopull
-
-wait_cmd:
-    mov Y, !STATUS      side 0 [D0]    ; Check if TX FIFO has data
-    jmp !Y wait_cmd     side 1 [D1]
-
-load_cmd:
-    out NULL, 32        side 0 [D0]    ; Load first word (trigger autopull)
-    out X, 8            side 1 [D1]    ; Number of bits to send
-    set pins, 1         side 0 [D0]    ; Initial state of CMD is high
-    set pindirs, 1      side 1 [D1]    ; Set SDIO_CMD as output
-
-send_cmd:
-    out pins, 1         side 0 [D0]    ; Write output on falling edge of CLK
-    jmp X-- send_cmd    side 1 [D1]
-
-prep_resp:
-    set pindirs, 0      side 0 [D0]    ; Set SDIO_CMD as input
-    out X, 8            side 1 [D1]    ; Get number of bits in response
-    nop                 side 0 [D0]    ; For clock alignment
-    jmp !X resp_done    side 1 [D1]    ; Check if we expect a response
-
-wait_resp:
-    nop                  side 0 [D0]
-    jmp PIN wait_resp    side 1 [D1]    ; Loop until SDIO_CMD = 0
-
-    ; Note: input bits are read at the same time as we write CLK=0.
-    ; Because the host controls the clock, the read happens before
-    ; the card sees the falling clock edge. This gives maximum time
-    ; for the data bit to settle.
-read_resp:
-    in PINS, 1          side 0 [D0]    ; Read input data bit
-    jmp X-- read_resp   side 1 [D1]    ; Loop to receive all data bits
-
-resp_done:
-    push                side 0 [D0]    ; Push the remaining part of response
-
-; State machine 1 is used to send and receive data blocks.
-; Pin mapping for this state machine:
-; - IN / OUT: SDIO_D0-D3
-; - GPIO defined at beginning of this file: SDIO_CLK
-
-; Data reception program
-; This program will wait for initial start of block token and then
-; receive a data block. The application must set number of nibbles
-; to receive minus 1 to Y register before running this program.
-.program sdio_data_rx
-
-wait_start:
-    mov X, Y                               ; Reinitialize number of nibbles to receive
-    wait 0 pin 0                           ; Wait for zero state on D0
-    wait 1 gpio SDIO_CLK_GPIO  [CLKDIV-1]  ; Wait for rising edge and then whole clock cycle
-
-rx_data:
-    in PINS, 4                 [CLKDIV-2]  ; Read nibble
-    jmp X--, rx_data
-
-; Data transmission program
-;
-; Before running this program, pindirs should be set as output
-; and register X should be initialized with the number of nibbles
-; to send minus 1 (typically 8 + 1024 + 16 + 1 - 1 = 1048)
-; and register Y with the number of response bits minus 1 (typically 31).
-;
-; Words written to TX FIFO must be:
-; - Word 0: start token 0xFFFFFFF0
-; - Word 1-128: transmitted data (512 bytes)
-; - Word 129-130: CRC checksum
-; - Word 131: end token 0xFFFFFFFF
-;
-; After the card reports idle status, RX FIFO will get a word that
-; contains the D0 line response from card.
-
-.program sdio_data_tx
-    wait 0 gpio SDIO_CLK_GPIO  
-    wait 1 gpio SDIO_CLK_GPIO  [CLKDIV + D1 - 1]; Synchronize so that write occurs on falling edge
-
-tx_loop:
-    out PINS, 4                [D0]    ; Write nibble and wait for whole clock cycle
-    jmp X-- tx_loop            [D1]
-
-    set pindirs, 0x00          [D0]    ; Set data bus as input
-
-.wrap_target
-response_loop:
-    in PINS, 1                 [D1]    ; Read D0 on rising edge
-    jmp Y--, response_loop     [D0]
-
-wait_idle:
-    wait 1 pin 0               [D1]    ; Wait for card to indicate idle condition
-    push                       [D0]    ; Push the response token
-.wrap

+ 0 - 121
lib/ZuluSCSI_platform_RP2MCU/sdio_Pico_2.pio.h

@@ -1,121 +0,0 @@
-// -------------------------------------------------- //
-// This file is autogenerated by pioasm; do not edit! //
-// -------------------------------------------------- //
-
-#pragma once
-
-#if !PICO_NO_HARDWARE
-#include "hardware/pio.h"
-#endif
-
-// ------------ //
-// sdio_cmd_clk //
-// ------------ //
-
-#define sdio_cmd_clk_wrap_target 0
-#define sdio_cmd_clk_wrap 17
-
-static const uint16_t sdio_cmd_clk_program_instructions[] = {
-            //     .wrap_target
-    0xb1e3, //  0: mov    osr, null       side 1 [1] 
-    0xa24d, //  1: mov    y, !status      side 0 [2] 
-    0x1161, //  2: jmp    !y, 1           side 1 [1] 
-    0x6260, //  3: out    null, 32        side 0 [2] 
-    0x7128, //  4: out    x, 8            side 1 [1] 
-    0xe201, //  5: set    pins, 1         side 0 [2] 
-    0xf181, //  6: set    pindirs, 1      side 1 [1] 
-    0x6201, //  7: out    pins, 1         side 0 [2] 
-    0x1147, //  8: jmp    x--, 7          side 1 [1] 
-    0xe280, //  9: set    pindirs, 0      side 0 [2] 
-    0x7128, // 10: out    x, 8            side 1 [1] 
-    0xa242, // 11: nop                    side 0 [2] 
-    0x1131, // 12: jmp    !x, 17          side 1 [1] 
-    0xa242, // 13: nop                    side 0 [2] 
-    0x11cd, // 14: jmp    pin, 13         side 1 [1] 
-    0x4201, // 15: in     pins, 1         side 0 [2] 
-    0x114f, // 16: jmp    x--, 15         side 1 [1] 
-    0x8220, // 17: push   block           side 0 [2] 
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_cmd_clk_program = {
-    .instructions = sdio_cmd_clk_program_instructions,
-    .length = 18,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_cmd_clk_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_cmd_clk_wrap_target, offset + sdio_cmd_clk_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// ------------ //
-// sdio_data_rx //
-// ------------ //
-
-#define sdio_data_rx_wrap_target 0
-#define sdio_data_rx_wrap 4
-
-static const uint16_t sdio_data_rx_program_instructions[] = {
-            //     .wrap_target
-    0xa022, //  0: mov    x, y                       
-    0x2020, //  1: wait   0 pin, 0                   
-    0x248A, //  2: wait   1 gpio, 10             [4] 
-    0x4304, //  3: in     pins, 4                [3] 
-    0x0043, //  4: jmp    x--, 3                     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_data_rx_program = {
-    .instructions = sdio_data_rx_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_data_rx_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_data_rx_wrap_target, offset + sdio_data_rx_wrap);
-    return c;
-}
-#endif
-
-// ------------ //
-// sdio_data_tx //
-// ------------ //
-
-#define sdio_data_tx_wrap_target 5
-#define sdio_data_tx_wrap 8
-
-static const uint16_t sdio_data_tx_program_instructions[] = {
-    0x200A, //  0: wait   0 gpio, 10                 
-    0x258A, //  1: wait   1 gpio, 10             [5] 
-    0x6204, //  2: out    pins, 4                [2] 
-    0x0142, //  3: jmp    x--, 2                 [1] 
-    0xe280, //  4: set    pindirs, 0             [2] 
-            //     .wrap_target
-    0x4101, //  5: in     pins, 1                [1] 
-    0x0285, //  6: jmp    y--, 5                 [2] 
-    0x21a0, //  7: wait   1 pin, 0               [1] 
-    0x8220, //  8: push   block                  [2] 
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_data_tx_program = {
-    .instructions = sdio_data_tx_program_instructions,
-    .length = 9,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_data_tx_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_data_tx_wrap_target, offset + sdio_data_tx_wrap);
-    return c;
-}
-#endif
-

+ 0 - 164
lib/ZuluSCSI_platform_RP2MCU/sdio_RP2350A.pio

@@ -1,164 +0,0 @@
-; ZuluSCSI™ - Copyright (c) 2022 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/>.
-
-; RP2040 PIO program for implementing SD card access in SDIO mode
-; Run "pioasm rp2040_sdio.pio rp2040_sdio.pio.h" to regenerate the C header from this.
-
-; The RP2040 official work-in-progress code at
-; https://github.com/raspberrypi/pico-extras/tree/master/src/rp2_common/pico_sd_card
-; may be useful reference, but this is independent implementation.
-;
-; For official SDIO specifications, refer to:
-; https://www.sdcard.org/downloads/pls/
-; "SDIO Physical Layer Simplified Specification Version 8.00"
-
-; Clock settings
-; For 3.3V communication the available speeds are:
-; - Default speed: max. 25 MHz clock
-; - High speed:    max. 50 MHz clock
-;
-; From the default RP2040 clock speed of 125 MHz, the closest dividers
-; are 3 for 41.7 MHz and 5 for 25 MHz. The CPU can apply further divider
-; through state machine registers for the initial handshake.
-;
-; Because data is written on the falling edge and read on the rising
-; edge, it is preferrable to have a long 0 state and short 1 state.
-;.define CLKDIV 3
-.define CLKDIV 5
-.define D0 ((CLKDIV + 1) / 2 - 1)
-.define D1 (CLKDIV/2 - 1)
-.define SDIO_CLK_GPIO 18
-
-; State machine 0 is used to:
-; - generate continuous clock on SDIO_CLK
-; - send CMD packets
-; - receive response packets
-;
-; Pin mapping for this state machine:
-; - Sideset    : CLK
-; - IN/OUT/SET : CMD
-; - JMP_PIN    : CMD
-;
-; The commands to send are put on TX fifo and must have two words:
-; Word 0 bits 31-24: Number of bits in command minus one (usually 47)
-; Word 0 bits 23-00: First 24 bits of the command packet, shifted out MSB first
-; Word 1 bits 31-08: Last 24 bits of the command packet, shifted out MSB first
-; Word 1 bits 07-00: Number of bits in response minus one (usually 47), or 0 if no response
-;
-; The response is put on RX fifo, starting with the MSB.
-; Partial last word will be padded with zero bits at the top.
-;
-; The state machine EXECCTRL should be set so that STATUS indicates TX FIFO < 2
-; and that AUTOPULL and AUTOPUSH are enabled.
-
-.program sdio_cmd_clk
-    .side_set 1
-
-    mov OSR, NULL       side 1 [D1]    ; Make sure OSR is full of zeros to prevent autopull
-
-wait_cmd:
-    mov Y, !STATUS      side 0 [D0]    ; Check if TX FIFO has data
-    jmp !Y wait_cmd     side 1 [D1]
-
-load_cmd:
-    out NULL, 32        side 0 [D0]    ; Load first word (trigger autopull)
-    out X, 8            side 1 [D1]    ; Number of bits to send
-    set pins, 1         side 0 [D0]    ; Initial state of CMD is high
-    set pindirs, 1      side 1 [D1]    ; Set SDIO_CMD as output
-
-send_cmd:
-    out pins, 1         side 0 [D0]    ; Write output on falling edge of CLK
-    jmp X-- send_cmd    side 1 [D1]
-
-prep_resp:
-    set pindirs, 0      side 0 [D0]    ; Set SDIO_CMD as input
-    out X, 8            side 1 [D1]    ; Get number of bits in response
-    nop                 side 0 [D0]    ; For clock alignment
-    jmp !X resp_done    side 1 [D1]    ; Check if we expect a response
-
-wait_resp:
-    nop                  side 0 [D0]
-    jmp PIN wait_resp    side 1 [D1]    ; Loop until SDIO_CMD = 0
-
-    ; Note: input bits are read at the same time as we write CLK=0.
-    ; Because the host controls the clock, the read happens before
-    ; the card sees the falling clock edge. This gives maximum time
-    ; for the data bit to settle.
-read_resp:
-    in PINS, 1          side 0 [D0]    ; Read input data bit
-    jmp X-- read_resp   side 1 [D1]    ; Loop to receive all data bits
-
-resp_done:
-    push                side 0 [D0]    ; Push the remaining part of response
-
-; State machine 1 is used to send and receive data blocks.
-; Pin mapping for this state machine:
-; - IN / OUT: SDIO_D0-D3
-; - GPIO defined at beginning of this file: SDIO_CLK
-
-; Data reception program
-; This program will wait for initial start of block token and then
-; receive a data block. The application must set number of nibbles
-; to receive minus 1 to Y register before running this program.
-.program sdio_data_rx
-
-wait_start:
-    mov X, Y                               ; Reinitialize number of nibbles to receive
-    wait 0 pin 0                           ; Wait for zero state on D0
-    wait 1 gpio SDIO_CLK_GPIO  [CLKDIV-1]  ; Wait for rising edge and then whole clock cycle
-
-rx_data:
-    in PINS, 4                 [CLKDIV-2]  ; Read nibble
-    jmp X--, rx_data
-
-; Data transmission program
-;
-; Before running this program, pindirs should be set as output
-; and register X should be initialized with the number of nibbles
-; to send minus 1 (typically 8 + 1024 + 16 + 1 - 1 = 1048)
-; and register Y with the number of response bits minus 1 (typically 31).
-;
-; Words written to TX FIFO must be:
-; - Word 0: start token 0xFFFFFFF0
-; - Word 1-128: transmitted data (512 bytes)
-; - Word 129-130: CRC checksum
-; - Word 131: end token 0xFFFFFFFF
-;
-; After the card reports idle status, RX FIFO will get a word that
-; contains the D0 line response from card.
-
-.program sdio_data_tx
-    wait 0 gpio SDIO_CLK_GPIO  
-    wait 1 gpio SDIO_CLK_GPIO  [CLKDIV + D1 - 1]; Synchronize so that write occurs on falling edge
-
-tx_loop:
-    out PINS, 4                [D0]    ; Write nibble and wait for whole clock cycle
-    jmp X-- tx_loop            [D1]
-
-    set pindirs, 0x00          [D0]    ; Set data bus as input
-
-.wrap_target
-response_loop:
-    in PINS, 1                 [D1]    ; Read D0 on rising edge
-    jmp Y--, response_loop     [D0]
-
-wait_idle:
-    wait 1 pin 0               [D1]    ; Wait for card to indicate idle condition
-    push                       [D0]    ; Push the response token
-.wrap

+ 0 - 121
lib/ZuluSCSI_platform_RP2MCU/sdio_RP2350A.pio.h

@@ -1,121 +0,0 @@
-// -------------------------------------------------- //
-// This file is autogenerated by pioasm; do not edit! //
-// -------------------------------------------------- //
-
-#pragma once
-
-#if !PICO_NO_HARDWARE
-#include "hardware/pio.h"
-#endif
-
-// ------------ //
-// sdio_cmd_clk //
-// ------------ //
-
-#define sdio_cmd_clk_wrap_target 0
-#define sdio_cmd_clk_wrap 17
-
-static const uint16_t sdio_cmd_clk_program_instructions[] = {
-            //     .wrap_target
-    0xb1e3, //  0: mov    osr, null       side 1 [1] 
-    0xa24d, //  1: mov    y, !status      side 0 [2] 
-    0x1161, //  2: jmp    !y, 1           side 1 [1] 
-    0x6260, //  3: out    null, 32        side 0 [2] 
-    0x7128, //  4: out    x, 8            side 1 [1] 
-    0xe201, //  5: set    pins, 1         side 0 [2] 
-    0xf181, //  6: set    pindirs, 1      side 1 [1] 
-    0x6201, //  7: out    pins, 1         side 0 [2] 
-    0x1147, //  8: jmp    x--, 7          side 1 [1] 
-    0xe280, //  9: set    pindirs, 0      side 0 [2] 
-    0x7128, // 10: out    x, 8            side 1 [1] 
-    0xa242, // 11: nop                    side 0 [2] 
-    0x1131, // 12: jmp    !x, 17          side 1 [1] 
-    0xa242, // 13: nop                    side 0 [2] 
-    0x11cd, // 14: jmp    pin, 13         side 1 [1] 
-    0x4201, // 15: in     pins, 1         side 0 [2] 
-    0x114f, // 16: jmp    x--, 15         side 1 [1] 
-    0x8220, // 17: push   block           side 0 [2] 
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_cmd_clk_program = {
-    .instructions = sdio_cmd_clk_program_instructions,
-    .length = 18,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_cmd_clk_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_cmd_clk_wrap_target, offset + sdio_cmd_clk_wrap);
-    sm_config_set_sideset(&c, 1, false, false);
-    return c;
-}
-#endif
-
-// ------------ //
-// sdio_data_rx //
-// ------------ //
-
-#define sdio_data_rx_wrap_target 0
-#define sdio_data_rx_wrap 4
-
-static const uint16_t sdio_data_rx_program_instructions[] = {
-            //     .wrap_target
-    0xa022, //  0: mov    x, y                       
-    0x2020, //  1: wait   0 pin, 0                   
-    0x2492, //  2: wait   1 gpio, 18             [4] 
-    0x4304, //  3: in     pins, 4                [3] 
-    0x0043, //  4: jmp    x--, 3                     
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_data_rx_program = {
-    .instructions = sdio_data_rx_program_instructions,
-    .length = 5,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_data_rx_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_data_rx_wrap_target, offset + sdio_data_rx_wrap);
-    return c;
-}
-#endif
-
-// ------------ //
-// sdio_data_tx //
-// ------------ //
-
-#define sdio_data_tx_wrap_target 5
-#define sdio_data_tx_wrap 8
-
-static const uint16_t sdio_data_tx_program_instructions[] = {
-    0x2012, //  0: wait   0 gpio, 18                 
-    0x2592, //  1: wait   1 gpio, 18             [5] 
-    0x6204, //  2: out    pins, 4                [2] 
-    0x0142, //  3: jmp    x--, 2                 [1] 
-    0xe280, //  4: set    pindirs, 0             [2] 
-            //     .wrap_target
-    0x4101, //  5: in     pins, 1                [1] 
-    0x0285, //  6: jmp    y--, 5                 [2] 
-    0x21a0, //  7: wait   1 pin, 0               [1] 
-    0x8220, //  8: push   block                  [2] 
-            //     .wrap
-};
-
-#if !PICO_NO_HARDWARE
-static const struct pio_program sdio_data_tx_program = {
-    .instructions = sdio_data_tx_program_instructions,
-    .length = 9,
-    .origin = -1,
-};
-
-static inline pio_sm_config sdio_data_tx_program_get_default_config(uint offset) {
-    pio_sm_config c = pio_get_default_sm_config();
-    sm_config_set_wrap(&c, offset + sdio_data_tx_wrap_target, offset + sdio_data_tx_wrap);
-    return c;
-}
-#endif
-

+ 1 - 0
lib/ZuluSCSI_platform_RP2MCU/sdio_RP2040.pio → lib/ZuluSCSI_platform_RP2MCU/sdio_RP2MCU.pio

@@ -40,6 +40,7 @@
 ; Because data is written on the falling edge and read on the rising
 ; edge, it is preferrable to have a long 0 state and short 1 state.
 ;.define CLKDIV 3
+; all Dummy values, to be recoded by C pico-sdk functions
 .define CLKDIV 5
 .define D0 ((CLKDIV + 1) / 2 - 1)
 .define D1 (CLKDIV/2 - 1)

+ 0 - 0
lib/ZuluSCSI_platform_RP2MCU/sdio_RP2040.pio.h → lib/ZuluSCSI_platform_RP2MCU/sdio_RP2MCU.pio.h


+ 40 - 101
lib/ZuluSCSI_platform_RP2MCU/timings.c

@@ -22,88 +22,8 @@
 #include <string.h>
 #include "scsi2sd_timings.h"
 
-#ifdef ZULUSCSI_MCU_RP23XX
-    zuluscsi_timings_t g_zuluscsi_timings =
-    {
-        .clk_hz = 150000000,
-        .scsi =
-        {
-            .delay0 = 0,
-            .delay1 = 0,
-            .req_delay = 0,
-            .gpio_ack = 0,
-            .gpio_req = 0,
-            .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE
-
-        },
-        .sdio =
-        {
-            .clk_div_1mhz = 0,
-            .clk_div_pio = 0,
-            .delay0 = 0,
-            .delay1 = 0
-        }
-    };
-#else
-    zuluscsi_timings_t g_zuluscsi_timings =
-    {
-        .clk_hz = 125000000,
-
-        .pll =
-        {
-            .refdiv = 1,
-            .vco_freq = 1500000000,
-            .post_div1 = 6,
-            .post_div2 = 2
-        },
-
-        .scsi =
-        {
-            .req_delay = 7,
-            .clk_period_ps = 5000
-        },
-
-        .scsi_20 =
-        {
-            .delay0 = 4,
-            .delay1 = 6,
-            .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
-            .total_delay_adjust = -1,
-            .max_sync = 25,
-
-        },
-
-        .scsi_10 =
-        {
-            .delay0 = 4,
-            .delay1 = 6,
-            .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
-            .total_delay_adjust = -1,
-            .max_sync = 25,
-
-        },
-
-        .scsi_5 =
-        {
-            .delay0 = 7,
-            .delay1 = 14,
-            .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
-            .total_delay_adjust = -1,
-            .max_sync = 50,
-
-        },
-
-        .sdio =
-        {
-            .clk_div_1mhz = 25, // = 125MHz clk / clk_div_pio
-            .clk_div_pio = 5,
-            .delay0 = 3 - 1, // subtract one for the instruction delay
-            .delay1 = 2 - 1  // clk_div_pio - delay0 and subtract one for the instruction delay
-        }
-    };
-#endif
 
-static zuluscsi_timings_t predefined_timings[] = {
+static zuluscsi_timings_t  predefined_timings[]  = {
     {
         .clk_hz = 125000000,
 
@@ -142,8 +62,8 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .scsi_5 =
         {
-            .delay0 = 7,
-            .delay1 = 14,
+            .delay0 = 10 - 1,
+            .delay1 = 15 - 1,
             .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
             .total_delay_adjust = -1,
             .max_sync = 50,
@@ -176,8 +96,8 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .scsi_20 =
         {
-            .delay0 = 3,
-            .delay1 = 4,
+            .delay0 = 3 - 1,
+            .delay1 = 4 - 1,
             .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
             .total_delay_adjust = 0,
             .max_sync = 18,
@@ -186,8 +106,8 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .scsi_10 =
         {
-            .delay0 = 4,
-            .delay1 = 6,
+            .delay0 = 4 - 1,
+            .delay1 = 5 - 1,
             .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
             .total_delay_adjust = 0,
             .max_sync = 25,
@@ -196,8 +116,8 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .scsi_5 =
         {
-            .delay0 = 7,
-            .delay1 = 14,
+            .delay0 = 10 - 1,
+            .delay1 = 15, // should be 18 - 1 but max currently is 15
             .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
             .total_delay_adjust = 0,
             .max_sync = 50,
@@ -206,7 +126,7 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .sdio =
         {
-            .clk_div_1mhz = 25, // = 125MHz clk / clk_div_pio
+            .clk_div_1mhz = 30, // = 150MHz clk / clk_div_pio
             .clk_div_pio = 5,
             .delay0 = 3 - 1, // subtract one for the instruction delay
             .delay1 = 2 - 1  // clk_div_pio - delay0 and subtract one for the instruction delay
@@ -231,8 +151,8 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .scsi_20 =
         {
-            .delay0 = 2,
-            .delay1 = 4,
+            .delay0 = 3 - 1,
+            .delay1 = 5 - 1,
             .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
             .total_delay_adjust = 1,
             .max_sync = 12,
@@ -241,8 +161,8 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .scsi_10 =
         {
-            .delay0 = 8,
-            .delay1 = 10,
+            .delay0 = 6 - 1,
+            .delay1 = 9 - 1,
             .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
             .total_delay_adjust = 1,
             .max_sync = 25,
@@ -250,13 +170,21 @@ static zuluscsi_timings_t predefined_timings[] = {
 
         .scsi_5 =
         {
-            .delay0 = 14,
-            .delay1 = 15,
+            .delay0 = 15, // maxed out should be 16
+            .delay1 = 15, // maxed out should be 30
             .mode = ZULUSCSI_PIO_TARGET_MODE_SIMPLE,
             .total_delay_adjust = 1,
             .max_sync = 50,
         },
-
+#ifdef ZULUSCSI_PICO_2
+        .sdio =
+        {
+            .clk_div_1mhz = 30, // set by trail and error
+            .clk_div_pio = 6, // SDIO at 41.7MHz
+            .delay0 = 4 - 1, // subtract one for the instruction delay
+            .delay1 = 2 - 1  // clk_div_pio - delay0 and subtract one for the instruction delay
+        }
+#else
         .sdio =
         {
             .clk_div_1mhz = 50, // = 250MHz clk / clk_div_pio
@@ -264,8 +192,18 @@ static zuluscsi_timings_t predefined_timings[] = {
             .delay0 = 4 - 1, // subtract one for the instruction delay
             .delay1 = 1 - 1  // clk_div_pio - delay0 and subtract one for the instruction delay
         }
+
+#endif
     }
 };
+    zuluscsi_timings_t  current_timings;
+#ifdef ZULUSCSI_MCU_RP23XX
+    zuluscsi_timings_t *g_zuluscsi_timings = &predefined_timings[1];
+#else
+    zuluscsi_timings_t *g_zuluscsi_timings = &predefined_timings[0];
+    
+#endif
+
 
 bool set_timings(uint32_t target_clk_in_khz)
 {
@@ -274,10 +212,11 @@ bool set_timings(uint32_t target_clk_in_khz)
     {
         if (target_clk_in_khz == predefined_timings[i].clk_hz / 1000)
         {
-            memcpy(&g_zuluscsi_timings, &predefined_timings[i], sizeof(g_zuluscsi_timings));
-            g_max_sync_10_period = g_zuluscsi_timings.scsi_10.max_sync;
-            g_max_sync_20_period = g_zuluscsi_timings.scsi_20.max_sync;
-            g_max_sync_5_period = g_zuluscsi_timings.scsi_5.max_sync;
+            g_zuluscsi_timings = &current_timings;
+            memcpy(g_zuluscsi_timings, &predefined_timings[i], sizeof(current_timings));
+            g_max_sync_10_period = g_zuluscsi_timings->scsi_10.max_sync;
+            g_max_sync_20_period = g_zuluscsi_timings->scsi_20.max_sync;
+            g_max_sync_5_period = g_zuluscsi_timings->scsi_5.max_sync;
             return true;
         }
     }

+ 11 - 4
lib/ZuluSCSI_platform_RP2MCU/timings.h

@@ -33,6 +33,9 @@ typedef struct
     uint32_t clk_hz;
     struct
     {
+        // These numbers are for pico-sdk's pll_init() function
+        // their values can be obtained using the script:
+        // "/src/rp2_common/hardware_clocks/scripts/vcocalc.py" 
         uint8_t refdiv;
         uint32_t vco_freq;
         uint8_t post_div1;
@@ -49,11 +52,15 @@ typedef struct
     } scsi;
 
 
-    // delay0: Delay from data write to REQ assertion (data setup)
-    // delay1: Delay from REQ assert to REQ deassert (req pulse width)
+    // 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 - (total_delay - d0 - d1): total_delay spec is the sync value * 4 in ns width)
     // both values are in clock cycles minus 1 for the pio instruction delay
+    // delay0 spec: Ultra(20):  11.5ns  Fast(10): 23ns  SCSI-1(5): 23ns
+    // delay1 spec: Ultra(20):  16.5ns  Fast(10): 33ns  SCSI-1(5): 53ns 
+    // delay2 spec: Ultra(20):  15ns    Fast(10): 30ns  SCSI-1(5): 80ns 
     // total_delay_adjust is manual adjustment value, when checked with a scope
-    // Max sync - the max sync period that is supported at this clock rate, the number is 1/4 the actual value in ns
+    // Max sync - the minimum sync period ("max" clock rate) that is supported at this clock rate, the number is 1/4 the actual value in ns
     struct
     {
         zuluscsi_pio_target_mode_t mode;
@@ -101,7 +108,7 @@ typedef struct
 
 } zuluscsi_timings_t;
 
-extern  zuluscsi_timings_t g_zuluscsi_timings;
+extern  zuluscsi_timings_t *g_zuluscsi_timings;
 
 bool set_timings(uint32_t target_clk_in_khz);
 #endif // ZULUSCSI_RP2MCU_TIMINGS_H