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.

ePWMs not shutting off with TZFRC

Other Parts Discussed in Thread: TMS320F28035

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

  • I should also mention that the top initialization is within EALLOW; EDIS; statements.
  • Hi Daniel

    I don't see any mistake too...

    I think in your case even the TZSEL.bit.OSHT1 = 1 is not necessary. This means that in case of TZ1 pin goes low, it will trigger a a OSHT. But you want to set the OSHT manually. Anyway, just to be sure: Before you try to OST event: Do you have any PWM running? Are the PWM pins Muxed to PWM function and PWM TBCLK is running?

    Roger

  • Thanks for the reply Roger,

    I removed the TZSEL.bit.OSHT1 = 1. The PWMs are running (counting up and down is working), and therefore the TBCLK must be working. I'm using a heavily modified version of the motor control HVACI_Sensorless example project. I'll try and do some research to understand better understand how the PWMs operate while "running" since they constantly change frequencies and such.

    Daniel

  • So here's something interesting:

    For debugging protection purposes, the HVACI_Sensorless example code includes an initialization (below) to prevent a breakpoint from allowing the PWMs to continue running. (force low and force high is altered from the original due to custom hardware). This works perfectly fine in the older HVACI_Sensorless project, but with the new project I'm working on (even though the PWM registers are exactly the same for trip zone events), this breakpoint hault only causes correct outputs on EPwm3. It's like Pwm1 & 2 aren't properly responding to a trip zone.


    EALLOW;
    // CPU Halt Trip
    EPwm1Regs.TZSEL.bit.CBC6=0x1;
    EPwm2Regs.TZSEL.bit.CBC6=0x1;
    EPwm3Regs.TZSEL.bit.CBC6=0x1;

    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
    EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_HI; // EPWMxB will go high

    EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
    EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_HI; // EPWMxB will go high

    EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
    EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_HI; // EPWMxB will go high

    EDIS;
  • Aha! before EPwmxRegs.TZCTL.bit.TZA & EPwmxRegs.TZCTL.bit.TZB gets set a one-shot Trip Zone event was occurring, causing the PWMs to be locked into an unknown state. Right before a run, the Trip Zone flag was cleared. Still not sure why the second Trip Zone event kept the same outputs as the initial accidental TZ event (and not the EPwmxRegs.TZCTL.bit.TZA/B settings that were in the registers). Do we know if those registers will lock after a trip zone event until a power cycle or something? Idk.