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.

TM4C1294NCPDT: ADC DMA issue

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Hi,

I want to use multiple channels of ADC with DMA in ping-pong mode, as my app requires multiple analog signal monitoring, and for that case DMA is necessity, I configured ADC and DMA both but, in ISR it stuck in udmatrasferset() function.  is there any issue in configuration please help,

Regards,

Sandeep Kore

below is my code

#include <stdbool.h>
#include <stdint.h>

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "inc/hw_types.h"
#include "inc/hw_udma.h"
#include "inc/hw_emac.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/emac.h"
//#define TARGET_IS_BLIZZARD_RB1
#include "driverlib/rom.h"
#define ADC_SAMPLE_BUF_SIZE (128)

uint32_t udmaCtrlTable[1024] __attribute__ ((aligned(1024)));
uint32_t ADC_OUT_1[8],ADC_OUT_2[8];
static uint32_t g_ui32RxBufACount = 0;
static uint32_t g_ui32RxBufBCount = 0;
enum BUFFER_STATUS
{
    EMPTY,
    FILLING,
    FULL
};
  uint32_t pui32ADC0Value[8];
 // static enum BUFFER_STATUS pui32BufferStatus[2];
  bool bufCtr=0;
  static uint32_t g_ui32uDMAErrCount = 0;

  void uDMAErrorHandler(void)
  {
      uint32_t ui32Status;

      ui32Status = uDMAErrorStatusGet();

      if(ui32Status)
      {
          uDMAErrorStatusClear();
          g_ui32uDMAErrCount++;
      }
  }

  void
  UART0IntHandler(void)
  {
      uint32_t ui32Mode;

      ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT);

      if(ui32Mode == UDMA_MODE_STOP)
      {
          g_ui32RxBufACount++;

          uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1, 8);

      }

      ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT);

      if(ui32Mode == UDMA_MODE_STOP)
      {
          g_ui32RxBufBCount++;

          uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADC_OUT_2,8);
      }

      if(uDMAChannelIsEnabled(UDMA_CHANNEL_ADC0))
      {
          uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_BASIC,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1,8);

          uDMAChannelEnable(UDMA_CHANNEL_ADC0);
      }
  }
  void ADCSeq0Handler(void)
  {
      //
      // Clear the Interrupt Flag.
      //
     // ADCIntClear(ADC0_BASE, 0);
      uint32_t ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0);
      if( ui32Mode == 4)
      {
          bufCtr = 1;
          uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1, 8);
      }
      else if( ui32Mode == 4)
      {
          bufCtr = 0;
          uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADC_OUT_2,8);
      }

      uDMAChannelEnable(UDMA_CHANNEL_ADC0);
      uDMAChannelRequest(UDMA_CHANNEL_ADC0);
  }

  void InitUDMA(void)
  {


          uDMAEnable(); // Enables uDMA
          uDMAControlBaseSet(udmaCtrlTable);
          //IntEnable(INT_UDMA);
          uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALL);

          // Configures the base address of the channel control table. Table resides in system memory and holds control
              //     information for each uDMA channel. Table must be aligned on a 1024-byte boundary. Base address must be
              //     configured before any of the channel functions can be used
          uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST );


         uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |UDMA_CHCTL_ARBSIZE_1);
         uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |UDMA_CHCTL_ARBSIZE_1);

         uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1, 8);
         uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADC_OUT_2,8);

         // uDMAChannelEnable(UDMA_CHANNEL_ADC0); // Enables DMA channel so it can perform transfers
         uDMAChannelEnable(UDMA_CHANNEL_ADC0);
         uDMAChannelRequest(UDMA_CHANNEL_ADC0);

         //IntEnable(INT_UDMA);
         //uDMAIntRegister(INT_UDMA,uDMAIntHandler);
         //IntMasterEnable();



  }

  void InitConsole(void)
  {
         SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
         SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
         //SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
         SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
         SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
         GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
         GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
         GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1);
         GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);

         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
         GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0);
         GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_1);

         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
         GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0);
         GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_1);

         IntDisable(INT_ADC0SS0);
         ADCIntDisable(ADC0_BASE, 0);
         ADCSequenceDisable(ADC0_BASE, 0);

         //ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0);
         ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_ALWAYS, 0);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH14);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH15);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH16);
         ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH17|ADC_CTL_END);

         ADCHardwareOversampleConfigure(ADC0_BASE, 64);
         ADCSequenceDMAEnable(ADC0_BASE, 0);
         ADCSequenceEnable(ADC0_BASE, 0);

         ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0); // Enables ADC interrupt source due to DMA on ADC sample sequence 0
         IntEnable(INT_ADC0SS0);
         ADCIntRegister(ADC0_BASE,0,ADCSeq0Handler);
         IntMasterEnable();

  }

int main(void)
{

    uint32_t ui32SysClock;
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN ), 25000000);
    //uint32_t ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0);
    InitConsole();
    InitUDMA();

    while(1)
    {
        //ADCProcessorTrigger(ADC0_BASE, 0);
        //ADCIntClear(ADC0_BASE, 1);
        //ADCSequenceDataGet(ADC0_BASE, 0, pui32ADC0Value);
        //ADCSequenceDataGet(ADC1_BASE, 2, pui32ADC1Value);
       // SysCtlDelay(ui32SysClock / 12);
        //uint32_t ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0);

    }
}

  • Hello,

    Few questions here to start off with:

    1) Have you looked at our adc_udma_pingpong example for the EK-TM4C1294XL LaunchPad? It does ADC DMA Ping Pong and all you would be missing is the UART piece which...

    2) You have a UART ISR but no UART configuration? Do you need the ISR at all at this point? Or did I miss something with your configurations?

    3) Are you stuck in the ADCSeq0Handler with the uDMAChannelTransferSet?

  • Hello,

    I'm trying to UDMA continue to read in ADC handler. Problem solved now uDMA read continuously.