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.

TMS320F28379D: ADC's are triggering only Once

Part Number: TMS320F28379D

Hello Experts,

I am configuring ADC A, B, and C in single-ended mode triggering with TIMER2 every 100uS. I see that the ADCs are triggering only once. I tried keeping break point in ISR and see that its hitting only once. Just to confirm, I added some led blink code in the timer ISR which is working fine. But ADCs are not triggering.

I am attaching the code. Can you please tell me what's wrong here?

// Main.c

//#############################################################################
//
// FILE:   led_ex1_blinky.c
//
// TITLE:  LED Blinky Example
//
//! \addtogroup driver_example_list
//! <h1> LED Blinky Example </h1>
//!
//! This example demonstrates how to blink a LED.
//!
//! \b External \b Connections \n
//!  - None.
//!
//! \b Watch \b Variables \n
//!  - None.
//!
//
//#############################################################################
// $TI Release: F2837xD Support Library v3.11.00.00 $
// $Release Date: Sun Oct  4 15:55:24 IST 2020 $
// $Copyright:
// Copyright (C) 2013-2020 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//   Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the
//   distribution.
//
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "header.h"

uint16_t _timer_1SEC = 0;

//
// Main
//
void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();
    Device_initGPIO();

    GPIO_setPadConfig(166, GPIO_PIN_TYPE_STD);
    GPIO_setDirectionMode(166, GPIO_DIR_MODE_OUT);

    GPIO_setPadConfig(167, GPIO_PIN_TYPE_STD);
    GPIO_setDirectionMode(167, GPIO_DIR_MODE_OUT);

    GPIO_setPadConfig(168, GPIO_PIN_TYPE_STD);
    GPIO_setDirectionMode(168, GPIO_DIR_MODE_OUT);


    Init_ADCs();        //Initialize ADC's & Initialize SOC's
    Init_ADC_SOCs();

    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    Interrupt_register(INT_ADCA1, &ADCA_ISR);
    Interrupt_enable(INT_ADCA1);

    Interrupt_register(INT_ADCB1, &ADCB_ISR);
    Interrupt_enable(INT_ADCB1);

    Interrupt_register(INT_ADCC1, &ADCC_ISR);
    Interrupt_enable(INT_ADCC1);

    Interrupt_register(INT_TIMER2, &TIMER2_ISR);

    INIT_CPU_TIMERS();
    Config_CPU_TIMER(CPUTIMER2_BASE, DEVICE_SYSCLK_FREQ, 100);

    CPUTimer_enableInterrupt(CPUTIMER2_BASE);
    Interrupt_enable(INT_TIMER2);
    CPUTimer_startTimer(CPUTIMER2_BASE);

    //
    // Loop Forever
    //
    for (;;)
    {
        IRX_PP = (IRX_PP_BUFFER * 18.182 / 4096.0) - 9.091;
        I_RX_INST = (ADC_I_RX_INST * 18.182 / 4096.0) - 9.091;

    }
}

//
// End of File
//



//Analog.h

/*
 * Analog.h
 *
 *  Created on: 16-Sep-2021
 *      Author: Vishal
 */

// +-+-+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+-+
// |A|u|t|h|o|r|:| |V|i|s|h|a|l| |K|a|k|a|d|e|
// +-+-+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+-+

// ____    ____    ____        ____    ____    ____            ___         __
///\  _`\ /\  _`\ /\  _`\     /\  _`\ /\  _`\ /\  _`\        /'___`\     /'__`\
//\ \ \L\_\ \ \L\ \ \ \L\ \   \ \ \L\ \ \ \L\ \ \,\L\_\     /\_\ /\ \   /\ \/\ \
// \ \  _\L\ \ ,__/\ \ ,  /    \ \ ,__/\ \ ,__/\/_\__ \     \/_/// /__  \ \ \ \ \
//  \ \ \L\ \ \ \/  \ \ \\ \    \ \ \/  \ \ \/   /\ \L\ \      // /_\ \__\ \ \_\ \
//   \ \____/\ \_\   \ \_\ \_\   \ \_\   \ \_\   \ `\____\    /\______/\_\\ \____/
//    \/___/  \/_/    \/_/\/ /    \/_/    \/_/    \/_____/    \/_____/\/_/ \/___/
//

#ifndef ANALOG_H_
#define ANALOG_H_

//********************************** Analog Signals*************************************


extern uint16_t ADC_IRX_PP;
extern uint16_t ADC_I_RX_INST;

extern float IRX_PP;
extern float I_RX_INST;

extern uint16_t ADCIN14_3V;
extern uint16_t ADCIN15_0V;

extern uint16_t IRX_PP_BUFFER;

extern uint16_t ADCINB0;
extern uint16_t ADCINB1;

void Init_ADCs(void);
void Init_ADC_SOCs(void);

//********** Functions to Read ADC's**************

__interrupt void ADCA_ISR(void);
__interrupt void ADCB_ISR(void);
__interrupt void ADCC_ISR(void);

__interrupt void TIMER2_ISR(void);

void INIT_CPU_TIMERS(void);
void Config_CPU_TIMER(uint32_t, float, float);


#endif /* ANALOG_H_ */


//Analog.c

/*
 * Config_ADC.c
 *
 *  Created on: 02-Dec-2019
 *      Author: Vishal
 */

// +-+-+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+-+
// |A|u|t|h|o|r|:| |V|i|s|h|a|l| |K|a|k|a|d|e|
// +-+-+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+-+
// ____    ____    ____        ____    ____    ____            ___         __
///\  _`\ /\  _`\ /\  _`\     /\  _`\ /\  _`\ /\  _`\        /'___`\     /'__`\
//\ \ \L\_\ \ \L\ \ \ \L\ \   \ \ \L\ \ \ \L\ \ \,\L\_\     /\_\ /\ \   /\ \/\ \
// \ \  _\L\ \ ,__/\ \ ,  /    \ \ ,__/\ \ ,__/\/_\__ \     \/_/// /__  \ \ \ \ \
//  \ \ \L\ \ \ \/  \ \ \\ \    \ \ \/  \ \ \/   /\ \L\ \      // /_\ \__\ \ \_\ \
//   \ \____/\ \_\   \ \_\ \_\   \ \_\   \ \_\   \ `\____\    /\______/\_\\ \____/
//    \/___/  \/_/    \/_/\/ /    \/_/    \/_/    \/_____/    \/_____/\/_/ \/___/
//
// This file contains Functions to initialize ADC's , Initialize start of Conversions, & Read All the RAW values of Analog Signals.
#include"header.h"

//Initialize the analog results.
//********** Analog Signals*************

uint16_t ADC_IRX_PP = 0;
uint16_t ADC_I_RX_INST = 0;

float IRX_PP = 0.0;
float I_RX_INST = 0.0;

extern uint16_t ADCIN14_3V = 0;
extern uint16_t ADCIN15_0V = 0;

uint16_t IRX_PP_BUFFER = 0;

uint16_t ADCINB0 = 0;
uint16_t ADCINB1 = 0;

//********** Initialize ADC's*************

void Init_ADCs(void)
{
    //
    // Set ADCCLK divider to /4
    //
    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);
    ADC_setPrescaler(ADCB_BASE, ADC_CLK_DIV_4_0);
    ADC_setPrescaler(ADCC_BASE, ADC_CLK_DIV_4_0);

    //
    // Set resolution and signal mode (see #defines above) and load
    // corresponding trims.
    //
    ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
    ADC_setMode(ADCB_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
    ADC_setMode(ADCC_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);

    //
    // Set pulse positions to late
    //
    ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);
    ADC_setInterruptPulseMode(ADCB_BASE, ADC_PULSE_END_OF_CONV);
    ADC_setInterruptPulseMode(ADCC_BASE, ADC_PULSE_END_OF_CONV);

    //
    // Power up the ADCs and then delay for 1 ms
    //
    ADC_enableConverter(ADCA_BASE);
    ADC_enableConverter(ADCB_BASE);
    ADC_enableConverter(ADCC_BASE);

    DEVICE_DELAY_US(1000);

}

//
// Function to configure Start of conversion (SOC) for ADC's
//
void Init_ADC_SOCs(void)
{

    // - For 12-bit resolution, a sampling window of 15 (75 ns at a 200MHz
    //   SYSCLK rate) will be used.  For 16-bit resolution, a sampling window
    //   of 64 (320 ns at a 200MHz SYSCLK rate) will be used.
    //

    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_CPU1_TINT2,
                 ADC_CH_ADCIN2, 15);
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER2);
    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

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

    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_CPU1_TINT2,
                 ADC_CH_ADCIN0, 15);
    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_CPU1_TINT2,
                 ADC_CH_ADCIN1, 15);
    ADC_setInterruptSource(ADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);
    ADC_enableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1);

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

    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_CPU1_TINT2,
                 ADC_CH_ADCIN2, 15);
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER14, ADC_TRIGGER_CPU1_TINT2,
                 ADC_CH_ADCIN14, 15);
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER15, ADC_TRIGGER_CPU1_TINT2,
                 ADC_CH_ADCIN15, 15);
    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER15);
    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);

}

//
// ADC A Interrupt 1 ISR
//
__interrupt void ADCA_ISR(void)
{

    ADC_IRX_PP = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2);

    if (ADC_IRX_PP > IRX_PP_BUFFER)
    {
        IRX_PP_BUFFER = ADC_IRX_PP;
        // IRX_PP = (IRX_PP_BUFFER * 18.182 / 4096.0) - 9.091;
    }

    if (true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1))
    {
        ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    }

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

__interrupt void ADCB_ISR(void)
{

    // Store results

    ADCINB0 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER0);
    ADCINB1 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER1);


    if (true == ADC_getInterruptOverflowStatus(ADCB_BASE, ADC_INT_NUMBER1))
    {
        ADC_clearInterruptOverflowStatus(ADCB_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1);
    }

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

__interrupt void ADCC_ISR(void)
{

    // Store results

    ADC_I_RX_INST = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER2);
    ADCIN14_3V = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER14);
    ADCIN15_0V = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER15);


    if (true == ADC_getInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1))
    {
        ADC_clearInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
    }

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}



//Timer 2 comfigured to interrupt every 100uS
__interrupt void TIMER2_ISR(void)
{

    _timer_1SEC++;

    if (_timer_1SEC >= 10000)
    {
        _timer_1SEC = 0;

        GPIO_togglePin(166);
        GPIO_togglePin(167);
        GPIO_togglePin(168);
    }

}

void Config_CPU_TIMER(uint32_t cpuTimer, float freq, float period)
{
    uint32_t temp;
    temp = (uint32_t) (freq / 1000000 * period);
    CPUTimer_setPeriod(cpuTimer, temp);
    CPUTimer_setPreScaler(cpuTimer, 0);
    CPUTimer_stopTimer(cpuTimer);
    CPUTimer_reloadTimerCounter(cpuTimer);
    CPUTimer_setEmulationMode(cpuTimer,
                              CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    CPUTimer_enableInterrupt(cpuTimer);

}

void INIT_CPU_TIMERS(void)
{

    CPUTimer_setPeriod(CPUTIMER2_BASE, 0xFFFFFFFF);
    CPUTimer_setPreScaler(CPUTIMER2_BASE, 0);
    CPUTimer_stopTimer(CPUTIMER2_BASE);
    CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);

}

//header.h

/*
 * header.h
 *
 *  Created on: 28-Oct-2021
 *      Author: Vishal
 */

// +-+-+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+-+
// |A|u|t|h|o|r|:| |V|i|s|h|a|l| |K|a|k|a|d|e|
// +-+-+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+-+

// ____    ____    ____        ____    ____    ____            ___         __
///\  _`\ /\  _`\ /\  _`\     /\  _`\ /\  _`\ /\  _`\        /'___`\     /'__`\
//\ \ \L\_\ \ \L\ \ \ \L\ \   \ \ \L\ \ \ \L\ \ \,\L\_\     /\_\ /\ \   /\ \/\ \
// \ \  _\L\ \ ,__/\ \ ,  /    \ \ ,__/\ \ ,__/\/_\__ \     \/_/// /__  \ \ \ \ \
//  \ \ \L\ \ \ \/  \ \ \\ \    \ \ \/  \ \ \/   /\ \L\ \      // /_\ \__\ \ \_\ \
//   \ \____/\ \_\   \ \_\ \_\   \ \_\   \ \_\   \ `\____\    /\______/\_\\ \____/
//    \/___/  \/_/    \/_/\/ /    \/_/    \/_/    \/_____/    \/_____/\/_/ \/___/
//



#ifndef HEADER_H_
#define HEADER_H_

#include "driverlib.h"
#include "device.h"

#include"Analog.h"

extern uint16_t _timer_1SEC;

//* Definition of standard bits *
//******************************************************************************/
#define BIT0                                     (uint16_t)(0x0001)
#define BIT1                                     (uint16_t)(0x0002)
#define BIT2                                     (uint16_t)(0x0004)
#define BIT3                                     (uint16_t)(0x0008)
#define BIT4                                     (uint16_t)(0x0010)
#define BIT5                                     (uint16_t)(0x0020)
#define BIT6                                     (uint16_t)(0x0040)
#define BIT7                                     (uint16_t)(0x0080)
#define BIT8                                     (uint16_t)(0x0100)
#define BIT9                                     (uint16_t)(0x0200)
#define BITA                                     (uint16_t)(0x0400)
#define BITB                                     (uint16_t)(0x0800)
#define BITC                                     (uint16_t)(0x1000)
#define BITD                                     (uint16_t)(0x2000)
#define BITE                                     (uint16_t)(0x4000)
#define BITF                                     (uint16_t)(0x8000)
#define BIT(x)                                 ((uint16_t)1 << (x))

//******************************END OF NEW CODE****************************************


#endif /* HEADER_H_ */

Regards

Vishal Kakade

  • Hi Vishal,

    For your ADC interrupts, it looks like you are only clearing the interrupt flag after the interrupt overflow flag is set. You need to clear this flag on every interrupt.

    I believe the following is happening: 

    1) ADCA interrupt flag is set

    2) ADCA ISR is executed, but ADCA interrupt flag stays high, then ISR is left

    3) ADCA interrupt overflow flag is set since the ADCA interrupt flag is already set

    4) Since ADCA interrupt flag was already set, the interrupt is not triggered again, and the ADCA interrupt flag and interrupt overflow flag stay high forever

    You could check this theory by looking at the registers after your program has been running for a bit to see if the interrupt flag and interrupt overflow flags are set.

    Also, if you look at the ADC result registers in the register viewer, do you see the ADC results being updated?  

    Best Regards,

    Ben Collier

  • Hi Benjamin,

    Thanks for your response. It resolved my issue. 

    I am facing another issue with the acquisition, My signal is 360KHz voltage sine wave it can vary its amplitude from 0 and 3V. I am required to detect the highest level of peak for which I have a peak detector circuit on my board. Whose output I am feeding it to the ADC.

    My Signal will last for 100mS so I have enough time to capture it.

    When I keep my sample window to 30 or 60, I am reading voltage "x" But when I increase my sample window to ~500, I am getting "x-100mV". How Can I solve this issue? 

  • Hi Vishal,

    I will need to ask my coworkers about this, please allow me a day or two to get back to you.

    Best Regards,

    Ben Collier

  • Vishal,

    Please see this app note: https://www.ti.com/lit/pdf/spracp5

    Gain and offset error can change with aCQPS value. Sometimes lower aCQPS can result in better performance. Do you have a reason to use the longer aCQPS? 

    Best Regards,

    Ben Collier