Hello,
I have discovered a very peculiar bug affecting DMA combined with
interrupts on C5505 DSP, which I will try to describe below:
- In the current case I am using only one interrupt for DMA channel 0,
all other DMA interrupts are disabled.
When a DMA block transfer is complete from an I2S device into internal
memory, the DMA triggers an interrupt
to the CPU.
As you are aware of, the interrupts from the four DMA controllers are
combined into a single CPU interrupt.
In order to determine which DMA channel generated the interrupt, the ISR
(interrupt service routine) reads the bits
of the DMA interrupt flag register (DMAIFR). The ISR needs to clear the
set bits manually by writing 1 ot them.
The DMAIFR contains 16 flag bits for DMA channel 0 to DMA channel A15.
In the normal situation, I expect to read 0x0001 in the DMAIFR (as our
only interrupt enabled channel is DMA channel 0).
However, in a very seldom situation (can happen after several hours), I
read 0x0000 in the DMAIFR:
which means that the global DMA interrupt is triggered to the CPU, but
when the ISR looks for the DMA channel
responsible for triggering the DMA, it finds none, and therefore the ISR
does not process the interrupt as it should.
Have you heard if such a bug/behaviour? Can you please forward this
e-mail to support? If you need any extra information,
I can provide this as well.
DSP type: C5505 BIOS version: version 5.41.10.36
Here is a copy of the ISR code used with the HWI dispatcher of DSP/BIOS:
/*** Interrupt Service Routines ***/
void dmaISR(void)
{
Uint16 dmaIfrReg;
/* Read DMAIFR regsiter - Determine the source of the interrupt */
dmaIfrReg = CSL_SYSCTRL_REGS->DMAIFR;
/* If DMA0 Ch.0 -> ADC interrupt */
if ((dmaIfrReg & 0x0001) == 0x0001)
{
hwiAdcDmaRcv(); /* Handle ADC interrupt */
CSL_SYSCTRL_REGS->DMAIFR |= 0x0001; /* Clear the interrupt bit in DMAIFR */
}
else
{
/* This should never happen as only DMA Channel 0 is interrupt enabled */
sendDebug(DBG_ERROR|DEBUG_ID_008, (int32_t) dmaIfrReg, 0);
}
}
Regards,
Cyrille