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;
}