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 90 degrees pwm phase shift

Hello,

I have a question regarding the following pwm settings in the C28x (F28M36):

pwm 4,5,6,7 work on 48 KHz (TBPRD: 3124)

the phase of pwm 5 and 7 is changed. 

There are 2 DCDC converters (DCDC1 use pwm 4,5. DCDC2 use pwm 6,7). because of power consumption we want to have a fixed phase shift between pwm 4,5 and pwm6,7 of 90 degrees.

To generate this I have configure pwm 4 as master and set the start counter value to 3124 / 4 (TBCTR). pwm 5 is set as slave with  a start counter value of 0. pwm 6 is set as master with start counter value 0. pwm 7 is set as slave with start counter value of 0. (Epwm 1 is also configured to 48 kHz)

Now I expected that pwm4 and pwm5 to be exact 90 degrees phase shifted again pwm 6 and 7. measurements show this was not the case. after tweaking I configured the TBCTR to 3124 / 4.58, this gives a 90 degrees phase shift.

Where does this difference come from? I have disabled TBCLKSYNC during configuration of the pwms

  • Hi Arno,

    What about enabling TBCLK? I hope you follow:

    EALLOW; 
           SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // DISABLE TBCLK TILL EPWM CONFIGURATION IS COMPLETED 
    EDIS; 
    
    // DO ALL EPWM CONFIG
    //
    //
    
    EALLOW;  
             SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;      // ENABLE TBCLK 
    EDIS; 

    Regards,

    Gautam

  • Yes I enable it again after epwm configuration
  • Then you should not have the offset. Can you paste the epwm configuration?
  • EALLOW;
    /* Stop all the TB clocks */
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    EALLOW;

    /* EPWM Module 4 config */
    EPwm4Regs.TBPRD = TBPRD_SABS; /* Period = TBPRD_SABS +1 TBCLK counts */
    EPwm4Regs.TBCTR = (TBPRD_SABS/4.58); /* set counter register to 1/4 of TBPRD_SABS (90 fase shift)
    the .58 is added after tweaking, original was not exat 90 fase */
    EPwm4Regs.CMPA.half.CMPA = START_DC_SABS; /* Set 50% fixed duty for EPWM4A */
    EPwm4Regs.TBPHS.half.TBPHS = 0; /* Set Phase register to zero */
    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; /* count up mode */
    EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE; /* Master module, do not load TBCTR */
    EPwm4Regs.TBCTL.bit.PRDLD = TB_SHADOW; /* Shadow mode when counter = 0 */
    EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; /* Sync down-stream module */
    EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; /* Clock ratio to SYSCLKO, divide by 1 */
    EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1; /* divide by 1 */
    EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; /* use shadow mode */
    EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; /* use shadow mode */
    EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm4Regs.AQCTLA.bit.ZRO = AQ_SET; /* output high, when counter = 0 */
    EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR; /* output low, when CMPA = counter */
    EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; /* enable full Dead-band module */
    EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; /* Active Hi complementary */
    EPwm4Regs.DBFED = DBFED_SABS; /* FED = DBFED_SABS TBCLKs initially */
    EPwm4Regs.DBRED = DBRED_SABS; /* RED = DBRED_SABS TBCLKs initially */
    /* EPWM Module 5 config */
    EPwm5Regs.TBPRD = TBPRD_SABS; /* Period = TBPRD_SABS + 1 TBCLK counts */
    EPwm5Regs.TBCTR = 0; /* set counter register to 0 */
    EPwm5Regs.CMPA.half.CMPA = START_DC_SABS; /* Set 50% fixed duty EPWM5A */
    EPwm5Regs.TBPHS.half.TBPHS = TBPRD_SABS; /* Set Phase register */
    EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; /* count up mode */
    EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE; /* Slave module, load TBPHS/shadow on EPWMxSYNCI */
    EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW; /* Shadow mode when counter = 0 */
    EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; /* EPWMxSYNC flow-through */
    EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; /* Clock ratio to SYSCLKO, divide by 1 */
    EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1; /* divide by 1 */
    EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; /* use shadow mode */
    EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; /* use shadow mode */
    EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm5Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm5Regs.AQCTLA.bit.ZRO = AQ_SET; /* output high, when counter = 0 */
    EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR; /* output low, when CMPA = counter */
    EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; /* enable full Dead-band module */
    EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; /* Active Hi complementary */
    EPwm5Regs.DBFED = DBFED_SABS; /* FED = DBFED_SABS TBCLKs initially */
    EPwm5Regs.DBRED = DBRED_SABS; /* RED = DBRED_SABS TBCLKs initially */
    /* EPWM Module 6 config */
    EPwm6Regs.TBPRD = TBPRD_SABS; /* Period = TBPRD_SABS + 1 TBCLK counts */
    EPwm6Regs.TBCTR = 0; /* set counter register to 0 */
    EPwm6Regs.CMPA.half.CMPA = START_DC_SABS; /* Set 50% fixed duty for EPWM6A */
    EPwm6Regs.TBPHS.half.TBPHS = 0; /* Set Phase register to 90° zero */
    EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; /* count up mode */
    EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; /* Master module, do not load TBCTR */
    EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW; /* Shadow mode when counter = 0 */
    EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; /* Sync down-stream module */
    EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; /* Clock ratio to SYSCLKO, divide by 1 */
    EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1; /* divide by 1 */
    EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; /* use shadow mode */
    EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; /* use shadow mode */
    EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET; /* output high, when counter = 0 */
    EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR; /* output low, when CMPA = counter */
    EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; /* enable full Dead-band module */
    EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; /* Active Hi complementary */
    EPwm6Regs.DBFED = DBFED_SABS; /* FED = DBFED_SABS TBCLKs initially */
    EPwm6Regs.DBRED = DBRED_SABS; /* RED = DBRED_SABS TBCLKs initially */
    /* EPWM Module 7 config */
    EPwm7Regs.TBPRD = TBPRD_SABS; /* Period = TBPRD_SABS + 1 TBCLK counts */
    EPwm7Regs.TBCTR = 0; /* set counter register to 0 */
    EPwm7Regs.CMPA.half.CMPA = START_DC_SABS; /* Set 50% fixed duty EPWM7A */
    EPwm7Regs.TBPHS.half.TBPHS = TBPRD_SABS; /* Set Phase register */
    EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; /* count up mode */
    EPwm7Regs.TBCTL.bit.PHSEN = TB_ENABLE; /* Slave module, load TBPHS/shadow on EPWMxSYNCI */
    EPwm7Regs.TBCTL.bit.PRDLD = TB_SHADOW; /* Shadow mode when counter = 0 */
    EPwm7Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; /* EPWMxSYNC flow-through */
    EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; /* Clock ratio to SYSCLKO, divide by 1 */
    EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1; /* divide by 1 */
    EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; /* use shadow mode */
    EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; /* use shadow mode */
    EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; /* load shadow register on CTR=Zero */
    EPwm7Regs.AQCTLA.bit.ZRO = AQ_SET; /* output high, when counter = 0 */
    EPwm7Regs.AQCTLA.bit.CAU = AQ_CLEAR; /* output low, when CMPA = counter */
    EPwm7Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; /* enable full Dead-band module */
    EPwm7Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; /* Active Hi complementary */
    EPwm7Regs.DBFED = DBFED_SABS; /* FED = DBFED_SABS TBCLKs initially */
    EPwm7Regs.DBRED = DBRED_SABS; /* RED = DBRED_SABS TBCLKs initially */

    EDIS;

    EALLOW;
    /* Start all the timers synced */
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;
  • Hi Arno,

    If you are still having issues with this, could you provide a bit more information on what isn't working?  For example, is PWM4&5 working as you expect, but PWM6&7 are not?

    ===

    It sounds to me like you want all these PWMs to be synchronized together.  Therefore PWM4 should be the synchronization master whereas the other PWMs should be synchronization slaves. 

    Furthermore, when PWM4 creates a synch pulse it seems like you want:
    PWM5 to be synchronized but with some variable offset.  (if I'm understanding things correct then this is something you'll be editing in your control loop)
    PWM6 to be synchronized but with 90degrees offset from PWM4 (this would mean that TBPHS for PWM6 should be constantly TBPRD/4.
    PWM7 to be synchronized but 90degrees offset from PWM5.  (again, if I'm correct you'll be changing this value in the control loop/ISR.  The value you write to the TBPHS register in the ISR will be TBPHS of PWM5 +/- TBPRD/4)

    Hopefully in my description I've mentioned some things that will help you in your project (whether I've completely understood your situation or not). 


    Thank you,
    Brett

  • Hello Brett,

    Thank you for the reply. I want to have pwm4 and 5 in sync and pwm 6 and 7 in sync. pwm 4 and 6 must have a constant phase shift of 90 degrees.

    The problem is solved by using the phase shift.

    I have configured the following now.

    now pwm 4 is set to slave and with a phase shift of 90 degrees

    pwm6 is set as master. (pwm 1 has the same frequency).

    The output is what I want it to be.

    This does not explain why when using the counter value itself is not working: TBCTR of pwm4 to 1/4 period and TBCTR of pwm 5,6, and 7 to 0. it seems that when TBCTR are all 0 it is OK, but when TBCTR of pwm4 is set to value 1 there is a big difference, when raising the value from 1 to higher it seems to adjust fine (still with the offset gotten from 0 to 1).

    This is not a problem for me now because I use the phase shift register now.

  • Hi Arno,

    OK, I now see what you were trying to do.  You were looking to initialize the ePWM with a one-time phase offset.  This should have been doable and the offset should stay over time.  However, there must be something very small in your code which was creating the issue you saw.  The biggest mistake made when doing that type of thing is what Gautam mentioned - not using the TBCLKSYNC - which doesn't appear to be your issue. 

    That being said, using the TBPHS method is better because you are more often synchronizing the ePWMs.  Among other benefits, this method allows you to more easily change the phase offset inside the control loop if you so desire.

    I'm glad to hear that you got things working!


    Thank you,
    Brett