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.

TMS320F280049C: How to obtain an ePWM2a rising edge DeadBand delay when ePWM2B is forced low, and ePWM2A is forced high via CMPSS compare function?

Part Number: TMS320F280049C
Other Parts Discussed in Thread: SYSCONFIG

I want to achieve a deadband delay via CMPSS ePWM CBC tripzone controlled function.

But when TripZone is happening at that instant, epwm2b is forced to low, and epwm2a is forced to high (at this point, I want epwm2a rising edge delay around 80ns).

I know the normal deadband function is not working here.

Ref: (e2e.ti.com/.../tms320f28384s-one-question-of-epwm-trip-zone-submodule)

So, I'm using the valley switching function, but it didn't work. (It is working like the below figure)

Oscilloscope recorded waveform.

Can someone please guide me... 

My written code is:

void main(void)
{
InitSysCtrl(); // Initialize device clock and peripherals
InitGpio(); // Initialize GPIO
DINT; // Disable CPU interrupts
InitPieCtrl(); // Initialize the PIE control registers to their default state.

// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;

InitPieVectTable(); // Initialize the PIE vector table with pointers to the shell Interrupt
setup1GPIO(); //User specific code to enable GPIO

// adc (A4) CMPSS (CMP2) is selected (P.No. 1415)
EALLOW;
AnalogSubsysRegs.CMPHPMXSEL.bit.CMP2HPMXSEL = 0;//IA-A4
EDIS;

// Map ISR functions
EALLOW;
PieVectTable.ADCA1_INT = &adcA1ISR; // Function for ADCA interrupt 1
EDIS;

initADC(); // Configure the ADC and power it up

initEPWM1(a); // Configure the ePWM1
initEPWM2(a); // Configure the ePWM2
initEPWM3(a); // Configure the ePWM2

initADCSOC(); // Setup the ADC for ePWM triggered conversions on channel 1
CMPSSInit(); // CMPSS initialized.
XBARInit(); // XBAR function call

// Enable global Interrupts and higher priority real-time debug events:
IER |= M_INT1; // Enable group 1 interrupts

EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable PIE interrupt

//// Sync ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;

//// Take conversions indefinitely in loop

while(1)
{
//
////Start ePWM
//
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // Unfreeze, and enter up count mode

////IDLE loop. Just sit and loop forever (optional):
////
for(;;)
{
__asm(" NOP");
}

}
}


void initEPWM2(Uint16 period)
{
EALLOW;

EPwm2Regs.TBPRD = a; // Set timer period
EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0

EPwm2Regs.TBCTR = 0x0000;
EPwm2Regs.TBCTL.bit.FREE_SOFT = 3;

EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable phase loading
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.SYNCOSEL=TB_CTR_ZERO;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up/down

EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;

EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // page.264
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable Dead-band module
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active High complementary mode(output inverted)
// EPwm2Regs.DBRED.bit.DBRED = DB;
EPwm2Regs.DBFED.bit.DBFED = DB;

/// By the below code lines, the DB delay is set to epwmB.
EPwm2Regs.CMPB.bit.CMPB = a-1; // Set compare 
EPwm2Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm2Regs.CMPA.bit.CMPA = a;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; //AQ_CLEAR


// DCAH = Comparator 2 output
// DCAEVT2 = DCAH HI (will become active as Comparator output goes HI)>>> for epmwA
EPwm2Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_TRIPIN4; //(Page. 1980)
EPwm2Regs.TZDCSEL.bit.DCAEVT2 = TZ_DCAH_HI;
EPwm2Regs.DCACTL.bit.EVT2SRCSEL = DC_EVT_FLT; // DCAEVT2 = DCAEVT2 (not filtered) DC_EVT2
EPwm2Regs.DCACTL.bit.EVT2FRCSYNCSEL = DC_EVT_ASYNC; // Take async path
EPwm2Regs.TZSEL.bit.DCAEVT2 = 1;
EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_HI; // EPWM1A will go low

//// Valley Switching.
///Step No.1.
EPwm2Regs.DCFCTL.bit.SRCSEL = 1; // digital filter input source is DCAEVT2. (P.No. 1984)
///Step No. 2.
EPwm2Regs.DCFCTL.bit.EDGEMODE = 0; // 0 = Low To High Edge is selected (Page No. 1983)
// 1 = hight to Low
// 2 = both
EPwm2Regs.DCFCTL.bit.EDGECOUNT = 0; // change the value to verify (P.No. 1983)
//Step No. 3.
EPwm2Regs.VCAPCTL.bit.TRIGSEL = 5; //Capture sequence is triggered by DCAEVT2 event. (P.No. 1905)
//Step No. 4.
EPwm2Regs.VCAPCTL.bit.VCAPE = 1; //enable valley capture
//Step No. 5.
EPwm2Regs.VCNTCFG.bit.STARTEDGE = 2; // (P.No.1907)
//Step No. 6.
EPwm2Regs.VCNTCFG.bit.STOPEDGE = 3; // this value must be greater than start edge.
///Step No. 7.
EPwm2Regs.VCAPCTL.bit.VDELAYDIV =1; //HWVDELVAL = SWVDELVAL (P.No. 1905)

EPwm2Regs.SWVDELVAL = 5; //
///Step No.8.
EPwm2Regs.VCAPCTL.bit.EDGEFILTDLYSEL = 1; //Hardware Valley Delay is applied (P.No. 1905)

// EPwm2Regs.HWVDELVAL = 5; //Hardware Valley Delay Value Register
/// Select
EPwm2Regs.DCFCTL.bit.EDGEFILTSEL = 1; // digital filter (P.No. 1984)

// DCAEVT2 = DCAH HI (will become active as Comparator output goes HI)>>> for epmwA
EPwm2Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_TRIPIN4;
EPwm2Regs.TZDCSEL.bit.DCBEVT2 = TZ_DCBH_HI;
EPwm2Regs.DCBCTL.bit.EVT2SRCSEL = DC_EVT2; // DCAEVT2 = DCAEVT2 (not filtered)
EPwm2Regs.DCBCTL.bit.EVT2FRCSYNCSEL = DC_EVT_ASYNC; // Take async path
EPwm2Regs.TZSEL.bit.DCBEVT2 = 1;
EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWM1B will go high

// Enable TZ interrupt
EPwm2Regs.TZEINT.bit.CBC = 1;
EPwm1Regs.TZCLR.bit.INT = 1;


EDIS;
}


__interrupt void adcA1ISR(void)
{
//
// Add the latest result to the buffer
// ADCRESULT0 is the result register of SOC0

V_out = AdcaResultRegs.ADCRESULT0*3.3/4095;
V_in = AdccResultRegs.ADCRESULT0*3.3/4095;
V1 = AdccResultRegs.ADCRESULT0*3.3/4095*30; //Number form


// DACAL value is changing w.r.to the load current

Cmpss2Regs.DACHVALS.bit.DACVAL = 2500; // CMPSS DACVAL

EPwm2Regs.TBPRD = (a + b);

// Clear the interrupt flag

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;


// Check if overflow has occurred
if(1 == AdcaRegs.ADCINTOVF.bit.ADCINT1)
{
AdcaRegs.ADCINTOVFCLR.bit.ADCINT1 = 1; //clear INT1 overflow flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
}

PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge the interrupt

}

void CMPSSInit(void){

EALLOW;
////CMP2_H for IL current detection
Cmpss2Regs.COMPCTL.bit.COMPDACE = 1; //Comparator/DAC enabled
Cmpss2Regs.COMPCTL.bit.ASYNCHEN = 0; //not feed into OR gate
Cmpss2Regs.COMPHYSCTL.bit.COMPHYS = 1;

/////Filter Function
Cmpss2Regs.CTRIPHFILCTL.bit.SAMPWIN = 4;
Cmpss2Regs.CTRIPHFILCTL.bit.THRESH = 2;
Cmpss2Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = 0;
Cmpss2Regs.CTRIPHFILCTL.bit.FILINIT = 1;
Cmpss2Regs.COMPSTSCLR.bit.HLATCHCLR = 1;

/////CTRIPOUTH = CLBX-BAR INPUT
Cmpss2Regs.COMPCTL.bit.CTRIPOUTHSEL = 2; //synchronous comparator output drives CTRIPOUTH
Cmpss2Regs.COMPCTL.bit.CTRIPHSEL = 2; //synchronous comparator output drives CTRIPH
Cmpss2Regs.COMPCTL.bit.COMPHINV = 0; //Output of comparator is not inverted
Cmpss2Regs.COMPCTL.bit.COMPHSOURCE = 0; //Inverting input of comparator driven by internal DAC

/////Selection of DACVAL source.
Cmpss2Regs.COMPDACCTL.bit.SWLOADSEL = 0; //DACxVALA is updated from DACxVALS on SYSCLK
Cmpss2Regs.COMPDACCTL.bit.DACSOURCE = 0; //DACHVALA is updated from DACHVALS
EDIS;

}


void XBARInit(void){
EALLOW;
//Configure EPWM_XBAR (Page No. 1029)
//TRIP4 for OVP/OVP TRIG
EPwmXbarRegs.TRIP4MUX0TO15CFG.bit.MUX2 = 0; //Configured to CMPSS2 CTRIPH
EPwmXbarRegs.TRIP4MUXENABLE.bit.MUX2 = 1; // Trip4 ePWM XBAR MUX enable

/// below code lines are written in order to view the CMPSS value
//Configure OUTPUT_XBAR3 GPIO5
//Configure OUTPUTXBAR3 = CMP2_H
OutputXbarRegs.OUTPUT1MUX0TO15CFG.bit.MUX2 = 0; //CMPSS2.CTRIPOUTH
OutputXbarRegs.OUTPUT1MUXENABLE.bit.MUX2 = 1;

// OutputXbarRegs.OUTPUT6MUX0TO15CFG.bit.MUX2 = 0; //CMPSS2.CTRIPOUTH
// OutputXbarRegs.OUTPUT6MUXENABLE.bit.MUX2 = 1;
EDIS;
}

  • Hi Faheem, 

    To clarify, you want a 80 ns delay of the rising edge of your output to occur AFTER the trip event occurs?

    If so, you cannot use the trip zone module to control your outputs in this case. Instead, you can generate an action qualifier event on T1 with the same behavior as your trip event, and configure T1 to be generated by a digital compare event, which would be generated by the EPWM XBAR. The dead-band module takes in the output of the action qualifier module as an input, so you would be able to apply a delay to the rising edge induced by T1.

    Let me know if this solution would fit the needs of your application.

    Thank you,

    Luke

  • Where could we see some examples?Plz

  • Hi Ginger,

    Unfortunately this is a one-time event until the next edge as Jason mentioned in his post.

    If you want the same behavior as the trip-zone module but apply a delay to when the trip affects your EPWM outputs, another potential solution is to route the CMPSS event through the CLB-XBAR, apply a delay using the CLB counters, route the event through a CLB output to the EPWMXBAR, and configure a trip how you would normally, but the signal will be delayed by the CLB and thus the effect on your EPWM outputs will be delayed.

    I would highly recommend using SysConfig to configure your XBARs and CLBs, let me know if you have any questions on using SysConfig.

    Thank you,

    Luke

  • Hello Mr. Luke,

    So, we need to use the CLB function to obtain the deadband delay in our case.

    It meaning is:  

    1- we have only one option to work, which is CLB block.

    2. via T1 operation of Action Qualifier will not work in our case. (Am I right?) please.

  • Hi Faheem,

    1) Yes the CLB block is necessary in this case. The reason for this is that the trip-zone module overrides the output of the dead-band module, so the only way to delay the effect of the trip event on your EPWM output is by feeding it through the CLB and applying some delay.

    2) It's possible the T1 event delayed via the deadband module will work depending on the behavior of the CMPSS compare condition. The T1 action qualifer will only trigger on a rising edge of the CMPSS condition, meaning that the T1 action qualifer event will not occur again until the CMPSS condition becomes false, and then true again. If you have an action qualifer event on TBCTR=0 that is doing the opposite of the T1 event, This may result in several periods of a 100% or 0% duty cycle depending on the behavior of the CMPSS condition, but perhaps this is okay for your system.

    Using the delayed trip event via the CLB will clear the trip condition at the beginning of every cycle, but the state of the CMPSS condition will be reevaluated at the beginning of every cycle and induce the trip zone behavior on the PWM output until the CMPSS condition becomes false, so the PWM output would not be affected by the action qualifer event on TBCTR=0 until the CMPSS condition becomes false. If this is your desired behavior, then I believe using the CLB is the only way to delay the effect of the CMPSS condition on the PWM output.

    Le me know if you have any further questions.

    Thank you,

    Luke