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.

EPWM1 interrupt triggering when it 'should' not

Other Parts Discussed in Thread: CONTROLSUITE

Hello there,

I am observing something strange with my F28335 microncontroller. I have configured EPWM2 to run at 25kHz and I want it to generate an interrupt request at the same frequency. EPWM2 is configured as follows:

void init_epwm2(void)
{
	EALLOW;
			GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1;    // Disable pull-up on GPIO2 (EPWM2A)
			GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1;    // Disable pull-up on GPIO3 (EPWM3B)

			/* Configure ePWM-2 pins using GPIO regs*/
			// This specifies which of the possible GPIO pins will be ePWM2 functional pins.

			GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;   // Configure GPIO2 as EPWM2A
			GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;   // Configure GPIO3 as EPWM2B
   EDIS;
   // Setup TBCLK
   EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
   EPwm2Regs.TBPRD = SWITCHING_PERIOD;//EPWM2_TIMER_TBPRD;       // Set timer period
   EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
   EPwm2Regs.TBPHS.half.TBPHS = 0x0000;       // Phase is 0
   EPwm2Regs.TBCTR = 0x0000;                  // Clear counter
   EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //TB_DIV2;   // Clock ratio to SYSCLKOUT
   EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; //TB_DIV2;

   // Setup shadow register load on ZERO
   EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
   EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
   EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

   // Set Compare values
   EPwm2Regs.CMPA.half.CMPA = 0;//SWITCHING_PERIOD;		      // Set compare A value. We want PWMB to be zero on start, so make PWMA maximum on start.
   EPwm2Regs.CMPB = 0;//EPWM2_MAX_CMPB;                 // Set Compare B value
   EPwm2Regs.CMPA.half.CMPAHR = (1 << 8); //Set initial value for CMPAHR

   // Set actions
   EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;//AQ_CLEAR;             // Clear PWM2A on Period
   EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;//AQ_SET;               // Set PWM2A on event A, up count

   EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;             // Clear PWM2B on Period
   EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;               // Set PWM2B on event B, up count

   // Configure Interrupt
   EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;        // Select INT on Zero event
   EPwm2Regs.ETSEL.bit.INTEN = 1;                   //Enable Interrupt
   EPwm2Regs.ETPS.bit.INTPRD = 0x01; //Interrupt on first event //ET_3RD;              // Generate INT on 3rd event

   // Active Low PWMs - Setup Deadband
   EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
   EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//DB_ACTV_LO;
   EPwm2Regs.DBRED = 10;//5;//EPWM1_MIN_DB;
   EPwm2Regs.DBFED = 20;//5;//50;//EPWM1_MIN_DB;

   //Trip-zone configuration for fault conditions and High-resoultion configuration
   EALLOW;
   EPwm2Regs.TZSEL.bit.OSHT1 = 0x01; //Enable TZ1 as a one-shot trip source for this ePWM module
   EPwm2Regs.TZCTL.bit.TZA = 0x02; //Force EPWM1A to a low state
   EPwm2Regs.TZCTL.bit.TZB = 0x02; //Force EPWM1B to a low state
   EPwm2Regs.TZFRC.bit.OST = 1; //Force one-shot trip condition

   EPwm2Regs.HRCNFG.bit.HRLOAD = 0; //High resolution counter loaded at "counter equal zero"
   EPwm2Regs.HRCNFG.bit.CTLMODE = 0; //CMPAHR controls edge position
   EPwm2Regs.HRCNFG.bit.EDGMODE = 0x02; //MEP control is done on falling edge
   EDIS;
}

I also want to use EPWM1 to generate ADC triggers. I have configured EPWM1 as follows:

void init_epwm1(void)
{
   EALLOW;
		   GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;    // Disable pull-up on GPIO0 (EPWM1A)
		   GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1;    // Disable pull-up on GPIO1 (EPWM1B)

		   /* Configure ePWM-1 pins using GPIO regs*/
		   // This specifies which of the possible GPIO pins will be ePWM1 functional pins.
		   GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
		   GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B
   EDIS;

   // Setup TBCLK
   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
   EPwm1Regs.TBPRD = 600;//EPWM1_TIMER_TBPRD;       // Set timer period
   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
   EPwm1Regs.TBPHS.half.TBPHS = 0x0000;       // Phase is 0
   EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
   EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

   // Setup shadow register load on ZERO
   EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
   EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
   EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

   // Set Compare values
   EPwm1Regs.CMPA.half.CMPA = 0;//EPWM1_MIN_CMPA;    // Set compare A value
   EPwm1Regs.CMPB = 0;//EPWM1_MIN_CMPB;              // Set Compare B value

   // Set actions
   EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on Zero
   EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM1A on event A, up count

   EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR;//AQ_SET;            // Set PWM1B on Zero
   EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;//AQ_CLEAR;          // Clear PWM1B on event B, up count


   //Enable SOCA
   EPwm1Regs.ETSEL.bit.SOCAEN = 0x01; //Enable EPWM1 SOCA Pulse. This will trigger the ADC conversion sequence
   EPwm1Regs.ETSEL.bit.SOCASEL = 0x01; //Enable event time-base counter equal to period (TBCTR = TBPRD)
   EPwm1Regs.ETPS.bit.SOCAPRD = 0x02;        // Generate pulse on 1st event

   // Interrupt where we will change the Compare Values
   EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
   EPwm1Regs.ETSEL.bit.INTEN = 0;               // Disable interrupt INT
   EPwm1Regs.ETPS.bit.INTPRD = 0x00;          // Disable the interrupt event counter. No interrupt will be generated and ETFRC[INT] is ignored.

   // Active Low PWMs - Setup Deadband
   EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
   EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//DB_ACTV_LO;
   EPwm1Regs.DBRED = 20;//5;//EPWM1_MIN_DB;
   EPwm1Regs.DBFED = 40;//5;//50;//EPWM1_MIN_DB; //Falling edge deadtime

   EALLOW;

   //Trip-zone configuration for fault conditions
   EPwm1Regs.TZSEL.bit.OSHT1 = 0x01; //Enable TZ1 as a one-shot trip source for this ePWM module
   EPwm1Regs.TZCTL.bit.TZA = 0x02; //Force EPWM1A to a low state
   EPwm1Regs.TZCTL.bit.TZB = 0x02; //Force EPWM1B to a low state

   EDIS;
}

I am using the software-prioritized interrupt files (for interrupt nesting) and I have configured the relevant lines as follows:

#define	INT1PL      2        // Group1 Interrupts (PIEIER1)
#define	INT3PL      1        // Group3 Interrupts (PIEIER3)

//...Some code ....

#define	G31PL       0        // EPWM1_INT   (ePWM1 Int)
#define	G32PL       1        // EPWM2_INT   (ePWM2 Int)
#define	G33PL       0        // EPWM3_INT   (ePWM3 Int)
#define	G34PL       2        // EPWM4_INT   (ePWM4 Int)

///...more code ....

In the main file, I have made the following configurations:

//.... some code which I have left out ...//

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


   EALLOW;	// This is needed to write to EALLOW protected registers
   PieVectTable.XINT1 = &xint1_isr;
   PieVectTable.EPWM4_INT = &epwm4_isr;
   PieVectTable.EPWM2_INT = &EPWM2_ISR;
   PieVectTable.SEQ1INT = &adc_isr;
   EDIS;   // This is needed to disable write to EALLOW protected registers

   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
   PieCtrlRegs.PIEIER1.bit.INTx4 = 1;  	// Enable PIE XINT1
   PieCtrlRegs.PIEIER1.bit.INTx1 = 1; 	//Enable SEQ1 interrupt in PIE
   PieCtrlRegs.PIEIER3.bit.INTx4 = 1;	// Enable EPWM INTn in the PIE: Group 3 interrupt 4 (EPWM4)
   PieCtrlRegs.PIEIER3.bit.INTx2 = 1;	// Enable EPWM INTn in the PIE: Group 3 interrupt 2 (EPWM2)
   PieCtrlRegs.PIEACK.all = 0xFFFF;   // Acknowledge then enable PIE interrupts
   IER |= M_INT1; // Enable CPU INT1 which is connected to external interrupt 1 (i.e. XINT1), to  CPU-Timer 0 (TMR0), and to the  ADC interrupt (ADCINT)
   IER |= M_INT3; // Enable CPU INT3 which is connected to EPWM4 INT and EPWM2 int:
   EINT;          // Enable Global interrupt INTM
   ERTM;          // Enable Global realtime interrupt DBGM

///...more code left out from this point...///

Clearly, I have disabled EPWM1_INT interrupt. However, upon running the program, it vectors in to the default EPWM1 int which appears as follows:

interrupt void EPWM1_INT_ISR(void)     // EPWM-1
{
  // Insert ISR Code here

  // To receive more interrupts from this PIE group, acknowledge this interrupt
  // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

  // Next two lines for debug only to halt the processor here
  // Remove after inserting ISR Code
  asm ("      ESTOP0");
  for(;;);
}

This should not be possible because the epwm1 interrupt has been disabled. How can this be? Checking the ETSEL register shows nothing wrong. Any tips here? Thanks.

  • Hi,

    Fonkwe Edwin said:
    I am observing something strange with my F28335 microncontroller. I have configured EPWM2 to run at 25kHz and I want it to generate an interrupt request at the same frequency.

    Very strange! Did you refer this example code:

    C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_examples_ccsv4\epwm_up_aq

    Regards,

    Gautam