Open FayCarsons opened 2 months ago
I see two issues with your code:
rp_pico::pac::NVIC::unmask(rp_pico::pac::Interrupt::DMA_IRQ_0)
only unmasks them in the NVIC, but that doesn't help if the DMA peripheral doesn't generate interrupts in the first place. Something like dma.ch0.enable_irq0(); dma.ch1.enable_irq0();
could help.@jannic thank you so much for taking a look at this!
So, if the interrupt is triggered the transfer is done? The busy loop was an attempt at being sure of that. In general, it's confusing what's necessary to re-enqueue the buffers once the transfer is complete, the doc comments of is_done
and wait
lead me to believe either they aren't actually necessary inside the interrupt, or the interrupt being triggered does not necessarily mean the transfer is complete.
Do both channels need interrupts enabled? With the way the configuration works, my assumption was that the transfer would be the thing to enable an interrupt for, not the channels. Should I maybe be using the lower-level DMA API here? It feels like this higher-level API is maybe not what I want
Sorry, I don't have a complete example available, and don't know the DMA interrupts well enough to quickly write one. As a rough sketch, I'd try something like this (pseudocode):
fn interrupt_handler() {
if check_irq0() && transfer.is_done() {
[your processing here]
}
}
check_irq0()
checks if the dma interrupt is pending, and if so, clears it.
Then, transfer.is_done()
is checked. If the transfer is not yet done (which would mean that the interrupt was triggered by something else - should not happen, but who knows?) the handler just returns. Note that there is no loop involved: If the DMA finishes after check_irq0()
was called, the interrupt is triggered again and the handler will be called once more.
And yes, both channels need interrupts enabled, because they will be used alternately by the double buffering transfer.
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:
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!!!!!