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.