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.

TMS320F28379D: glitch in PWM

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Dear Team TI, 

As shown in attached image, 

There appears a glitch because of PWM at output. The glitches are shown in red color text. 

The waveform in red is value to be put in EPwm3Regs.CMPA.bit.CMPA value. The pink is output of PWM3 (GPIO 4). The green is ISR probbed at one of the GPIO. 

So, the value of CMPA register is changing at the end of ISR (point 1 of image) , so output of PWM should change in next ISR i.e. at point 2 (of image), instead it is changing at point 3 (of image), and hence the delay from point 2 to 3 is appearing in output, which is undesirable. 

I have 3 PWMs in the system and out of which PWM 1 is also used for ISR (Freq. of ISR is 10 kHz).  I am changing the value of CMPA in PWM1 ISR

The freq.of glitch is 20 kHz. 

KINDLY HELP.

Below is how I have defined 3 PWMs. 

void InitEPwm1()
{
    EPwm1Regs.TBPRD = 5000;                 // Set timer period for 10KHz
    EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        
    EPwm1Regs.TBCTR = 0x0000;                    

    //
    // Setup TBCLK
    //
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; 
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;      
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;      
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
    EPwm1Regs.TBCTL.bit.PHSDIR = TB_UP;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;  
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    //
    // Setup compare
    //
    EPwm1Regs.CMPA.bit.CMPA = 2500;

    //
    // Set actions
    //

    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;            
    EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;

    EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;       
    EPwm1Regs.AQCTLB.bit.CBD = AQ_SET;

    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;
    EPwm1Regs.ETSEL.bit.INTEN = 1;              
    EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;          

}

//
// InitEPwm2Example - Initialize EPWM2 configuration
//
void InitEPwm2()
{
    EPwm2Regs.TBPRD = 5000;                      
    EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;           
    EPwm2Regs.TBCTR = 0x0000;                     
    //
    // Setup TBCLK
    //
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; 
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;        
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;     
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;         
                                                 


    EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
    EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;   
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    //
    // Setup compare
    //
    EPwm2Regs.CMPA.bit.CMPA = 5000;

    //
    // Set actions
    //

    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;            
    EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;

    EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;        
    EPwm2Regs.AQCTLB.bit.CBD = AQ_SET;

}

//
// InitEPwm3Example - Initialize EPWM3 configuration
//
void InitEPwm3()
{
    EPwm3Regs.TBPRD = 5000;                 // Set timer period for 10KHz
    EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
    EPwm3Regs.TBCTR = 0x0000;                     // Clear counter

    //
    // Setup TBCLK
    //
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up DOWN
    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;//TB_ENABLE;        // Disable phase loading
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
    EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
    EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP;// already set correctly

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

    //
    // Setup compare
    //
    EPwm3Regs.CMPA.bit.CMPA = 2500;

    //
    // Set actions
    //

    EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;             // Set PWM3A on Zero
    EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;

    EPwm3Regs.AQCTLB.bit.CBU = AQ_CLEAR;         // Set PWM3A on Zero
    EPwm3Regs.AQCTLB.bit.CBD = AQ_SET;



}

  • Hi,

    Your configuration of the PWM seems alright. You've it configured for Shadow loading on counter zero event.
    Can you try moving the update of CMPx values from the end of the ISR to the beginning or the middle? I want to rule out the possibility of ISR extending and CMPx update entering into the next counter reload time. This could easily happen if your ISR is too long.
    Or, you can simply slowdown the PWM frequency to validate if this is the cause of the problem. 
    Also, are you changing frequency in this application (TBPRD)? if so, there may be boundary conditions with respect the period change vs. duty change you need to consider.

  • Hello, 

    Thank you for responding. 

    I have tried with lower frequency of ISR, but then changes the frequency of glitch, but it exists. 

    I have also tried updating the value of CMPx at start of ISR, but glitch exists. 

    Also, I am not changing the value of TBPRD. 

  • Hi,

    Can you start with an example code provided and check this behavior?
    You can start with 
    C:\ti\c2000\C2000Ware_2_01_00_00\driverlib\f2837xd\examples\cpu1\epwm
    epwm_ex2_updown_aq

    Your configuration seems fairly basic and i do not expect to see any issues in this mode.

  • Hello, 

    I will try that, but I do not understand that by changing below registers, it changes the position of glitch. 

    1. when I change in 

    " EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO" to  " EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPA"

    the glitch is removed from PWM1 , but exist in PWM2 and 3, as PWM 1 is used as ISR. Also, it changes the time between two ISR only at the time of change in CMPA value. 

    2. When changed

    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO ; 
    
    to 
    
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;

    the glitch shifts to the upper side of output. 

    I do not understand this. Does above changes signifies that there is configuration mistake?

    Thanks again. 

  • Hi,

    It clearly seems to be an issue with interrupt timing w.r.t. the update of registers in your software.
    It's difficult for me to predict the sequence of event (in your ISR vs PWM update events).
    Please start with provided example so that we can replicate the issue and event dependencies easily.
    When you run the example as it is, you'll obviously not see any glitch - then you can tweak the example to reflect your configuration step by step to narrow down to the issue. As I said - to me it seems to be an issue with event timing w.r.t. ISR update.

  • Hello, 

    I tried the example file but obviously there is no glitch if I use as it is. When I substitute with my CMPA value, I had the same problem there, i.e. its problem with this type of CMPA value 

    My CMPA value moves from 0 to 1 and 1 to 0 as seen in image also. The glitch exist only on rising edge and I clamped it to 0.0004 to 0.9996 , the glitch is not there. 

    Thanks

    Vidhi Patel

  • Hi,

    Ok. That explains it. It wasn't clear to me, from your code, that you were changing the values from 0 to 1.
    There are certain limitations in attaining 0 to 100% duty cycle with normal CMPx values.
    TRM has a chapter and reference to application note on how to achieve 0 to 100% duty cycle.
    Refer to 15.6.5 Waveforms for Common Configurations
    and details on how to achieve 0 to 100% duty cycle.
    This should fix your problem - in case you want to use CMPx values all the way to zero and you do not want to clamp duty.

  • Hello, 

    I read that section, I can not keep CMPx greater than 1, because, for my application, CMPx goes varies from 0 to 1, so, I have to clamp it. 

    Right ?

  • Hi,

    Yes - you need to do the steps detailed in section  15.6.5 to achieve 0 to 100% duty cycle without any glitches or anomalies.
    If not you've to clamp the values.

  • I  get it. Thank you for support.