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.

Epwm Timer Interrupt & execution time



Hello,

I based this part of the code from the Example_2833xEPwmTimerInt sample project.  I am using EPwm1 to generate a 10MHz clock signal and also I used the code from the sample project to generate an interrupt.

I have added an instruction to toggle a pin which I am monitoring on an oscilloscope.

interrupt void epwm_timer_isr(void)
{
EPwmTimerIntCount++;

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

GpioDataRegs.GPBTOGGLE.bit.GPIO32 = 1;

}

I see that the pin is toggling every ~2uS.  Given that the cycle time for this chip is 6.67nS, I was expecting the interrupt to trigger at a much faster frequency.  I was wondering if there was something in my configuration that is causing it go trigger at this speed?  I am reading through the various documentation but have not found the culprit.

void InitEPwm(void)
{
//---------------------------------------------------------------------
//--- Must disable the clock to the ePWM modules if you
//--- want all ePWM modules synchronized.
//---------------------------------------------------------------------
	EALLOW;						// Enable EALLOW protected register access
	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
	EDIS;							// Disable EALLOW protected register access

//---------------------------------------------------------------------
//--- Configure ePWM1 for 10MHz symmetric PWM on EPWM1A pin
//---------------------------------------------------------------------
	EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  // Pass through
	EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
	EPwm1Regs.TBCTL.bit.CTRMODE = 0x3;		// Disable the timer
	EPwm1Regs.TBCTL.all = 0xC033;			// Configure timer control register
	EPwm1Regs.TBCTR = 0x0000;				// Clear timer counter
	EPwm1Regs.TBPRD = PWM_HALF_PERIOD;		// Set timer period (value = 7)
	EPwm1Regs.TBPHS.half.TBPHS = 100;	// Set timer phase
	EPwm1Regs.CMPA.half.CMPA = PWM_DUTY_CYCLE;	// Set PWM duty cycle (value = 4)
	EPwm1Regs.CMPCTL.all = 0x0002;			// Compare control register
	EPwm1Regs.AQCTLA.all = 0x0060;		// Action-qualifier control register A
	EPwm1Regs.AQSFRC.all = 0x0000;		// Action-qualifier s/w force register
	EPwm1Regs.AQCSFRC.all = 0x0000;		// Action-qualifier continuous s/w force register
	EPwm1Regs.DBCTL.bit.OUT_MODE = 0;	// Deadband disabled
	EPwm1Regs.PCCTL.bit.CHPEN = 0;		// PWM chopper unit disabled
	EPwm1Regs.TZCTL.bit.TZA = 0x3;		// Trip action disabled for output A
	EPwm1Regs.TBCTL.bit.CTRMODE = 0x2;	// Enable the timer in count up/down mode
	//EPwm1Regs.TBPRD = PWM1_TIMER_TBPRD;
	//EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;    // Count up
	EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
	EPwm1Regs.ETSEL.bit.INTEN = PWM1_INT_ENABLE;  // Enable INT
	EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st event
//---------------------------------------------------------------------
//--- Enable the clocks to the ePWM module.
//--- Note: this should be done after all ePWM modules are configured
//--- to ensure synchronization between the ePWM modules.
//---------------------------------------------------------------------
	asm(" EALLOW");							// Enable EALLOW protected register access
	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;	// HSPCLK to ePWM modules enabled
	asm(" EDIS");							// Disable EALLOW protected register access

} // end InitEPwms()

Thanks in advance,

-Alex

  • Alejandro,

    It looks like you've set up ePWM1 with a 10 MHz period (100 ns), and are triggering the ePWM1 interrupt on zero match.  This means your interrupt rate is 10 MHz.  On the 150 MHz F28335, this is only 15 cycles.  The interrupt response time alone is 10 cycles, and the interrupt return takes another 8.  These two items alone mean that the CPU is not going to be able to keep up with your interrupt rate not to mention that there is additional stuff going on in your ISR.

    You say your seeing the pin toggle every 2 uS.  This does seem too slow however.  Have you confirmed the timebase correctness? In other words, is your ePWM1 signal correctly 10 MHz on the scope?

    - David

  • David,

    So you are saying that the absolute minimum, assuming no other stuff is going on withing the ISR is 18 cycles which means the max interrupt rate is about 8.33 MHz.  So for safe measure I have dropped ePWM1 frequency to 5MHz.  I left the rest of the parameters the same.

    #define PWM_HALF_PERIOD		15		// period/2 for 5MHz symmetric PWM
    #define PWM_DUTY_CYCLE		8		// ~50% duty cycle

    I do see on my scope that the clock signal coming out of ePWM1 is 5 MHz.  However there is no change in the time it takes to toggle the pin which is at 1.62uS (I was rounding the last time when I said about 2uS).  I do not understand why this is happening.  I would expect the toggle to occur at least once every 200nS.  Could something else be limiting how often a pin toggles?

    Thanks,

    -Alex

  • I placed a toggle instruction at the beginning and at the end of this interrupt and I see on my scope that the time it takes to toggle a pin on and off is 530nS. This seems too high for those two instructions within the toggles. Any idea what may be going on?

    interrupt void epwm_timer_isr(void)
    {
       GpioDataRegs.GPBTOGGLE.bit.GPIO32 = 1;
    
       // 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;
    
       GpioDataRegs.GPBTOGGLE.bit.GPIO32 = 1;
    }
    

  • Alejandro,

    The reason you didn't see any change in the ISR execution time when you dropped the ePWM down to 5 MHz is that the ISR execution time takes longer than than the 5 MHz period.  So, the ISRs are running back to back, as fast as they can.  Makes sense.  Now the question is why the ISR takes so long, seemingly 1.62 us, or actually longer than that when you include entry and exit to the ISR (before and after your toggle code).

    You say 530 ns to toggle?  That's ~79 cycles.  Kind of long.  Do you have the flash wait-states configured properly?

    - David