Dear C2000 expert,
I would like to use F28023's epwm works in CBC mode, and require epwm to be latched after CBC occurs in 5 consecutive switch cycle.
But I got a problem that PWM doesn't works in CBC mode if I clears TZCLR register. It seems that TZ condition disappeared after TZCLR register clears. Can you please share your comments on this?
What I doing sequence shown as below:
In each pwm period isr:
- read TZFLG to see if CBC occurs
- If CBC, then count the number and set TZCLR register(it will cause pwm issue), if consecutive 5 pwm cycle, latch pwm
- else clear counter
Here is my test wave, the normal pwm period is 50us, but the pwm cycle is changed after Clearing TZCLR register.
Here is my code about CBC initialization:
void init_pfc_acomp_trip_epwm(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // Enable Clock to the ADC
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Comparator shares the internal BG reference of the ADC, must be powered even if ADC is unused
//enable analog comparator
DELAY_US(1000); // Delay for Power Up
SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1; // Enable clock to the Comparator 1 block
Comp1Regs.COMPCTL.bit.COMPDACEN = 1; // Power up Comparator 1 locally
//Comp1Regs.COMPCTL.bit.COMPSOURCE = 1; // Connect the inverting input to pin COMP1B
////////////////Uncomment following 2 lines to use DAC instead of pin COMP1B //////////////////
Comp1Regs.COMPCTL.bit.SYNCSEL = 1; //Synchronous version of comparator output is passed
Comp1Regs.COMPCTL.bit.QUALSEL = 31; //Input to the block must be consistent for 3 consecutive clocks before output of Qual block can
//change
Comp1Regs.COMPCTL.bit.COMPSOURCE = 0; // Connect the inverting input to the internal DAC
Comp1Regs.DACVAL.bit.DACVAL = COMP_DAC_VALUE; // Set DAC output to midpoint
EDIS;
EALLOW;
// Define an event (DCAEVT1) based on TZ1 and TZ2
EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP1OUT; // DCAH = Comparator 1 output
EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_TZ2; // DCAL = TZ2
//EPwm1Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_LOW; // DCAEVT1 = DCAH low(will become active as Comparator output goes low)
//EPwm1Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1; // DCAEVT1 = DCAEVT1 (not filtered)
//EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC; // Take async path
EPwm1Regs.TZDCSEL.bit.DCAEVT2 = TZ_DCAH_LOW;
EPwm1Regs.DCACTL.bit.EVT2SRCSEL = DC_EVT2; // DCAEVT2 = DCAEVT2 (not filtered)
EPwm1Regs.DCACTL.bit.EVT2FRCSYNCSEL = DC_EVT_ASYNC; // Take async path // Enable DCAEVT2 as
//a one shot trip source
// Note: DCxEVT1 events can be define
// Enable DCAEVT1 and DCBEVT1 are one shot trip sources
// Note: DCxEVT1 events can be defined as one-shot.
// DCxEVT2 events can be defined as cycle-by-cycle.
EPwm1Regs.TZSEL.bit.DCAEVT1 = 0;
EPwm1Regs.TZSEL.bit.DCAEVT2 = 1;
// What do we want the DCAEVT1 and DCBEVT1 events to do?
// DCAEVTx events can force EPWMxA
// DCBEVTx events can force EPWMxB
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWM1A will go high
EDIS;
}
CBC handler code in ISR:
inline void epwm_cbc_handler(void)
{
volatile union TZFLG_REG tzflg;
static int16 cbc_count = 0;
EALLOW;
tzflg.all = EPwm1Regs.TZFLG.all;
if(tzflg.bit.CBC == 1) //CBC occurs
{
EPwm1Regs.TZCLR.all = tzflg.all; //clear cbc flag
cbc_count ++;
if(cbc_count == 5)
{
TURN_OFF_PFC();
PFC_VCC_OFF;
pfc_vars.cbc_fault = 1;
}
}
else
{
cbc_count = 0;
}
EDIS;
}
Regards,
Jack

