I've got some PIO code that counts bits in an incoming bit stream; and for every 8 clock transitions; it pushes the count into a FIFO; which then fills up a DMA buffer. Once the buffer is full, an IRQ is called - which then processes the data. Currently this is a simple printf().
I am struggling to 1) re-start the DMA after the read. It hangs. And 2) to run this in the background/non-blocking - I need to call dma_channel_wait_for_finish_blocking().
The full code is at https://github.com/dirkx/pdm-experiment ... receiver.c
I've got it working for sending data DMA-FIFO->Sending works (https://github.com/dirkx/pdm-experiment ... 7/sender.c -- but am struggling to get it to work for receiving.
The pertinent lines of code are:
With the IRQ handler:
This works once if call dma_channel_wait_for_finish_blocking(dma_channel_rx); . How does one restart the FIFO/DMA process at this point - and how do you initially start it fully in the background. dma_channel_start() does not seem to be right.
Any and all suggestions appreciated. As to the context - it is a Pulse Density Microphone simulator (Sender) and a a receiver.
I am struggling to 1) re-start the DMA after the read. It hangs. And 2) to run this in the background/non-blocking - I need to call dma_channel_wait_for_finish_blocking().
The full code is at https://github.com/dirkx/pdm-experiment ... receiver.c
I've got it working for sending data DMA-FIFO->Sending works (https://github.com/dirkx/pdm-experiment ... 7/sender.c -- but am struggling to get it to work for receiving.
The pertinent lines of code are:
Code:
uint32_t buffer_rx[32] __attribute__((aligned(256)));void init_pdm_receiver(int pin_dat, int pin_clk, uint64_t sampleBitRate) { pio = pio1; offset = pio_add_program(pio, &receiver_program); sm = pio_claim_unused_sm(pio, true); receiver_program_init(pio, sm, offset, pin_dat, pin_clk, sampleBitRate); irq_add_shared_handler(dma_get_irq_num(DMA_IRQ_TO_USE), dma_irq_handler, DMA_IRQ_PRIORITY); irq_set_enabled(dma_get_irq_num(DMA_IRQ_TO_USE), true); dma_channel_config config_rx; dma_channel_rx = dma_claim_unused_channel(true); config_rx = dma_channel_get_default_config(dma_channel_rx); channel_config_set_transfer_data_size(&config_rx, DMA_SIZE_32); channel_config_set_read_increment(&config_rx, false); // do not increment; FIFO channel_config_set_write_increment(&config_rx, true); // Wire DMA to FIFO channel_config_set_dreq(&config_rx, pio_get_dreq(pio, sm, false /* is rx */)); dma_channel_configure(dma_channel_rx, &config_rx, buffer_rx, // write addr(io_rw_8*)&pio->rxf[sm], // read addrsizeof(buffer_rx) / sizeof(*buffer_rx), // -- number of transactionstrue // dma started ); if (0 /* does not make a difference*) channel_config_set_ring( &config_rx, true, // Apply to write addresses. 7 // bits for wrap around; buffer is 256 bytes; 32 transfer ); dma_irqn_set_channel_enabled(DMA_IRQ_TO_USE, dma_channel_rx, true); pio_sm_set_enabled(pio, sm, true);}Code:
static void dma_irq_handler() { dma_irqn_acknowledge_channel(DMA_IRQ_TO_USE, dma_channel_rx); printf("dma_rx complete\n"); // Reset DMA process for next block from PIO FIFO // dma_channel_set_write_addr(dma_channel_rx,buffer_rx,true); dma_channel_hw_addr(dma_channel_rx)->al2_write_addr_trig = (uintptr_t) buffer_rx;}Any and all suggestions appreciated. As to the context - it is a Pulse Density Microphone simulator (Sender) and a a receiver.
Statistics: Posted by dirkx — Sat Sep 13, 2025 10:34 pm