This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Problem with DMA interrupt in PingPong mode

I am reading adc data using DMA in PingPong mode. The issue is that UDMAChannelModeGet() function is not returning UDMA_MODE_STOP for both PRI_SELECT and ALT_SELECT. Thus in effect the buffer in which adc data is obtained is unidentifiable.

Would be very pleased for any hints or help. Thanks in advance

The code I used is

void DMAInterruptHandler_CH1(void)
{
    unsigned long ulStatus;
    unsigned long ulMode, ulChannelStructIndex, ulControl;
    tDMAControlTable *pControlTable;
    int validInterrupt = false;

    ulStatus = ADCIntStatus(ADC_BASE, ADC_CH_1);
    ADCIntClear(ADC_BASE, ADC_CH_1, ulStatus|ADC_DMA_DONE);

    ulMode = MAP_uDMAChannelModeGet(UDMA_CH15_ADC_CH1 | UDMA_PRI_SELECT);
    if (ulMode == UDMA_MODE_STOP)
    {
        LoadADCData(0);

        ulChannelStructIndex = UDMA_CH15_ADC_CH1 | UDMA_PRI_SELECT;
        ulChannelStructIndex &= 0x3f;
        pControlTable = uDMAControlBaseGet();
        ulControl = (pControlTable[ulChannelStructIndex].ulControl &
                ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
        ulControl |= UDMA_MODE_PINGPONG | ((DMA_ITEM_NUM - 1) << 4);
        uDMAChannelControlSet(ulChannelStructIndex,ulControl);

        if (g_iPacketReceived >= TOTAL_PACKETS)
            ADCDMADisable(ADC_BASE, ADC_CH_1);
    }
    ulMode = MAP_uDMAChannelModeGet(UDMA_CH15_ADC_CH1 | UDMA_ALT_SELECT);
    if (ulMode == UDMA_MODE_STOP)
    {
        LoadADCData(1);
        
        ulChannelStructIndex = UDMA_CH15_ADC_CH1 | UDMA_ALT_SELECT;
        ulChannelStructIndex &= 0x3f;
        pControlTable = uDMAControlBaseGet();
        ulControl = (pControlTable[ulChannelStructIndex].ulControl &
                ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));
        ulControl |= UDMA_MODE_PINGPONG | ((DMA_ITEM_NUM - 1) << 4);
        uDMAChannelControlSet(ulChannelStructIndex,ulControl);

        if (g_iPacketReceived_CH1 >= TOTAL_PACKETS)
            ADCDMADisable(ADC_BASE, ADC_CH_1);
    }

}

  • Nidhin,

    Few Qs:
    - Why bit ADC_DMA_DONE ORed at line 'ADCIntClear(ADC_BASE, ADC_CH_1, ulStatus|ADC_DMA_DONE)'?
    - Do you have other interrupts enabled? If yes, most likely the interrupt has occurred 'coz of that and not a DMA completion.

    Can you please share the complete code for review?

    -/Praneet
  • Praneet,

    I was using the code from thread e2e.ti.com/.../408687.
    ADCIntClear(ADC_BASE, ADC_CH_1, ulStatus|ADC_DMA_DONE) was used there.

    I set up ADC_CH1 and ADC_CH2 likewise.

    Also I have SysTick interrupt enabled. Will it affect DMA interrupts?