Part Number: TMS320F28P659DK-Q1
Other Parts Discussed in Thread: SYSCONFIG
Hi Texas Team,
I am currently testing a three-phase inverter.
I have the outputs working, but I am struggling to find the proper method to override the PWM outputs using the Trip Zone. Specifically, I need three PWMs with complementary outputs that can be simultaneously forced to zero (or released) based on software control.
The three PWMs are configured identically, except that PWM_A generates a sync out signal, while PWM_B and PWM_C use it as a sync in signal. They operate as expected, but when I call the functions PwmRunModeOff and PwmRunModeOn to control the override, the code sometimes only turns off one or two outputs instead of all three.
The relevant code is attached below:
void PwmRunModeOff(void) {
uint16_t i;
// Optional: freeze TBCLK if you want simultaneity across modules
// SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
for (i = 0; i < sizeof(kPwmBases) / sizeof(kPwmBases[0]); ++i) {
const uint32_t base = kPwmBases[i];
EALLOW;
// Ensure trip actions will force final outputs LOW
EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);
// Prevent a TZ ISR from clearing OST while we hold
EPWM_disableTripZoneInterrupt(base, EPWM_TZ_INTERRUPT_OST | EPWM_TZ_INTERRUPT_CBC);
// Make sure AQ continuous SW forces are not active
EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_SW_DISABLED);
EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_SW_DISABLED);
// Clear stale latches so our new OST is the only one observed
EPWM_clearTripZoneFlag(base,
EPWM_TZ_INTERRUPT_OST | EPWM_TZ_INTERRUPT_CBC |
EPWM_TZ_FLAG_DCAEVT1 | EPWM_TZ_FLAG_DCAEVT2 |
EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_DCBEVT2);
// Latch OST (post-deadband outputs go LOW)
EPWM_forceTripZoneEvent(base, EPWM_TZ_FORCE_EVENT_OST);
EDIS;
}
// Verify latch once
for (i = 0; i < sizeof(kPwmBases) / sizeof(kPwmBases[0]); ++i) {
const uint32_t base = kPwmBases[i];
if ((EPWM_getTripZoneFlagStatus(base) & EPWM_TZ_FLAG_OST) == 0U) {
EALLOW;
EPWM_forceTripZoneEvent(base, EPWM_TZ_FORCE_EVENT_OST);
EDIS;
}
}
// SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
turn_off_drivers();
}
void PwmRunModeOn(void) {
uint16_t i;
// Optional: align release to TBCTR==0 on your master for a clean first edge
// while (EPWM_getTimeBaseCounter(PWM_A_BASE) != 0U) {}
for (i = 0; i < sizeof(kPwmBases) / sizeof(kPwmBases[0]); ++i) {
const uint32_t base = kPwmBases[i];
EALLOW;
// Clear OST/CBC & DC flags so PWM resumes
EPWM_clearTripZoneFlag(base,
EPWM_TZ_INTERRUPT_OST | EPWM_TZ_INTERRUPT_CBC |
EPWM_TZ_FLAG_DCAEVT1 | EPWM_TZ_FLAG_DCAEVT2 |
EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_DCBEVT2);
// Ensure no AQ SW force
EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_SW_DISABLED);
EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_SW_DISABLED);
// Unmask TZ interrupts again if you use them elsewhere
EPWM_enableTripZoneInterrupt(base, EPWM_TZ_INTERRUPT_OST | EPWM_TZ_INTERRUPT_CBC);
EDIS;
}
turn_on_drivers();
}
Could you please advise on the correct or recommended way to implement this simultaneous, synchronized PWM override using the Trip Zone?
Thank you in advance,

