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.

CCS/DK-TM4C129X: Sampling a external analog signal through board's ADC with DMA

Part Number: DK-TM4C129X

Tool/software: Code Composer Studio

Hello everybody!!!

I am working on sampling a external analog signal (by a arbitraryfunction generator) with the help of ADC via DMA at 1msps. I am using the ping pong technique to store the continuous data from AFG. I am giving a sinusoidal input of frequency 1kHz and amplitude 1V at PE3/AIN0 pin of the board. Below is the complete code that I got successfully compiled on CCSv6.

#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/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/emac.h"

uint32_t gui32ADC0Value[2];

uint32_t gui32ADC1Value[2];

volatile uint32_t gui32ADCIntDone[2];

#pragma DATA_ALIGN(pui8ControlTable, 1024)

uint8_t pui8ControlTable[1024];

#define MEM_BUFFER_SIZE         256

static uint32_t g_ui8RxBufA[MEM_BUFFER_SIZE];

static uint32_t g_ui8RxBufB[MEM_BUFFER_SIZE];

//*****************************************************************************

//

//! <h1>Single Ended ADC (single_ended)</h1>

//

//*****************************************************************************

void

uDMAErrorHandler(void)

{

    uint32_t ui32Status;

    //

    // Check for uDMA error bit

    //

    ui32Status = uDMAErrorStatusGet();


    //

    // If there is a uDMA error, then clear the error and increment

    // the error counter.

    //

    if(ui32Status)

    {
        uDMAErrorStatusClear();

    }

}

void ADCseq0Handler()

{
    uint32_t ui32Status;
    uint32_t ui32Mode;

    ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS3);

    ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);

    if(ui32Mode == UDMA_MODE_STOP)
    {

        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,

                                   UDMA_MODE_PINGPONG,

                                   (void *)(ADC0_BASE + ADC_O_SSFIFO3),

                                   g_ui8RxBufA, MEM_BUFFER_SIZE);

        uDMAChannelEnable(UDMA_CHANNEL_ADC0);

    }

    ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);

    if(ui32Mode == UDMA_MODE_STOP)

    {
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,

                                    UDMA_MODE_PINGPONG,

                                    (void *)(ADC0_BASE + ADC_O_SSFIFO3),

                                    g_ui8RxBufB, MEM_BUFFER_SIZE);

        uDMAChannelEnable(UDMA_CHANNEL_ADC0);

    }

}

void

InitUART1Transfer(uint32_t sysclock)

{

    uint32_t div;

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0);

    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);
   // ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 30);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);

    //ADCSequenceConfigure(ADC0_BASE, 0 /*SS0*/, ADC_TRIGGER_ALWAYS, 3 /*priority*/);  // SS0-SS3 priorities must always be different
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                             ADC_CTL_END);

    ADCSequenceEnable(ADC0_BASE, 3);

    ADCSequenceDMAEnable(ADC0_BASE, 3);

    uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0,

                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |

                                    UDMA_ATTR_HIGH_PRIORITY |

                                    UDMA_ATTR_REQMASK);

    uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,

                            UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |

                              UDMA_ARB_256);

    uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,

                            UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |

                            UDMA_ARB_256);

    uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,

                               UDMA_MODE_PINGPONG,

                               (void *)(ADC0_BASE + ADC_O_SSFIFO3),

                               g_ui8RxBufA, MEM_BUFFER_SIZE);


    uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,

                                UDMA_MODE_PINGPONG,

                                (void *)(ADC0_BASE + ADC_O_SSFIFO3),

                                g_ui8RxBufB, MEM_BUFFER_SIZE);

    uDMAChannelEnable(UDMA_CHANNEL_ADC0);

    ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS3);

    IntEnable(INT_ADC0SS3);

}

int

main(void)

{

        uint32_t sysclock;

        sysclock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |

                                              SYSCTL_OSC_MAIN |

                                              SYSCTL_USE_PLL |

                                              SYSCTL_CFG_VCO_480), 20000000);


     SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

     SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);

     IntMasterEnable();

      IntEnable(INT_UDMAERR);

      uDMAEnable();

      uDMAControlBaseSet(pui8ControlTable);

      InitUART1Transfer(sysclock);

    while(1)

    {

    }

}

It compiled without any errors but all the values of the output (g_ui8RxBufA) were 0. I am not able to figure out what is wrong with the code.

Thank you

  • You are specifying the processor trigger as in ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0) but I don't see you generate the processor trigger to the ADC module. I will suggest you make sure the ADC works without the uDMA first and after ADC is working, you can then integrate the uDMA.

    Also why would you want to use a processor trigger?You might want to consider using Timer as your trigger.
  • Hello Charles, sorry for the late reply. I considered using the timer to trigger the ADC. Here is the modified code. When I run it, it goes into the IntDefaultHandler() infinite loop. 

    #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/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/adc.h"
    #include "driverlib/udma.h"
    #include "driverlib/emac.h"
    #include "driverlib/timer.h"
    
    uint32_t gui32ADC0Value[2];
    
    uint32_t gui32ADC1Value[2];
    
    volatile uint32_t gui32ADCIntDone[2];
    
    #pragma DATA_ALIGN(pui8ControlTable, 1024)
    
    uint8_t pui8ControlTable[1024];
    
    #define MEM_BUFFER_SIZE         256
    
    static uint32_t g_ui8RxBufA[MEM_BUFFER_SIZE];
    
    static uint32_t g_ui8RxBufB[MEM_BUFFER_SIZE];
    
    //*****************************************************************************
    
    //
    
    //! <h1>Single Ended ADC (single_ended)</h1>
    
    //
    
    //*****************************************************************************
    
    void
    
    uDMAErrorHandler(void)
    
    {
    
        uint32_t ui32Status;
    
        //
    
        // Check for uDMA error bit
    
        //
    
        ui32Status = uDMAErrorStatusGet();
    
    
        //
    
        // If there is a uDMA error, then clear the error and increment
    
        // the error counter.
    
        //
    
        if(ui32Status)
    
        {
            uDMAErrorStatusClear();
    
        }
    
    }
    
    void ADCseq0Handler()
    
    {
        //uint32_t ui32Status;
        uint32_t ui32Mode;
    
        ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS3);
    
        ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);
    
        if(ui32Mode == UDMA_MODE_STOP)
        {
    
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                       UDMA_MODE_PINGPONG,
    
                                       (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                       g_ui8RxBufA, MEM_BUFFER_SIZE);
    
            uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        }
    
        ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);
    
        if(ui32Mode == UDMA_MODE_STOP)
    
        {
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                        UDMA_MODE_PINGPONG,
    
                                        (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                        g_ui8RxBufB, MEM_BUFFER_SIZE);
    
            uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        }
    
    }
    
    void
    
    InitUART1Transfer(uint32_t sysclock)
    
    {
    
        //uint32_t div;
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)));
    
        SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0);
    
        ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);
       // ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 30);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)));
    
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
    
        //ADCSequenceConfigure(ADC0_BASE, 0 /*SS0*/, ADC_TRIGGER_ALWAYS, 3 /*priority*/);  // SS0-SS3 priorities must always be different
        ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_TIMER, 0);
    
        ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                                 ADC_CTL_END);
    
        ADCSequenceEnable(ADC0_BASE, 3);
    
        ADCIntClear(ADC0_BASE, 3);
    
        // Enable the Timer peripheral
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    
        // Timer should run periodically
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    
        // Set the value that is loaded into the timer everytime it finishes
        //   it's the number of clock cycles it takes till the timer triggers the ADC
        #define F_SAMPLE    1000
        TimerLoadSet(TIMER0_BASE, TIMER_A, sysclock/F_SAMPLE);
    
        // Enable triggering
        TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
    
        ADCIntEnable(ADC0_BASE, 2);
    
        // Enable the timer
        TimerEnable(TIMER0_BASE, TIMER_A);
    
        ADCSequenceDMAEnable(ADC0_BASE, 3);
    
        uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0,
    
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    
                                        UDMA_ATTR_HIGH_PRIORITY |
    
                                        UDMA_ATTR_REQMASK);
    
        uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |
    
                                  UDMA_ARB_256);
    
        uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |
    
                                UDMA_ARB_256);
    
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                   UDMA_MODE_PINGPONG,
    
                                   (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                   g_ui8RxBufA, MEM_BUFFER_SIZE);
    
    
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                    UDMA_MODE_PINGPONG,
    
                                    (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                    g_ui8RxBufB, MEM_BUFFER_SIZE);
    
        uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS3);
    
        IntEnable(INT_ADC0SS3);
    
    }
    
    int
    
    main(void)
    
    {
    
            uint32_t sysclock;
    
            sysclock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    
                                                  SYSCTL_OSC_MAIN |
    
                                                  SYSCTL_USE_PLL |
    
                                                  SYSCTL_CFG_VCO_480), 120000000);
    
    
         SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    
         while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)));
    
         SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    
         IntMasterEnable();
    
          IntEnable(INT_UDMAERR);
    
          uDMAEnable();
    
          uDMAControlBaseSet(pui8ControlTable);
    
          InitUART1Transfer(sysclock);
    
        while(1)
    
        {
    
        }
    
    }
    

  • I suggested you to try the ADC without the uDMA. Did you have a chance to do that and make sure it works first?

    If you are getting IntDefaultHandler then it means you didn't have a interrupt handler. I see the uDMAErrorHandler and ADCseq0Handler you created. But did you add these to your vector table in the startup_ccs.c file?
  • I am sorry, I forgot to mention earlier. The ADC works fine. You were right. I didnt add them to the vector table in startup file. I now added ADCseq0Handler at ADC sequence 0 and uDMAErrorHandler at uDMA error. But still when I run the code, it gets stuck in IntDefaultHandler. Here are my main source file and the startup file now.

    #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/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/adc.h"
    #include "driverlib/udma.h"
    #include "driverlib/emac.h"
    #include "driverlib/timer.h"
    
    uint32_t gui32ADC0Value[2];
    
    uint32_t gui32ADC1Value[2];
    
    volatile uint32_t gui32ADCIntDone[2];
    
    #pragma DATA_ALIGN(pui8ControlTable, 1024)
    
    uint8_t pui8ControlTable[1024];
    
    #define MEM_BUFFER_SIZE         256
    
    static uint32_t g_ui8RxBufA[MEM_BUFFER_SIZE];
    
    static uint32_t g_ui8RxBufB[MEM_BUFFER_SIZE];
    
    //*****************************************************************************
    
    //
    
    //! <h1>Single Ended ADC (single_ended)</h1>
    
    //
    
    //*****************************************************************************
    void
    uDMAErrorHandler(void)
    
    {
    
        uint32_t ui32Status;
    
        //
    
        // Check for uDMA error bit
    
        //
    
        ui32Status = uDMAErrorStatusGet();
    
    
        //
    
        // If there is a uDMA error, then clear the error and increment
    
        // the error counter.
    
        //
    
        if(ui32Status)
    
        {
            uDMAErrorStatusClear();
    
        }
    
    }
    
    void
    ADCseq0Handler(void)
    
    {
        //uint32_t ui32Status;
        uint32_t ui32Mode;
    
        ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS3);
    
        ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);
    
        if(ui32Mode == UDMA_MODE_STOP)
        {
    
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                       UDMA_MODE_PINGPONG,
    
                                       (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                       g_ui8RxBufA, MEM_BUFFER_SIZE);
    
            uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        }
    
        ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);
    
        if(ui32Mode == UDMA_MODE_STOP)
    
        {
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                        UDMA_MODE_PINGPONG,
    
                                        (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                        g_ui8RxBufB, MEM_BUFFER_SIZE);
    
            uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        }
    
    }
    
    void
    
    InitUART1Transfer(uint32_t sysclock)
    
    {
    
        //uint32_t div;
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)));
    
        SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0);
    
        ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);
       // ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 30);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)));
    
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
    
        //ADCSequenceConfigure(ADC0_BASE, 0 /*SS0*/, ADC_TRIGGER_ALWAYS, 3 /*priority*/);  // SS0-SS3 priorities must always be different
        ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_TIMER, 0);
    
        ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                                 ADC_CTL_END);
    
        ADCSequenceEnable(ADC0_BASE, 3);
    
        ADCIntClear(ADC0_BASE, 3);
    
        // Enable the Timer peripheral
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    
        // Timer should run periodically
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    
        // Set the value that is loaded into the timer everytime it finishes
        //   it's the number of clock cycles it takes till the timer triggers the ADC
        #define F_SAMPLE    1000
        TimerLoadSet(TIMER0_BASE, TIMER_A, sysclock/F_SAMPLE);
    
        // Enable triggering
        TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
    
        ADCIntEnable(ADC0_BASE, 2);
    
        // Enable the timer
        TimerEnable(TIMER0_BASE, TIMER_A);
    
        ADCSequenceDMAEnable(ADC0_BASE, 3);
    
        uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0,
    
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    
                                        UDMA_ATTR_HIGH_PRIORITY |
    
                                        UDMA_ATTR_REQMASK);
    
        uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |
    
                                  UDMA_ARB_256);
    
        uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |
    
                                UDMA_ARB_256);
    
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                   UDMA_MODE_PINGPONG,
    
                                   (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                   g_ui8RxBufA, MEM_BUFFER_SIZE);
    
    
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                    UDMA_MODE_PINGPONG,
    
                                    (void *)(ADC0_BASE + ADC_O_SSFIFO3),
    
                                    g_ui8RxBufB, MEM_BUFFER_SIZE);
    
        uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS3);
    
        IntEnable(INT_ADC0SS3);
    
    }
    
    int
    
    main(void)
    
    {
    
            uint32_t sysclock;
    
            sysclock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    
                                                  SYSCTL_OSC_MAIN |
    
                                                  SYSCTL_USE_PLL |
    
                                                  SYSCTL_CFG_VCO_480), 120000000);
    
    
         SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    
         while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)));
    
         SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    
         IntMasterEnable();
    
          IntEnable(INT_UDMAERR);
    
          uDMAEnable();
    
          uDMAControlBaseSet(pui8ControlTable);
    
          InitUART1Transfer(sysclock);
    
        while(1)
    
        {
    
        }
    
    }
    

    //*****************************************************************************
    //
    // Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Software License Agreement
    //
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    //*****************************************************************************
    #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/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/adc.h"
    #include "driverlib/udma.h"
    #include "driverlib/emac.h"
    #include "driverlib/timer.h"
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    
    //#define MEM_BUFFER_SIZE         256
    //volatile static uint32_t g_ui8RxBufA[MEM_BUFFER_SIZE];
    //
    //volatile static uint32_t g_ui8RxBufB[MEM_BUFFER_SIZE];
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // External declarations for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    extern void ADCseq0Handler(void);
    extern void uDMAErrorHandler(void);
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,                      // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
    	ADCseq0Handler,                      	// ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        IntDefaultHandler,                      // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
    	uDMAErrorHandler,                     	// uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        IntDefaultHandler,                      // I2C6 Master and Slave
        IntDefaultHandler,                      // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        IntDefaultHandler,                      // I2C8 Master and Slave
        IntDefaultHandler,                      // I2C9 Master and Slave
        IntDefaultHandler,                      // GPIO Port T
        IntDefaultHandler,                      // Fan 1
        0,                                      // Reserved
    };
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    
    
    

  • Hello Charles, in my code if I change my sequencer from 3 to 0, by just modifying some part the code works fine and gives almost correct output. It doesn't go in the IntDefaultHandler loop with SS0. Almost correct as in if I give a square wave as input from function generator, I get some sort of distorted wave in buffer. Why is this issue occuring that if I use sequence 0, it works fine, but if I use sequence 3 it doesn't?

    Updated 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/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/adc.h"
    #include "driverlib/udma.h"
    #include "driverlib/emac.h"
    #include "driverlib/timer.h"
    
    uint32_t gui32ADC0Value[2];
    
    uint32_t gui32ADC1Value[2];
    
    volatile uint32_t gui32ADCIntDone[2];
    
    #pragma DATA_ALIGN(pui8ControlTable, 1024)
    
    uint8_t pui8ControlTable[1024];
    
    #define MEM_BUFFER_SIZE         256
    
    static uint32_t g_ui8RxBufA[MEM_BUFFER_SIZE];
    
    static uint32_t g_ui8RxBufB[MEM_BUFFER_SIZE];
    
    //*****************************************************************************
    
    //
    
    //! <h1>Single Ended ADC (single_ended)</h1>
    
    //
    
    //*****************************************************************************
    void uDMAErrorHandler(void)
    
    {
    
        uint32_t ui32Status;
    
        //
    
        // Check for uDMA error bit
    
        //
    
        ui32Status = uDMAErrorStatusGet();
    
    
        //
    
        // If there is a uDMA error, then clear the error and increment
    
        // the error counter.
    
        //
    
        if(ui32Status)
    
        {
            uDMAErrorStatusClear();
    
        }
    
    }
    
    void ADCseq0Handler()
    
    {
        //uint32_t ui32Status;
        uint32_t ui32Mode;
    
        ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0);
    
        ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);
    
        if(ui32Mode == UDMA_MODE_STOP)
        {
    
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                       UDMA_MODE_PINGPONG,
    
                                       (void *)(ADC0_BASE + ADC_O_SSFIFO0),
    
                                       g_ui8RxBufA, MEM_BUFFER_SIZE);
    
            uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        }
    
        ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);
    
        if(ui32Mode == UDMA_MODE_STOP)
    
        {
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                        UDMA_MODE_PINGPONG,
    
                                        (void *)(ADC0_BASE + ADC_O_SSFIFO0),
    
                                        g_ui8RxBufB, MEM_BUFFER_SIZE);
    
            uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        }
    
    }
    
    void
    
    InitUART1Transfer(uint32_t sysclock)
    
    {
    
        //uint32_t div;
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)));
    
        SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0);
    
        ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);
       // ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 30);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)));
    
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
    
        //ADCSequenceConfigure(ADC0_BASE, 0 /*SS0*/, ADC_TRIGGER_ALWAYS, 3 /*priority*/);  // SS0-SS3 priorities must always be different
        ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0);
    
        ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                                 ADC_CTL_END);
    
        ADCSequenceEnable(ADC0_BASE, 0);
    
        ADCIntClear(ADC0_BASE, 0);
    
        // Enable the Timer peripheral
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    
        // Timer should run periodically
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    
        // Set the value that is loaded into the timer everytime it finishes
        //   it's the number of clock cycles it takes till the timer triggers the ADC
        #define F_SAMPLE    1000
        TimerLoadSet(TIMER0_BASE, TIMER_A, sysclock/F_SAMPLE);
    
        // Enable triggering
        TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
    
        ADCIntEnable(ADC0_BASE, 0);
    
        // Enable the timer
        TimerEnable(TIMER0_BASE, TIMER_A);
    
        ADCSequenceDMAEnable(ADC0_BASE, 0);
    
        uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0,
    
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    
                                        UDMA_ATTR_HIGH_PRIORITY |
    
                                        UDMA_ATTR_REQMASK);
    
        uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |
    
                                  UDMA_ARB_256);
    
        uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |
    
                                UDMA_ARB_256);
    
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
    
                                   UDMA_MODE_PINGPONG,
    
                                   (void *)(ADC0_BASE + ADC_O_SSFIFO0),
    
                                   g_ui8RxBufA, MEM_BUFFER_SIZE);
    
    
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
    
                                    UDMA_MODE_PINGPONG,
    
                                    (void *)(ADC0_BASE + ADC_O_SSFIFO0),
    
                                    g_ui8RxBufB, MEM_BUFFER_SIZE);
    
        uDMAChannelEnable(UDMA_CHANNEL_ADC0);
    
        ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0);
    
        IntEnable(INT_ADC0SS0);
    
    }
    
    int
    
    main(void)
    
    {
    
            uint32_t sysclock;
    
            sysclock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    
                                                  SYSCTL_OSC_MAIN |
    
                                                  SYSCTL_USE_PLL |
    
                                                  SYSCTL_CFG_VCO_480), 120000000);
    
    
         SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    
         while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA)));
    
         SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    
         IntMasterEnable();
    
          IntEnable(INT_UDMAERR);
    
          uDMAEnable();
    
          uDMAControlBaseSet(pui8ControlTable);
    
          InitUART1Transfer(sysclock);
    
        while(1)
    
        {
    
        }
    
    }
    

    Regards,

    Harshul

  • Your vector table as shown below in the startup file. You put the ADCseq0Handler correspond to ADC0 Sequence 0 but in your application you are configuring for the Sequence 3. You just need to fix the startup file by moving the ADCseq0Handler to the ADC0 Sequence 3 then it should work.

    ADCseq0Handler, // ADC Sequence 0
    IntDefaultHandler, // ADC Sequence 1
    IntDefaultHandler, // ADC Sequence 2
    IntDefaultHandler, // ADC Sequence 3
  • Yeah Charles, you were right. I did the changes and the code worked. I still have a query. I want to get clarity about this one thing. My system clock frequency is set at 120MHZ, I loaded 1000 in timer conversion rate to get the timer load value 120KHz and I increased my number of samples to 1024. So, it means after every 1000 clock cycles of timer, it triggers the ADC one time. Now, as g_ui8RxBufA buffer as 1024 length, so time taken to get this buffer full becomes 1024/120000. So, my sampling rate....is it 120KHz. Am I right? Because if sampling rate is 120KHz, then my input analog sinusoidal signal should have a frequency less than or equal to 60KHz to satisfy nyquist criterion to avoid aliasing. But when I gave a sinusoidal wave of amplitude 1Vpp and 200KHz frequency and 0.5V offset, and plotted the g_ui8RxBufA buffer values, the result was proper sinusoids. So, this shouldn't happen. What actually is going on inside, can you please clarify and share your thoughts?

    Regards,
    Harshul
  • The ADC source clock is 16MHz as you specified the PIOSC as the clock source for the ADC. The ADC has a 12-bit resolution. This means it takes 12 ADC clock cycles to complete the conversion after the AINx input is sampled and charge coupled to the internal capacitor. The minimum sample/hold time is 4 cycles. Therefore, it takes 16 cycles to complete one ADC channel conversion. With the ADC clock at 16MHz, the max sample rate is (16Mhz / 16) 1 msps. To get the 1 msps rate you need to set the timer at 1MHz rate as a trigger for conversion, not 120Khz.
  • Thanks for the clarification Charles.

    Regards,

    Harshul