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

Troubleshooting • RP2040 SPI/DMA Line Busy

$
0
0
Hello.

I am working on a project that requires reading from an external ADC via SPI. To save on computing cost, I would like to go down the DMA route. I've looked at several examples on interfacing DMA with SPI. However, I haven't had any success implementing my own code. I am experiencing a problem where the DMA channel is always busy. Not only that, but I do not see any clock signals out of the SCK pin. My main function looks a lot like the code below...minus the commented out section which I excluded for this post.

Code:

   // Setup Inits  stdio_init_all();  // Initialize SPI  spi_init(SPI_PORT, 1000000); // Set channel and baud rate  spi_set_format(SPI_PORT, 16, SPI_CPOL_0, SPI_CPHA_0,                 SPI_LSB_FIRST);              // Format channel  gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); // Map GPIO  gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);  gpio_init(PIN_CS);  bi_decl(bi_2pins_with_func(PIN_MISO, PIN_SCK, GPIO_FUNC_SPI));  gpio_set_dir(PIN_CS, GPIO_OUT);  gpio_put(PIN_CS, 1);  bi_decl(bi_1pin_with_name(PIN_CS, "SPI CS"));     // Channel Configs  dma_channel_config c_rx = dma_channel_get_default_config(sample_chan);  dma_channel_config c_ctrl = dma_channel_get_default_config(ctrl_chan);  // Set up ADC sample channel  channel_config_set_transfer_data_size(      &c_rx,      DMA_SIZE_16); // SPI ADC data transfer is 16 bits.  channel_config_set_read_increment(      &c_rx, false); // We are always reading from SPI receive buffer.  channel_config_set_write_increment(      &c_rx, true); // Increment write address as we are writing to a buffer.  channel_config_set_dreq(      &c_rx,      spi_get_dreq(SPI_PORT, false)); // Pull data when its ready from the ADC.  channel_config_set_chain_to(&c_rx, ctrl_chan); // Chain to sample chan  dma_channel_configure(sample_chan, &c_rx, sample_data,                        &spi_get_hw(SPI_PORT)->dr, NUM_SAMPLES, false);  // Set up control channel  channel_config_set_transfer_data_size(&c_ctrl,                                        DMA_SIZE_32); // DMA comm bits is 32  channel_config_set_read_increment(      &c_ctrl, false); // Always read from the same register  channel_config_set_write_increment(      &c_ctrl, false); // Always write to the same register  channel_config_set_chain_to(&c_ctrl, sample_chan); // Chain to sample chan  dma_channel_configure(ctrl_chan, &c_ctrl, &dma_hw->ch[sample_chan].write_addr,                        &sample_address_pointer, 1, false);  dma_start_channel_mask(1u << ctrl_chan);  while (dma_channel_is_busy(ctrl_chan)) {      __breakpoint();  }  while (dma_channel_is_busy(sample_chan)) {    __breakpoint();  }
Where:

Code:

// SPI/DMA definitions#define PIN_MISO 20#define PIN_CS 1#define PIN_SCK 18#define SPI_PORT spi0#define NUM_SAMPLES 9const uint16_t sample_chan = 0;const uint16_t ctrl_chan = 1;uint16_t sample_data[9];uint16_t *sample_address_pointer = &sample_data[0];uint16_t n = sizeof(sample_data) / sizeof(sample_data[0]);
Basically what I want to do is have the DMA fill out a 9 element data array. I managed to get a similar code working for the internal ADC, but that doesn't involve SPI. Does anyone have any ideas as to what could be the issue?

Thank you.

Statistics: Posted by Tominator-LMG — Thu Nov 14, 2024 12:49 am — Replies 0 — Views 36



Viewing all articles
Browse latest Browse all 4474

Trending Articles