Description
I'm working on a library (my first serious embedded project) which needs to write to a PIO FIFO continuously. I'm trying to do this with DMA, using an interrupt to re-enqueue the buffers whenever a write finishes, but I'm unsure how to enable an interrupt for a double-buffered DMA transfer in the way I would with, say, a, ADC or PWM. The documentation is a bit confusing and from what I understand some features it mentions are maybe not actually implemented?
I'm initializing DMA like this:
let transfer = unsafe {
double_buffer::Config::new((dma.ch0, dma.ch1), &mut BITSTREAM, tx)
.start()
.read_next(&mut TX_BUF)
};
unsafe {
TRANSFER_HANDLER = Some(transfer);
BUFFERS = Some((bitstream, tx_buf));
rp_pico::pac::NVIC::unmask(rp_pico::pac::Interrupt::DMA_IRQ_0);
}
/* unrelated code ... */
#[hal::pac::interrupt]
unsafe fn DMA_IRQ_0() {
if let Some((transfer, bufs)) = TRANSFER_HANDLER.take().zip(BUFFERS.take()) {
loop {
if transfer.is_done() {
let (tx_buf, next) = transfer.wait();
let transfer = next.read_next(tx_buf);
let bufs = (bufs.1, bufs.0);
TRANSFER_HANDLER = Some(transfer);
BUFFERS = Some(bufs);
break;
}
}
}
}
With the buffers (BITSTREAM and TX_BUF) being [u32; N]
and 'tx' being the PIO FIFO.
Do you think this should work as is? Is there something I'm missing? Here's the repo for context: https://github.com/FayCarsons/cosmic-unicorn-rs, the file in question is src/cosmic_unicorn.rs
Any help at all would be deeply appreciated!!!!!