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.

EPWM6 INTERRUPT 28377D

Other Parts Discussed in Thread: CONTROLSUITE

Dear e2e community

I am quite new with 28377D, and I have a question.

I would like to configure EPWM6 to generate an interrupt every time that TBCTR = ZERO, and increment a counter named "epwm6_int_count " for every time that the interrupt routine is run.

In order to do so, I have configured EPWM6 as follow:

EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;

EPwm6Regs.ETSEL.bit.INTEN = 1; // 1 enable EPWMx_INT interrupt 
EPwm6Regs.ETSEL.bit.INTSEL = 1; // 001 generate interrupt when TBCTR = 0
EPwm6Regs.ETPS.bit.INTPRD = 1; // generate an interrupt in the first event 

In the main.c program though I also have other interrupts, the configuration is as follow:

...

...
void main() {

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

InitGpio();
InitCpuTimers(); //*******

//Map ISR functions
EALLOW;
PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
PieVectTable.ADCB1_INT = &adcb1_isr; //function for ADCB interrupt 1
PieVectTable.ADCC1_INT = &adcc1_isr; //function for ADCC interrupt 1
PieVectTable.ADCD1_INT = &adcd1_isr; //function for ADCD interrupt 1
PieVectTable.TIMER0_INT = &cpu_timer0_isr; //******* CPU timer #0 generated interrupt

PieVectTable.EPWM6_INT = &epwm6_isr; // function for interrupt based on ePWM6
EDIS;

//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

// Enable PIE interrupt (ref Table 2-2. PIE Channel Mapping, pag. 90)
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // enable adc_int_A_1
PieCtrlRegs.PIEIER1.bit.INTx2 = 1; // enable adc_int_B_1
PieCtrlRegs.PIEIER1.bit.INTx3 = 1; // enable adc_int_C_1
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // enable adc_int_D_1
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable TINT0 in the PIE: Group 1 interrupt 7 *******

PieCtrlRegs.PIEIER3.bit.INTx6 = 3; // enable EPWM6 interrupts (row 3:PIEIER3, column 6:INTx6)

...

...

interrupt void epwm6_isr(void){
epwm6_int_count =epwm6_int_count + 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

To see if the epwm6_isr works I would like the counter "epwm6_int_count" to increment its value every time that the ISR is entered, but as it is this counter is always zero, meaning that epwm6_isr() routine is never entered I guess.

I am not sure of where the mistake is, and also I am not sure of the values I set such: IER = 0x0000; IFR = 0x0000;

Other interrupts are exactly like:

interrupt void adca1_isr(void) {

...

...

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

and they work fine.

Appreciate your help.

Leo

  • Leonardo,

    After looking at the code, my recommendation is to add code in the ISR to write a 1 to the INT bit of the ETCLR register. This will clear the INT bit of the ETFLG register and will enable further interrupts to be generated. You can find more information on this in Chapter 14 of the TRM at www.ti.com/.../spruhm8e.pdf

    If you haven’t already, I also suggest reviewing EPWM examples found in ControlSUITE at \controlSUITE\device_support\F2837xD\v200\F2837xD_examples_Cpu1

    For debugging purposes, I recommend checking the values of the EPWM registers in the Registers window through CCS to see if they are the expected values after configuration. Also, you can set breakpoints within the ISR to see whether or not the interrupts are generated.


    Elizabeth

  • Hi Elizabeth,

    I added the line

    EPwm6Regs.ETCLR.bit.INT = 1; // clear EPWM6 INT flag

    in the epwm6 interrupt routine, which is now:

    interrupt void epwm6_isr(void) {
    epwm6_int_count = epwm6_int_count + 1;
    //GpioDataRegs.GPATOGGLE.bit.GPIO4 = 1;
    EPwm6Regs.ETCLR.bit.INT = 1; // clear EPWM6 INT flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }

    but still the counter "epwm6_int_count " is never incremented (the interrupt is never entered)... perhaps the line PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; is incorrect?

    Thanks for your help

    Leo
  • Leo,

    Yes, I would add this line in the ISR:

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    EPWM interrupts are in PIE group 3. You can refer to Table 2.2 PIE Channel Mapping in the TRM.

    Hope this helps.

    Elizabeth

  • Hi Elizabeth

    Thanks for your kind answer. Still the counter "epwm6_int_count" doesn't update (meaning that the interrupt is never entered).

    I have modified my ISR as suggested, by adding "PieCtrlRegs.PIEACK.all = PIEACK_GROUP3"

    interrupt void epwm6_isr(void) {

    epwm6_int_count = epwm6_int_count + 1;

    EPwm6Regs.ETCLR.bit.INT = 1; // clear EPWM6 INT flag

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    }

    Please note, I am unsure I have declared something incorrectly at the beginning of my main program. I have highlighted in red one of the instructions below. I am not sure if that serves to enable the group 3 (and therefore epwm6) interrupts too.

    Thanks

    Leo

    //###########################################################################

    // main program

    //###########################################################################

    void main() {

    InitSysCtrl();

    DINT;

    InitPieCtrl();

    IER = 0x0000;

    IFR = 0x0000;

    InitPieVectTable();

    InitGpio();

    InitCpuTimers();

    //Map ISR functions

    EALLOW;

    PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1

    PieVectTable.ADCB1_INT = &adcb1_isr; //function for ADCB interrupt 1

    PieVectTable.ADCC1_INT = &adcc1_isr; //function for ADCC interrupt 1

    PieVectTable.ADCD1_INT = &adcd1_isr; //function for ADCD interrupt 1

    PieVectTable.TIMER0_INT = &cpu_timer0_isr; //******* CPU timer #0 generated interrupt

    PieVectTable.EPWM6_INT = &epwm6_isr; // function for interrupt based on ePWM6

    EDIS;

    //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

    // Enable PIE interrupt (ref Table 2-2. PIE Channel Mapping, pag. 90)

    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;  // enable adc_int_A_1

    PieCtrlRegs.PIEIER1.bit.INTx2 = 1;  // enable adc_int_B_1

    PieCtrlRegs.PIEIER1.bit.INTx3 = 1;  // enable adc_int_C_1

    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;  // enable adc_int_D_1

    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable TINT0 in the PIE: Group 1 interrupt 7

    PieCtrlRegs.PIEIER3.bit.INTx6 = 3; // enable EPWM6 interrupts (row 3:PIEIER3, column 6:INTx6)

  • Leonardo,

    ====== IER |= M_INT1; //Enable group 1 interrupts======= this statement enable only Group1

    For enabling group 3, make change
    IER |=M_INT3; // Enable only group 3
  • Hi Asim,

    thanks for your answer.

    So both group 1 and group 3 interrupts will work if I write the following commands in succession:

    IER |= M_INT1;
    IER |=M_INT3;

    I thought that if I write IER |=M_INT3 this will 'overwrite' the IER |= M_INT1 command... I will try to add both these lines in my code and see if it works.

    Thanks again,

    Leo
  • Leo,

    Yes, you can write the code as you did in your latest post to set both Groups 1 and 3. As it is a bitwise OR operation, those lines of code will not change any other bits in IER except setting both M_INT1 and M_INT3 bits.

    If you’re still having issues, I recommend checking the configuration in epwm_up_aq and the other ePWM example projects in controlSUITE. I shared the directory where you can find them in my first reply above.

    Elizabeth
  • Thanks Elizhabeth, I did not know that I can write the commands IER |= M_INT1; IER |=M_INT3 together.

    I realize that the symbol "|" stands for OR now.

    Thank you the pwm6 interrupt now works :)

    Leo