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

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

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

1,411 次查看
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?

标签 (3)
标记 (2)
0 项奖励
2 回复数

806 次查看
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 项奖励

806 次查看
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 项奖励