From 2d815abf55d82a974b469e8bf35e7c37340e4c39 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 15:35:25 -0500 Subject: [PATCH 01/18] Take I --- main.c | 75 ++++++++++++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/main.c b/main.c index 1a0657c..b575860 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,7 @@ #include "hardware/spi.h" #include "tusb.h" #include "serprog.h" +#include "pio_spi.h" #define CDC_ITF 0 // USB CDC interface no @@ -23,9 +24,9 @@ #define SPI_MISO 4 #define SPI_MOSI 3 #define SPI_SCK 2 -#define MAX_BUFFER_SIZE 1024 -#define MAX_OPBUF_SIZE 1024 -#define SERIAL_BUFFER_SIZE 1024 +#define MAX_BUFFER_SIZE 512 +#define MAX_OPBUF_SIZE 512 +#define SERIAL_BUFFER_SIZE 512 // Define a global operation buffer and a pointer to track the current position uint8_t opbuf[MAX_OPBUF_SIZE]; @@ -100,6 +101,7 @@ static inline uint8_t readbyte_blocking(void) return b; } + static void wait_for_write(void) { do { @@ -123,6 +125,29 @@ static inline void sendbyte_blocking(uint8_t b) tud_cdc_n_write(CDC_ITF, &b, 1); } + +void handle_spi_op(uint32_t slen, uint32_t rlen) { + uint8_t tx_buffer[MAX_BUFFER_SIZE]; // Buffer for transmit data + uint8_t rx_buffer[MAX_BUFFER_SIZE]; // Buffer for receive data + + // Read data to be sent + if (slen > 0) { + readbytes_blocking(tx_buffer, slen); // Assuming you have this function + } + + // Perform PIO SPI operation + cs_select(SPI_CS); // Assuming cs_select function is defined + pio_spi_write_read_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function + cs_deselect(SPI_CS); // Assuming cs_deselect function is defined + + // Send ACK and received data + sendbyte_blocking(S_ACK); // Assuming sendbyte_blocking function is defined + if (rlen > 0) { + sendbytes_blocking(rx_buffer, rlen); // Assuming sendbytes_blocking function is defined + } +} + + static void command_loop(void) { uint baud = spi_get_baudrate(SPI_IF); @@ -199,49 +224,10 @@ static void command_loop(void) slen &= 0x00FFFFFF; // Mask to use only the lower 24 bits rlen &= 0x00FFFFFF; // Mask to use only the lower 24 bits - uint8_t tx_buffer[MAX_BUFFER_SIZE]; // Buffer for transmit data - uint8_t rx_buffer[MAX_BUFFER_SIZE]; // Buffer for receive data - - // Read data to be sent (if slen > 0) - if (slen > 0) { - readbytes_blocking(tx_buffer, slen); - } - - // Perform SPI operation - cs_select(SPI_CS); - if (slen > 0) { - spi_write_blocking(SPI_IF, tx_buffer, slen); - } - if (rlen > 0 && rlen < MAX_BUFFER_SIZE ) { - spi_read_blocking(SPI_IF, 0, rx_buffer, rlen); - // Send ACK followed by received data - sendbyte_blocking(S_ACK); - if (rlen > 0) { - sendbytes_blocking(rx_buffer, rlen); - } - - cs_deselect(SPI_CS); - break; - } - - // Send ACK after handling slen (before reading) - sendbyte_blocking(S_ACK); - - // Handle receive operation in chunks for large rlen - uint32_t chunk; - char buf[128]; - - for(uint32_t i = 0; i < rlen; i += chunk) { - chunk = MIN(rlen - i, sizeof(buf)); - spi_read_blocking(SPI_IF, 0, buf, chunk); - // Send ACK followed by received data - sendbyte_blocking(S_ACK); - sendbytes_blocking(buf, rlen); - } - cs_deselect(SPI_CS); + handle_spi_op(slen, rlen); break; } - case S_CMD_S_SPI_FREQ: + case S_CMD_S_SPI_FREQ: { uint32_t want_baud; readbytes_blocking(&want_baud, 4); @@ -343,6 +329,7 @@ int main() { // Setup USB tusb_init(); + stdio_init_all(); // Setup PL022 SPI enable_spi(SPI_BAUD); From 79128658c74a1b85abe66a5706be73199b1c3a8f Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 15:37:02 -0500 Subject: [PATCH 02/18] Add SPI files --- pio_spi.c | 68 ++++++++++++++++++++ pio_spi.h | 24 +++++++ spi.pio | 168 +++++++++++++++++++++++++++++++++++++++++++++++++ spi_loopback.c | 77 +++++++++++++++++++++++ 4 files changed, 337 insertions(+) create mode 100644 pio_spi.c create mode 100644 pio_spi.h create mode 100644 spi.pio create mode 100644 spi_loopback.c diff --git a/pio_spi.c b/pio_spi.c new file mode 100644 index 0000000..6306b7d --- /dev/null +++ b/pio_spi.c @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pio_spi.h" + +// Just 8 bit functions provided here. The PIO program supports any frame size +// 1...32, but the software to do the necessary FIFO shuffling is left as an +// exercise for the reader :) +// +// Likewise we only provide MSB-first here. To do LSB-first, you need to +// - Do shifts when reading from the FIFO, for general case n != 8, 16, 32 +// - Do a narrow read at a one halfword or 3 byte offset for n == 16, 8 +// in order to get the read data correctly justified. + +void __time_critical_func(pio_spi_write8_blocking)(const pio_spi_inst_t *spi, const uint8_t *src, size_t len) { + size_t tx_remain = len, rx_remain = len; + // Do 8 bit accesses on FIFO, so that write data is byte-replicated. This + // gets us the left-justification for free (for MSB-first shift-out) + io_rw_8 *txfifo = (io_rw_8 *) &spi->pio->txf[spi->sm]; + io_rw_8 *rxfifo = (io_rw_8 *) &spi->pio->rxf[spi->sm]; + while (tx_remain || rx_remain) { + if (tx_remain && !pio_sm_is_tx_fifo_full(spi->pio, spi->sm)) { + *txfifo = *src++; + --tx_remain; + } + if (rx_remain && !pio_sm_is_rx_fifo_empty(spi->pio, spi->sm)) { + (void) *rxfifo; + --rx_remain; + } + } +} + +void __time_critical_func(pio_spi_read8_blocking)(const pio_spi_inst_t *spi, uint8_t *dst, size_t len) { + size_t tx_remain = len, rx_remain = len; + io_rw_8 *txfifo = (io_rw_8 *) &spi->pio->txf[spi->sm]; + io_rw_8 *rxfifo = (io_rw_8 *) &spi->pio->rxf[spi->sm]; + while (tx_remain || rx_remain) { + if (tx_remain && !pio_sm_is_tx_fifo_full(spi->pio, spi->sm)) { + *txfifo = 0; + --tx_remain; + } + if (rx_remain && !pio_sm_is_rx_fifo_empty(spi->pio, spi->sm)) { + *dst++ = *rxfifo; + --rx_remain; + } + } +} + +void __time_critical_func(pio_spi_write8_read8_blocking)(const pio_spi_inst_t *spi, uint8_t *src, uint8_t *dst, + size_t len) { + size_t tx_remain = len, rx_remain = len; + io_rw_8 *txfifo = (io_rw_8 *) &spi->pio->txf[spi->sm]; + io_rw_8 *rxfifo = (io_rw_8 *) &spi->pio->rxf[spi->sm]; + while (tx_remain || rx_remain) { + if (tx_remain && !pio_sm_is_tx_fifo_full(spi->pio, spi->sm)) { + *txfifo = *src++; + --tx_remain; + } + if (rx_remain && !pio_sm_is_rx_fifo_empty(spi->pio, spi->sm)) { + *dst++ = *rxfifo; + --rx_remain; + } + } +} + diff --git a/pio_spi.h b/pio_spi.h new file mode 100644 index 0000000..dfa929d --- /dev/null +++ b/pio_spi.h @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _PIO_SPI_H +#define _PIO_SPI_H + +#include "hardware/pio.h" +#include "spi.pio.h" + +typedef struct pio_spi_inst { + PIO pio; + uint sm; + uint cs_pin; +} pio_spi_inst_t; + +void pio_spi_write8_blocking(const pio_spi_inst_t *spi, const uint8_t *src, size_t len); + +void pio_spi_read8_blocking(const pio_spi_inst_t *spi, uint8_t *dst, size_t len); + +void pio_spi_write8_read8_blocking(const pio_spi_inst_t *spi, uint8_t *src, uint8_t *dst, size_t len); + +#endif diff --git a/spi.pio b/spi.pio new file mode 100644 index 0000000..eba785e --- /dev/null +++ b/spi.pio @@ -0,0 +1,168 @@ +; +; Copyright (c) 2020 Raspberry Pi (Trading) Ltd. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +; These programs implement full-duplex SPI, with a SCK period of 4 clock +; cycles. A different program is provided for each value of CPHA, and CPOL is +; achieved using the hardware GPIO inversion available in the IO controls. +; +; Transmit-only SPI can go twice as fast -- see the ST7789 example! + + +.program spi_cpha0 +.side_set 1 + +; Pin assignments: +; - SCK is side-set pin 0 +; - MOSI is OUT pin 0 +; - MISO is IN pin 0 +; +; Autopush and autopull must be enabled, and the serial frame size is set by +; configuring the push/pull threshold. Shift left/right is fine, but you must +; justify the data yourself. This is done most conveniently for frame sizes of +; 8 or 16 bits by using the narrow store replication and narrow load byte +; picking behaviour of RP2040's IO fabric. + +; Clock phase = 0: data is captured on the leading edge of each SCK pulse, and +; transitions on the trailing edge, or some time before the first leading edge. + + out pins, 1 side 0 [1] ; Stall here on empty (sideset proceeds even if + in pins, 1 side 1 [1] ; instruction stalls, so we stall with SCK low) + +.program spi_cpha1 +.side_set 1 + +; Clock phase = 1: data transitions on the leading edge of each SCK pulse, and +; is captured on the trailing edge. + + out x, 1 side 0 ; Stall here on empty (keep SCK deasserted) + mov pins, x side 1 [1] ; Output data, assert SCK (mov pins uses OUT mapping) + in pins, 1 side 0 ; Input data, deassert SCK + +% c-sdk { +#include "hardware/gpio.h" +static inline void pio_spi_init(PIO pio, uint sm, uint prog_offs, uint n_bits, + float clkdiv, bool cpha, bool cpol, uint pin_sck, uint pin_mosi, uint pin_miso) { + pio_sm_config c = cpha ? spi_cpha1_program_get_default_config(prog_offs) : spi_cpha0_program_get_default_config(prog_offs); + sm_config_set_out_pins(&c, pin_mosi, 1); + sm_config_set_in_pins(&c, pin_miso); + sm_config_set_sideset_pins(&c, pin_sck); + // Only support MSB-first in this example code (shift to left, auto push/pull, threshold=nbits) + sm_config_set_out_shift(&c, false, true, n_bits); + sm_config_set_in_shift(&c, false, true, n_bits); + sm_config_set_clkdiv(&c, clkdiv); + + // MOSI, SCK output are low, MISO is input + pio_sm_set_pins_with_mask(pio, sm, 0, (1u << pin_sck) | (1u << pin_mosi)); + pio_sm_set_pindirs_with_mask(pio, sm, (1u << pin_sck) | (1u << pin_mosi), (1u << pin_sck) | (1u << pin_mosi) | (1u << pin_miso)); + pio_gpio_init(pio, pin_mosi); + pio_gpio_init(pio, pin_miso); + pio_gpio_init(pio, pin_sck); + + // The pin muxes can be configured to invert the output (among other things + // and this is a cheesy way to get CPOL=1 + gpio_set_outover(pin_sck, cpol ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL); + // SPI is synchronous, so bypass input synchroniser to reduce input delay. + hw_set_bits(&pio->input_sync_bypass, 1u << pin_miso); + + pio_sm_init(pio, sm, prog_offs, &c); + pio_sm_set_enabled(pio, sm, true); +} +%} + +; SPI with Chip Select +; ----------------------------------------------------------------------------- +; +; For your amusement, here are some SPI programs with an automatic chip select +; (asserted once data appears in TX FIFO, deasserts when FIFO bottoms out, has +; a nice front/back porch). +; +; The number of bits per FIFO entry is configured via the Y register +; and the autopush/pull threshold. From 2 to 32 bits. +; +; Pin assignments: +; - SCK is side-set bit 0 +; - CSn is side-set bit 1 +; - MOSI is OUT bit 0 (host-to-device) +; - MISO is IN bit 0 (device-to-host) +; +; This program only supports one chip select -- use GPIO if more are needed +; +; Provide a variation for each possibility of CPHA; for CPOL we can just +; invert SCK in the IO muxing controls (downstream from PIO) + + +; CPHA=0: data is captured on the leading edge of each SCK pulse (including +; the first pulse), and transitions on the trailing edge + +.program spi_cpha0_cs +.side_set 2 + +.wrap_target +bitloop: + out pins, 1 side 0x0 [1] + in pins, 1 side 0x1 + jmp x-- bitloop side 0x1 + + out pins, 1 side 0x0 + mov x, y side 0x0 ; Reload bit counter from Y + in pins, 1 side 0x1 + jmp !osre bitloop side 0x1 ; Fall-through if TXF empties + + nop side 0x0 [1] ; CSn back porch +public entry_point: ; Must set X,Y to n-2 before starting! + pull ifempty side 0x2 [1] ; Block with CSn high (minimum 2 cycles) +.wrap ; Note ifempty to avoid time-of-check race + +; CPHA=1: data transitions on the leading edge of each SCK pulse, and is +; captured on the trailing edge + +.program spi_cpha1_cs +.side_set 2 + +.wrap_target +bitloop: + out pins, 1 side 0x1 [1] + in pins, 1 side 0x0 + jmp x-- bitloop side 0x0 + + out pins, 1 side 0x1 + mov x, y side 0x1 + in pins, 1 side 0x0 + jmp !osre bitloop side 0x0 + +public entry_point: ; Must set X,Y to n-2 before starting! + pull ifempty side 0x2 [1] ; Block with CSn high (minimum 2 cycles) + nop side 0x0 [1]; CSn front porch +.wrap + +% c-sdk { +#include "hardware/gpio.h" +static inline void pio_spi_cs_init(PIO pio, uint sm, uint prog_offs, uint n_bits, float clkdiv, bool cpha, bool cpol, + uint pin_sck, uint pin_mosi, uint pin_miso) { + pio_sm_config c = cpha ? spi_cpha1_cs_program_get_default_config(prog_offs) : spi_cpha0_cs_program_get_default_config(prog_offs); + sm_config_set_out_pins(&c, pin_mosi, 1); + sm_config_set_in_pins(&c, pin_miso); + sm_config_set_sideset_pins(&c, pin_sck); + sm_config_set_out_shift(&c, false, true, n_bits); + sm_config_set_in_shift(&c, false, true, n_bits); + sm_config_set_clkdiv(&c, clkdiv); + + pio_sm_set_pins_with_mask(pio, sm, (2u << pin_sck), (3u << pin_sck) | (1u << pin_mosi)); + pio_sm_set_pindirs_with_mask(pio, sm, (3u << pin_sck) | (1u << pin_mosi), (3u << pin_sck) | (1u << pin_mosi) | (1u << pin_miso)); + pio_gpio_init(pio, pin_mosi); + pio_gpio_init(pio, pin_miso); + pio_gpio_init(pio, pin_sck); + pio_gpio_init(pio, pin_sck + 1); + gpio_set_outover(pin_sck, cpol ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL); + hw_set_bits(&pio->input_sync_bypass, 1u << pin_miso); + + uint entry_point = prog_offs + (cpha ? spi_cpha1_cs_offset_entry_point : spi_cpha0_cs_offset_entry_point); + pio_sm_init(pio, sm, entry_point, &c); + pio_sm_exec(pio, sm, pio_encode_set(pio_x, n_bits - 2)); + pio_sm_exec(pio, sm, pio_encode_set(pio_y, n_bits - 2)); + pio_sm_set_enabled(pio, sm, true); +} +%} diff --git a/spi_loopback.c b/spi_loopback.c new file mode 100644 index 0000000..ac5897f --- /dev/null +++ b/spi_loopback.c @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "pico/stdlib.h" +#include "pio_spi.h" + +// This program instantiates a PIO SPI with each of the four possible +// CPOL/CPHA combinations, with the serial input and output pin mapped to the +// same GPIO. Any data written into the state machine's TX FIFO should then be +// serialised, deserialised, and reappear in the state machine's RX FIFO. + +#define PIN_SCK 18 +#define PIN_MOSI 16 +#define PIN_MISO 16 // same as MOSI, so we get loopback + +#define BUF_SIZE 20 + +void test(const pio_spi_inst_t *spi) { + static uint8_t txbuf[BUF_SIZE]; + static uint8_t rxbuf[BUF_SIZE]; + printf("TX:"); + for (int i = 0; i < BUF_SIZE; ++i) { + txbuf[i] = rand() >> 16; + rxbuf[i] = 0; + printf(" %02x", (int) txbuf[i]); + } + printf("\n"); + + pio_spi_write8_read8_blocking(spi, txbuf, rxbuf, BUF_SIZE); + + printf("RX:"); + bool mismatch = false; + for (int i = 0; i < BUF_SIZE; ++i) { + printf(" %02x", (int) rxbuf[i]); + mismatch = mismatch || rxbuf[i] != txbuf[i]; + } + if (mismatch) + printf("\nNope\n"); + else + printf("\nOK\n"); +} + +int main() { + stdio_init_all(); + + pio_spi_inst_t spi = { + .pio = pio0, + .sm = 0 + }; + float clkdiv = 31.25f; // 1 MHz @ 125 clk_sys + uint cpha0_prog_offs = pio_add_program(spi.pio, &spi_cpha0_program); + uint cpha1_prog_offs = pio_add_program(spi.pio, &spi_cpha1_program); + + for (int cpha = 0; cpha <= 1; ++cpha) { + for (int cpol = 0; cpol <= 1; ++cpol) { + printf("CPHA = %d, CPOL = %d\n", cpha, cpol); + pio_spi_init(spi.pio, spi.sm, + cpha ? cpha1_prog_offs : cpha0_prog_offs, + 8, // 8 bits per SPI frame + clkdiv, + cpha, + cpol, + PIN_SCK, + PIN_MOSI, + PIN_MISO + ); + test(&spi); + sleep_ms(10); + } + } +} From e39126fe4b6ff16bd6e039ed8ab14c5dcb6ad197 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 15:40:14 -0500 Subject: [PATCH 03/18] update CMakeLists --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f952409..189d86b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ project(pico_serprog) pico_sdk_init() add_executable(pico_serprog) -target_sources(pico_serprog PRIVATE main.c usb_descriptors.c) -target_link_libraries(pico_serprog PRIVATE pico_stdlib hardware_spi tinyusb_device) +pico_generate_pio_header(pico_i2s_mic ${CMAKE_CURRENT_LIST_DIR}/mic_i2s.pio) +target_sources(pico_serprog PRIVATE main.c usb_descriptors.c pio_spi.c) +target_link_libraries(pico_serprog PRIVATE pico_stdlib hardware_spi hardware_pio tinyusb_device) pico_add_extra_outputs(pico_serprog) From c1375741677fbc50ade4e238dc0d740d1df18b77 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 15:44:13 -0500 Subject: [PATCH 04/18] correction --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 189d86b..7f61291 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(pico_serprog) pico_sdk_init() add_executable(pico_serprog) -pico_generate_pio_header(pico_i2s_mic ${CMAKE_CURRENT_LIST_DIR}/mic_i2s.pio) +pico_generate_pio_header(pico_serprog ${CMAKE_CURRENT_LIST_DIR}/spi.pio) target_sources(pico_serprog PRIVATE main.c usb_descriptors.c pio_spi.c) target_link_libraries(pico_serprog PRIVATE pico_stdlib hardware_spi hardware_pio tinyusb_device) pico_add_extra_outputs(pico_serprog) From 3c82de463db703ff188e68b5a6ec9648c115c26d Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 15:56:08 -0500 Subject: [PATCH 05/18] Checkpt --- main.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index b575860..4f51f7d 100644 --- a/main.c +++ b/main.c @@ -8,7 +8,9 @@ * https://github.com/dword1511/stm32-vserprog * */ - +#include +#include +#include #include "pico/stdlib.h" #include "pico/time.h" #include "hardware/spi.h" @@ -16,6 +18,8 @@ #include "serprog.h" #include "pio_spi.h" + + #define CDC_ITF 0 // USB CDC interface no #define SPI_IF spi0 // Which PL022 to use @@ -32,6 +36,30 @@ uint8_t opbuf[MAX_OPBUF_SIZE]; uint32_t opbuf_pos = 0; + +void sendbytes_usb(const uint8_t *buf, size_t len) { + // Check if USB is ready for data transfer + if (tud_cdc_connected()) { + // Write data to the USB CDC interface + tud_cdc_write(buf, len); + tud_cdc_write_flush(); + } +} + + +void read_spi_and_send_via_usb(const pio_spi_inst_t *spi) { + static uint8_t rxbuf[BUF_SIZE]; + memset(rxbuf, 0, BUF_SIZE); // Clear the receive buffer + + // Assuming you have a function to initiate SPI read + pio_spi_write8_read8_blocking(spi, rxbuf, BUF_SIZE); // Reads BUF_SIZE bytes into rxbuf + + // Transfer data via USB + // Assuming you have a function like sendbytes_usb for this + sendbytes_usb(rxbuf, BUF_SIZE); // You need to implement this function +} + + static void enable_spi(uint baud) { // Setup chip select GPIO @@ -224,7 +252,9 @@ static void command_loop(void) slen &= 0x00FFFFFF; // Mask to use only the lower 24 bits rlen &= 0x00FFFFFF; // Mask to use only the lower 24 bits - handle_spi_op(slen, rlen); + // Now call the modified function to read from SPI and send via USB + // Assuming rlen is the length of data to read and send + read_spi_and_send_via_usb(rlen); break; } case S_CMD_S_SPI_FREQ: @@ -328,8 +358,10 @@ static void command_loop(void) int main() { // Setup USB - tusb_init(); stdio_init_all(); + + tusb_init(); + // Setup PL022 SPI enable_spi(SPI_BAUD); From 1c78f1f55c4f4c67ad461f36089a1c3f25336e03 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:00:56 -0500 Subject: [PATCH 06/18] Correction --- main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 4f51f7d..fe7ec50 100644 --- a/main.c +++ b/main.c @@ -48,15 +48,15 @@ void sendbytes_usb(const uint8_t *buf, size_t len) { void read_spi_and_send_via_usb(const pio_spi_inst_t *spi) { - static uint8_t rxbuf[BUF_SIZE]; - memset(rxbuf, 0, BUF_SIZE); // Clear the receive buffer + static uint8_t rxbuf[MAX_BUFFER_SIZE]; + memset(rxbuf, 0, MAX_BUFFER_SIZE); // Clear the receive buffer // Assuming you have a function to initiate SPI read - pio_spi_write8_read8_blocking(spi, rxbuf, BUF_SIZE); // Reads BUF_SIZE bytes into rxbuf + pio_spi_write8_read8_blocking(spi, rxbuf, MAX_BUFFER_SIZE); // Reads BUF_SIZE bytes into rxbuf // Transfer data via USB // Assuming you have a function like sendbytes_usb for this - sendbytes_usb(rxbuf, BUF_SIZE); // You need to implement this function + sendbytes_usb(rxbuf, MAX_BUFFER_SIZE); // You need to implement this function } From 5a5c70340051de1d911b4ef58e12c682f20dc2b5 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:01:10 -0500 Subject: [PATCH 07/18] Correction --- main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 4f51f7d..b3fccf2 100644 --- a/main.c +++ b/main.c @@ -49,14 +49,14 @@ void sendbytes_usb(const uint8_t *buf, size_t len) { void read_spi_and_send_via_usb(const pio_spi_inst_t *spi) { static uint8_t rxbuf[BUF_SIZE]; + static uint8_t dummy_tx_buf[BUF_SIZE] = {0}; // Dummy buffer for transmit memset(rxbuf, 0, BUF_SIZE); // Clear the receive buffer - // Assuming you have a function to initiate SPI read - pio_spi_write8_read8_blocking(spi, rxbuf, BUF_SIZE); // Reads BUF_SIZE bytes into rxbuf + // Perform a dummy write and then read + pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, BUF_SIZE); // Transfer data via USB - // Assuming you have a function like sendbytes_usb for this - sendbytes_usb(rxbuf, BUF_SIZE); // You need to implement this function + sendbytes_usb(rxbuf, BUF_SIZE); } From 69b8069b19397a78123654b615ecd139d64bf29d Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:01:29 -0500 Subject: [PATCH 08/18] Correction --- main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index b3fccf2..e9bdac6 100644 --- a/main.c +++ b/main.c @@ -48,15 +48,15 @@ void sendbytes_usb(const uint8_t *buf, size_t len) { void read_spi_and_send_via_usb(const pio_spi_inst_t *spi) { - static uint8_t rxbuf[BUF_SIZE]; - static uint8_t dummy_tx_buf[BUF_SIZE] = {0}; // Dummy buffer for transmit - memset(rxbuf, 0, BUF_SIZE); // Clear the receive buffer + static uint8_t rxbuf[MAX_BUFFER_SIZE]; + static uint8_t dummy_tx_buf[MAX_BUFFER_SIZE] = {0}; // Dummy buffer for transmit + memset(rxbuf, 0, MAX_BUFFER_SIZE); // Clear the receive buffer // Perform a dummy write and then read - pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, BUF_SIZE); + pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, MAX_BUFFER_SIZE); // Transfer data via USB - sendbytes_usb(rxbuf, BUF_SIZE); + sendbytes_usb(rxbuf, MAX_BUFFER_SIZE); } From d081a25174cf09a4951838ddd8227b47c585ec34 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:03:08 -0500 Subject: [PATCH 09/18] Correction --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 3e24add..dbddd4d 100644 --- a/main.c +++ b/main.c @@ -166,7 +166,7 @@ void handle_spi_op(uint32_t slen, uint32_t rlen) { // Perform PIO SPI operation cs_select(SPI_CS); // Assuming cs_select function is defined - pio_spi_write_read_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function + pio_spi_write8_read_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function cs_deselect(SPI_CS); // Assuming cs_deselect function is defined // Send ACK and received data From f36c056574f218f3f0bff25e985c963b68125368 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:03:27 -0500 Subject: [PATCH 10/18] Correction --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index dbddd4d..c545690 100644 --- a/main.c +++ b/main.c @@ -166,7 +166,7 @@ void handle_spi_op(uint32_t slen, uint32_t rlen) { // Perform PIO SPI operation cs_select(SPI_CS); // Assuming cs_select function is defined - pio_spi_write8_read_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function + pio_spi_write8_read8_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function cs_deselect(SPI_CS); // Assuming cs_deselect function is defined // Send ACK and received data From 24ad55661740c8d914b0be7215f8348ae2b55617 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:05:20 -0500 Subject: [PATCH 11/18] Correction --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index c545690..3e24add 100644 --- a/main.c +++ b/main.c @@ -166,7 +166,7 @@ void handle_spi_op(uint32_t slen, uint32_t rlen) { // Perform PIO SPI operation cs_select(SPI_CS); // Assuming cs_select function is defined - pio_spi_write8_read8_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function + pio_spi_write_read_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function cs_deselect(SPI_CS); // Assuming cs_deselect function is defined // Send ACK and received data From 226a709b1edf49009668e10db62f0dcc4700dd97 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:06:45 -0500 Subject: [PATCH 12/18] Correction --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 3e24add..00d4995 100644 --- a/main.c +++ b/main.c @@ -166,7 +166,7 @@ void handle_spi_op(uint32_t slen, uint32_t rlen) { // Perform PIO SPI operation cs_select(SPI_CS); // Assuming cs_select function is defined - pio_spi_write_read_blocking(tx_buffer, rx_buffer, slen, rlen); // Replace with your PIO SPI function + pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, rlen); cs_deselect(SPI_CS); // Assuming cs_deselect function is defined // Send ACK and received data From cf6de7aeb1443da084677a6479d1c874eff46b2a Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:07:47 -0500 Subject: [PATCH 13/18] Correction --- main.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/main.c b/main.c index 00d4995..c0a2e1f 100644 --- a/main.c +++ b/main.c @@ -155,28 +155,6 @@ static inline void sendbyte_blocking(uint8_t b) } -void handle_spi_op(uint32_t slen, uint32_t rlen) { - uint8_t tx_buffer[MAX_BUFFER_SIZE]; // Buffer for transmit data - uint8_t rx_buffer[MAX_BUFFER_SIZE]; // Buffer for receive data - - // Read data to be sent - if (slen > 0) { - readbytes_blocking(tx_buffer, slen); // Assuming you have this function - } - - // Perform PIO SPI operation - cs_select(SPI_CS); // Assuming cs_select function is defined - pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, rlen); - cs_deselect(SPI_CS); // Assuming cs_deselect function is defined - - // Send ACK and received data - sendbyte_blocking(S_ACK); // Assuming sendbyte_blocking function is defined - if (rlen > 0) { - sendbytes_blocking(rx_buffer, rlen); // Assuming sendbytes_blocking function is defined - } -} - - static void command_loop(void) { uint baud = spi_get_baudrate(SPI_IF); From 9f44f633b1ee79cf0ed853360c5af0472788be98 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:09:32 -0500 Subject: [PATCH 14/18] Correction --- main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index c0a2e1f..406cad5 100644 --- a/main.c +++ b/main.c @@ -47,13 +47,13 @@ void sendbytes_usb(const uint8_t *buf, size_t len) { } -void read_spi_and_send_via_usb(const pio_spi_inst_t *spi) { +void read_spi_and_send_via_usb(const pio_spi_inst_t *spi, const uint32_t rlen) { static uint8_t rxbuf[MAX_BUFFER_SIZE]; static uint8_t dummy_tx_buf[MAX_BUFFER_SIZE] = {0}; // Dummy buffer for transmit memset(rxbuf, 0, MAX_BUFFER_SIZE); // Clear the rx buffer // Perform a dummy write and then read - pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, MAX_BUFFER_SIZE); + pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, rlen); // Transfer data via USB sendbytes_usb(rxbuf, MAX_BUFFER_SIZE); @@ -233,7 +233,7 @@ static void command_loop(void) // Now call the modified function to read from SPI and send via USB // Assuming rlen is the length of data to read and send - read_spi_and_send_via_usb(rlen); + read_spi_and_send_via_usb(SPI_IF, rlen); break; } case S_CMD_S_SPI_FREQ: From 555a6ed15332af7c92eeed839adfc101b90d1c12 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:11:49 -0500 Subject: [PATCH 15/18] Correction --- main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index 406cad5..8982a5a 100644 --- a/main.c +++ b/main.c @@ -233,7 +233,11 @@ static void command_loop(void) // Now call the modified function to read from SPI and send via USB // Assuming rlen is the length of data to read and send - read_spi_and_send_via_usb(SPI_IF, rlen); + pio_spi_inst_t spi = { + .pio = pio0, + .sm = 0 + }; + read_spi_and_send_via_usb(spi, rlen); break; } case S_CMD_S_SPI_FREQ: From e9fc3833c6ed94c76ca197456a3f1d06dece997f Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:13:20 -0500 Subject: [PATCH 16/18] Correction --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 8982a5a..ef21d1f 100644 --- a/main.c +++ b/main.c @@ -237,7 +237,7 @@ static void command_loop(void) .pio = pio0, .sm = 0 }; - read_spi_and_send_via_usb(spi, rlen); + read_spi_and_send_via_usb(&spi, rlen); break; } case S_CMD_S_SPI_FREQ: From bf3ec1c6338ebf88572f9590b440e5127445b2cb Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:29:33 -0500 Subject: [PATCH 17/18] Correction --- main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/main.c b/main.c index ef21d1f..52584b5 100644 --- a/main.c +++ b/main.c @@ -49,15 +49,13 @@ void sendbytes_usb(const uint8_t *buf, size_t len) { void read_spi_and_send_via_usb(const pio_spi_inst_t *spi, const uint32_t rlen) { static uint8_t rxbuf[MAX_BUFFER_SIZE]; - static uint8_t dummy_tx_buf[MAX_BUFFER_SIZE] = {0}; // Dummy buffer for transmit memset(rxbuf, 0, MAX_BUFFER_SIZE); // Clear the rx buffer // Perform a dummy write and then read - pio_spi_write8_read8_blocking(spi, dummy_tx_buf, rxbuf, rlen); + pio_spi_read8_blocking(spi, rxbuf, rlen); // Transfer data via USB sendbytes_usb(rxbuf, MAX_BUFFER_SIZE); - } From 69d5ce0d98b3c5288d351ed5e892f18fb127bcb7 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sat, 23 Dec 2023 16:39:23 -0500 Subject: [PATCH 18/18] Correction --- main.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index 52584b5..9978029 100644 --- a/main.c +++ b/main.c @@ -51,11 +51,17 @@ void read_spi_and_send_via_usb(const pio_spi_inst_t *spi, const uint32_t rlen) { static uint8_t rxbuf[MAX_BUFFER_SIZE]; memset(rxbuf, 0, MAX_BUFFER_SIZE); // Clear the rx buffer - // Perform a dummy write and then read - pio_spi_read8_blocking(spi, rxbuf, rlen); - - // Transfer data via USB - sendbytes_usb(rxbuf, MAX_BUFFER_SIZE); + // Ensure we send rlen bytes + uint32_t remaining = rlen; + while (remaining) { + // Perform a dummy write and then read + uint32_t chunk_size = (remaining < MAX_BUFFER_SIZE) ? remaining : MAX_BUFFER_SIZE; + pio_spi_read8_blocking(spi, rxbuf, chunk_size); + remaining -= chunk_size; + + // Transfer data via USB + sendbytes_usb(rxbuf, chunk_size); + } } @@ -229,6 +235,31 @@ static void command_loop(void) slen &= 0x00FFFFFF; // Mask to use only the lower 24 bits rlen &= 0x00FFFFFF; // Mask to use only the lower 24 bits + uint8_t tx_buffer[MAX_BUFFER_SIZE]; // Buffer for transmit data + uint8_t rx_buffer[MAX_BUFFER_SIZE]; // Buffer for receive data + + // Read data to be sent (if slen > 0) + if (slen > 0) { + readbytes_blocking(tx_buffer, slen); + } + + // Perform SPI operation + cs_select(SPI_CS); + if (slen > 0) { + spi_write_blocking(SPI_IF, tx_buffer, slen); + } + if (rlen > 0 && rlen < MAX_BUFFER_SIZE ) { + spi_read_blocking(SPI_IF, 0, rx_buffer, rlen); + // Send ACK followed by received data + sendbyte_blocking(S_ACK); + if (rlen > 0) { + sendbytes_blocking(rx_buffer, rlen); + } + + cs_deselect(SPI_CS); + break; + } + // Now call the modified function to read from SPI and send via USB // Assuming rlen is the length of data to read and send pio_spi_inst_t spi = {