I've got a current project where I have ePWM outputs in a 3 phase system (using ePWM1, 2 & 3). I have an interrupt routine in which I'm trying to force the PWM outputs off. I believe I have everything set-up correctly and the TZFLG register is changing to 1 (indicating a TZ event occured). Yet the outputs do not change to the values set in TZCTL.
I initially placed a breakpoint after setting TZFRC (and a delay) and checked the physical PWM outputs with a multimeter. No dice. I also placed an infinite loop after setting TZFRC and nothing happens to the output there either (even though the TZFLG gets sets properly). The output just stays at it's previous ePWM output.
Is there something I'm missing? What else can I do? Is there something about using the debugger that could be causing the problem? I'm using a TMS320F28035.
Initialization:
// // Initialize PWM module
EALLOW;
pwm1.PeriodMax = SYSTEM_FREQUENCY*1000000*g_HOOD_periodSample/2; // Prescaler X1 (T1), ISR period = T x 1
pwm1.HalfPerMax=pwm1.PeriodMax/2;
pwm1.Deadband = 4.0*SYSTEM_FREQUENCY; // 240 counts -> 4.0 usec for TBCLK = SYSCLK/1
PWM_INIT_MACRO(1,2,3,pwm1)
//magic to make active hi/lo gate drives work together
EPwm1Regs.AQCTLA.all = (CAU_SET + CAD_CLEAR + PRD_SET + ZRO_CLEAR);
EPwm2Regs.AQCTLA.all = (CAU_SET + CAD_CLEAR + PRD_SET + ZRO_CLEAR);
EPwm3Regs.AQCTLA.all = (CAU_SET + CAD_CLEAR + PRD_SET + ZRO_CLEAR);
EPwm1Regs.AQCTLB.all = (CAU_CLEAR + CAD_SET + PRD_CLEAR + ZRO_SET);
EPwm2Regs.AQCTLB.all = (CAU_CLEAR + CAD_SET + PRD_CLEAR + ZRO_SET);
EPwm3Regs.AQCTLB.all = (CAU_CLEAR + CAD_SET + PRD_CLEAR + ZRO_SET);
EPwm1Regs.DBCTL.all = (BP_ENABLE + POLSEL_ACTIVE_HI);
EPwm2Regs.DBCTL.all = (BP_ENABLE + POLSEL_ACTIVE_HI);
EPwm3Regs.DBCTL.all = (BP_ENABLE + POLSEL_ACTIVE_HI);
//Set deadbands seperately for rising and falling edges
EPwm1Regs.DBRED = 2.0 * SYSTEM_FREQUENCY; //rising deadband = 2 uSec
EPwm1Regs.DBFED = 4.0 * SYSTEM_FREQUENCY; //falling deadband = 4 uSec
EPwm2Regs.DBRED = 2.0 * SYSTEM_FREQUENCY; //rising deadband = 2 uSec
EPwm2Regs.DBFED = 4.0 * SYSTEM_FREQUENCY; //falling deadband = 4 uSec
EPwm3Regs.DBRED = 2.0 * SYSTEM_FREQUENCY; //rising deadband = 2 uSec
EPwm3Regs.DBFED = 4.0 * SYSTEM_FREQUENCY; //falling deadband = 4 uSec
// Setting ePWM to use trip zones (trip zone will be called in xINT ISR)
EPwm1Regs.TZSEL.bit.OSHT1 = 1; // Use one-shot trip zone 1
EPwm2Regs.TZSEL.bit.OSHT1 = 1; // Use one-shot trip zone 1
EPwm3Regs.TZSEL.bit.OSHT1 = 1; // Use one-shot trip zone 1
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Force high-side low on trip
EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_HI; // Force low-side high on trip
EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Force high-side low on trip
EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_HI; // Force low-side high on trip
EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Force high-side low on trip
EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_HI; // Force low-side high on trip
EPwm1Regs.TZCLR.bit.OST = 1;
EPwm2Regs.TZCLR.bit.OST = 1;
EPwm3Regs.TZCLR.bit.OST = 1;
EDIS;
Interrupt routine: (I've verified that this does indeed get called properly)
interrupt void DesatFaultISR(void)
{
Uint16 i = 0;
EALLOW;
// force trip zone event
EPwm1Regs.TZFRC.bit.OST = 1;
EPwm2Regs.TZFRC.bit.OST = 1;
EPwm3Regs.TZFRC.bit.OST = 1;
for(i = 0; i <1000; i++) //(can see here that the TZFLG flags get set to 1 properly
EDIS;
STATEMACHINE_enterStop();
flags2 |= DESAT_FAULT_FLAG;
PieCtrlRegs.PIEACK.all|= (BIT0 | BIT11); // Issue PIE ACK for all possible interrupt triggers
// clear trip zone event
EALLOW;
EPwm1Regs.TZCLR.bit.OST = 1;
EPwm2Regs.TZCLR.bit.OST = 1;
EPwm3Regs.TZCLR.bit.OST = 1;
EDIS;
}