Part Number: TMS320F28035
Hi,
While prototyping a new device with external sync, we observed that, if the CMPA value is never reached due to TBPHS reload at sync, the PWM is maintained at HIGH level. We are using the 6 PWMA peripherals, each one being phase shifted by PI/3 from the precedent:
- 0°
- 60°
- 120°
- 180°
- 240°
- 300°
Here is a picture explaining the problem (the last one is our concerning case):

Here is our PWM configuration code:
void pwm_RegisterConfiguration(int16 n, Uint16 period, int16 mode, uint16_t phase)
{
// Time Base SubModule Registers
(*ePWM[n]).TBCTR = 0;
(*ePWM[n]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
(*ePWM[n]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[n]).TBCTL.bit.CLKDIV = TB_DIV1;
(*ePWM[n]).DBCTL.bit.OUT_MODE = DB_DISABLE; // disable dead-band module
// Master config
if (mode == PWM_MASTER)
{
pwm_MasterSlaveConfig[n-1] = PWM_MASTER;
(*ePWM[n]).TBCTL.bit.PHSEN = TB_DISABLE;
(*ePWM[n]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // sync "down-stream"
(*ePWM[n]).TBCTL.bit.PRDLD = TB_SHADOW; // set shadow load
(*ePWM[n]).TBPHS.half.TBPHS = 0;
}
// Slave config
else if (mode == PWM_SLAVE)
{
pwm_MasterSlaveConfig[n-1] = PWM_SLAVE;
(*ePWM[n]).TBCTL.bit.PHSEN = TB_ENABLE;
if (n == PWM1)
{
(*ePWM[n]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync "down-stream"
(*ePWM[n]).TBCTL.bit.PRDLD = TB_SHADOW; // set shadow load
(*ePWM[n]).TBPHS.half.TBPHS = 0; // this value should stay at 0 in any case for PWM1
}
else
{
(*ePWM[n]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through
(*ePWM[n]).TBCTL.bit.PRDLD = TB_SHADOW; // set Immediate load
(*ePWM[n]).TBPHS.half.TBPHS = (period - phase);
}
}
// Mandatory to fill TBPRD after setting an IMMEDIATE register
// note : it's not mandatory for SHADOW register
(*ePWM[n]).TBPRD = period - 1; // PWM frequency = 1 / period
// Counter Compare Submodule Registers
(*ePWM[n]).CMPA.half.CMPA = 0; // set duty 0% initially
(*ePWM[n]).CMPB = 0; // set duty 0% initially
(*ePWM[n]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[n]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
(*ePWM[n]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
(*ePWM[n]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// When CPU forces a PWM it is forced without sync
(*ePWM[n]).AQSFRC.bit.RLDCSF = PWM_AQSFRC_LOAD_IMMEDIATELY;
// Action Qualifier SubModule Registers: DISABLE ALL
(*ePWM[n]).AQCTLA.bit.ZRO = AQ_NO_ACTION;
(*ePWM[n]).AQCTLA.bit.CAU = AQ_NO_ACTION;
(*ePWM[n]).AQCTLA.bit.CBU = AQ_NO_ACTION;
(*ePWM[n]).AQCTLA.bit.PRD = AQ_NO_ACTION;
(*ePWM[n]).AQCTLB.bit.ZRO = AQ_NO_ACTION;
(*ePWM[n]).AQCTLB.bit.CAU = AQ_NO_ACTION;
(*ePWM[n]).AQCTLB.bit.CBU = AQ_NO_ACTION;
(*ePWM[n]).AQCTLB.bit.PRD = AQ_NO_ACTION;
}
When starting the function, we set the AQCTLx register as follow:
void PWM_EnablePwmADisablePwmB()
{
PWM_list_e i;
for (i = PWM1; i < PWM_NUM_PWM_IN_USE+1; ++i)
{
// Action Qualifier SubModule Registers
ePWM[i]->AQCTLA.bit.ZRO = AQ_CLEAR;
ePWM[i]->AQCTLA.bit.CAU = AQ_SET;
ePWM[i]->AQCTLA.bit.CBU = AQ_NO_ACTION;
ePWM[i]->AQCTLA.bit.PRD = AQ_NO_ACTION;
ePWM[i]->AQCTLB.bit.ZRO = AQ_CLEAR;
ePWM[i]->AQCTLB.bit.CAU = AQ_CLEAR;
ePWM[i]->AQCTLB.bit.CBU = AQ_CLEAR;
ePWM[i]->AQCTLB.bit.PRD = AQ_CLEAR;
ePWM[i]->AQCSFRC.bit.CSFB = PWM_FORCE_CONTINUOUS_LOW;
}
}
Is there a special configuration needed to ensure the good behavior of the PWMs in this very particular case?
Best regards,
Alexis L.
Embedded Software Engineer

