Skip to content

Unsure how to enable DMA interrupts #852

Open
@FayCarsons

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!!!!!

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions