Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
21 years ago

DMA transfert inside interrupt routine

Hi,

with a NIOSII and uCosII system, I'm trying to implement a DMA memory to memory transfert inside a interrupt routine (as described below).

However the DMA transfert never finishs, due to the fact that the IRQ related to DMA controller never rises.

Question:

Do all the interrupts be disable when entering in a interrupt routine ?

If yes, how to manage such a DMA transfert very quickly (I have to transfert the data before to acknoledge the IT) ?

If no, what's wrong with my code ?

Thanks in advance for your help.

Gaël

===================================

static void DmaDoneCallBack(void *handle, void *data)

{

DmaDone = 1;

}

/* alt_avalon_my_irq: The Interrupt handler */

static void alt_avalon_my_irq(void* context, alt_u32 interrupt)

{

/* set up and kick the DMA */

DmaDone = 0;

alt_dma_txchan_send (dev->dma_tx, (void *)src, len, NULL, NULL);

alt_dma_rxchan_prepare (dev->dma_rx, (void *)dest, len, DmaDoneCallBack, NULL);

while( !DmaDone ) ;

}

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes, all interrupts are disabled (by default) when you are in an interrupt routine. You can reenable higher priority interrupts but it isn't usually a good idea.

    The usual way to do this would be to start the DMA transfer from one interrupt and finish it from another interrupt (the DMA completion routine).

    So if you aren&#39;t able to acknowledge the interrupt before you have transferred the data then you have two options: a) redesign the hardware so that you are able to acknowledge the interrupt before you have transferred the data or http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/cool.gif disable the interrupt from your interrupt routine and reenable it from the DMA completion function (which, as you know, runs from the DMA controllers interrupt routine).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi there,

    I&#39;ve used interrupt driven DMAs in my uCOS application, however to get around the problem of the hardware finishing the DMA whilst i&#39;m still servicing the previous interrupt I normally use a uCOS semaphore. That way you set the DMA running in a normal piece of code (i.e. a task), and then when it completes call the dmaDone function which sets the semaphore. This frees the held task which handles servicing the DMA and starting a new DMA.

    Obviously your latency is higher in this case but probably won&#39;t be a problem since you are using uCOS and your latency is going to be a bit higher anwyways.

    Regards,

    .....