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.

CCS/TMS320F28377S: EPWM glitch

Part Number: TMS320F28377S
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hi,

I have a problem that is related to EPWM output from DSP TMS320F28377S.

In my code, the EPWM7 output is updated based on the sensing signal and real-time calculation of the duty cycle in one interrupt. As shown in the following picture, the PWM output is occasionally all high in A and all low in B in one switching cycle, looking like a glitch or bug. i used complementary mode in PWM generation. And such glitch occurs in very low frequency (sometimes it takes ten seconds to capture one glitch). The sensed external signal and real-time calculation should be all right. Since my sampling frequency is 50kHz, and switching frequency is averagely 300kHz, if something wrong with the calculation and sensing signal, the PWM glitch will last for several switching cycles instead of only one cycle and occurs in so low frequency. so it looks more like a PWM glitch when updating the duty cycle.

I wonder, what will cause the EPWM module glitch or bug like this? How can i avoid such phenomenon?

 

By the way, the initialization function of the PWM is shown below. Values for EPWM_TIMER_TBPRD, EPWM_CMPA, EPWM_CMPB, EPWM_TIMER_PHASE, RED and FED are updated based on the calculation in one ADC interrupt.

// code/////////////
void InitEPwm7()
{
// Setup TBCLK
EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm7Regs.TBPRD = EPWM_TIMER_TBPRD; // Set timer period
EPwm7Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable phase loading
EPwm7Regs.TBPHS.bit.TBPHS =0x0000; // Phase is 0
EPwm7Regs.TBCTL.bit.PRDLD = TB_SHADOW; //
EPwm7Regs.TBCTL2.bit.SYNCOSELX=1; //extended selection for sync out, EPWMxSYNCO = CMPC
EPwm7Regs.TBCTL.bit.SYNCOSEL = 3; //0:Sync Output Select is sync signal;1: when TB counter = zero; 3: extended,

EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1;
//
// Setup shadow register load on ZERO
EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm7Regs.CMPCTL2.bit.SHDWCMODE = CC_SHADOW;
EPwm7Regs.CMPCTL2.bit.LOADCMODE = CC_CTR_ZERO;
//
// Set Compare values
EPwm7Regs.CMPA.bit.CMPA = EPWM_CMPA; // Set compare A value
EPwm7Regs.CMPB.bit.CMPB = EPWM_CMPB; // Set Compare B value
EPwm7Regs.CMPC = EPWM_TIMER_PHASE; // 0.5 Ts
//
// Set actions on outputA, EPWM7A is the original PWM for SR switch
EPwm7Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up count
EPwm7Regs.AQCTLA.bit.CBU = AQ_CLEAR; // Clear PWM1A on event B, up count
//
// Set Dead-Band Generator
EPwm7Regs.DBCTL.bit.IN_MODE = DBA_ALL; //EPWMA is the source for both falling edge and rising edge
EPwm7Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable dead-band module, bothFED and RED are active
EPwm7Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active high complementary
EPwm7Regs.DBRED.bit.DBRED = RED; // set dead time before turning on SR switch
EPwm7Regs.DBFED.bit.DBFED= FED; // set dead time before turning on AC switch, Tr

// turn off gate signals when Vo over voltage through trip 1
EALLOW;
EPwm7Regs.TZSEL.bit.OSHT1 = 1; // enable T1 as the trigger signal
EPwm7Regs.TZCTL.bit.TZA = 2; // force EPWM7A to be LOW
EPwm7Regs.TZCTL.bit.TZB = 2; // force EPWM7B to be LOW
EDIS;

// turn off gate signals when over current through trip 2
EALLOW;
EPwm7Regs.TZSEL.bit.OSHT2 = 1; // enable T2 as the trigger signal
EPwm7Regs.TZCTL.bit.TZA = 2; // force EPWM7A to be LOW
EPwm7Regs.TZCTL.bit.TZB = 2; // force EPWM7B to be LOW
EDIS;

// turn off gate signals when over current through trip 3
EALLOW;
EPwm7Regs.TZSEL.bit.OSHT3 = 1; // enable T3 as the trigger signal
EPwm7Regs.TZCTL.bit.TZA = 2; // force EPWM7A to be LOW
EPwm7Regs.TZCTL.bit.TZB = 2; // force EPWM7B to be LOW
EDIS;
}

I really appreciate it if you could give me any hint or suggestions. This problem is really critical for my whole experiment.

Looking forward to your reply.

  • I think the problem is not in your initialization code. It seems you are updating multiple parameters in your control ISR. The fact that one of them is PWM phase implies you have multiple PWMs updating at the same time? In any case, issues can arise when updating period and compare values in the same module; for example, if a new TB period is written which is lower than the current TBCTR, the counter will miss the threshold and just keep on counting up. Possibly something like this is going on.

    The PWM module on this device is fitted with a 'one-shot' reload feature which allows you to update all new parameters in the same clock cycle. In the current version of the user's guide for this device, the one-shot reload feature is described in Fig. 14-12 and section 14.4.7.2. I don't see the GLDCTL register configured in your code so you may not be using this feature. Please take a look at the description in the UG document to see if it applies to your situation.

    Can you also please clarify the red text in the 'scope capture: "TBCTR is reset by external signal"? Thanks.

    Regards,

    Richard
  • Can you debug this for me? I would like to know what value is in CMPA, CMPB when the signal is all the way LOW or HIGH in the PWM period.

  • Hi, 

    Thanks so much for your reply. The external signal is the zero-current detection signal from the hardware circuit. I send this signal through GPIO and link to EPWM7SYNCIN for reset the time-based counter. Everytime the reset signal is active, phase 0 will be loaded and the counter will start from zero. as you can seen in the following picture, the external reset signal is active just before the PWM glitch occurs. so it is like the time-based counter somehow did not reset with the EPWM7SYNCIN signal.

     As you mentioned, if it is true that a new TB period is written which is lower than the current TBCTR, the counter will miss the threshold and just keep on counting up, this may be one reason, i will check this later. Also, although i used synchronization function between master phase and slave phase (2 PWM modules), i did not set the slave phase PWM when debugging this problem.

    I have to run the code in FLash mode with operating my converter. So I cannot directly show the values in CMPA and CMPB. I will try to identify it. But i do have limited the values of EPMW_CMPA and EPWM_CMPB, making sure it will not overflow when loading to EPWM module. Below is the partial code for calculations in ADC interrupt.

    // real-time calculation code in ADC interrupt

    a=1/wr;
    //tdelay = 100e-9;
    if (v_comp < 0.64)
    {
    tdelay = 1e-9*(12.346*v_comp*v_comp-46.173*v_comp+124.49);
    }
    else
    {
    tdelay = 1e-9*(-250*v_comp*v_comp+285*v_comp+20);
    }

    co_delay = sqrt(1+tdelay_m2*wr*wr);
    bound = co_delay/(k1+co_delay);
    if(bound < 0.52 )
    {
    bound = 0.52;
    }
    if(bound > 0.56)
    {
    bound = 0.55;
    }
    b=Vout/Vin_abs;
    c=1/(b-1); // = Vin/(Vo-Vin)

    if (Vin_abs<bound*Vout)  // mode 1
    {
    k=(b-1)*sqrt(1+tdelay*tdelay*wr*wr); //
    tr1 = 150e-9;
    }
    else        // mode 2
    {
    k=k1;
    tr1 = 80e-9;
    }
    d=1/k;

    ton_ac = Ton_c+k*a;
    ten_sr = a*sqrt(k*k*c*c-1)-tdelay;
    ton_sr = ton_ac*c+ten_sr+tdelay;
    tr2 = a*(pi-acos((b-1)*d)-acos(d))+10e-9;
    tzvs = a*sqrt(k*k-1);

    tsw=ton_ac+tr1+ton_sr+tr2+tzvs+200e-9;
    // }

    if (Vout>Vo_th2) // enable ZCD external reset signal when Vout is fully larger than Vin
    {
    EALLOW;
    EPwm7Regs.TBCTL.bit.PHSEN = 1;//TB_ENABLE;
    EDIS;
    }

    // update compare values for EPWM

    EPWM_CMPA = ten_sr*2e8;
    EPWM_CMPB = (ten_sr+tr2+tzvs+ton_ac)*2e8;
    RED = tr2*2e8;
    FED = tr1*2e8;
    EPWM_TIMER_TBPRD = tsw*2e8;
    EPWM_TIMER_PHASE = tsw*1e8;

  • Please do go ahead and monitor the controlled variables, especially CMPA, CMPB, TBPRD, and PHASE. Perhaps you can set up a data logger to log values into a rolling buffer, then freeze it when the issue occurs.

    BTW, are you converting these to fixed-point before actually writing to the registers?

    EPWM_CMPA = ten_sr*2e8;
    EPWM_CMPB = (ten_sr+tr2+tzvs+ton_ac)*2e8;
    RED = tr2*2e8;
    FED = tr1*2e8;
    EPWM_TIMER_TBPRD = tsw*2e8;
    EPWM_TIMER_PHASE = tsw*1e8;

    Regards,

    Richard
  • Thanks so much ! Yes, I am trying monitor the variables. BTW, i am not clear how to set up a data logger in flash mode. Could you provide me any link or reference about this.
    Also, I defined the time variables tsen_sr, tr2, etc as float data, and EPWM_CMPA, EPWM_CMPB, etc as Uint16 data. then i directly send the Uint16 data to EPWM registers. Do i need to do any converting during the process?

    Thanks so much.
  • There are several solutions for data logging on the TI site. One I prefer for logging floating point data is in the Digital Control Library, which is part of C2000Ware. After you download and install that in the default location, look for the library at:
    C:\ti\c2000\C2000Ware_1_00_06_00\libraries\control\DCL
    The data logger is in the header file "DCL_fdlog.h". This is just my preference. You should be able to integrate this with your code pretty easily and run from flash. Post back if you run into any issues.

    You need to carefully consider the numerical type when writing to registers: on C28x, 'float' is a 32-bit single precision number, while Uint16 is an un-signed 16-bit fixed point. The compiler will take care of the conversion for you, but you should still check the value of the 'float' to be sure it can actually be represented in 16-bits. This is where the data logger comes in, and I suspect it might turn out to be the issue.

    Regards,

    Richard
  • Hi,

    Thanks so much for your help. I have just found the reason for the issue.
    In my setup, i load these compare values on TBCTR = zero. When the glitch happens, the value of CMPA is too small (actually, it is zero), so the PWM cannot be generated normally. After i limit CMPA >=2, it works well and no more glitch.

    Thanks again, and i really learned a lot from this.

    Best,
  • Great! Glad to know you solved it, and thanks for letting us know.

    Regards,

    Richard