Why is DMA_IRQHandler() called, but no DMA-related IRQ appears to be active?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why is DMA_IRQHandler() called, but no DMA-related IRQ appears to be active?

1,390 Views
g_mocken
Contributor I

I am using the GPDMA for SPI tranfers on a LPC-4078, closely following the provided sample code.

My application is basically working, but I noticed that the DMA_IRQHandler() is called more often than it should be.

In fact, LPC_GPDMA->INTSTAT and all similar registers are zero at the very beginning of the IRQ handler, but it is still called.

How is that possible? How can I find out what triggers the call to the DMA_IRQHandler() if it is not an IRQ of the DMA unit?

Labels (3)
Tags (2)
0 Kudos
2 Replies

785 Views
g_mocken
Contributor I

I might have found the answer myself. Following the SSP sample code, I used something like:

void DMA_IRQHandler(void){
   if (Chip_GPDMA_Interrupt(LPC_GPDMA, dmaChSSPTx) == SUCCESS) {
      isDmaTxfCompleted = 1;
   }

   if (Chip_GPDMA_Interrupt(LPC_GPDMA, dmaChSSPRx) == SUCCESS) {
      isDmaRxfCompleted = 1;
   }

   // more code ...
}

Apparently, if both IRQ are triggered at almost the same time, then the handler is still called twice.

Because the handler checks and resets both flags during its first execution, when it is called for the second time, no IRQ source is active anymore.  The following code eliminates the problem:

void DMA_IRQHandler(void){

   bool cleared = false;

   // more code ...

   if (!cleared && (Chip_GPDMA_Interrupt(LPC_GPDMA, dmaChSSPTx) == SUCCESS)) {

      isDmaTxfCompleted = 1;
      cleared = true;
   }

   if (!cleared && (Chip_GPDMA_Interrupt(LPC_GPDMA, dmaChSSPRx) == SUCCESS)) {
      isDmaRxfCompleted = 1;
      cleared = true;
   }

   // more code ...

}

Please note that in the example shown, it does not matter, but for my actual, much more complicated handler (shared between multiple DMA IRQ sources), it does complicate debugging significantly, if IRQs occur that cannot be accounted for.

It would be nice if somebody could confirm this particular behavior (i.e. storing and queueing of multiple IRQs that go to the same NVIC interrupt), which I did neither expect nor find documented anywhere.

0 Kudos

785 Views
isaacavila
NXP Employee
NXP Employee

Hello Guido,

Probably you are seeing a tail-chainning exception for DMA IRQ vector. NVIC describes Tail-chaining as:

This mechanism speeds up exception servicing. On completion of an
exception handler, if there is a pending exception that meets the
requirements for exception entry, the stack pop is skipped and control
transfers to the new exception handler.

In this case, the new exception handler is the same handler that has been completed before (due both dma channels uses same handler).

This information is available on http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/DUI0553A_cortex_m4_dgug.pdf 

I hope this helps!

Regards,

Isaac

0 Kudos