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.

ePWM 2 cycle delay on sync

Other Parts Discussed in Thread: TMS320F28027

Hello all,

I am using the TMS320F28027 Piccolo ePWM modules 1 through 4. I am only using the A outputs because I plan to use the high resolution PWM eventually. For now I am using 1A, 2A, 3A, and 4A all synced in the following way. ePWM1 sync select output (TBCTL.SYNCOSEL) is set to 1: CTR = zero. The other three are set to 0: EPWMxSYNC. When I first enable the TBCLKSYNC they are all in phase perfect, but when PWM1 CTR reaches zero PWM2, PWM3, and PWM4 are all delayed by 2 clock cycles (60 MHz SYSCLK with no division for any ePWM module). I have tested this on a board we put together with the 28027DA package as well as the 28027PA Launch Pad development. Same results on both.

Has anyone else been able to fix this without having to compensate with the TBPHS registers? Below is an oscilloscope screenshot and code setup detail.

Thanks,

Kelly

Channel 4 on the scope is PWM1. In up-down count mode and a 60MHz clock, 32.8ns (33.3ns) is two clock cycles (the delay shown by the measurement on the bottom right.)

PWM module configuration code:

*** MY pwm4_setup FUNCTION IS FOR ePWM1. pwm4 POINTS TO EPWM1 ***

...

    // enable ePWM clocks
    EALLOW;
    SysCtrlRegs.PCLKCR1.all |= 0xF;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    pwm1_setup();
    pwm2_setup();
    pwm3_setup();
    pwm4_setup();

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

...

void pwm1_setup(void)
{
    uint16_t temp;

    pwm1 = &EPwm3Regs;
    pwm1->TBCTL.all = 0x6006;   // up-down mode, PHSDIR = 1, sync = EPWMxSYNC

    temp = pwm1->CMPCTL.all;    // shadow CMPA, load on CTR = PRD
    temp &= ~0x005F;
    temp |=  0x0001;
    pwm1->CMPCTL.all = temp;

    pwm1->TBCTR     = 0;        // initial values
    pwm1->TBPRD     = PWM_PRD;
    pwm1->CMPA.all  = (PWM_PRD/2 + dead12) << 16;
    pwm1->TBPHS.all = phs1;

    temp = pwm1->AQCTLA.all;    // CmpA up set, CmpA down clear
    temp &= ~0x0FFF;
    temp |=  0x0060;
    pwm1->AQCTLA.all = temp;
}

void pwm2_setup(void)
{
    uint16_t temp;

    pwm2 = &EPwm4Regs;
    pwm2->TBCTL.all = 0x6006;   // up-down mode, PHSDIR = 1, sync = EPWMxSYNC

    temp = pwm2->CMPCTL.all;    // shadow CMPA, load on CTR = PRD
    temp &= ~0x005F;
    temp |=  0x0001;
    pwm2->CMPCTL.all = temp;

    pwm2->TBCTR     = 0;        // initial values
    pwm2->TBPRD     = PWM_PRD;
    pwm2->CMPA.all  = (PWM_PRD/2 - dead12) << 16;
    pwm2->TBPHS.all = phs2;

    temp = pwm2->AQCTLA.all;    // CmpA up clear, CmpA down set
    temp &= ~0x0FFF;
    temp |=  0x0090;
    pwm2->AQCTLA.all = temp;
}

void pwm3_setup(void)
{
    uint16_t temp;

    pwm3 = &EPwm2Regs;
    pwm3->TBCTL.all = 0x6006;   // up-down mode, PHSDIR = 1, sync = EPWMxSYNC

    temp = pwm3->CMPCTL.all;    // shadow CMPA, load on CTR = PRD
    temp &= ~0x005F;
    temp |=  0x0001;
    pwm3->CMPCTL.all = temp;

    pwm3->TBCTR     = 0;        // initial values
    pwm3->TBPRD     = PWM_PRD;
    pwm3->CMPA.all  = (PWM_PRD/2 + dead34) << 16;
    pwm3->TBPHS.all = phs3;

    temp = pwm3->AQCTLA.all;    // CmpA up set, CmpA down clear
    temp &= ~0x0FFF;
    temp |=  0x0060;
    pwm3->AQCTLA.all = temp;
}

void pwm4_setup(void)
{
    uint16_t temp;

    pwm4 = &EPwm1Regs;
    pwm4->TBCTL.all = 0x6016;   // up-down mode, PHSDIR = 1, sync = (CTR=zero)

    temp = pwm4->CMPCTL.all;    // shadow CMPA, load on CTR = PRD
    temp &= ~0x005F;
    temp |=  0x0001;
    pwm4->CMPCTL.all = temp;

    pwm4->TBCTR     = 0;        // initial values
    pwm4->TBPRD     = PWM_PRD;
    pwm4->CMPA.all  = (PWM_PRD/2 - dead34) << 16;
    pwm4->TBPHS.all = phs4;

    temp = pwm4->AQCTLA.all;    // CmpA up clear, CmpA down set
    temp &= ~0x0FFF;
    temp |=  0x0090;
    pwm4->AQCTLA.all = temp;
}

  • Hello Kelly,

    This is mentioned in the ePWM User's Guide for your device.  When TBCLK = SYSCLKOUT, you should expect 2 SYSCLKOUT cycles of delay between the master and slave PWM modules.  In the current F2802x ePWM User's Guide, see Section 2.2.3.3:



    I've found that the best way to compensate this delay is via the TBPHS register.


    Thank you,
    Brett

  • Thank you, Brett! Not sure how I missed that. I am somewhat relieved to find this documented.

    Kelly

  • Hi Brett,

    compensate with TBPHS seems will cause another problem that the period of the slave module will be 2 clock less. Further more, CTR=ZERO event will be missing for the slave module. Are there any further solution for this now? The processor I'm using is F28075
  • Hi,

    Actually, it won't.

    The 2 cycles are the deterministic latency it takes for a master ePWM's synch pulse to get output and trigger a synchronization in any slave ePWM. 

    2 ePWMs with TBPRD as 999

    EPWM1
    0999 -> 0000 -> 0001 -> 0002 -> 0003 -> 0004 .... 0999 -> 0000 -> 0001 -> 0002 -> 0003 ....
        (sync gen'd)                                      (sync gen'd)
                  (delay)                                           (delay)
                          

    EPWM2 (configured to synch and its TBPHS set to 2)
    0105 -> 0106 -> 0107 -> 0002 -> 0003 -> 0004 .... 0999 -> 0000 -> 0001 -> 0002 -> 0003 ....
                       (synch occurs)                                    (synch occurs)



    As you can see EPWM2 will count the full range. 


    Thank you,
    Brett

  • Hi Brett,

    I've tested and found that you are so correct! Thank you for help!

    There's just a  little bit error with F28075 user manual that the system clock is firstly divided by ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV, secondly by TBCTL.HSPCLKDIV, then by TBCTL.CLKDIV, so we get TBCLK, but the 1 clock delay when TBCLK!=EPWMCLK is of EPWMCLKDIV divided by TBCTL.HSPCLKDIV rather than TBCLK.

    Best regards

    Seven