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.

TMS320F28069: When PWM2 was operated by adding a phase difference to PWM1, In a phase difference, the output of PWM2 periodically becomes a skip cycle.

Part Number: TMS320F28069
Other Parts Discussed in Thread: TMDSCNCD28069

Hello. everyone.

I have a question about HRPWM of TMS320F28069.

When PWM2 was operated by adding a phase difference to PWM1, In a phase difference, the output of PWM2 periodically becomes a skip cycle. *1

How can I get rid of the PWM2 output skip cycle?

* 1 Phase value at which skip occurs (EPwm2Regs.TBPHS.all)
0x00AE9800 to 0x00AEFF00
0x00AF2000 to 0x00AFFF00
0x00B02000 to 0x00B09700

Normal waveform

Yellow:PWM1A, Cyan:PWM1B, Magenta:PWM2A, Green:PWM2B

Illegal waveform

Yellow:PWM1A, Cyan:PWM1B, Magenta:PWM2A, Green:PWM2B


The project file can be sent immediately.

Best Regards,
Maekawa

  • Hi Maekawa,

    Could you please post your EPWM and HRPWM configuration code for both EPWM1 and 2?

    Regards,
    Kris
  • Hi Kris-san.

    Thank you for quick reply.

    Register settings of PWM and HRPWM are as follows.

    	// ePWM1
        EALLOW;
    	EPwm1Regs.TBPRD = 0x0160;
        EPwm1Regs.TBPRDHR = 0xF000;
        EPwm1Regs.TBPHS.half.TBPHS = 0U;
        EPwm1Regs.TBPHS.half.TBPHSHR = 0U;
        EPwm1Regs.TBCTR = 0;
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
       	EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
       	EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
        EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
    	EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    	EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        EPwm1Regs.CMPA.all = 0x00B07800;
       	EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    
       	EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
        EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    
        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm1Regs.DBCTL.bit.HALFCYCLE = 1;
        EPwm1Regs.DBRED = 24;
        EPwm1Regs.DBFED = 24;
    
        EPwm1Regs.TZSEL.bit.OSHT1       = TZ_ENABLE;
        EPwm1Regs.TZSEL.bit.OSHT2       = TZ_ENABLE;
        EPwm1Regs.TZSEL.bit.OSHT3       = TZ_ENABLE;
        EPwm1Regs.TZSEL.bit.DCAEVT1     = TZ_ENABLE;
        EPwm1Regs.TZSEL.bit.DCBEVT1     = TZ_ENABLE;
        EPwm1Regs.TZSEL.bit.DCAEVT2     = TZ_DISABLE;
        EPwm1Regs.TZSEL.bit.DCBEVT2     = TZ_DISABLE;
        EPwm1Regs.TZSEL.bit.CBC1        = TZ_DISABLE;
        EPwm1Regs.TZSEL.bit.CBC2        = TZ_DISABLE;
        EPwm1Regs.TZSEL.bit.CBC3        = TZ_DISABLE;
    
        EPwm1Regs.TZCTL.bit.TZA         = TZ_FORCE_LO;
        EPwm1Regs.TZCTL.bit.TZB         = TZ_FORCE_LO;
        EPwm1Regs.TZCTL.bit.DCAEVT1     = TZ_NO_CHANGE;
        EPwm1Regs.TZCTL.bit.DCBEVT1     = TZ_NO_CHANGE;
        EPwm1Regs.TZCTL.bit.DCAEVT2     = TZ_NO_CHANGE;
        EPwm1Regs.TZCTL.bit.DCBEVT2     = TZ_NO_CHANGE;
    
        EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP2OUT;
        EPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_COMP3OUT;
        EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_TZ2;
        EPwm1Regs.DCTRIPSEL.bit.DCBLCOMPSEL = DC_TZ3;
    
        EPwm1Regs.TZDCSEL.bit.DCAEVT1   = TZ_DCAH_HI;
        EPwm1Regs.TZDCSEL.bit.DCBEVT1   = TZ_DCBH_HI;
        EPwm1Regs.TZDCSEL.bit.DCAEVT2   = TZ_DCAL_LOW;
        EPwm1Regs.TZDCSEL.bit.DCBEVT2   = TZ_DCBL_LOW;
    
        EPwm1Regs.TZCLR.all             = 0x007F;
    
        EPwm1Regs.DCACTL.bit.EVT1SRCSEL     = DC_EVT1;
        EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_SYNC;
        EPwm1Regs.DCBCTL.bit.EVT1SRCSEL     = DC_EVT1;
        EPwm1Regs.DCBCTL.bit.EVT1FRCSYNCSEL = DC_EVT_SYNC;
        EPwm1Regs.DCACTL.bit.EVT2SRCSEL     = DC_EVT2;
        EPwm1Regs.DCACTL.bit.EVT2FRCSYNCSEL = DC_EVT_SYNC;
        EPwm1Regs.DCBCTL.bit.EVT2SRCSEL     = DC_EVT2;
        EPwm1Regs.DCBCTL.bit.EVT2FRCSYNCSEL = DC_EVT_SYNC;
    
        EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP;
        EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;
        EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;
        EPwm1Regs.HRCNFG.bit.SELOUTB = HR_NORM_B;
        EPwm1Regs.HRCNFG.bit.AUTOCONV = 1;
        EPwm1Regs.HRCNFG.bit.SWAPAB = HR_NORM_B;
    
        EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
        EPwm1Regs.HRPCTL.bit.HRPE = 1;
        EDIS;
    
        // ePWM2
        EALLOW;
        EPwm2Regs.TBPRD = 0x0160;
        EPwm2Regs.TBPRDHR = 0xF000;
        uiDebug_TBPHS_ePWM2 = 0x00B07800;
        EPwm2Regs.TBPHS.all = uiDebug_TBPHS_ePWM2;
        EPwm2Regs.TBCTR = 0;
        EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
        EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
        EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
        EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
        EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
        EPwm2Regs.TBCTL.bit.PHSDIR = TB_DOWN;
    
        EPwm2Regs.CMPA.all = 0x00B07800;
        EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
        EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    
        EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
        EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
    
        EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm2Regs.DBCTL.bit.HALFCYCLE = 1;
        EPwm2Regs.DBRED = 24;
        EPwm2Regs.DBFED = 24;
    
        EPwm2Regs.TZSEL.bit.OSHT1       = TZ_ENABLE;
        EPwm2Regs.TZSEL.bit.OSHT2       = TZ_ENABLE;
        EPwm2Regs.TZSEL.bit.OSHT3       = TZ_ENABLE;
        EPwm2Regs.TZSEL.bit.DCAEVT1     = TZ_ENABLE;
        EPwm2Regs.TZSEL.bit.DCBEVT1     = TZ_ENABLE;
        EPwm2Regs.TZSEL.bit.DCAEVT2     = TZ_DISABLE;
        EPwm2Regs.TZSEL.bit.DCBEVT2     = TZ_DISABLE;
        EPwm2Regs.TZSEL.bit.CBC1        = TZ_DISABLE;
        EPwm2Regs.TZSEL.bit.CBC2        = TZ_DISABLE;
        EPwm2Regs.TZSEL.bit.CBC3        = TZ_DISABLE;
    
        EPwm2Regs.TZCTL.bit.TZA         = TZ_FORCE_LO;
        EPwm2Regs.TZCTL.bit.TZB         = TZ_FORCE_LO;
        EPwm2Regs.TZCTL.bit.DCAEVT1     = TZ_NO_CHANGE;
        EPwm2Regs.TZCTL.bit.DCBEVT1     = TZ_NO_CHANGE;
        EPwm2Regs.TZCTL.bit.DCAEVT2     = TZ_NO_CHANGE;
        EPwm2Regs.TZCTL.bit.DCBEVT2     = TZ_NO_CHANGE;
    
        EPwm2Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP2OUT;
        EPwm2Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_COMP3OUT;
        EPwm2Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_TZ2;
        EPwm2Regs.DCTRIPSEL.bit.DCBLCOMPSEL = DC_TZ3;
    
        EPwm2Regs.TZDCSEL.bit.DCAEVT1   = TZ_DCAH_HI;
        EPwm2Regs.TZDCSEL.bit.DCBEVT1   = TZ_DCBH_HI;
        EPwm2Regs.TZDCSEL.bit.DCAEVT2   = TZ_DCAL_LOW;
        EPwm2Regs.TZDCSEL.bit.DCBEVT2   = TZ_DCBL_LOW;
    
        EPwm2Regs.TZCLR.all             = 0x007F;
    
        EPwm2Regs.DCACTL.bit.EVT1SRCSEL     = DC_EVT1;
        EPwm2Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_SYNC;
        EPwm2Regs.DCBCTL.bit.EVT1SRCSEL     = DC_EVT1;
        EPwm2Regs.DCBCTL.bit.EVT1FRCSYNCSEL = DC_EVT_SYNC;
        EPwm2Regs.DCACTL.bit.EVT2SRCSEL     = DC_EVT2;
        EPwm2Regs.DCACTL.bit.EVT2FRCSYNCSEL = DC_EVT_SYNC;
        EPwm2Regs.DCBCTL.bit.EVT2SRCSEL     = DC_EVT2;
        EPwm2Regs.DCBCTL.bit.EVT2FRCSYNCSEL = DC_EVT_SYNC;
    
        EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP;
        EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;
        EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;
        EPwm2Regs.HRCNFG.bit.SELOUTB = HR_NORM_B;
        EPwm2Regs.HRCNFG.bit.AUTOCONV = 1;
        EPwm2Regs.HRCNFG.bit.SWAPAB = HR_NORM_B;
    
        EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
        EPwm2Regs.HRPCTL.bit.HRPE = 1;
        EDIS;
    
    

    Best Regards,

    Maekawa

  • Hi Maekawa,

    The register settings look fine from what I can tell. I'm going to work on getting your code running on a local device to see if I can replicate it.

    Regards,

    Kris

  • Hi Kris-san,

    Thank you for reply.

    I can provide project files that work with TMDX28069USB or TMDSCNCD28069.

    Best regards,
    Maekawa

  • Hi Maekawa,

    That would be very helpful. Please upload the project, and that should accelerate the debug.

    Regards,

    Kris

  • Hi Kris-san,

    Share the project file.

    F28069_HRPWM_skip_cycle.zip

    Best regards,
    Maekawa

  • Hi Maekawa,

    This is happening because you are loading a phase value that is within 3 cycles of your CMPA up-count event. Therefore, your PWM is not getting cleared and is remaining high until the next cycle.

    This is due to the 3-cycle restriction which comes with the HRPWM. In up-down mode with HR enabled, the first 3 cycles following the start of your period cannot have a compare event as it will produce undefined behavior similar to what you are seeing. This can be confirmed by setting the TBPHSHR = 0 and seeing that your waveform now works as expected or loading any value that is less than TBPHS - 3 and seeing a correct waveform while having a non-zero value in TBPHSHR.

    A few other notes from your example that I noticed, just to be aware of, though I realize this may have just been for debug:

    - Make sure to calibrate the HRPWM. Usually you will just do this by running the SFO() at initialization. When I ran your code, the HRMSTEP was set to 0 which could cause lots of issues down the road (beyond inaccuracy). The SFO will automatically populate this upon completion based on your specific device.

    - You were continuously programming the the TBPHSHR register at nearly 3 MHz. This can also cause many problems with any of the CMP/PRD/PHS registers. It's best to write to this once per PWM cycle. I used an interrupt based on EPWM1 TBCTR = 0 for example.

    Regards,
    Kris
  • Hi Kris-san,

    Thank you for answer.

    Best regards,
    Maekawa
  • Hi Kris-san,

    Is there a workaround other than not setting the problematic value to EPwm2Regs.TBPHS.all?

    Best regards,
    Maekawa
  • Hi Maekawa,

    There is not a workaround for this- it is just how the peripheral was designed. The HRPWM is performing updates to the registers during those first few cycles so there is a chance of missing the event. If you need to load those values, from bench it seems to work if the HR portion of the CMP register is 0. However, I'm not convinced that is going to always be the case.

    Regards,

    Kris

  • Hi Kris-san,

    Thank you for reply.

    I understanded that there is no workaround.

    Best regards,
    Maekawa

  • Hi Kris-san,

    There are additional questions from customers.
    ※ There was a request to post from TIJ FAE to E2E.

    【Question 1】
    If EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP is set, it seems to be (direction in which PWM2 moves toward PWM1).

     PWM2A = Low / PWM2B = High

    → When actually checking, there was no skip cycle.

    From this, it seems that skip cycle will occur only when EPwm2Regs.TBCTL.bit.PHSDIR = TB_DOWN.


    【Question 2】
    When set to Up Mode or Down Mode, set TBPRD = 0x02C0E100 (set the same frequency as in UpdownMode).

    · When TBPHS = 0x00000000 (no deviation),
     PWM2A = Low / PWM2B = High

    · When TBPHS = 0x015FF000 (180 [deg] shift),
     PWM2A = High / PWM2B = Low remains

    Or, it seems that it may not occur in Up Mode because skip cycle occurs only in Down Mode.
     → This is unconfirmed.

    Is it a occur skip cycle only when Up-Down Mode and PHSDIR = TB_DOWN?
    Even in other operation modes it is a phenomenon occurring depending on the SYNC signal and the rise / fall timing of PWM2?


    In the sample project, it is for debugging that the TBPHS register is written at about 3 MHz cycle.
    Normally, it is written at the depending timing of PWM update.

    for (;;)
    {
        GpioDataRegs.GPBTOGGLE.bit.GPIO 34 = 1;
        EALLOW;
        EPwm2Regs.TBPHS.all = uiDebug_TBPHS_ePWM2;
        EDIS;
    }

    Best regards,
    Maekawa
  • I posted the additional question back to the following thread.
    e2e.ti.com/.../638299