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/TMS320F28379D: ADC Interrupt Stop Inquiry

Part Number: TMS320F28379D

Tool/software: Code Composer Studio


I have programmed three ADCAs, ADCB and ADCC to use interrupts.

There is an interrupt source at the end of the source code below.

PWM 20 kHz was used as an interrupt trigger for all ADCs when the TBPRD value and the TBCTR value were equal.

Obtain data 50 times at each ADC for every 20 kHz and then obtain the RMS value.

When the program is run, the ADCB interrupt stops after 21 actions.

Please let me know where I made the mistake.

#include <math.h>
#include "F28x_Project.h"


#define CPU_SYS_CLK     200E6       //CPU Main Clock
#define PWM_SYS_CLK     100E6       //ePWM Module Clock

// PWM Module Define
#define PWM_FREQ            (float32)20E3                                     //PWM Frequency
#define PWM_PERIOD          PWM_SYS_CLK / PWM_FREQ                          //100M / 20kHz = 5000
#define PWM_DEAD_BAND       PWM_SYS_CLK * PWM_DEAD_BAND_US * 0.000001       //100M * 0.2u = 20
#define PWM_DEAD_BAND_US    0.2                                             //200ns Dead Band



#define ADC_DATA_GET_CNT    50      //RMS Value Max Counter
Uint32 ADC_VBUS_HEX;            //Square Accumulation of Inverter Input DC Volt - ADC HEX Result Value
Uint32 ADC_VLINE_HEX;           //square accumulation of Inverter Output AC volt - ADC HEX Result Value
Uint32 ADC_VHALL_HEX;           //square accumulation of Current Hall Sensor - ADC HEX Result Value

Uint16 ADC_VBUS_RMS_HEX;        //RMS Hex Value
Uint16 ADC_VLINE_RMS_HEX;
Uint16 ADC_VHALL_RMS_HEX;

Uint16 ADC_VBUS_CNT;            //Now Counter value
Uint16 ADC_VLINE_CNT;
Uint16 ADC_VHALL_CNT;




void main(void)
{

    DINT;
    IER = 0x0000;
    IFR = 0x0000;
    InitSysCtrl();

    InitPieVectTable();
    EALLOW;
    PieVectTable.ADCA1_INT = &adca5_isr;        //Bus.V : Inverter Input Voltage 380Vdc
    PieVectTable.ADCB1_INT = &adcb2_isr;        //I.inv : Current Hall Sensor
    PieVectTable.ADCC1_INT = &adcc14_isr;       //Line.V : Inverter Output 0~220Vac
    EDIS;

    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;  //PIE Interrupt ADCA1 
    PieCtrlRegs.PIEIER1.bit.INTx2 = 1;  //PIE Interrupt ADCB1 
    PieCtrlRegs.PIEIER1.bit.INTx3 = 1;  //PIE Interrupt ADCC1 
    IER = IER | M_INT1 | M_INT2 | M_INT3;


    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; 
    EDIS;                                 




    //-------------PWM1 & 2 Config ------------//
    EALLOW;
    EPwm1Regs.TBCTL.bit.PRDLD = 0;                      
    EPwm1Regs.TBPRD = ((Uint16)(PWM_PERIOD) >> 1);    
    EPwm1Regs.TBCTR = 0;                                
    EPwm1Regs.TBPHS.bit.TBPHS = 0;                      
    EPwm1Regs.TBCTL.bit.CTRMODE = 2;                    
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;                     
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;                  

    EPwm1Regs.CMPA.bit.CMPA = 0;                        
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;                 
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;                 

    EPwm1Regs.AQCTLA.bit.CAU = 2;                       
    EPwm1Regs.AQCTLA.bit.CAD = 3;                       
    EPwm1Regs.AQCTLA.bit.ZRO = 1;                       

    EPwm1Regs.DBCTL.bit.HALFCYCLE = 0;                  
    EPwm1Regs.DBRED.bit.DBRED = PWM_DEAD_BAND;          
                                                        

    EPwm1Regs.DBFED.bit.DBFED = PWM_DEAD_BAND;
    EPwm1Regs.DBCTL.bit.IN_MODE = 0;                    
    EPwm1Regs.DBCTL.bit.POLSEL = 2;                     
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3;                   

    EPwm1Regs.TBCTL.bit.PHSEN = 0;                      
    EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;                   


    EPwm2Regs.TBCTL.bit.PRDLD = 0;
    EPwm2Regs.TBPRD = ((uint16_t)(PWM_PERIOD) >> 1);
    EPwm2Regs.TBCTR = 0;
    EPwm2Regs.TBPHS.bit.TBPHS = 0;
    EPwm2Regs.TBCTL.bit.CTRMODE = 2;
    EPwm2Regs.TBCTL.bit.CLKDIV = 0;
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0;

    EPwm2Regs.CMPA.bit.CMPA = 0;
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = 1;                 

    EPwm2Regs.AQCTLA.bit.CAD = 1;                       

    EPwm2Regs.DBCTL.bit.HALFCYCLE = 0;
    EPwm2Regs.DBRED.bit.DBRED = PWM_DEAD_BAND;
    EPwm2Regs.DBFED.bit.DBFED = PWM_DEAD_BAND;
    EPwm2Regs.DBCTL.bit.IN_MODE = 0;
    EPwm2Regs.DBCTL.bit.POLSEL = 2;
    EPwm2Regs.DBCTL.bit.OUT_MODE = 3;

    EPwm2Regs.TBCTL.bit.PHSEN = 1;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;                   
    EPwm2Regs.TBCTL.bit.PHSDIR = 1;                     
    EPwm2Regs.TBPHS.bit.TBPHS = 0;                      

    //ADC SOC(Start of Conversion) Event Trigger = PWM1
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;                     //ADC SOCA Event Trigger Enable
    EPwm1Regs.ETSEL.bit.SOCASEL = 2;                    //TBCTR = TBPRD Event Trigger
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;                     //Prescale 1
    EDIS;


    //Step3. GPIO0(PWM1A), 1(PWM1B), 2(PWM2A), 3(PWM2B)
    EALLOW;
    GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;    
    GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;
    GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;
    GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;    
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;

    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;   
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;   
    EDIS;

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;





    //----------------   ADC Config    ----------------//
    ADC_VBUS_CNT = 0;
    ADC_VBUS_HEX = 0;
    ADC_VBUS_RMS_HEX = 0;

    EALLOW;
    //ADCA : Config ADC of Inverter Input DC Volt
    AdcaRegs.ADCCTL2.bit.PRESCALE = 0;          //ADCCLK = 5ns = SYSCLK(5ns@200MHz) / 1 = 5ns
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);  //12bit Single Mode
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;       //1: Interrupt event after First Conversion
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 5;          //SOC0 : ADC-A Channel 5
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 19;         //Sample Window time 100ns = (ACQPS + 1) * SYSCLK(200Mhz , 5ns)
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;        //SOC0 : ePWM1 SOCA Trigger
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;      //0: EOC0 is trigger for ADCINT1
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;        //ADCINT1 Interrupt Enable
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;      //Interrupt Flag Clear

    //ADCB : Config ADC of Current Hall Sensor
    AdcbRegs.ADCCTL2.bit.PRESCALE = 0;
    AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);  //12bit Single Mode
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = 5;
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = 19;
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0;
    AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1;
    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;

    //ADCC : Config ADC of Inverter Output AC Volt
    AdccRegs.ADCCTL2.bit.PRESCALE = 0;
    AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);  //12bit Single Mode
    AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    AdccRegs.ADCSOC0CTL.bit.CHSEL = 5;
    AdccRegs.ADCSOC0CTL.bit.ACQPS = 19;
    AdccRegs.ADCSOC0CTL.bit.TRIGSEL = 5;
    AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 0;
    AdccRegs.ADCINTSEL1N2.bit.INT1E = 1;
    AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;

    //ADC A,B,C Power ON
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;          
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    EDIS;
    DELAY_US(1000);                             

    EPwm1Regs.CMPA.bit.CMPA = 2000;                        //Comparator A Level
    EINT;
    ERTM;

    while(1)
    {

    }

}


//Inverter DC Input Voltage
interrupt void adca5_isr(void)
{
    Uint16 tmp;
    ADC_VBUS_CNT++;
    tmp = AdcaResultRegs.ADCRESULT0;           
    if(ADC_VBUS_CNT < ADC_DATA_GET_CNT)
    {
        AdcaRegs.ADCSOCFRC1.bit.SOC0 = 1;      //SOC Software Start
        ADC_VBUS_HEX = ADC_VBUS_HEX + (tmp * tmp);
    }
    else
    {
        ADC_VBUS_HEX = ADC_VBUS_HEX + (tmp * tmp);
        ADC_VBUS_RMS_HEX = sqrt((float32)(ADC_VBUS_HEX / ADC_DATA_GET_CNT));
        ADC_VBUS_CNT = 0;
        ADC_VBUS_HEX = 0;
    }
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; 
//    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    PieCtrlRegs.PIEACK.bit.ACK1 = 1;         
}

//Inverter AC Output Voltage
interrupt void adcc14_isr(void)
{
    Uint16 tmp;
    ADC_VLINE_CNT++;
    tmp = AdccResultRegs.ADCRESULT0;         
    if(ADC_VLINE_CNT < ADC_DATA_GET_CNT)
    {
        AdccRegs.ADCSOCFRC1.bit.SOC0 = 1;      //SOC Software Start
        ADC_VLINE_HEX = ADC_VLINE_HEX + (tmp * tmp);
    }
    else
    {
        ADC_VLINE_HEX = ADC_VLINE_HEX + (tmp * tmp);
        ADC_VLINE_RMS_HEX = sqrt((float32)(ADC_VLINE_HEX / ADC_DATA_GET_CNT));
        ADC_VLINE_CNT = 0;
        ADC_VLINE_HEX = 0;
    }

    AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;  
//    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; 
    PieCtrlRegs.PIEACK.bit.ACK1 = 1;         
}

//Inverter Current Hall Sensor
interrupt void adcb2_isr(void)
{
    Uint16 tmp;
    ADC_VHALL_CNT++;
    tmp = AdcbResultRegs.ADCRESULT0;           
    if(ADC_VHALL_CNT < ADC_DATA_GET_CNT)
    {
        AdcbRegs.ADCSOCFRC1.bit.SOC0 = 1;      //SOC Software Start
        ADC_VHALL_HEX = ADC_VHALL_HEX + (tmp * tmp);
    }
    else
    {
        ADC_VHALL_HEX = ADC_VHALL_HEX + (tmp * tmp);
        ADC_VHALL_RMS_HEX = sqrt((float32)(ADC_VHALL_HEX / ADC_DATA_GET_CNT));
        ADC_VHALL_CNT = 0;
        ADC_VHALL_HEX = 0;
    }

    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;     
//    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  
    PieCtrlRegs.PIEACK.bit.ACK1 = 1;         
}

  • Hi Bae,

    One thing you might check is AdcbRegs.ADCINTOVF register. Bits being set in this register indicate the ISR was triggered again before the previous ISR could be serviced.

    Note that if you are using the same trigger source for multiple SOCs you'd typically one use one ISR to collect the results. This includes SOCs on different ADCs. Instead, just pick an ADC and then collect the samples for all the SOCs from all the ADCs inside that single ISR. In your case all your SOCs use trigsel = '5' so you might e.g. collect all the results in an ISR triggered by ADCA EOC0.
  • Thanks to your advice, I solved the problem.