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.

F28M36; PWM-PhaseShift

Other Parts Discussed in Thread: F28M36P63C2

Dear TI team,

we use the PWM1 and PWM2 Phase-Shift (PS) to control an H-Bridge.


Following issue is happen.

To start the PWM signals (with PS - ZERO)
the PWM startup procedure [see code c28PwmPsStart()] is called.
The PWM works then as expected (see TEK00000.PNG).

With the 1st PS correction [see Code c28PwmCtrlPhaseVoltHR()],
the PWM2 PS Signal is discontinue for one period, see TEK00001.PNG .

All further PS correction works then correct and do not show this issue.



My question would be, what should I change to prevent this issue.
Also I could not see any Errata regarding the PWM-PS.


Following setup is in use:

- Code Composer Studio
  Version: 6.0.1.00040
- F28M36P63C2


Thanks & Regards

WJ


 TEK00000.PNG

 TEK00000.PNG

SW-Code:

/****************************************************************************
*
****************************************************************************/
static void c28PwmPsInit( void )
{
    /*  enable EPWM 1/2 GPIO's */
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0  = 1u;   /* cfg GPIO0 as EPWM1A - Chn-A */
    GpioCtrlRegs.GPAMUX1.bit.GPIO1  = 1u;   /* cfg GPIO1 as EPWM1B - Chn-B */
    GpioCtrlRegs.GPAMUX1.bit.GPIO2  = 1u;   /* cfg GPIO2 as EPWM2A - Chn-C */
    GpioCtrlRegs.GPAMUX1.bit.GPIO3  = 1u;   /* cfg GPIO3 as EPWM2B - Chn-D */
    GpioG1CtrlRegs.GPADIR.bit.GPIO0 = 1u;   /* Set as output */
    GpioG1CtrlRegs.GPADIR.bit.GPIO1 = 1u;   /* Set as output */
    GpioG1CtrlRegs.GPADIR.bit.GPIO2 = 1u;   /* Set as output */
    GpioG1CtrlRegs.GPADIR.bit.GPIO3 = 1u;   /* Set as output */
    /* enable trip zone GPIO's */
    GpioG1CtrlRegs.GPADIR.bit.GPIO20 = 0u;              /* Set as input */
    GpioG1CtrlRegs.GPBDIR.bit.GPIO44 = 0u;              /* Set as input */
    GpioG1TripRegs.GPTRIP1SEL.bit.GPTRIP1SEL = 20u;     /* PD4 GPIO20 as TZ1n */
    GpioG1TripRegs.GPTRIP2SEL.bit.GPTRIP2SEL = 44u;     /* PG4 GPIO44 as TZ2n */
    PieVectTable.EPWM1_TZINT = &c28PwmTZ1Isr;           /* TZ1 ISR */
    PieVectTable.EPWM2_TZINT = &c28PwmTZ2Isr;           /* TZ2 ISR */

    /*  EPWM 1 setup */
    EPwm1Regs.TBCTR                = 0x0000u;           /* clr counter              */
    EPwm1Regs.TBPRD                = EPWM1_TIMER_TBPRD; /* set timer period         */
    EPwm1Regs.TBPRDHR              = 0u;         /*      */
    EPwm1Regs.AQCTLA.bit.ZRO       = AQ_SET;            /* set actions qualifier    */
    EPwm1Regs.AQCTLA.bit.CAU       = AQ_CLEAR;           
    EPwm1Regs.AQCTLB.bit.ZRO       = AQ_CLEAR;          /* set actions qualifier    */
    EPwm1Regs.AQCTLB.bit.CAU       = AQ_SET;           
    EPwm1Regs.CMPA.half.CMPA       = EPWM1_MIN_CMPA;    /* initial compare A value  */
    EPwm1Regs.CMPA.half.CMPAHR     = 0u;

    EPwm1Regs.TBPHS.all            = 0uL;               /* phase is 0               */
    EPwm1Regs.TBCTL.bit.CTRMODE    = TB_FREEZE;         /* freeze                   */
    EPwm1Regs.TBCTL.bit.PHSEN      = TB_DISABLE;        /* disable phase loading    */
    EPwm1Regs.TBCTL.bit.PRDLD      = TB_SHADOW;
    EPwm1Regs.TBCTL.bit.SYNCOSEL   = TB_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;
    EPwm1Regs.TZSEL.bit.OSHT2      = 1u;                /* I_LOCK_I triggered */
    EPwm1Regs.TZSEL.bit.OSHT1      = 1u;                /* C_LIM triggered    */
    /* TZ1 and TZ2 action */
    EPwm1Regs.TZCTL.bit.TZA        = TZ_FORCE_LO;       /* EPwm1A Low */
    EPwm1Regs.TZCTL.bit.TZB        = TZ_FORCE_LO;       /* EPwm1B Low */
    /* clr PWM TZ flags */
    EPwm1Regs.TZCLR.all            = EPwm1Regs.TZFLG.all;
    /* DeadBand control */
    EPwm1Regs.DBCTL.bit.OUT_MODE   = DB_FULL_ENABLE;
    EPwm1Regs.DBCTL.bit.POLSEL     = DB_ACTV_HIC;
    EPwm1Regs.DBFED                = EPWM1_FED;
    EPwm1Regs.DBRED                = EPWM1_RED;

    /* more HR setting  */
    EPwm1Regs.HRMSTEP              = 44u;
    EPwm1Regs.HRCNFG.all = 0x0;
    EPwm1Regs.HRCNFG.bit.EDGMODE   = HR_BEP;              /* MEP both edge */
    EPwm1Regs.HRCNFG.bit.CTLMODE   = HR_CMP;
    EPwm1Regs.HRCNFG.bit.HRLOAD    = HR_CTR_ZERO_PRD;
    EPwm1Regs.HRCNFG.bit.EDGMODEB  = HR_BEP;              /* MEP both edge */
    EPwm1Regs.HRCNFG.bit.CTLMODEB  = HR_CMP;
    EPwm1Regs.HRCNFG.bit.HRLOADB   = HR_CTR_ZERO_PRD;
    EPwm1Regs.HRPCTL.bit.HRPE      = 0u;                 /* HR period control */


    /*  EPWM 2 setup */
    EPwm2Regs.TBCTR                = 0x0000u;           /* clr counter              */
    EPwm2Regs.TBPRD                = EPWM2_TIMER_TBPRD; /* set timer period         */
    EPwm2Regs.TBPRDHR              = 0u;
    EPwm2Regs.AQCTLA.bit.ZRO       = AQ_SET;            /* set actions qualifier    */
    EPwm2Regs.AQCTLA.bit.CAU       = AQ_CLEAR;
    EPwm2Regs.AQCTLB.bit.ZRO       = AQ_CLEAR;          /* set actions qualifier    */
    EPwm2Regs.AQCTLB.bit.CAU       = AQ_SET;
    EPwm2Regs.CMPA.half.CMPA       = EPWM2_MIN_CMPA;    /* initial compare A value  */
    EPwm2Regs.CMPA.half.CMPAHR     = 0u;
    EPwm2Regs.TBPHS.half.TBPHS     = 0u;
    EPwm2Regs.TBPHS.half.TBPHSHR   = 0u;
    EPwm2Regs.TBCTL.bit.CTRMODE    = TB_FREEZE;         /* freeze                   */
    EPwm2Regs.TBCTL.bit.PHSEN      = TB_ENABLE;         /* enable phase loading     */
    EPwm2Regs.TBCTL.bit.PRDLD      = TB_SHADOW;
    EPwm2Regs.TBCTL.bit.SYNCOSEL   = TB_SYNC_IN;
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;
    EPwm2Regs.TZSEL.bit.OSHT2      = 1u;                /* I_LOCK_I triggered */
    EPwm2Regs.TZSEL.bit.OSHT1      = 1u;                /* C_LIM triggered    */
    /* TZ1 and TZ2 action */
    EPwm2Regs.TZCTL.bit.TZA        = TZ_FORCE_LO;       /* EPwm2A Low */
    EPwm2Regs.TZCTL.bit.TZB        = TZ_FORCE_LO;       /* EPwm2B Low */
    /* clr PWM TZ flags */
    EPwm2Regs.TZCLR.all            = EPwm2Regs.TZFLG.all;
    /* DeadBand control */
    EPwm2Regs.DBCTL.bit.OUT_MODE   = DB_FULL_ENABLE;
    EPwm2Regs.DBCTL.bit.POLSEL     = DB_ACTV_HIC;
    EPwm2Regs.DBFED                = EPWM2_FED;
    EPwm2Regs.DBRED                = EPWM2_RED;

    /* more HR setting  */
    EPwm2Regs.HRMSTEP              = 44u;
    EPwm2Regs.HRCNFG.all = 0x0;
    EPwm2Regs.HRCNFG.bit.EDGMODE   = HR_BEP;           /* MEP both edge */
    EPwm2Regs.HRCNFG.bit.CTLMODE   = HR_PHS;
    EPwm2Regs.HRCNFG.bit.EDGMODEB  = HR_BEP;           /* MEP both edge */
    EPwm2Regs.HRCNFG.bit.CTLMODEB  = HR_PHS;
    EPwm2Regs.HRPCTL.bit.HRPE      = 1u;               /* HR period control */
    EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1u;            /* HR period control */


    /* enable TZ IRQ */
    EPwm1Regs.TZEINT.bit.OST       = 1u;
    EPwm2Regs.TZEINT.bit.OST       = 1u;
    PieCtrlRegs.PIEIER2.bit.INTx1  = 1u;                 /* EPWM1-TZINT  */
    PieCtrlRegs.PIEIER2.bit.INTx2  = 1u;                 /* EPWM2-TZINT  */
    EDIS;

    IER |= M_INT2;                                      /* enable IRQ */
    c28SciaPrintf("C28 PWM PB-PS Ready\n");
} /* end c28PwmPsInit() */

/****************************************************************************
*
****************************************************************************/
void c28PwmCtrlPhaseVoltHR( float volt )
{
    Uint16 tmp1;
    Uint16 tmp2;
    float  frac;
    
    if ( 0.0f > volt )
    {
        volt *= -1.0f;
    }
    tmp2 = (Uint16)volt;
    tmp1 = (Uint16)(volt/c28BitVolt);
    frac = volt-(float)tmp2;
    frac *= 44.4444f;
    tmp2 = (Uint16)frac;
    tmp2 <<= 8u;
    /* feed TBPHS register */
    EPwm2Regs.TBPHS.half.TBPHS = tmp1;
    EPwm2Regs.TBPHS.half.TBPHSHR = tmp2;
} /* end c28PwmCtrlPhaseVoltHR() */


/****************************************************************************
*
****************************************************************************/
void c28PwmPsStart( void )
{
    EALLOW;
    EPwm1Regs.TZCLR.all         = EPwm1Regs.TZFLG.all;
    EPwm2Regs.TZCLR.all         = EPwm2Regs.TZFLG.all;
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    EIDS;
} /* end c28PwmPsStart() */

  • Hi WJ,

    Let's consider the case when the phase value for PWM2 is changed from 0 to a non-zero value for the first time. In the very first cycle after this change PWM2 counter will not reach CTR = PRD/0 (shadow to active register loading event) but instead counts from the new phase value. This means that any shadow register loads set to happen at CTR = 0/PRD, will not happen at the right time. What's worse is that any CTR = 0/PRD action qualifier (AQ)  events will not happen, which is probably why you get this behavior for one full cycle.

    A simple trick I use to overcome this problem is to set 'PWM2 period = PWM1 period - 1'. This will make sure that CTR = 0/PRD event is not skipped. This doesn't really affect the operation frequency either because of the syncing and as long as duty values do not approach 100% (which should not be the case for this topology). Additionally, you can restrict phase value to be always greater than 0 if your system allows it.

    I hope this helps.

    Hrishi

  • Hi Hrishi,

    your instruction solve the issue by now.

    Many thanks for your excellent support.

    Best Regards

    WJ