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

SDK • External ADC via SPI and DMA

$
0
0
Hello everyone,

I've been trying to make readings from an external ADC (SPI, 16bit) with continuous sampling using DMA.

Here is my approach in a nutshell.

Configure SPI/DMA:

Code:

spi_init(spi0, 1000000); // Init SPI at 1 MHz                                                                                                            gpio_set_function(SPI_RX_PIN, GPIO_FUNC_SPI);gpio_set_function(SPI_SCK_PIN, GPIO_FUNC_SPI);gpio_set_function(SPI_TX_PIN, GPIO_FUNC_SPI);bi_decl(bi_3pins_with_func(SPI_RX_PIN, SPI_TX_PIN, SPI_SCK_PIN, GPIO_FUNC_SPI));gpio_init(SPI_CS_PIN);gpio_set_dir(SPI_CS_PIN, GPIO_OUT);gpio_put(SPI_CS_PIN, 1); // Disable                                                                                                                      bi_decl(bi_1pin_with_name(SPI_CS_PIN, "SPI CS"));dma_tx = dma_claim_unused_channel(true);dma_rx = dma_claim_unused_channel(true);dma_channel_config_tx = dma_channel_get_default_config(dma_tx);channel_config_set_transfer_data_size(&dma_channel_config_tx, DMA_SIZE_16);channel_config_set_dreq(&dma_channel_config_tx, DREQ_SPI0_TX);channel_config_set_read_increment(&dma_channel_config_tx, true);channel_config_set_write_increment(&dma_channel_config_tx, false);dma_channel_config_rx = dma_channel_get_default_config(dma_rx);channel_config_set_transfer_data_size(&dma_channel_config_rx, DMA_SIZE_16);channel_config_set_dreq(&dma_channel_config_rx, DREQ_SPI0_RX);channel_config_set_read_increment(&dma_channel_config_rx, false);channel_config_set_write_increment(&dma_channel_config_rx, true);dma_channel_set_irq1_enabled(dma_rx, true);irq_set_exclusive_handler(DMA_IRQ_1, dma_handler_rx);irq_set_enabled(DMA_IRQ_1, true);
Start the acquisition for 10 consecutive measurements:

Code:

dma_channel_configure(dma_rx,                        &dma_channel_config_rx,                        capture_rxbuf16,                        &spi_get_hw(spi0)->dr,                        10,                        false);dma_channel_configure(dma_tx,                        &dma_channel_config_tx,                        &spi_get_hw(spi0)->dr,                        capture_txbuf16,                        10,                        false);  gpio_put(SPI_CS_PIN, 0); // Enable                                                                                                                         dma_start_channel_mask((1u << dma_tx) | (1u << dma_rx));  dma_channel_wait_for_finish_blocking(dma_rx);  if (dma_channel_is_busy(dma_tx)) {    panic("RX completed before TX");  }
With the following interrupt:

Code:

void dma_handler_rx() {  imeas += 1;  gpio_put(SPI_CS_PIN, 0); // Enable                                                                                                                         gpio_put(SPI_CS_PIN, 1); // Disable                                                                                                                        if( imeas == 10 ) {    dma_hw->ints1 = 1u << dma_rx; // Clear interrupt                                                                                                           imeas = 0;  }}
Does anyone see any fault in my logic?

Many thanks in advance!

Statistics: Posted by hallok — Thu Dec 25, 2025 2:06 pm



Viewing all articles
Browse latest Browse all 9497

Trending Articles