Bug: DMA interrupt callbacks in Scatter/Gather array not registered

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

Bug: DMA interrupt callbacks in Scatter/Gather array not registered

271 Views
abemat
Contributor III

For DMA (tested for Scatter/Gather) when setting the Enable Major Interrupt for the last element of a S/G Array (where the array is configured to be repeatedly called to trigger the same sequence of SGA DMA transfers), the interrupt function specified is not reached. It does not work, since the interrupt handler function IrqHandler first checks if an interrupt is enabled for the currently configured channel:

if(0U != ChIntEnable) { … }

However, if the SGA array is set up in a way where it does not stop at the channel where the interrupt was requested, the interrupt handler will not call the user requested interrupt handler. This happens since a new TCD is loaded before the interrupt handler can check if the current channel has an interrupt enabled. This seems wrong to me. If an interrupt request has happened and no error has occurred, I think we should fallback to always calling the user specified interrupt handler.

For us specifically, we have configured it the following way:

Element index

Enable Start

Enable Major Interrupt

Last Element of the Link

Element Link

0

0

0

0

1

1

1

0

0

2

2

1

1

0

0

 

We configured this in this way so that repeatedly calling it triggers the same sequence of DMA transfers. With this setup, no major interrupts are handled by the user specified handler, since the TCD reloads element 0 before the interrupt request generated by element 2 is handled.

A workaround would be to enable the major interrupt for element 0 as well, but that does not seem proper. Instead I propose to change the IrqHandler to (with changed bits in bold):

static void IrqHandler(const uint32 LocHwVers, const uint32 LocHwInst, const uint32 LocHwCh)
{
    uint32 ChIntStatus = (uint32)(DMA_IP_HWV3_TCD_CH_VALUE(LocHwInst, LocHwCh).reg_CH_INT & DMA_IP_TCD_CH_INT_INT_MASK);
    uint32 ChErrStatus = (uint32)(DMA_IP_HWV3_TCD_CH_VALUE(LocHwInst, LocHwCh).reg_CH_ES & DMA_IP_TCD_CH_ES_ERR_MASK);
    uint32 ChIntEnable = (uint32)(DMA_IP_HWV3_TCD_TCD_VALUE(LocHwInst, LocHwCh).reg_CSR & ((uint32)DMA_IP_TCD_CSR_INTMAJOR_MASK | (uint32)DMA_IP_TCD_CSR_INTHALF_MASK));
    uint32 ChErrEnable = (uint32)(DMA_IP_HWV3_TCD_CH_VALUE(LocHwInst, LocHwCh).reg_CH_CSR & DMA_IP_TCD_CH_CSR_EEI_MASK);

if(0U != ChErrStatus)
    {
if(0U != ChErrEnable)
        {
Dma_Ip_ErrorIrqHandler(LocHwVers, LocHwInst, LocHwCh);
        }
/* The event status flag is cleared after execution of the irq handler sue to requirement exception. */
DMA_IP_HWV3_TCD_CH_VALUE(LocHwInst, LocHwCh).reg_CH_ES = DMA_IP_TCD_CH_ES_ERR_MASK;
    }
else if(0U != ChIntStatus)
    {
DMA_IP_HWV3_TCD_CH_VALUE(LocHwInst, LocHwCh).reg_CH_INT = DMA_IP_TCD_CH_INT_INT_MASK;
if(0U!= ChIntEnable)
        {
Dma_Ip_IntIrqHandler(LocHwVers, LocHwInst, LocHwCh);
        }
    }
}
So how do I report this bug to NXP directly?
0 Kudos
0 Replies