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.

LAUNCHXL-F280039C: How to trigger the ADC SOCs by PMW?

Part Number: LAUNCHXL-F280039C

Tool/software:

Hi everyone,

I wrote a program that uses PWM to trigger an interrupt, but the ADCs inside the interrupt didn't return any values.
Can someone tell me what might be wrong with the settings?

// Included Files
#include "f28x_project.h"
#include "stdio.h"
#include "math.h"

// Defines
#define RESULTS_BUFFER_SIZE     256

// Globals
uint16_t adcAResults[RESULTS_BUFFER_SIZE];   // Buffer for results
uint16_t index;                              // Index into result buffer
volatile uint16_t bufferFull;                // Flag to indicate buffer is full

// ------------------------------------- Digital Variables ------------------------------------- //
// ADC pins for detecting analog values (digital)
unsigned int ADC_A6;                         // ADC_A6_Voltage_N
unsigned int ADC_B6;                         // ADC_B6_Voltage_L
unsigned int ADC_C0;                         // ADC_C0_Voltage_Out

// ------------------------------------- Analog Variables -------------------------------------- //
// Values for digital turning to analog (analog)
float VAC_N_A6;                              // A6_Voltage_N
float VAC_L_B6;                              // B6_Voltage_L
float VO_C0;                                 // C0_Voltage_Out

int CMPA = 600.0;
int CMPB = 1199.0;

// Function Prototypes
__interrupt void EPWM1ISR(void);

void initEPWM(void);
void initADC(void);
void initADCSOC(void);




// Main
void main(void){

    // Initialize device clock and peripherals
    InitSysCtrl();
    // Initialize GPIO
    InitGpio();

    EALLOW;
    // Setup GPIO ----------------------------------------------------------------------------- ///
    // GPIO20: It is for checking the EPWM1 interrupt is working properly or not.
    GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;         // Disable pull-up res. on GPIO20
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0;        // Configure GPIO20 as a GPIO pin
    GpioCtrlRegs.GPADIR.bit.GPIO20 = 1;         // Configure GPIO20 as a output pin

    // GPIO0.GPIO1: They are set for output pins of the fast-legs ----------------------------- ///
    GpioCtrlRegs.GPAPUD.bit.GPIO0=1;            // Disable pull-up res. on GPIO0 (EPWM1A)
    GpioCtrlRegs.GPAMUX1.bit.GPIO0=1;           // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPAPUD.bit.GPIO1=1;            // Disable pull-up res. on GPIO1 (EPWM1B)
    GpioCtrlRegs.GPAMUX1.bit.GPIO1=1;           // Configure GPIO1 as EPWM1B
    EDIS;

    // Disable CPU interrupts
    DINT;

    InitPieCtrl();

    IER = 0x0000;
    IFR = 0x0000;

    InitPieVectTable();

    // Map ISR functions
    EALLOW;
    PieVectTable.EPWM1_INT = &EPWM1ISR;         // Function for EPWM1 interrupt 1
    EDIS;

    // Configure the ePWM
    initEPWM();
    // Configure the ADC and power it up
    initADC();
    // Setup the ADC for ePWM triggered conversions on channel 1
    initADCSOC();
    // Configure the DAC
    //initDACA();

    // Enable global Interrupts and higher priority real-time debug events:
    IER |= M_INT3;                              // Enable group 3 interrupts

    EINT;                                       // Enable Global interrupt INTM
    ERTM;                                       // Enable Global realtime interrupt DBGM

    // Initialize results buffer
    for(index = 0; index < RESULTS_BUFFER_SIZE; index++){
        adcAResults[index] = 0;
    }
    index = 0;
    bufferFull = 0;

    // Enable PIE interrupt
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

    // Sync ePWM
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    // Take conversions indefinitely in loop
    while(1){
    }
}



//
// EPWM1ISR - EPWM1 Interrupt ISR
//
__interrupt void EPWM1ISR(void){

    // For checking the start of the interrupt.
    GpioDataRegs.GPASET.bit.GPIO20 = 1;

    // For reading the ADC values of A6 & B6 & C0 pins of SOC0...
    // and A3 & B14 pins of SOC1. SOC2. SOC3
    ADC_A6 = AdcaResultRegs.ADCRESULT0;           // ADC of VAC_N
    ADC_B6 = AdcbResultRegs.ADCRESULT0;           // ADC of VAC_L
    ADC_C0 = AdccResultRegs.ADCRESULT0;           // ADC of Vout

    //For checking the end of the interrupt.
    GpioDataRegs.GPACLEAR.bit.GPIO20 = 1;

    EPwm1Regs.ETCLR.bit.INT = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;     // Acknowledge the interrupt
}
//
// End of program
//


//
// initEPWM - Function to configure ePWM1 to generate the SOC.
//
void initEPWM(void){
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;    // Set TBCLKSYNC = 0
    CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;        // Enable ePWM module clocks in the PCLKCRx register

    //EPwm1Regs.EPWMSYNCINSEL.all = SYNC_IN_SRC_DISABLE_ALL;
    //EPwm1Regs.EPWMSYNCOUTEN.all = SYNC_OUT_SRC_DISABLE_ALL;

    // ePWM Phase setting
    EPwm1Regs.TBCTL.bit.PHSEN = 0;           // (0)Disable phase loading
    EPwm1Regs.TBPHS.bit.TBPHS = 0;           // Phase is 0

    // TBCLK = EPWMCLK / (HSPCLKDIV * CLKDIV)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;       // HSPCLKDIV = 1
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;          // CLKDIV = 1

    // Config for the frequency and duty cycle of the EPWM1
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;         // Counter mode: (0)Count up
    EPwm1Regs.TBCTR = 0;                     // Time Base Counter Register
    EPwm1Regs.TBPRD = 1199;                  // Set period counts
    EPwm1Regs.CMPA.bit.CMPA = CMPA;
    EPwm1Regs.CMPB.bit.CMPB = CMPB;

    // Setup Counter-Compare(CC) Submodule ---------------------------------------------------- ///
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;      // Load registers every ZERO
    EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;      // Load registers every ZERO

    // Setup Action-Qualifier(AQ) Submodule --------------------------------------------------- ///
    EPwm1Regs.AQCTLA.bit.ZRO = 2;          // Action when TBCTR = 0               ; 2: force EPWM1A output high.
    EPwm1Regs.AQCTLA.bit.CAU = 1;          // Action when TBCTR = CMPA on Up-count; 1: force EPWM1A output low.
    EPwm1Regs.AQCTLB.bit.CAU = 1;          // Action when TBCTR = CMPA on Up-count; 1: force EPWM1B output low.
    EPwm1Regs.AQCTLB.bit.CBU = 2;          // Action when TBCTR = CMPB on Up-count; 2: force EPWM1B output high.

    // Setup Dead-Band(DB) Submodule --------------------------------------------------- ///
    EPwm1Regs.DBCTL.bit.IN_MODE = 2;
    EPwm1Regs.DBCTL.bit.POLSEL = 2;        // EPWMxA directly output(D); EPWMxB inverted output(1-D)
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3;      // Enable the dead-time.
    EPwm1Regs.DBRED.bit.DBRED = 48;        // 1u = DBRED * (1/120M) => DBRED = 120
    EPwm1Regs.DBFED.bit.DBFED = 47;        // 24 = 200n(= 10u*2% );48 = 400n(= 10u*4% )

    //EPwm1Regs.EPWMSYNCOUTEN.bit.ZEROEN = 1;

    EPwm1Regs.ETSEL.bit.SOCAEN = 1;
    EPwm1Regs.ETSEL.bit.SOCASEL = 1;

    // Event Trigger and Interrupt(ET) Submodule:
    EPwm1Regs.ETSEL.bit.INTEN = 1;          // Enable SOCA
    EPwm1Regs.ETSEL.bit.INTSEL = 1;         // 001: Enable event time-base counter equal to zero
    EPwm1Regs.ETPS.bit.INTPRD = 1;          // Generate pulse on 1st event

    EDIS;
}

//
// initADC - Function to configure and power up ADCA.
//
void initADC(void){
    // Setup VREF as internal for ADC-A & ADC-B & ADC-C
    SetVREF(ADC_ADCA, ADC_INTERNAL, ADC_VREF3P3);
    SetVREF(ADC_ADCB, ADC_INTERNAL, ADC_VREF3P3);
    SetVREF(ADC_ADCC, ADC_INTERNAL, ADC_VREF3P3);
    EALLOW;
    // ADC-A Group Settings
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6;      // Set ADCCLK divider to /4
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;   // Set pulse positions to late
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;      // Power up the ADC and then delay for 1 ms
    // ADC-B Group Settings
    AdcbRegs.ADCCTL2.bit.PRESCALE = 6;      // Set ADCCLK divider to /4
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;   // Set pulse positions to late
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;      // Power up the ADC and then delay for 1 ms
    // ADC-C Group Settings
    AdccRegs.ADCCTL2.bit.PRESCALE = 6;      // Set ADCCLK divider to /4
    AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;   // Set pulse positions to late
    AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;      // Power up the ADC and then delay for 1 ms
    EDIS;
    DELAY_US(1000);
}

//
// initADCSOC - Function to configure ADCA's SOC0 to be triggered by ePWM1.
//
void initADCSOC(void){
    EALLOW;
    /// SOCs Configuration -------------------------------------------------------------------- ///
    /// A6 & B6 & C0 Settings of SOC0
    /// A6 - SOC0
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 6;      // SOC0 will convert pin A6
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 19;     // Sample window is 20 SYSCLK cycles
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;    // Triggered by ePWM1
    /// B6 - SOC0
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = 6;      // SOC0 will convert pin B6
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = 19;     // Sample window is 20 SYSCLK cycles
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5;    // Triggered by ePWM1
    /// C0 - SOC0
    AdccRegs.ADCSOC0CTL.bit.CHSEL = 0;      // SOC0 will convert pin C0
    AdccRegs.ADCSOC0CTL.bit.ACQPS = 19;     // Sample window is 20 SYSCLK cycles
    AdccRegs.ADCSOC0CTL.bit.TRIGSEL = 5;    // Triggered by ePWM1

    ///The INT1 settings.  "INT1SEL" must configure according to the end of the SOCs.(ex: this program is end of SOC1)
    //AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 2; // End of SOC1 will set INT1 flag
    //AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   // Enable INT1 flag
    //AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Make sure INT1 flag is cleared
    EDIS;
}

Best Regards,

Eric Tsai