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:
Start the acquisition for 10 consecutive measurements:
With the following interrupt:
Does anyone see any fault in my logic?
Many thanks in advance!
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);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"); }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; }}Many thanks in advance!
Statistics: Posted by hallok — Thu Dec 25, 2025 2:06 pm