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.

TMS320F280039C: Interrupt for epwm1 fires only once and never again

Part Number: TMS320F280039C
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hi Guys,

I'm working on EPWM peripheral. I have written the following code and the epwm1_ISR() is triggered only once. I have seen during debug, that the interrupt flag is not cleared. But in my ISR function, I have explicitly cleared the epwm1 interrupt, and also the group 3 interrupts of the PIE controller. Please help

 


/**
* epwm1 = 2kHz switching freq and produces interrupt to toggle gpio22
* epwm2 = 4kHz switching freq and produces interrupt to toggle gpio20
*/

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

static volatile uint32_t t1,t2;
static volatile uint16_t f2,f1;

__interrupt void epwm1_ISR(void);
__interrupt void epwm2_ISR(void);

void main(void)
{
// Init System
InitSysCtrl();

// Disable the global Interrupts
DINT;

// Disable Interrupts in IER and clear the IFR
IER = 0x0;
IFR = 0x0;

// Init the peripherals(Init PIE Control functions), to clear flags in IER register and IFR registers
InitPieCtrl();

// Init the PIE Vector
InitPieVectTable();

// Assign our ISR addresses to the Vector Table Elements
EALLOW;
PieVectTable.EPWM1_INT = epwm1_ISR;
/*PieVectTable.EPWM2_INT = epwm2_ISR;*/
EDIS;

// Configure EPWM1
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; //enabling epwm1 clock.
EDIS;
EPwm1Regs.TBCTL.bit.CTRMODE = 0; //0 = upcount
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // 1X for free run
//Now we have a 60MHz clock. ( as HSPCLKDIV divider is 1 by default)

EPwm1Regs.TBPRD = 15000 - 1; //(1/4000)/(1/60e+6) = 15000 ----> 2000Hz period on 60MHz

EPwm1Regs.ETSEL.bit.INTEN = 1; //enable epwm interrupt
EPwm1Regs.ETSEL.bit.INTSEL = 1; // end/beginning of pwm cycle

EPwm1Regs.ETPS.bit.INTPSSEL = 0;
EPwm1Regs.ETPS.bit.INTPRD = 1; //generate interrupt in every pwm cycle.

/*
// Configure EPWM2
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM2 = 1; //enabling epwm2 clock.
EDIS;

EPwm2Regs.TBCTL.bit.CTRMODE = 0; //0 = upcount
EPwm2Regs.TBCTL.bit.FREE_SOFT = 2; // 1X for free run
//Now we have a 60MHz clock. ( as HSPCLKDIV divider is 1 by default)

EPwm2Regs.TBPRD = 30000 - 1; //(1/2000)/(1/60e+6) = 30000 ----> 2000Hz period on 60MHz

EPwm2Regs.ETSEL.bit.INTEN = 1; //enable epwm interrupt
EPwm2Regs.ETSEL.bit.INTSEL = 1; // end/beginning of pwm cycle

EPwm2Regs.ETPS.bit.INTPSSEL = 0;
EPwm2Regs.ETPS.bit.INTPRD = 1; //generate interrupt in every pwm cycle.
*/


// Enable appropriate interrupts in the PIE Module

PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //pwm1
/*PieCtrlRegs.PIEIER3.bit.INTx2 = 1;*/ //pwm2

// Enable interrupt in the gloabl IER register.
IER |= M_INT3; //group 3 as above(pieier3)
// CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; not work
// Enable the global interrupt
EINT;

//setup gpio pins
EALLOW;
GpioCtrlRegs.GPAGMUX2.bit.GPIO22 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO22 = 1;
GpioCtrlRegs.GPAGMUX2.bit.GPIO20 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO20 = 1;
GpioCtrlRegs.GPAAMSEL.bit.GPIO20 = 0; //gpio20 was in analog mode by default. so resetting the analog mode
EDIS;

//infinite loop
for(;;);
}


__interrupt void
epwm1_ISR(void)
{
//action
if(f1 == 0)
{
GpioDataRegs.GPASET.bit.GPIO22 = 1;
}
else
{
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1;
}
f1 ^= 1;
t1++;

//cleanup

EPwm1Regs.ETCLR.bit.INT = 1; //clear the epwm interrupt

PieCtrlRegs.PIEACK.bit.ACK3; //acknowledge grp3 interrupts.
}

__interrupt void
epwm2_ISR(void)
{
//action
if(f2 == 0)
{
GpioDataRegs.GPASET.bit.GPIO20 = 1;
}
else
{
GpioDataRegs.GPACLEAR.bit.GPIO20 = 1;
}
f2 ^= 1;
t2++;
//cleanup

PieCtrlRegs.PIEACK.bit.ACK3; //acknowledge grp3 interrupts.
EPwm2Regs.ETCLR.bit.INT = 1; //clear the epwm interrupt

}

  • Hi Dev,

    Can you try using the instruction EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE); Please refer to below code in interruot_ex4_epwm_realtime_interrupt available in C2000ware examples. ( available at C:\ti\c2000\C2000Ware_5_02_00_00\driverlib\f28003x\examples\interrupt)

    __interrupt void
    epwm1ISR(void)
    {
    EPwm1TimerIntCount++;
    LEDcount++;

    //
    // Toggle LED2 when the count reaches 500
    //
    if (LEDcount == 500)
    {
    GPIO_togglePin(DEVICE_GPIO_PIN_LED2);
    LEDcount=0;
    }

    //
    // Clear INT flag for this timer
    //
    EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE);

    //
    // Acknowledge this interrupt to receive more interrupts from group 3
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }

    Thanks

    Srikanth