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-F28379D: ADC interrupt not generating when ADC module is changed

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: TMS320F28379D

Hi

I am trying to implement the example program  "adc_soc_epwm_cpu1" for TMSF28379D. 

The example code works fine. However, if I just change the Adca module to Adcb module in the code (code attached) the ADCINTFLG is set and the code does not enter the ISR.

I am trying to understand the relation between ADCINT and how its triggers PIE to enter the ISR.

I also tried using different ADCINT even for Adca module but the code does not enter ISR.

So, if i have to conclude the code works fine as given for ADCINT1 for PIER1 but if any of this is changed or tha ADC module is changed, it does not enter the ISR.

Can anyone please help?

#include "F28x_Project.h"

//
// Function Prototypes
//
void ConfigureADC(void);
void ConfigureEPWM(void);
void SetupADCEpwm(Uint16 channel);
interrupt void adcb2_isr(void);
float V =0.0;

//
// Defines
//
#define RESULTS_BUFFER_SIZE 256

//
// Globals
//
Uint16 AdcbResults[RESULTS_BUFFER_SIZE];
Uint16 resultsIndex;
volatile Uint16 bufferFull;

void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
    InitSysCtrl();

//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
    InitGpio(); // Skipped for this example

//
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
    DINT;

//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
//
    InitPieCtrl();

//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
    IER = 0x0000;
    IFR = 0x0000;

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
    InitPieVectTable();

//
// Map ISR functions
//
    EALLOW;
    PieVectTable.ADCB1_INT = &adcb2_isr; //function for ADCA interrupt 1
    EDIS;

//
// Configure the ADC and power it up
//
    ConfigureADC();

//
// Configure the ePWM
//
    ConfigureEPWM();

//
// Setup the ADC for ePWM triggered conversions on channel 0
//
    SetupADCEpwm(0);

//
// Enable global Interrupts and higher priority real-time debug events:
//
    IER |= M_INT1; //Enable group 1 interrupts
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

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

//
// enable PIE interrupt
//
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;

//
// sync ePWM
//
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;

//
//take conversions indefinitely in loop
//
    do
    {
        //
        //start ePWM
        //
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
        EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode

        //
        //wait while ePWM causes ADC conversions, which then cause interrupts,
        //which fill the results buffer, eventually setting the bufferFull
        //flag
        //
        while(!bufferFull);
        bufferFull = 0; //clear the buffer full flag

        //
        //stop ePWM
        //
        EPwm1Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA
        EPwm1Regs.TBCTL.bit.CTRMODE = 3; //freeze counter

        //
        //at this point, AdcaResults[] contains a sequence of conversions
        //from the selected channel
        //

        //
        //software breakpoint, hit run again to get updated conversions
        //
        asm("   ESTOP0");
    }while(1);
}

//
// ConfigureADC - Write ADC configurations and power up the ADC for both
//                ADC A and ADC B
//
void ConfigureADC(void)
{
    EALLOW;

    //
    //write configurations
    //
    AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);

    //
    //Set pulse positions to late
    //
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    //
    //power up the ADC
    //
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    //
    //delay for 1ms to allow ADC time to power up
    //
    DELAY_US(1000);

    EDIS;
}

//
// ConfigureEPWM - Configure EPWM SOC and compare values
//
void ConfigureEPWM(void)
{
    EALLOW;
    // Assumes ePWM clock is already enabled
    EPwm1Regs.ETSEL.bit.SOCAEN    = 0;    // Disable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL    = 4;   // Select SOC on up-count
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;       // Generate pulse on 1st event
    EPwm1Regs.CMPA.bit.CMPA = 0x0800;     // Set compare A value to 2048 counts
    EPwm1Regs.TBPRD = 0x1000;             // Set period to 4096 counts
    EPwm1Regs.TBCTL.bit.CTRMODE = 3;      // freeze counter
    EDIS;
}

//
// SetupADCEpwm - Setup ADC EPWM acquisition window
//
void SetupADCEpwm(Uint16 channel)
{
    Uint16 acqps;

    //
    //determine minimum acquisition window (in SYSCLKS) based on resolution
    //
    if(ADC_RESOLUTION_12BIT == AdcbRegs.ADCCTL2.bit.RESOLUTION)
    {
        acqps = 14; //75ns
    }
    else //resolution is 16-bit
    {
        acqps = 63; //320ns
    }

    //
    //Select the channels to convert and end of conversion flag
    //
    EALLOW;
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin A0
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C
    AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    EDIS;
}

//
// adca1_isr - Read ADC Buffer in ISR
//
interrupt void adcb2_isr(void)
{
    AdcbResults[resultsIndex++] = AdcbResultRegs.ADCRESULT0;
    V = 0.2*AdcbResultRegs.ADCRESULT0;
    if(RESULTS_BUFFER_SIZE <= resultsIndex)
    {
        resultsIndex = 0;
        bufferFull = 1;
    }

    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

  • Hi Sneha,

    In the PIE vector table, the classification is based on groups and channels. ADC A1 belongs to group 1 channel 1, while ADC B1 belongs to group 1 channel 2. You can find this classification in the TMS320F28379D reference manual under section 3.4.5 PIE Channel Mapping.

    You have enabled the interrupt group properly but not the channel.

        IER |= M_INT1; //Enable group 1 interrupts -- Enables the group

        PieCtrlRegs.PIEIER1.bit.INTx1 = 1; -- Enables the channel (This is for ADC A1)

    Please change the above line to 

    PieCtrlRegs.PIEIER1.bit.INTx2 = 1;

     

    Let me know if this change solves your problem.

    Thanks,

    Aditya

  • Hi Aditya

    Thank you for your response. It did resolve my issue.

    I have another question related to this now. I am using CPU timer 0 to generate CMPA for ePWM1. I am also using ePWM1 as a trigger for SOC.  Everything works fine ADC result registers also show the required value, however ADC does not enter the ISR.

    As per my understanding, CPU timer0 has higher priority then ADC ISR and thus this might be the issue for code not entering ADC ISR.

    Can you please suggest a solution wherein I can use CPU timer 0 and ADC ISRs?

    Code is attached.

    #include "F28x_Project.h"
    #include "math.h"

    #define EPWM1_MAX_DB 20 // max deadband for pv/pfc 150 ns
    #define EPWM1_MIN_DB 15 // min deadband for pv/pfc
    #define EPWM3_MAX_DB 20 // max deadband for pv/pfc 150 ns
    #define EPWM3_MIN_DB 15 // min deadband for pv/pfc
    #define phase_bridge 20;// PS between two DAB bridges
    #define phase_leg 0x0000//20;PS between two legs of a bridge

    // To keep track of which way the compare value is moving
    #define EPWM_CMP_UP 1
    #define EPWM_CMP_DOWN 0
    #define DB_UP 1
    #define DB_DOWN 0

    #define RESULTS_BUFFER_SIZE 256

    float result_V =0.0;
    float result_Vx =0.0;

    float mod = 0.9; // modulation index
    float pi = 3.14285714;
    float f_clk = 100000000.0f; // DSp clock frequency = SYSCLK/2 = 100MHz
    float fg = 60.0f; // grid frquency
    float f_pfc = 300000.0f; // pfc, pv frquency
    float f_sw = 300000.0f; // dab frquency
    float dt = 0.000005; // sampling frequency for SPWm generation, pfc = 1/f_pfc

    float time = 0.00000000000;
    float ref = 0.0;
    float ref_offset = 0.0;
    float TBDAB = 0;
    float TBPFC = 0;
    float dutyA_DAB = 0;
    float dutyB_DAB = 0;
    float dutyA_pv = 0;
    float dutyB_pv = 0;

    typedef struct
    {
    volatile struct EPWM_REGS *EPwmRegHandle;
    Uint16 EPwmDB_Direction;
    Uint16 EPwmTimerIntCount; //these definitions here are required for update_compare11 routine for updating the deadband
    Uint16 EPWMMAX_DB;
    Uint16 EPWMMIN_DB;
    }EPWM_INFO; // should only be defined here, otherwise causes type name error
    EPWM_INFO epwm1_info;
    EPWM_INFO epwm3_info;
    EPWM_INFO epwm4_info;
    EPWM_INFO epwm5_info;
    EPWM_INFO epwm6_info;


    Uint16 AdcaResults[RESULTS_BUFFER_SIZE];
    Uint16 resultsIndex;
    volatile Uint16 bufferFull;

    void ConfigureADC(void);
    void SetupADCEpwm(Uint16 channel);

    void InitEPwm1Example(void);

    void InitEPwm3Example(void);
    void InitEPwm4Example(void);

    void InitEPwm5Example(void);
    void InitEPwm6Example(void);

    void update_compare1(EPWM_INFO*);

    __interrupt void epwm1_isr(void);

    __interrupt void epwm3_isr(void);
    __interrupt void epwm4_isr(void);

    __interrupt void epwm5_isr(void);
    __interrupt void epwm6_isr(void);


    // Function Prototypes
    //
    __interrupt void cpu_timer0_isr(void);
    interrupt void adca1_isr(void);

    Uint32 EPwm1TimerIntCount;


    Uint32 EPwm3TimerIntCount;
    Uint32 EPwm4TimerIntCount;

    Uint32 EPwm5TimerIntCount;
    Uint32 EPwm6TimerIntCount;


    Uint16 EPwm1_DB_Direction;


    Uint16 EPwm3_DB_Direction;
    Uint16 EPwm4_DB_Direction;

    Uint16 EPwm5_DB_Direction;
    Uint16 EPwm6_DB_Direction;

    void main(void)
    {
    //
        // rounding the prd register to highest value
        TBDAB = ceil(f_clk/(2*f_sw)); // ceil value for dab period register
        TBPFC = ceil(f_clk / (2 * f_pfc)); // ceil value for pv, tpfc period register
        dutyA_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
        dutyB_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
    
        //D =0.5 tbpfc/2, D<0.5 tbpfc/2
        dutyA_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
        dutyB_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
        // Initialise this code for using GPIO2 and 3 for ePWM2 TPFC line frequency pulse generation
        InitGpio();
      
    
        CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM4 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM5 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM6 = 1;
     
        InitEPwm1Gpio();
        InitEPwm3Gpio();
        InitEPwm4Gpio();
        InitEPwm5Gpio();
        InitEPwm6Gpio();
      
    //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
        DINT;
    
    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
    //
        InitPieCtrl();
    
    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
        IER = 0x0000;
        IFR = 0x0000;
    
    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
    //
        InitPieVectTable();
    
    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
        EALLOW;
        // This is needed to write to EALLOW protected registers
    
        PieVectTable.TIMER0_INT = &cpu_timer0_isr;
    
        PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
    
        PieVectTable.EPWM1_INT = &epwm1_isr;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        PieVectTable.EPWM4_INT = &epwm4_isr;
        PieVectTable.EPWM5_INT = &epwm5_isr;
        PieVectTable.EPWM6_INT = &epwm6_isr;
        EDIS;
    
    //
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in F2837xD_CpuTimers.c
    //
        InitCpuTimers();   // For this example, only initialize the Cpu Timers
    
    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
        ConfigCpuTimer(&CpuTimer0, 200, 5);
    
        // Step 4. Initialize all the Device Peripherals:
        // This function is found in DSP2833x_InitPeripherals.c
        // InitPeripherals(); // Not required for this example
    
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        InitEPwm1Example();
        InitEPwm3Example();
        InitEPwm4Example();
        InitEPwm5Example();
        InitEPwm6Example();
      
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xD_cputimervars.h), the below
    // settings must also be updated.
    //
        CpuTimer0Regs.TCR.all = 0x4000;
    
        // Configure the ADC and power it up
        //
        ConfigureADC();
    
    
        // Setup the ADC for ePWM triggered conversions on channel 0
        //
        SetupADCEpwm(0); //Input ADC channel here
      
        
    //
    // Step 5. User specific code, enable interrupts:
    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
        IER |= M_INT1;
        
        // Initialize results buffer
        //
        for (resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
        {
            AdcaResults[resultsIndex] = 0;
        }
        resultsIndex = 0;
        bufferFull = 0;
    
    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
        PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx4 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx5 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx6 = 1;
      
    //
        PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //ADC A1 group1 channel 1
    
    // Enable global Interrupts and higher priority real-time debug events:
    //
        EINT;
        // Enable Global interrupt INTM
        ERTM;
        // Enable Global realtime interrupt DBGM
    
    //
    // Step 6. IDLE loop. Just sit and loop forever (optional):
    //
        do
            {
                //
                //start ePWM
                //
                EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
                EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode
    
                //
                //wait while ePWM causes ADC conversions, which then cause interrupts,
                //which fill the results buffer, eventually setting the bufferFull
                //flag
                //
    
    
               while(!bufferFull);
    
                bufferFull = 0; //clear the buffer full flag
    
                //
                //stop ePWM
                //
                EPwm1Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA
                EPwm1Regs.TBCTL.bit.CTRMODE = 3; //freeze counter
    
                //
                //at this point, AdcaResults[] contains a sequence of conversions
                //from the selected channel
                //
    
                //
                //software breakpoint, hit run again to get updated conversions
                //
                asm("   ESTOP0");
            }while(1);
    }
    
    //
    // ConfigureADC - Write ADC configurations and power up the ADC for both
    //                ADC A and ADC B
    //
    void ConfigureADC(void)
    {
        EALLOW;
    
        //
        //write configurations
        //
        AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
        AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // ADC module selection
        //
        //Set pulse positions to late
        //
        AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
        //
        //power up the ADC
        //
        AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
        //
        //delay for 1ms to allow ADC time to power up
        //
        DELAY_US(1000);
    
        EDIS;
    }
    // cpu_timer0_isr - CPU Timer0 ISR with interrupt counter
    //
    __interrupt void cpu_timer0_isr(void)
    {
        if (time < 10)
        {
            time = time + dt;
        }
        else
        {
            time = 0;
        }
    
        ref = mod * sin(2 * 3.14 * fg * time);
        ref_offset = (TBPFC * ref) / 2 + TBPFC / 2;
    
        // Update the CMPA and CMPB values
    
        // Clear INT flag for this timer
        EPwm1Regs.ETCLR.bit.INT = 1;
        //EPwm2Regs.ETCLR.bit.INT = 1;
    
        //PWM1........
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset; //EPWM1_MAX_CMPB;               // Set Compare B value
    
     
        CpuTimer0.InterruptCount++;
    
        
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1
    
    }
    
    __interrupt void epwm1_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm1_info);
    
        // Clear INT flag for this timer
        //
        EPwm1Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    
    
    __interrupt void epwm3_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm3_info);
    
        // Clear INT flag for this timer
        //
        EPwm3Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    __interrupt void epwm4_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm4_info);
    
        // Clear INT flag for this timer
        //
        EPwm4Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    __interrupt void epwm5_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm5_info);
    
        // Clear INT flag for this timer
        //
        EPwm5Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    __interrupt void epwm6_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm6_info);
    
        // Clear INT flag for this timer
        //
        EPwm6Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    interrupt void adca1_isr(void)
    {
        result_V = AdcaResultRegs.ADCRESULT0;
        result_Vx = 0.0007324 * result_V;
    
        if(RESULTS_BUFFER_SIZE <= resultsIndex)
        {
            resultsIndex = 0;
            bufferFull = 1;
        }
    
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    
    }
    
    
    // PWM1
    void InitEPwm1Example()
    {
    
        // Setup TBCLK
        EPwm1Regs.TBPRD = TBPFC;          // Set timer period 801 TBCLKs
        EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset;   // Set Compare B value
    
        // Setup counter mode
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
        //EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // required to disable this master and for independent pwm generation
    
        // Setup shadowing
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // Load on Zero
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        //Enable ADC SOC
        EPwm1Regs.ETSEL.bit.SOCAEN = 0;    // Disable SOC on A group
        EPwm1Regs.ETSEL.bit.SOCASEL = 4;   // Select SOC on up-count
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;    // Generate pulse on 1st event
    
    
        // Set actions
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //AQ_SET;         // When sine<triangle set lower switch 51
        EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; //AQ_CLEAR;   // Clear PWM1A on event A, down count
    
        EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; //AQ_CLEAR;       // // When sine>triangle set upper switch 49
        EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; //AQ_SET;     // Clear PWM1B on event B, down count
    
        //essentially first upper switch conducts with leg 2 lower
    
        // Active high complementary PWMs - Setup the deadband
        //
        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm1Regs.DBRED.bit.DBRED = EPWM1_MIN_DB;
        EPwm1Regs.DBFED.bit.DBFED = EPWM1_MIN_DB;
        EPwm1_DB_Direction = DB_UP;
    
        //
        // Interrupt where we will change the deadband
        //
        EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Select INT on Zero event
        EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT
        EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;            // Generate INT on 3rd event
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm1_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm1_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm1_info.EPwmRegHandle = &EPwm1Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm1_info.EPWMMAX_DB = EPWM1_MAX_DB;      // Setup min/max
        epwm1_info.EPWMMIN_DB = EPWM1_MIN_DB;      // Setup min/max
    
    }
    
    // PWM3
    void InitEPwm3Example(void)
    {
    
        // Setup TBCLK
        EPwm3Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm3Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm3Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm3Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM3A on period
        EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;   // Clear PWM3A on event B, down count
    
        EPwm3Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Clear PWM3A on period
        EPwm3Regs.AQCTLB.bit.CBD = AQ_SET;         // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm3Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm3Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm3_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm3Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm3Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm3_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm3_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm3_info.EPwmRegHandle = &EPwm3Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm3_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm3_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    // PWM4
    void InitEPwm4Example(void)
    {
    
        // Setup TBCLK
        EPwm4Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm4Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm4Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm4Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm4Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Set PWM3A on period
        EPwm4Regs.AQCTLA.bit.CAD = AQ_SET;    // Clear PWM3A on event B, down count
    
        EPwm4Regs.AQCTLB.bit.CBU = AQ_SET;            // Clear PWM3A on period
        EPwm4Regs.AQCTLB.bit.CBD = AQ_CLEAR;       // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm4Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm4Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm4Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm4_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm4Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm4Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm4Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm4_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm4_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm4_info.EPwmRegHandle = &EPwm4Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm4_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm4_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    
    // PWM5
    void InitEPwm5Example(void)
    {
    
        // Setup TBCLK
        EPwm5Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm5Regs.TBPHS.bit.TBPHS = phase_bridge;             // Phase is 0
        EPwm5Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm5Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm5Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
    
        // Setup shadow register load on ZERO
        EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm5Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm5Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM3A on period
        EPwm5Regs.AQCTLA.bit.CAD = AQ_CLEAR;   // Clear PWM3A on event B, down count
    
        EPwm5Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Clear PWM3A on period
        EPwm5Regs.AQCTLB.bit.CBD = AQ_SET;         // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm5Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm5Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm5Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm5_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm5Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm5Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm5Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm5_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm5_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm5_info.EPwmRegHandle = &EPwm5Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm5_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm5_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    // PWM6
    void InitEPwm6Example(void)
    {
    
        // Setup TBCLK
        EPwm6Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm6Regs.TBPHS.bit.TBPHS = phase_bridge;            // Phase is 0
        EPwm6Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm6Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm6Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Set PWM3A on period
        EPwm6Regs.AQCTLA.bit.CAD = AQ_SET;    // Clear PWM3A on event B, down count
    
        EPwm6Regs.AQCTLB.bit.CBU = AQ_SET;            // Clear PWM3A on period
        EPwm6Regs.AQCTLB.bit.CBD = AQ_CLEAR;       // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm6Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm6Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm6Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm6_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm6Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm6Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm6_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm6_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm6_info.EPwmRegHandle = &EPwm6Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm6_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm6_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    
    //
    void update_compare1(EPWM_INFO *epwm_info)
    {
        if (epwm_info->EPwmDB_Direction == DB_UP)
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED < epwm_info->EPWMMAX_DB)
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmDB_Direction = DB_DOWN;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
        else
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED == epwm_info->EPWMMIN_DB)
            {
                epwm_info->EPwmDB_Direction = DB_UP;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
    
        epwm_info->EPwmTimerIntCount++;
    
        //   return;
    }
    //
    void SetupADCEpwm(Uint16 channel)
    {
        Uint16 acqps;
    
        //
        //determine minimum acquisition window (in SYSCLKS) based on resolution
        //
        if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
        {
            acqps = 14; //75ns
        }
        else //resolution is 16-bit
        {
            acqps = 63; //320ns
        }
    
        //
        //Select the channels to convert and end of conversion flag
        //
        EALLOW;
        AdcaRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin A0
        AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
        AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C
    
        AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
        AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
        EDIS;
    
    }
    
    
    // End of file

    Thanks 

    Sneha

  • Hi Sneha,

    Everything works fine ADC result registers also show the required value, however ADC does not enter the ISR.

    How are you checking the results from the ADC register if the CPU doesn't enter the ISR? I see that the result is being checked in the ISR.

    As per my understanding, CPU timer0 has higher priority then ADC ISR and thus this might be the issue for code not entering ADC ISR.

    It is actually the other way round. ADC has higher priority than the timer. ADCA1 is group 1 channel 1 interrupt while timer0 is group 1 channel 7. Lowest numbered channel in the lowest numbered group is serviced first. In this case, ADCA1 is higher priority. Attaching an image from the reference manual for better understanding.

    Thanks,

    Aditya

  • Hi Aditya

    How are you checking the results from the ADC register if the CPU doesn't enter the ISR? I see that the result is being checked in the ISR.

    I am checking the ADC result registers which have the result. I have defined a variable result_Vx1 and result_Vxd1 in ADC ISR to check the results. I am observing these variables which do not show any value even if ADC result registers show the conversion and this confirms to me code is not entering ISR.

    ADC has higher priority than the timer.

    Thank you for sharing this. Then I guess the problem is something else. And now I also observe that ePWM1 does not generate any pulses. CPU timer 0 is actually generating the CMPA for ePWM1. So, I will try looking into this issue and will share the results this evening.

    Thanks

    Sneha

  • Thank you for updating. Let me know if you need any additional support.

    Aditya

  • Hi 

    Can someone please look at this code and point out my mistake. I want to use ePWM1 to trigger ADC_A and ePWM3 to trigger ADC_D and generate respective PWM pulses on ePWM1 and ePWM3. The problems I am facing are:

    1. When ePWM1 is used to trigger both ADC_A and ADC_D I can see the results in ADCa Result register as well as ADCd Result register. However, the code does not enter adcd_isr, as I cannot see the results in variable resuly_Vxd1. The code does enter adca_isr as i can see the result in variable result_Vx. Also, if I move line 414 and 415 for result_Vxd1 in adca_isr after line 394/395 I can see the results in these variables. Why does the code not enter adcd_ISR even though I have initialized correct PIE group and channel for these?

    2. When I use ePWM3 to trigger ADC conversion for both ADC_A and ADC_D, No conversion takes place.

    3. If I use ePWM1 for ADC_A and ePWM3 for ADC_D, then ADC_A works correctly, whereas no conversion takes place for ADC_D.

    I will appreciate your time for this.

    Thanks 

    Sneha

    #include "F28x_Project.h"
    #include "math.h"

    #define EPWM1_MAX_DB 20 // max deadband for pv/pfc 150 ns
    #define EPWM1_MIN_DB 15 // min deadband for pv/pfc
    #define EPWM3_MAX_DB 20 // max deadband for pv/pfc 150 ns
    #define EPWM3_MIN_DB 15 // min deadband for pv/pfc
    #define phase_bridge 20;// PS between two DAB bridges
    #define phase_leg 0x0000//20;PS between two legs of a bridge

    // To keep track of which way the compare value is moving
    #define EPWM_CMP_UP 1
    #define EPWM_CMP_DOWN 0
    #define DB_UP 1
    #define DB_DOWN 0

    #define RESULTS_BUFFER_SIZE 256
    #define RESULTS_BUFFER_SIZEd 256

    float result_V =0.0;
    float result_Vx =0.0;
    float result_Vd =0.0;
    float result_Vxd =0.0;
    float result_Vxd1 =0.0;
    float gain_vdc2 = 215.28;
    float Vdc2 = 0.0;
    
    float mod  = 0.9; // modulation index
    float pi = 3.14285714;
    float f_clk =   100000000.0f;  // DSp clock frequency = SYSCLK/2 = 100MHz
    float fg   = 60.0f;  // grid frquency
    float f_pfc = 300000.0f;  // pfc, pv frquency
    float f_sw  = 300000.0f;  // dab  frquency
    float dt   = 0.000005;  // sampling frequency for SPWm generation, pfc = 1/f_pfc
    
    float time = 0.00000000000;
    float ref = 0.0;
    float ref_offset = 0.0;
    float TBDAB = 0;
    float TBPFC = 0;
    float dutyA_DAB = 0;
    float dutyB_DAB = 0;
    float dutyA_pv = 0;
    float dutyB_pv = 0;
    
    typedef struct
    {
        volatile struct EPWM_REGS *EPwmRegHandle;
        Uint16 EPwmDB_Direction;
        Uint16 EPwmTimerIntCount; //these definitions here are required for update_compare11 routine for updating the deadband
        Uint16 EPWMMAX_DB;
        Uint16 EPWMMIN_DB;
    }EPWM_INFO; // should only be defined here, otherwise causes type name error
    EPWM_INFO epwm1_info;
    EPWM_INFO epwm3_info;
    
    
    Uint16 AdcaResults[RESULTS_BUFFER_SIZE];
    Uint16 AdcdResults[RESULTS_BUFFER_SIZEd];
    Uint16 resultsIndex;
    volatile Uint16 bufferFull;
    Uint16 resultsIndexd;
    volatile Uint16 bufferFulld;
    
    
    void ConfigureADC(void);
    void SetupADCEpwm(Uint16 channel);
    void SetupADCEpwmd0(Uint16 channel);
    
    void InitEPwm1Example(void);
    
    void InitEPwm3Example(void);
    
    void update_compare1(EPWM_INFO*);
    
    __interrupt void epwm1_isr(void);
    
    __interrupt void epwm3_isr(void);
    
    
    // Function Prototypes
    //
    __interrupt void cpu_timer0_isr(void);
    interrupt void adca1_isr(void);
    interrupt void adcd1_isr(void);
    
    Uint32 EPwm1TimerIntCount;
    
    Uint32 EPwm3TimerIntCount;
    
    Uint16 EPwm1_DB_Direction;
    
    Uint16 EPwm3_DB_Direction;
    
    void main(void)
    {
    //
        // rounding the prd register to highest value
        TBDAB = ceil(f_clk/(2*f_sw)); // ceil value for dab period register
        TBPFC = ceil(f_clk / (2 * f_pfc)); // ceil value for pv, tpfc period register
        dutyA_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
        dutyB_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
    
        //D =0.5 tbpfc/2, D<0.5 tbpfc/2
        dutyA_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
        dutyB_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
        // Initialise this code for using GPIO2 and 3 for ePWM2 TPFC line frequency pulse generation
        InitGpio();
        CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
        
    
        InitEPwm1Gpio();
        InitEPwm3Gpio();
         //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
        DINT;
    
    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
    //
        InitPieCtrl();
    
    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
        IER = 0x0000;
        IFR = 0x0000;
    
    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
    //
        InitPieVectTable();
    
    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
        EALLOW;
        // This is needed to write to EALLOW protected registers
    
        PieVectTable.TIMER0_INT = &cpu_timer0_isr;
    
        PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
        PieVectTable.ADCD1_INT = &adcd1_isr;
    
        PieVectTable.EPWM1_INT = &epwm1_isr;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        EDIS;
    
    //
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in F2837xD_CpuTimers.c
    //
        InitCpuTimers();   // For this example, only initialize the Cpu Timers
    
    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
        ConfigCpuTimer(&CpuTimer0, 200, 5);
    
        // Step 4. Initialize all the Device Peripherals:
        // This function is found in DSP2833x_InitPeripherals.c
        // InitPeripherals(); // Not required for this example
    
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        InitEPwm1Example();
        InitEPwm3Example();
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xD_cputimervars.h), the below
    // settings must also be updated.
    //
        CpuTimer0Regs.TCR.all = 0x4000;
    
        // Configure the ADC and power it up
        //
        ConfigureADC();
    
    
        // Setup the ADC for ePWM triggered conversions on channel 0
        //
        SetupADCEpwm(0); //Input ADC channel here
        /*SetupADCEpwm1(1);
        SetupADCEpwmb2(2); //V3 bat, pin 18, adcB2
        //SetupADCEpwmb14(14);//I3 bat, pin 25/27, adcB14
        //SetupADCEpwmb15(15);//I3 bat, pin 25/27, adcB15
        //SetupADCEpwmc(33);//I3 wdg bat, pin 33, adcC3*/
        SetupADCEpwmd0(0);        //V2 DC link, pin 28, adcD0
    //
    // Step 5. User specific code, enable interrupts:
    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
        IER |= M_INT1;
        /*EINT;     // Enable Global interrupt INTM
        ERTM;     // Enable Global realtime interrupt DBGM*/
        // Initialize results buffer
        //
        for (resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
        {
            AdcaResults[resultsIndex] = 0;
        }
        resultsIndex = 0;
        bufferFull = 0;
        for (resultsIndexd = 0; resultsIndexd < RESULTS_BUFFER_SIZEd;
                resultsIndexd++)
        {
            AdcdResults[resultsIndexd] = 0;
        }
        resultsIndexd = 0;
        bufferFulld = 0;
    
    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
        PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
        
    //
        PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //ADC A1 group1 channel 1
     /*   PieCtrlRegs.PIEIER1.bit.INTx2 = 1; //ADC B1 group1 channel 2
        //PieCtrlRegs.PIEIER1.bit.INTx3 = 1; //ADC C1 group1 channel 3*/
        PieCtrlRegs.PIEIER1.bit.INTx6 = 1; //ADC D1 group1 channel 6
    
    // Enable global Interrupts and higher priority real-time debug events:
    //
        EINT;
        // Enable Global interrupt INTM
        ERTM;
        // Enable Global realtime interrupt DBGM
    
    //
    // Step 6. IDLE loop. Just sit and loop forever (optional):
    //
        do
        {
            //
            //start ePWM
            //
            EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
            EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //unfreeze, and enter up count mode
            //required when ePWM3 is the trigger
            EPwm3Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
            EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //unfreeze, and enter up count mode
            //
            //wait while ePWM causes ADC conversions, which then cause interrupts,
            //which fill the results buffer, eventually setting the bufferFull
            //flag
            //
    
            while (!bufferFull);
    
            bufferFull = 0; //clear the buffer full flag
    
            //
            //stop ePWM
            //
            EPwm1Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA
            EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
            //required when ePWM3 is the trigger
            EPwm3Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA
            EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    
            //at this point, AdcaResults[] contains a sequence of conversions
            //from the selected channel
            //
    
            //
            //software breakpoint, hit run again to get updated conversions
            //
            asm("   ESTOP0");
        }
        while (1);
    }
    
    //
    // ConfigureADC - Write ADC configurations and power up the ADC for both
    //                ADC A and ADC B
    //
    void ConfigureADC(void)
    {
        EALLOW;
    
        //
        //write configurations
        //
        AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
        AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // ADC module selection
        //
        AdcdRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
        AdcSetMode(ADC_ADCD, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // ADC module selection
        //Set pulse positions to late
        //
        AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
        AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1;
        //
        //power up the ADC
        //
        AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
        AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1;
        //
        //delay for 1ms to allow ADC time to power up
        //
        DELAY_US(1000);
    
        EDIS;
    }
    // cpu_timer0_isr - CPU Timer0 ISR with interrupt counter
    //
    __interrupt void cpu_timer0_isr(void)
    {
        if (time < 10)
        {
            time = time + dt;
        }
        else
        {
            time = 0;
        }
    
        ref = mod * sin(2 * 3.14 * fg * time);
        ref_offset = (TBPFC * ref) / 2 + TBPFC / 2;
    
        // Update the CMPA and CMPB values
    
        // Clear INT flag for this timer
        EPwm1Regs.ETCLR.bit.INT = 1;
    
        //PWM1........
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset; //EPWM1_MAX_CMPB;               // Set Compare B value
    
         CpuTimer0.InterruptCount++;
    
         PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1
    
    }
    
    __interrupt void epwm1_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm1_info);
    
        // Clear INT flag for this timer
        //
        EPwm1Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    __interrupt void epwm3_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm3_info);
    
        // Clear INT flag for this timer
        //
        EPwm3Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    
    interrupt void adca1_isr(void)
    {
        result_V = AdcaResultRegs.ADCRESULT0;
        result_Vx = 0.0007324 * result_V;
    
    
    
        /*result_V1 = AdcaResultRegs.ADCRESULT1;
        result_Vy = 0.0007324 *result_V1;*/
    
        if(RESULTS_BUFFER_SIZE <= resultsIndex)
        {
            resultsIndex = 0;
            bufferFull = 1;
        }
    
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    
    }
    interrupt void adcd1_isr(void)
    {
        result_Vd = AdcdResultRegs.ADCRESULT0;
        result_Vxd1 = 0.1 + (0.0007324 * result_Vd);
    
        if (result_Vxd1 >= 1.1)
        {
            result_Vxd = result_Vxd1 - 0.6;
    
        }
        if (result_Vxd1 >= 0.7 && result_Vxd1 < 1.1)
        {
            result_Vxd = result_Vxd1 - 0.3;
        }
        if (result_Vxd1 >= 0.15 && result_Vxd1 < 0.7)
        {
            result_Vxd = result_Vxd1 - 0.15;
        }
        if (result_Vxd1 < 0.15)
        {
            result_Vxd = result_Vxd1;
        }
        Vdc2 = result_Vxd * gain_vdc2;
    
        if (RESULTS_BUFFER_SIZEd <= resultsIndexd)
        {
            resultsIndexd = 0;
            bufferFulld = 1;
        }
    
        AdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }
    
    // PWM1
    void InitEPwm1Example()
    {
    
        // Setup TBCLK
        EPwm1Regs.TBPRD = TBPFC;          // Set timer period 801 TBCLKs
        EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset;   // Set Compare B value
    
        // Setup counter mode
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
        //EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // required to disable this master and for independent pwm generation
    
        // Setup shadowing
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // Load on Zero
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        //Enable ADC SOC
        EPwm1Regs.ETSEL.bit.SOCAEN = 0;    // Disable SOC on A group
        EPwm1Regs.ETSEL.bit.SOCASEL = 4;   // Select SOC on up-count
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;    // Generate pulse on 1st event
    
    
        // Set actions
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //AQ_SET;         // When sine<triangle set lower switch 51
        EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; //AQ_CLEAR;   // Clear PWM1A on event A, down count
    
        EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; //AQ_CLEAR;       // // When sine>triangle set upper switch 49
        EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; //AQ_SET;     // Clear PWM1B on event B, down count
    
        //essentially first upper switch conducts with leg 2 lower
    
        // Active high complementary PWMs - Setup the deadband
        //
        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm1Regs.DBRED.bit.DBRED = EPWM1_MIN_DB;
        EPwm1Regs.DBFED.bit.DBFED = EPWM1_MIN_DB;
        EPwm1_DB_Direction = DB_UP;
    
        //
        // Interrupt where we will change the deadband
        //
        EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Select INT on Zero event
        EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT
        EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;            // Generate INT on 3rd event
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm1_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm1_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm1_info.EPwmRegHandle = &EPwm1Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm1_info.EPWMMAX_DB = EPWM1_MAX_DB;      // Setup min/max
        epwm1_info.EPWMMIN_DB = EPWM1_MIN_DB;      // Setup min/max
    
    }
    // PWM3
    void InitEPwm3Example(void)
    {
    
        // Setup TBCLK
        EPwm3Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm3Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm3Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm3Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        //Enable ADC SOC
        EPwm1Regs.ETSEL.bit.SOCAEN = 0;    // Disable SOC on A group
        EPwm1Regs.ETSEL.bit.SOCASEL = 4;   // Select SOC on up-count
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;    // Generate pulse on 1st event
    
        // Set Actions
        EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM3A on period
        EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;   // Clear PWM3A on event B, down count
    
        EPwm3Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Clear PWM3A on period
        EPwm3Regs.AQCTLB.bit.CBD = AQ_SET;         // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm3Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm3Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm3_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm3Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm3Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm3_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm3_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm3_info.EPwmRegHandle = &EPwm3Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm3_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm3_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    // update_compare1 TPFC/PV -and  update_compare3 DAB Update the compare values for the specified EPWM
    //
    void update_compare1(EPWM_INFO *epwm_info)
    {
        if (epwm_info->EPwmDB_Direction == DB_UP)
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED < epwm_info->EPWMMAX_DB)
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmDB_Direction = DB_DOWN;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
        else
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED == epwm_info->EPWMMIN_DB)
            {
                epwm_info->EPwmDB_Direction = DB_UP;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
    
        epwm_info->EPwmTimerIntCount++;
    
        //   return;
    }
    //
    void SetupADCEpwm(Uint16 channel)
    {
        Uint16 acqps;
    
        //
        //determine minimum acquisition window (in SYSCLKS) based on resolution
        //
        if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
        {
            acqps = 14; //75ns
        }
        else //resolution is 16-bit
        {
            acqps = 63; //320ns
        }
    
        //
        //Select the channels to convert and end of conversion flag
        //
        EALLOW;
        AdcaRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin A0
        AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
        AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C
    
        AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
        AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
        EDIS;
    
    }
    void SetupADCEpwmd0(Uint16 channel)
    {
        Uint16 acqps;
    
        //
        //determine minimum acquisition window (in SYSCLKS) based on resolution
        //
        if(ADC_RESOLUTION_12BIT == AdcdRegs.ADCCTL2.bit.RESOLUTION)
        {
            acqps = 14; //75ns
        }
        else //resolution is 16-bit
        {
            acqps = 63; //320ns
        }
    
        //
        //Select the channels to convert and end of conversion flag
        //
        EALLOW;
        AdcdRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin D0
        AdcdRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
        AdcdRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCA/C
    
        AdcdRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
        AdcdRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
        AdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
        EDIS;
    }
    
    // End of file
    //
    

  • Sneha,

    I couldn't recreate the issue on my end because of some file linking issues, but from the primary look over the source code, I found these bugs:

    1. EPWM INT belongs to group 3. You have just enabled group 1 interrupt using IER =| M_INT1. Please enable the group 3 interrupts as well.

    2. Some registers are write protected which have to be updated within EALLOW, EDIS bracket. Some write protected regs are written over without the permission. Eg. ADCCTL2 in ADCa and ADCd, PCLKCR2 for EPWM1 and EPWM3.

    Please check for any other such registers as well. You can go through the TRM register summary section for information about its write protection. Other way round is that you can anyways add EALLOW; EDIS for all the registers to avoid any confusion.

    If this doesn't help solving the issue, please send the zipped project folder along so that I can recreate the issue at my end.

    Thanks,

    Aditya 

  • Ok, Thank you Aditya,

    I will follow these steps this evening and update you.

    Thanks

    Sneha

  • Hi Aditya

    I am attaching the zip folder here, as I am not able to resolve the issues mentioned in my previous post. I have even enabled IER =| M_INT3 now. I am using ADC_D0 pin 28, and ADC_A0 pin 09.

    2. Some registers are write protected which have to be updated within EALLOW, EDIS bracket. Some write protected regs are written over without the permission. Eg. ADCCTL2 in ADCa and ADCd, PCLKCR2 for EPWM1 and EPWM3.

    Can you please elaborate on this?

    Thanks

    Sneha Thakur2626.cpu01.zip

  • Sneha,

    Can you please elaborate on this?

    There are some critical registers such as control registers which cannot be written over directly. These are the write protected registers. If you look through the code, some register/bit configurations are done after writing EALLOW and before EDIS. For updating the write protected registers, you need to include EALLOW before updating and end with EDIS.

    TRM mentions whether the register is write protected or not. Please see the image below.

    In the source code, it looks like this:

        EALLOW;
        // This is needed to write to EALLOW protected registers
    
        PieVectTable.TIMER0_INT = &cpu_timer0_isr;
    
        PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
    
        PieVectTable.EPWM1_INT = &epwm1_isr;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        PieVectTable.EPWM4_INT = &epwm4_isr;
        PieVectTable.EPWM5_INT = &epwm5_isr;
        PieVectTable.EPWM6_INT = &epwm6_isr;
        EDIS;

    Please let me know if this helps solve your problem. Unless and until these are mentioned, the registers won't be updated.

    Thanks,

    Aditya

  • HI Aditya

    I will check this out.

    Were you able to recreate the issue at your end using the files I shared?

    Thanks

    Sneha

  • Sneha,

    Yes, I ran the code on the device and the code is well entering the ISR. I checked by keeping a breakpoint within the ISR. Attaching an image of the same. I have not made any change to the code that you shared.

    Aditya

  • Hi Aditya

    I mark this issue resolved by mistake.

    The same code does not work at my end. DO you see the results in ADC_D result registers and in the variables result_Vd, result_Vxd1 in the adc_d isr?

    Thanks

    Sneha

  • Hi Sneha,

    I am able to see the respective values properly. Can you check by putting a breakpoint within the D1 ISR?

    Aditya

  • Sneha,

    Since we haven't heard back from you, I believe this query has been resolved. I am marking this thread as resolved for now. Incase, you still have any questions, feel free to mark it as not resolved and continue the thread. If this thread locks, you can ask a new question.

    Thanks,

    Aditya