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/TM4C123BH6PZ: ADC capture and DMA question

Part Number: TM4C123BH6PZ
Other Parts Discussed in Thread: TM4C1294NCZAD

Tool/software: Code Composer Studio

Hey Bob, I was working on a project involving sampling external analog signal. I saw your post above in which you provided with a example file. So, I tried to run the code with small modification as I am working on DK-TM4C129X. My project files are attached below.

8662.single_ended.c
#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 "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/timer.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/systick.h"
#include "utils/uartstdio.h"

#define ADC_SAMPLE_BUF_SIZE     64

enum BUFFERSTATUS
                  { EMPTY,
                    FILLING,
                    FULL
                  };

#pragma DATA_ALIGN(ucControlTable, 1024)
uint8_t ucControlTable[1024];

static uint16_t ADC_Out1[ADC_SAMPLE_BUF_SIZE];
static uint16_t ADC_Out2[ADC_SAMPLE_BUF_SIZE];
static enum BUFFERSTATUS BufferStatus[2];

void ConfigureUART(void);
void init_ADC(void);
void init_TIMER(void);
void init_DMA(void);
static uint32_t g_ui32DMAErrCount = 0u;
static uint32_t g_ui32SysTickCount;


void uDMAErrorHandler(void)
{
    uint32_t ui32Status;
    ui32Status = MAP_uDMAErrorStatusGet();
    if(ui32Status)
    {
        MAP_uDMAErrorStatusClear();
        g_ui32DMAErrCount++;
    }
}

// Not used in this example, but used to debug to make sure timer interrupts happen
void Timer0AIntHandler(void)
{
    //
    // Clear the timer interrupt flag.
    //
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
}

void SysTickIntHandler(void)
{
    // Update our system tick counter.
    g_ui32SysTickCount++;
}

void ADCseq0Handler()
{
    ADCIntClear(ADC0_BASE, 0);

    if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)
            && (BufferStatus[0] == FILLING))
    {
        BufferStatus[0] = FULL;
        BufferStatus[1] = FILLING;
    }
    else if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT) == UDMA_MODE_STOP)
            && (BufferStatus[1] == FILLING))

    {
        BufferStatus[0] = FILLING;
        BufferStatus[1] = FULL;
    }
}

int main(void)
{
    uint32_t i, average1, average2, samples_taken;
    // Set the system clock to run at 80MHz from the PLL.
    //SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                            SYSCTL_OSC_MAIN |
                               SYSCTL_USE_PLL |
                              SYSCTL_CFG_VCO_480), 120000000);

    SysCtlDelay(20u);

    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);  //Enable the clock to TIMER0
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);    //Enable the clock to ADC module
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);    //Enable the clock to uDMA
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);   //Enables the clock to PORT E
    MAP_SysCtlDelay(30u);

    MAP_SysTickPeriodSet(SysCtlClockGet() / 100000u); //Sets the period of the SysTic counter to 10us
    MAP_SysTickIntEnable();
    MAP_SysTickEnable();

    BufferStatus[0] = FILLING;
    BufferStatus[1] = EMPTY;
    samples_taken = 0u;

    ConfigureUART();
    UARTprintf("Timer->ADC->uDMA demo!\n");
    UARTprintf("\tAverage1\tAverage2\tTotal Samples\n");

    init_DMA();
    init_ADC();
    init_TIMER();

    MAP_IntMasterEnable();
    MAP_TimerEnable(TIMER0_BASE, TIMER_A); // Start everything


    while(1)
    {
        if(BufferStatus[0u] == FULL)
        {
            // Do something with data in ADC_OUT1
            average1 = 0u;
            for(i =0u; i < ADC_SAMPLE_BUF_SIZE; i++)
            {
                average1 += ADC_Out1[i];
                ADC_Out1[i] = 0u;
            }
            BufferStatus[0u] = EMPTY;
            // Enable for another uDMA block transfer
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &ADC_Out1, ADC_SAMPLE_BUF_SIZE);
            uDMAChannelEnable(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT); // Enables DMA channel so it can perform transfers
            samples_taken += ADC_SAMPLE_BUF_SIZE;
            average1 = (average1 + (ADC_SAMPLE_BUF_SIZE / 2u)) / ADC_SAMPLE_BUF_SIZE;
        }
        if(BufferStatus[1u] == FULL)
        {
            // Do something with data in ADC_OUT2
            average2 = 0u;
            for(i =0u; i < ADC_SAMPLE_BUF_SIZE; i++)
            {
                average2 += ADC_Out2[i];
                ADC_Out2[i] = 0u;
            }
            BufferStatus[1u] = EMPTY;
            // Enable for another uDMA block transfer
            uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &ADC_Out2, ADC_SAMPLE_BUF_SIZE);
            uDMAChannelEnable(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);
            samples_taken += ADC_SAMPLE_BUF_SIZE;
            average2 = (average2 + (ADC_SAMPLE_BUF_SIZE / 2u)) / ADC_SAMPLE_BUF_SIZE;
            UARTprintf("\t%d\t\t%d\t\t%d\r", average1,average2,samples_taken);
        }
    }
}


void init_TIMER()
{
    MAP_TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);
    // Set sample frequency to 16KHz (every 62.5uS)
    MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, MAP_SysCtlClockGet()/16000 -1);   //TODO: Timer Load Value is set here
    MAP_TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
    MAP_TimerControlStall(TIMER0_BASE, TIMER_A, true); //Assist in debug by stalling timer at breakpoints
}

void init_ADC()
{
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
    SysCtlDelay(80u);

    // Use ADC0 sequence 0 to sample channel 0 once for each timer period
    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_HALF, 1);

    SysCtlDelay(10); // Time for the clock configuration to set

    IntDisable(INT_ADC0SS0);
    ADCIntDisable(ADC0_BASE, 0u);
    ADCSequenceDisable(ADC0_BASE,0u);
    // With sequence disabled, it is now safe to load the new configuration parameters

    ADCSequenceConfigure(ADC0_BASE, 0u, ADC_TRIGGER_TIMER, 0u);
    ADCSequenceStepConfigure(ADC0_BASE,0u,0u,ADC_CTL_CH0| ADC_CTL_END | ADC_CTL_IE);
    ADCSequenceEnable(ADC0_BASE,0u); //Once configuration is set, re-enable the sequencer
    ADCIntClear(ADC0_BASE,0u);
    ADCSequenceDMAEnable(ADC0_BASE,0);
    IntEnable(INT_ADC0SS0);

}

void init_DMA()
{
    uDMAEnable(); // Enables uDMA
    uDMAControlBaseSet(ucControlTable);

    uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);

    uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST);
    // Only allow burst transfers

    uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);

    uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &ADC_Out1, ADC_SAMPLE_BUF_SIZE);
    uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &ADC_Out2, ADC_SAMPLE_BUF_SIZE);

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

}

//*****************************************************************************
//
// Configure the UART and its pins.  This must be called before UARTprintf().
//
//*****************************************************************************
void
ConfigureUART(void)
{
    //
    // Enable the GPIO Peripheral used by the UART.
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable UART0
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Configure GPIO Pins for UART mode.
    //
    MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
    MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
    MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 115200, 16000000);
}

1738.tm4c1294nczad_startup_ccs.c
//*****************************************************************************
//
// 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 <stdint.h>

//*****************************************************************************
//
// Forward declaration of the default fault handlers.
//
//*****************************************************************************
void ResetISR(void);
static void NmiSR(void);
static void FaultISR(void);
static void IntDefaultHandler(void);

//*****************************************************************************
//
// 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 uDMAErrorHandler(void);
extern void Timer0AIntHandler(void);
extern void SysTickIntHandler(void);
extern void ADCseq0Handler();

//*****************************************************************************
//
// 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
	SysTickIntHandler,                      // 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
	Timer0AIntHandler,                      // 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)
    {
    }
}

I gave analog signal input as a square wave of 1kHz and 1Vpp at PE2 from a function generator and connected ground of function generator pin to board's ground. When I ran this code in CCSv6, the buffers ADC_Out1 and ADC_Out2 were filled, and when I plotted them using CCS graph window, how do I verify if the values are correct or not? Like I should get a square wave or part of it in graph, but it was nothing like that. My ADC_Out1 was plotted like this.

And ADC_Out2 was like this:

Can you please help me to figure out whats wrong or how can I get something similar to sqaure wave as an output in array, because my project involves calculation of FFT after getting that array.

And one more question, can I just change the buffer size to like 128,256 or high to get large buffer size or do I also have to change some uDMA part of the code also?

Regards,

Harshul Agarwal

  • Also, in the above-attached code, I didn't change the sequencer (SS0 was used as you did in the code). I now changed the sequencer to SS3, and plotted the results. I have attached images below. My modified source files with SS3 configured is:

    2055.single_ended.c
    #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 "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/timer.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/systick.h"
    #include "utils/uartstdio.h"
    
    #define ADC_SAMPLE_BUF_SIZE     64
    
    enum BUFFERSTATUS
                      { EMPTY,
                        FILLING,
                        FULL
                      };
    
    #pragma DATA_ALIGN(ucControlTable, 1024)
    uint8_t ucControlTable[1024];
    
    static uint16_t ADC_Out1[ADC_SAMPLE_BUF_SIZE];
    static uint16_t ADC_Out2[ADC_SAMPLE_BUF_SIZE];
    static enum BUFFERSTATUS BufferStatus[2];
    
    void ConfigureUART(void);
    void init_ADC(void);
    void init_TIMER(void);
    void init_DMA(void);
    static uint32_t g_ui32DMAErrCount = 0u;
    static uint32_t g_ui32SysTickCount;
    
    
    void uDMAErrorHandler(void)
    {
        uint32_t ui32Status;
        ui32Status = MAP_uDMAErrorStatusGet();
        if(ui32Status)
        {
            MAP_uDMAErrorStatusClear();
            g_ui32DMAErrCount++;
        }
    }
    
    // Not used in this example, but used to debug to make sure timer interrupts happen
    void Timer0AIntHandler(void)
    {
        //
        // Clear the timer interrupt flag.
        //
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    }
    
    void SysTickIntHandler(void)
    {
        // Update our system tick counter.
        g_ui32SysTickCount++;
    }
    
    void ADCseq0Handler()
    {
        ADCIntClear(ADC0_BASE, 3);
    
        if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)
                && (BufferStatus[0] == FILLING))
        {
            BufferStatus[0] = FULL;
            BufferStatus[1] = FILLING;
        }
        else if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT) == UDMA_MODE_STOP)
                && (BufferStatus[1] == FILLING))
    
        {
            BufferStatus[0] = FILLING;
            BufferStatus[1] = FULL;
        }
    }
    
    int main(void)
    {
        uint32_t i, average1, average2, samples_taken;
        // Set the system clock to run at 80MHz from the PLL.
        //SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
        SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                SYSCTL_OSC_MAIN |
                                   SYSCTL_USE_PLL |
                                  SYSCTL_CFG_VCO_480), 120000000);
    
        SysCtlDelay(20u);
    
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);  //Enable the clock to TIMER0
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);    //Enable the clock to ADC module
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);    //Enable the clock to uDMA
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);   //Enables the clock to PORT E
        MAP_SysCtlDelay(30u);
    
        MAP_SysTickPeriodSet(120000000u / 100000u); //Sets the period of the SysTic counter to 10us
        MAP_SysTickIntEnable();
        MAP_SysTickEnable();
    
        BufferStatus[0] = FILLING;
        BufferStatus[1] = EMPTY;
        samples_taken = 0u;
    
        ConfigureUART();
        UARTprintf("Timer->ADC->uDMA demo!\n");
        UARTprintf("\tAverage1\tAverage2\tTotal Samples\n");
    
        init_DMA();
        init_ADC();
        init_TIMER();
    
        MAP_IntMasterEnable();
        MAP_TimerEnable(TIMER0_BASE, TIMER_A); // Start everything
    
    
        while(1)
        {
            if(BufferStatus[0u] == FULL)
            {
                // Do something with data in ADC_OUT1
                average1 = 0u;
                for(i =0u; i < ADC_SAMPLE_BUF_SIZE; i++)
                {
                    average1 += ADC_Out1[i];
                    ADC_Out1[i] = 0u;
                }
                BufferStatus[0u] = EMPTY;
                // Enable for another uDMA block transfer
                uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO3), &ADC_Out1, ADC_SAMPLE_BUF_SIZE);
                uDMAChannelEnable(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT); // Enables DMA channel so it can perform transfers
                samples_taken += ADC_SAMPLE_BUF_SIZE;
                average1 = (average1 + (ADC_SAMPLE_BUF_SIZE / 2u)) / ADC_SAMPLE_BUF_SIZE;
            }
            if(BufferStatus[1u] == FULL)
            {
                // Do something with data in ADC_OUT2
                average2 = 0u;
                for(i =0u; i < ADC_SAMPLE_BUF_SIZE; i++)
                {
                    average2 += ADC_Out2[i];
                    ADC_Out2[i] = 0u;
                }
                BufferStatus[1u] = EMPTY;
                // Enable for another uDMA block transfer
                uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO3), &ADC_Out2, ADC_SAMPLE_BUF_SIZE);
                uDMAChannelEnable(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT);
                samples_taken += ADC_SAMPLE_BUF_SIZE;
                average2 = (average2 + (ADC_SAMPLE_BUF_SIZE / 2u)) / ADC_SAMPLE_BUF_SIZE;
                UARTprintf("\t%d\t\t%d\t\t%d\r", average1,average2,samples_taken);
            }
        }
    }
    
    
    void init_TIMER()
    {
        MAP_TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);
        // Set sample frequency to 16KHz (every 62.5uS)
        MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, MAP_SysCtlClockGet()/16000 -1);   //TODO: Timer Load Value is set here
        MAP_TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
        MAP_TimerControlStall(TIMER0_BASE, TIMER_A, true); //Assist in debug by stalling timer at breakpoints
    }
    
    void init_ADC()
    {
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
        SysCtlDelay(80u);
    
        // Use ADC0 sequence 0 to sample channel 0 once for each timer period
        ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_HALF, 1);
    
        SysCtlDelay(10); // Time for the clock configuration to set
    
        IntDisable(INT_ADC0SS3);
        ADCIntDisable(ADC0_BASE, 3u);
        ADCSequenceDisable(ADC0_BASE,3u);
        // With sequence disabled, it is now safe to load the new configuration parameters
    
        ADCSequenceConfigure(ADC0_BASE, 3u, ADC_TRIGGER_TIMER, 0u);
        ADCSequenceStepConfigure(ADC0_BASE,3u,0u,ADC_CTL_CH0| ADC_CTL_END | ADC_CTL_IE);
        ADCSequenceEnable(ADC0_BASE,3u); //Once configuration is set, re-enable the sequencer
        ADCIntClear(ADC0_BASE,3u);
        ADCSequenceDMAEnable(ADC0_BASE,3);
        IntEnable(INT_ADC0SS3);
    
    }
    
    void init_DMA()
    {
        uDMAEnable(); // Enables uDMA
        uDMAControlBaseSet(ucControlTable);
    
        uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC3, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
    
        uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC3, UDMA_ATTR_USEBURST);
        // Only allow burst transfers
    
        uDMAChannelControlSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        uDMAChannelControlSet(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO3), &ADC_Out1, ADC_SAMPLE_BUF_SIZE);
        uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO3), &ADC_Out2, ADC_SAMPLE_BUF_SIZE);
    
        uDMAChannelEnable(UDMA_CHANNEL_ADC3); // Enables DMA channel so it can perform transfers
    
    }
    
    //*****************************************************************************
    //
    // Configure the UART and its pins.  This must be called before UARTprintf().
    //
    //*****************************************************************************
    void
    ConfigureUART(void)
    {
        //
        // Enable the GPIO Peripheral used by the UART.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Enable UART0
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Configure GPIO Pins for UART mode.
        //
        MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
        MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
        MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Use the internal 16MHz oscillator as the UART clock source.
        //
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, 16000000);
    }
    

    This is the ADC_Out2 plot:

    This is ADC_Out1 plot:

    Is this correct or not? I am not able to verify this.

  • In converting the program from a TM4C123 device to a TM4C129 device you properly changed the function that sets the PLL, but failed to replace the function"MAP_SysCtlClockGet()". It is called in lines 109 and 172 in the file 8662.single-ended.c. That function is only supported on the TM4C123 devices. You can replace that function call with the constant value of the frequency, 120000000, or with the value returned by the function SysCtlClockFreqSet().
  • Harshul Agarwal said:
    can I just change the buffer size to like 128,256 or high to get large buffer size or do I also have to change some uDMA part of the code also?

    The maximum uDMA transfer size is 1024. You can build a bigger buffer using the ping-pong transfer mode by changing the destination address after each uDMA interrupt.

  • You were right. I changed the function to SysCtlClockFreqSet() and it worked. I also read the manual about this and it was written in that clearly. Thank You very much Bob for helping me out.