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.

EK-TM4C1294XL: ADC not running at 2MSPS (capped at 1MSPS) - Related Question

Part Number: EK-TM4C1294XL

Hi to all.

I am developing a 2MSps ADC application and I am having some problems with the configuration of the system.

I thought that following the excellent explanations I found in this thread in e2e forum (https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/690227/ccs-ek-tm4c1294xl-adc-not-running-at-2msps-capped-at-1msps/2545036#2545036) I would solve my problem, but my surprise was that the g_ui32SysClock variable which is where the master clock frequency number is saved, show a 80000000Hz clock when I set it to 120MHz. I use the next piece of code:

g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_320),
120000000);

I attach you my full code in the post.

Could you help me to understand why is this happening and kindly explain me how to solve it?

Thank you very much

Enric Puigvert

.

//*****************************************************************************
//
// blinky.c - Simple example to blink the on-board LED.
//
// Copyright (c) 2013-2020 Texas Instruments Incorporated.  All rights reserved.
// 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.
// 
// This is part of revision 2.2.0.295 of the EK-TM4C1294XL Firmware Package.
//
//*****************************************************************************

/*
 * ====== Includes ============================================================
 */

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

#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "inc/hw_gpio.h"

#include "driverlib/adc.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

/*
 * ====== Defines =============================================================
 */

#define USER_LED1  GPIO_PIN_0
#define USER_LED2  GPIO_PIN_1

#define ADC0_ISC_R              (*((volatile uint32_t *)0x4003800C))

#define ADC0_STEPS          1   //number of conversions in one ADC interruption
                                //(Permited: 1 to 8).

#define MSTR_CLK            120000000 //Master Clock frequency (Hz)

#define TIMERA0_FREQ        2000000 //Timer A0 frequency (Hz)

/*
 * ====== Global Variables ====================================================
 */

uint32_t g_ui32SysClock; //clock system

uint32_t ui32Value[ADC0_STEPS]; //buffer to save data from ADC

uint32_t lost_measurements = 0; //lost measurements control variable

uint8_t adc_flag = 0; //new ADC0 data flag

uint8_t dbg_flag = 0; //debug pin flag
/*
 * ====== Function Definition =================================================
 */

/*
 *
 * ====== void ADCSeq0Handler(void) ======
 * Interrupt handler for ADC0 Sequence Zero. Interrupt function for ADC0
 * sequencer 0 step finish. It will clear the interrupt flags and get ADC
 * conversion results to its buffer.
 *
 */
void ADCSeq0Handler(void)
{
//    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, dbg_flag+1);

//    ADCIntClear(ADC0_BASE, 0); //Clear the Interrupt Flag.

    HWREG(GPIO_PORTF_BASE +(GPIO_O_DATA + (GPIO_PIN_1<<2))) =  dbg_flag+1;

    HWREG(ADC0_BASE + ADC_ISC_IN0 ) = 1;


    adc_flag = 1;

    if(dbg_flag){
        dbg_flag = 0;
    }
    else{
        dbg_flag = 2;
    }

}

/*
 *
 * ====== void ConfigureUART (void) ======
 * Configure the UART and its pins to enable a printf clone through UART
 * This must be called before UARTprintf().
 *
 */
void ConfigureUART(void)
{
    //
    // Enable the GPIO Peripheral used by the UART.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable UART0.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

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

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

/*
 *
 * ====== void init_ADC0 (void) ======
 * Initialization and configuration of the ADC0
 *
 */
void init_ADC0(void)
{
    /************************ Peripheral enabling ****************************/
    //
    // Enable ADC0 Peripheral for analog readings.
    // Enable PORT E for ADC0 input.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0))
    {
        UARTprintf("Error! ADC0 not initialized.\n");
    }

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE))
    {
        UARTprintf("Error! PORT E not initialized.\n");
    }

    /************************* GPIO Port E config ****************************/
    //
    // Initialize GPIO E0 for ADC input
    //
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
    SysCtlDelay(80); //delay to wait for config

    GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_0,
                     GPIO_STRENGTH_2MA,
                     GPIO_PIN_TYPE_ANALOG); //TODO: This may be unnecessary

    /************************** ADC clock config *****************************/
    //
    // Configure the ADC clock to use PLL VCO clock (configured in
    // SysCtlClockFreqSet() at 320MHz) at full rate (means that is predivided
    // by 2), and divided by 5 by us:
    //                 -----------------------------------
    //                | F_adc = F_pll_vco/5 = (F_pll/2)/5 |
    //                 -----------------------------------
    // -> Remember: To use 2MSps function, we need to set F_adc to 32MHz as
    //    datasheet says. For other sampling options read datasheet.
    //
    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 5);

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

    /************** Disable all Interruptions for configuration **************/
    //
    // Disable the ADC0 sequence 0 interrupt on the processor (NVIC).
    //
    IntDisable(INT_ADC0SS0);

    //
    // Disable interrupts for ADC0 sample sequence 0 to configure it.
    //
    ADCIntDisable(ADC0_BASE, 0);

    /********************** Sequencer0 configuration *************************/
    //
    // Disable ADC0 sample sequence 0.  With the sequence disabled, it is now
    // safe to load the new configuration parameters.
    //
    ADCSequenceDisable(ADC0_BASE, 0);

    //    //
    //    // Enable sample sequence 0 with a processor signal trigger.  Sequence 0
    //    // will do a single sample when the processor sends a signal to start the
    //    // conversion. The trigger is generated by ADCProcessorTrigger() function.
    //    //
    //    ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);

    //
    // Enable sample sequence 0 with a timer signal trigger.  Sequence 0
    // will do a single sample when the TimerA0 sends a signal to start the
    // conversion.
    //
    ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0);

    //
    // Configure step 0 on sequence 0.  Sample channel 3 (ADC_CTL_CH3) which is
    // AIN3 that corresponds to PB0 pin as datasheet says. Single-ended mode
    // (default) and configure the interrupt flag (ADC_CTL_IE)define to be set when
    // the sample is done. Tell the ADC logic that this is the last conversion
    // on sequence 0 (ADC_CTL_END).
    // Sequence 0 has 8 programmable steps (from 0 to 7).  Since we are only
    // doing a single conversion using sequence 0 we will only
    // configure step 0. For more information on the ADC sequences and steps,
    // reference the datasheet.
    //
    ADCSequenceStepConfigure(ADC0_BASE, 0, ADC0_STEPS - 1,
                             ADC_CTL_CH3 | ADC_CTL_END | ADC_CTL_IE);

    //
    // Since sample sequence 0 is now configured, it must be enabled.
    //
    ADCSequenceEnable(ADC0_BASE, 0);

    /******************* Interrupt enable -************************************/
    //
    // Clear the interrupt status flag.  This is done to make sure the
    // interrupt flag is cleared before we sample.
    //
    ADCIntClear(ADC0_BASE, 0);

    //
    // Enable the ADC 0 sample sequence 0 interrupt.
    //
    ADCIntEnable(ADC0_BASE, 0);

    //
    // Enable the interrupt for ADC0 sequence 0 on the processor (NVIC).
    //
    IntEnable(INT_ADC0SS0);
}

/*
 *
 * ====== void init_timerA0(void) ======
 * Initialization and configuration of the TimerA0 to trigger the ADC0
 *
 */
void init_timerA0(void)
{
    //
    // Enable the timerA0 peripheral
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

    //
    // Configure a 32-bit periodic timer. We use a pair of two counters
    // to reach the capacity of the desired counter:
    //
    //         --------------------------------------------------
    //        | 16 bit counter + 16 bit counter = 32 bit counter |
    //         --------------------------------------------------
    //
    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);

    //
    // Set ADC sampling frequency to be TIMERA0_FREQ Hz.
    //
    TimerLoadSet(TIMER0_BASE, TIMER_A, (g_ui32SysClock / TIMERA0_FREQ) - 1);

    //
    // Enable the ADC trigger output for Timer A.
    //
    TimerControlTrigger(TIMER0_BASE, TIMER_A, true);

    /**************************** DEBUG ***************************************/
    //
    // Enable the timer stall for debugging purposes. It halts the timer
    // when the debugger stops the program.
    //
    TimerControlStall(TIMER0_BASE, TIMER_A, true);
}

/*******************************************************************************
 *
 * ====== int main(void) ======
 * Main runtime function
 *
 ******************************************************************************/
int main(void)
{
    //
    // Run from the PLL at 120 MHz.
    // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and
    // later to better reflect the actual VCO speed due to SYSCTL#22.
    //
    // @formatter:off
    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                        SYSCTL_OSC_MAIN |
                                        SYSCTL_USE_PLL |
                                        SYSCTL_CFG_VCO_320),
                                        120000000);
            // @formatter:on

    //
    // Initialize UART0 and write initial status.
    //
    ConfigureUART();
    UARTprintf("Initializing system...\n");

    //
    // Enable PORT N Peripheral for debugging and config led1 as output
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
    {
        UARTprintf("Error! GPION not initialized.\n");
    }
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);


    //
    // Initilize ADC0 with all configurations
    //
    init_ADC0();

    //
    // Initialize TimerA0 with all configurations
    //
    init_timerA0();

    //
    // Enable processor interrupts
    //
    IntMasterEnable();

    //
    // Start timerA0
    //
    TimerEnable(TIMER0_BASE, TIMER_A);

    //
    //Header print
    //
    UARTprintf("ADC Value: \n\r");

    //
    // Loop forever
    //
    while (1)
    {
        if(adc_flag)
        {
            //
            //Read the value from the ADC
            //
            ADCSequenceDataGet(ADC0_BASE, 0, ui32Value);

//            UARTprintf("%d\r", ui32Value); //print it

            adc_flag = 0;
        }
    }
}

  • Hello Enric,

    You cannot get a 120MHz clock when using the PLL VCO at 320 MHz. The PLL only has integer dividers and you can't get to 120 MHz from 320MHz those. 80 MHz is the max clock speed when operating from the 320 MHz PLL VCO.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph, 

    Thanks for your response. 

    I didn't mention it but before to do the configuration I show in my last post, I tried the configuration with the PLL VCO at 480MHz. But it don't works. The timer works at ~1.25MHz (like the related post does) and I believe it makes sense because of the same reason you mention: there is no integer can divide 480MHz to result in 32MHz. 

    But if you do the calculations, there is no option in where you can divide PLL VCO by integer to result in a 120MHz master clock and at same time an ADC clock of 32MHz (to work with 2MSps). 

    What I am loosing? 

    Thank you,

    Enric

    PD: This is the modifications I did made when I configured the PLLVCO at 480MHz:

    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480),
    120000000);

    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 15);

  • Hello Enric,

    Your analysis is correct - unfortunately you have to choose between the 120MHz system clock and 1MSps rate vs the 2MSps ADC rate with a 80MHz system clock.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph,

    Thank you for your aclarations.

    Now I am trying to update my code to configure the ADC at 2MSps with a 80MHz system clock. My configurations are showed below:

    #define MSTR_CLK        80000000
    #define TIMERA0_FREQ    2000000
    
    [some code]
    
    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                            SYSCTL_OSC_MAIN |
                                            SYSCTL_USE_PLL |
                                            SYSCTL_CFG_VCO_320),
                                            MSTR_CLK);
                                            
    [some code ]
    
    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 5);
    
    [some code]
    
    TimerLoadSet(TIMER0_BASE, TIMER_A,(g_ui32SysClock / TIMERA0_FREQ) - 1); 

    As you can see, I configure the system clock to 80MHz from PLL VCO at 320MHz. Then I divide this 320MHz by 5 to get the 64MHz will be divided by to in the prescaler for ADC. In addition, I configure the timer to reach the 2MHz frequency by doing: (system clock /timer frequency) - 1.

    Despite doing this configurations my ADC interruption only gets handled at 1MHz (in fact is 1.2MHz). What I am missing? 

    (For more information I attach my new code below.)

    Thank you!

    Enric Puigvert

    //*****************************************************************************
    //
    // blinky.c - Simple example to blink the on-board LED.
    //
    // Copyright (c) 2013-2020 Texas Instruments Incorporated.  All rights reserved.
    // 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.
    // 
    // This is part of revision 2.2.0.295 of the EK-TM4C1294XL Firmware Package.
    //
    //*****************************************************************************
    
    /*
     * ====== Includes ============================================================
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_adc.h"
    #include "inc/hw_gpio.h"
    
    #include "driverlib/adc.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    /*
     * ====== Defines =============================================================
     */
    
    #define USER_LED1  GPIO_PIN_0
    #define USER_LED2  GPIO_PIN_1
    
    #define ADC0_ISC_R              (*((volatile uint32_t *)0x4003800C))
    
    #define ADC0_STEPS          1   //number of conversions in one ADC interruption
                                    //(Permited: 1 to 8).
    
    #define MSTR_CLK            80000000//120000000 //Master Clock frequency (Hz)
    
    #define TIMERA0_FREQ        2000000 //Timer A0 frequency (Hz)
    
    /*
     * ====== Global Variables ====================================================
     */
    
    uint32_t g_ui32SysClock; //clock system
    
    uint32_t ui32Value[ADC0_STEPS]; //buffer to save data from ADC
    
    uint32_t lost_measurements = 0; //lost measurements control variable
    
    uint8_t adc_flag = 0; //new ADC0 data flag
    
    uint8_t dbg_flag = 0; //debug pin flag
    /*
     * ====== Function Definition =================================================
     */
    
    /*
     *
     * ====== void ADCSeq0Handler(void) ======
     * Interrupt handler for ADC0 Sequence Zero. Interrupt function for ADC0
     * sequencer 0 step finish. It will clear the interrupt flags and get ADC
     * conversion results to its buffer.
     *
     */
    void ADCSeq0Handler(void)
    {
    //    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, dbg_flag+1);
    
    //    ADCIntClear(ADC0_BASE, 0); //Clear the Interrupt Flag.
    
        HWREG(GPIO_PORTF_BASE +(GPIO_O_DATA + (GPIO_PIN_1<<2))) =  dbg_flag+1;
    
        HWREG(ADC0_BASE + ADC_ISC_IN0 ) = 1;
    
    
        adc_flag = 1;
    
        if(dbg_flag){
            dbg_flag = 0;
        }
        else{
            dbg_flag = 2;
        }
    
    }
    
    /*
     *
     * ====== void ConfigureUART (void) ======
     * Configure the UART and its pins to enable a printf clone through UART
     * This must be called before UARTprintf().
     *
     */
    void ConfigureUART(void)
    {
        //
        // Enable the GPIO Peripheral used by the UART.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Enable UART0.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Configure GPIO Pins for UART mode.
        //
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, g_ui32SysClock);
    }
    
    /*
     *
     * ====== void init_ADC0 (void) ======
     * Initialization and configuration of the ADC0
     *
     */
    void init_ADC0(void)
    {
        /************************ Peripheral enabling ****************************/
        //
        // Enable ADC0 Peripheral for analog readings.
        // Enable PORT E for ADC0 input.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0))
        {
            UARTprintf("Error! ADC0 not initialized.\n");
        }
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE))
        {
            UARTprintf("Error! PORT E not initialized.\n");
        }
    
        /************************* GPIO Port E config ****************************/
        //
        // Initialize GPIO E0 for ADC input
        //
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
        SysCtlDelay(80); //delay to wait for config
    
        GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_0,
                         GPIO_STRENGTH_2MA,
                         GPIO_PIN_TYPE_ANALOG); //TODO: This may be unnecessary
    
        /************************** ADC clock config *****************************/
        //
        // Configure the ADC clock to use PLL VCO clock (configured in
        // SysCtlClockFreqSet() at 320MHz) at full rate (means that is predivided
        // by 2), and divided by 5 by us:
        //                 -----------------------------------
        //                | F_adc = F_pll_vco/5 = (F_pll/2)/5 |
        //                 -----------------------------------
        // -> Remember: To use 2MSps function, we need to set F_adc to 32MHz as
        //    datasheet says. For other sampling options read datasheet.
        //
        ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 5);
    
        //
        // Wait for the clock configuration to set.
        //
        SysCtlDelay(10);
    
        /************** Disable all Interruptions for configuration **************/
        //
        // Disable the ADC0 sequence 0 interrupt on the processor (NVIC).
        //
        IntDisable(INT_ADC0SS0);
    
        //
        // Disable interrupts for ADC0 sample sequence 0 to configure it.
        //
        ADCIntDisable(ADC0_BASE, 0);
    
        /********************** Sequencer0 configuration *************************/
        //
        // Disable ADC0 sample sequence 0.  With the sequence disabled, it is now
        // safe to load the new configuration parameters.
        //
        ADCSequenceDisable(ADC0_BASE, 0);
    
        //    //
        //    // Enable sample sequence 0 with a processor signal trigger.  Sequence 0
        //    // will do a single sample when the processor sends a signal to start the
        //    // conversion. The trigger is generated by ADCProcessorTrigger() function.
        //    //
        //    ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
    
        //
        // Enable sample sequence 0 with a timer signal trigger.  Sequence 0
        // will do a single sample when the TimerA0 sends a signal to start the
        // conversion.
        //
        ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0);
    
        //
        // Configure step 0 on sequence 0.  Sample channel 3 (ADC_CTL_CH3) which is
        // AIN3 that corresponds to PB0 pin as datasheet says. Single-ended mode
        // (default) and configure the interrupt flag (ADC_CTL_IE)define to be set when
        // the sample is done. Tell the ADC logic that this is the last conversion
        // on sequence 0 (ADC_CTL_END).
        // Sequence 0 has 8 programmable steps (from 0 to 7).  Since we are only
        // doing a single conversion using sequence 0 we will only
        // configure step 0. For more information on the ADC sequences and steps,
        // reference the datasheet.
        //
        ADCSequenceStepConfigure(ADC0_BASE, 0, ADC0_STEPS - 1,
                                 ADC_CTL_CH3 | ADC_CTL_END | ADC_CTL_IE);
    
        //
        // Since sample sequence 0 is now configured, it must be enabled.
        //
        ADCSequenceEnable(ADC0_BASE, 0);
    
        /******************* Interrupt enable -************************************/
        //
        // Clear the interrupt status flag.  This is done to make sure the
        // interrupt flag is cleared before we sample.
        //
        ADCIntClear(ADC0_BASE, 0);
    
        //
        // Enable the ADC 0 sample sequence 0 interrupt.
        //
        ADCIntEnable(ADC0_BASE, 0);
    
        //
        // Enable the interrupt for ADC0 sequence 0 on the processor (NVIC).
        //
        IntEnable(INT_ADC0SS0);
    }
    
    /*
     *
     * ====== void init_timerA0(void) ======
     * Initialization and configuration of the TimerA0 to trigger the ADC0
     *
     */
    void init_timerA0(void)
    {
        //
        // Enable the timerA0 peripheral
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    
        //
        // Configure a 32-bit periodic timer. We use a pair of two counters
        // to reach the capacity of the desired counter:
        //
        //         --------------------------------------------------
        //        | 16 bit counter + 16 bit counter = 32 bit counter |
        //         --------------------------------------------------
        //
        TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);
    
        //
        // Set ADC sampling frequency to be TIMERA0_FREQ Hz.
        //
        TimerLoadSet(TIMER0_BASE, TIMER_A,(g_ui32SysClock / TIMERA0_FREQ) - 1);
    
        //
        // Enable the ADC trigger output for Timer A.
        //
        TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
    
        /**************************** DEBUG ***************************************/
        //
        // Enable the timer stall for debugging purposes. It halts the timer
        // when the debugger stops the program.
        //
        TimerControlStall(TIMER0_BASE, TIMER_A, true);
    }
    
    /*******************************************************************************
     *
     * ====== int main(void) ======
     * Main runtime function
     *
     ******************************************************************************/
    int main(void)
    {
        //
        // Run from the PLL at 120 MHz.
        // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and
        // later to better reflect the actual VCO speed due to SYSCTL#22.
        //
        // @formatter:off
        g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                            SYSCTL_OSC_MAIN |
                                            SYSCTL_USE_PLL |
                                            SYSCTL_CFG_VCO_320),
                                            MSTR_CLK);
                // @formatter:on
    
        //
        // Initialize UART0 and write initial status.
        //
        ConfigureUART();
        UARTprintf("Initializing system...\n");
    
        //
        // Enable PORT N Peripheral for debugging and config led1 as output
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
        {
            UARTprintf("Error! GPION not initialized.\n");
        }
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    
    
        //
        // Initilize ADC0 with all configurations
        //
        init_ADC0();
    
        //
        // Initialize TimerA0 with all configurations
        //
        init_timerA0();
    
        //
        // Enable processor interrupts
        //
        IntMasterEnable();
    
        //
        // Start timerA0
        //
        TimerEnable(TIMER0_BASE, TIMER_A);
    
        //
        //Header print
        //
        UARTprintf("ADC Value: \n\r");
    
        //
        // Loop forever
        //
        while (1)
        {
            if(adc_flag)
            {
                //
                //Read the value from the ADC
                //
                ADCSequenceDataGet(ADC0_BASE, 0, ui32Value);
    
    //            UARTprintf("%d\r", ui32Value); //print it
    
                adc_flag = 0;
            }
        }
    }
    

  • Hello Enric,

        adc_flag = 1;
    
        if(dbg_flag){
            dbg_flag = 0;
        }
        else{
            dbg_flag = 2;
        }

    This is adding too much overhead to the ISR. Its the same reason Bob's example did not use TivaWare APIs but instead of DRM calls. The ISR needs to be extremely minimalistic to hit those speeds.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph,

    You were right! I was overpassing the runtime of the ADC interruption.

    I very appreciate your recommendations and I wish this conversation can help  someone with a similar problem.

    Thank you very much!

    Enric