Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 7503

General • SPI master CSN question

$
0
0
Hello all

// Example of an SPI bus master using the PL022 SPI interface
// Modified to toggle CS manually for interrupt-driven SPI slave

Code:

#include <stdio.h>#include "pico/stdlib.h"#include "pico/binary_info.h"#include "hardware/spi.h"#define BUF_LEN         0x100#define PICO_DEFAULT_SPI_RX_PIN 0   // MOSI from master → receive on slave#define PICO_DEFAULT_SPI_SCK_PIN 2  // SPI clock#define PICO_DEFAULT_SPI_TX_PIN 3   // MISO to master#define PICO_DEFAULT_SPI_CSN_PIN 1  // Chip select (manual toggle)#define BAUD_RATE 115200int main() {    // Enable UART for printing    stdio_init_all();#if !defined(spi_default) || !defined(PICO_DEFAULT_SPI_SCK_PIN) || \    !defined(PICO_DEFAULT_SPI_TX_PIN) || !defined(PICO_DEFAULT_SPI_RX_PIN) || \    !defined(PICO_DEFAULT_SPI_CSN_PIN)#warning spi/spi_master example requires a board with SPI pins    puts("Default SPI pins were not defined");#else    // Enable SPI0 at 1 MHz and connect pins    spi_init(spi_default, 1000 * 1000); // 1 MHz    gpio_set_function(PICO_DEFAULT_SPI_RX_PIN, GPIO_FUNC_SPI);    gpio_set_function(PICO_DEFAULT_SPI_SCK_PIN, GPIO_FUNC_SPI);    gpio_set_function(PICO_DEFAULT_SPI_TX_PIN, GPIO_FUNC_SPI);    // CSN manually controlled    gpio_set_function(PICO_DEFAULT_SPI_CSN_PIN, GPIO_FUNC_SIO);    gpio_set_dir(PICO_DEFAULT_SPI_CSN_PIN, true);    gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 1); // idle high    // Make pins available to picotool    bi_decl(bi_4pins_with_func(PICO_DEFAULT_SPI_RX_PIN,                                PICO_DEFAULT_SPI_TX_PIN,                                PICO_DEFAULT_SPI_SCK_PIN,                                PICO_DEFAULT_SPI_CSN_PIN, GPIO_FUNC_SPI));    uint8_t out_buf[BUF_LEN], in_buf[BUF_LEN];    // Initialize output buffer    for (size_t i = 0; i < BUF_LEN; ++i) {        out_buf[i] = i;        in_buf[i] = 0;    }    while (1) {        // Pull CS low to start transfer        gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 0);        // SPI transfer (write & read)        spi_write_read_blocking(spi_default, out_buf, in_buf, BUF_LEN);        // Pull CS high to end transfer        gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 1);        // Optional: print received data (for debugging)        // for (size_t i = 0; i < BUF_LEN; ++i) {        //     printf("%02X ", in_buf[i]);        // }        // printf("\n");        sleep_ms(10); // optional delay between packets    }#endif}

I have modified the code to work with the SPI slave interrupt, and this is my trace in Logic Analyser

My question is to do with the CSN. Does it have to toggle for the spi interrupt to pick it up, or does it have to just go down and then goes up whe the data has been transmitted.

Code:

bool spi_irq_setup_init(void){    irq_set_enabled(SPI0_IRQ, false);    irq_set_exclusive_handler(SPI0_IRQ, irq_handler);    irq_set_priority(SPI0_IRQ, 0);    // Disable SPI before touching interrupt mask    // Clear any pending interrupts    hw_clear_bits(&spi_get_hw(spi0)->icr, SPI_SSPICR_RTIC_BITS| SPI_SSPICR_RORIC_BITS);    hw_clear_bits(&spi_get_hw(spi0)->imsc, SPI_SSPIMSC_BITS);    // Enable desired interrupt sources    hw_set_bits(&spi_get_hw(spi0)->imsc,                SPI_SSPIMSC_RTIM_BITS |                SPI_SSPIMSC_RXIM_BITS);    irq_set_enabled(SPI0_IRQ, true);    return irq_is_enabled(SPI0_IRQ);}
The above is my irq setup.

Any help would be appreciated.
Kind regards
spi_data_dump.png

Statistics: Posted by Maaz1 — Wed Feb 11, 2026 1:33 pm — Replies 0 — Views 33



Viewing all articles
Browse latest Browse all 7503

Trending Articles