I´m operating with a Master SPI device, that sends Serial Data via SPI, but there is no ChipSelect / SlaveSelect available. The input Data has to go to the PC Com Port. My idea was to work with either DMA or SPI interrupts, because the data words are always 16 bits long. I could not get the SPI interrupts working without a chip select, because it seems to look like that the SPI interrupts are getting triggerd by the CS signal. So I tried to rout the SPI receive register to the DMA input register and get an interrupt after every 16 bits / when the DMA register is filled up. For some reason the DMA interrupt is getting triggerd permanently, even when my SPI input is not connected. I guess the routing did not work properly or for some reason the DMA Fifo is full all the time. I´m working on a Raspberry Pi Pico and writing in C. Any ideas or suggestions? When I run the Code i´m getting

Interrupt 0000

printed on the console in max. Speed of the Raspberry - as if I had dma_handler() in the void loop.

This is the code:

    *#include "pico/stdlib.h"
    #include "hardware/spi.h"
    #include "hardware/dma.h"
    #define BUF_LEN         2
    uint16_t spi1out_buf[BUF_LEN];
    int chan = dma_claim_unused_channel(true);
    dma_channel_config c = dma_channel_get_default_config(chan);
    int i = 0;
    void setup() {
        //SPI Init
        gpio_set_function(12, GPIO_FUNC_SPI);
        gpio_set_function(13, GPIO_FUNC_SPI);
        gpio_set_function(14, GPIO_FUNC_SPI);
        spi_init(spi1, 1000 * 1000);
        spi_set_slave(spi1, 1);
        spi_get_hw(spi1)->dmacr = SPI_SSPDMACR_RXDMAE_BITS;
        //DMA init
        channel_config_set_transfer_data_size(&c, DMA_SIZE_16);
        channel_config_set_dreq(&c, spi_get_dreq(spi1, true));
        channel_config_set_read_increment(&c, true);
        channel_config_set_write_increment(&c, false);  
        dma_channel_configure(chan,&c,spi1out_buf, NULL,BUF_LEN, false);
        dma_channel_set_irq0_enabled(chan, true);
        irq_set_exclusive_handler(DMA_IRQ_0, dma_handler);
        irq_set_enabled(DMA_IRQ_0, true);
        dma_start_channel_mask(1u << chan);    

    // Interrupt handler

    void dma_handler(){      
        dma_hw->ints0 = 1u << chan;
        dma_channel_set_read_addr(chan, &spi_get_hw(spi1)->dr, true);

    // MAIN Loop

    void loop() {


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.