Hi Wen Tang.
It appears to be occurring as a result of a race condition.
The error handler will get invoked as a result of a DMA request being activated before the DMA can service the previous request. With the DMA reading from a FIFO, this does not cause a loss of data, but does cause the DMA interrupt.
I believe that the following was happening. The second DMA request occurred and caused the error interrupt to be pending. Before the error ISR is run, the DMA is given a new buffer and started. The error condition is gone, but the interrupt is still pending.
There isn't a way around the race other than to redo the DMA buffer setup such that it never runs out of space. Rather, the solution was to accept this condition and clear up the interrupt properly. In dma_ccerr_handler(), that means writing to EEVAL and indicating that the interrupt was handled:
if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
(edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
(edma_read(ctlr, EDMA_QEMR) == 0) &&
(edma_read(ctlr, EDMA_CCERR) == 0))
{
edma_write(ctlr, EDMA_EEVAL, 1);
return IRQ_HANDLED;
}
Regards,
Steve