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.

TMS320F28379D: Problem with phase shift

Part Number: TMS320F28379D

Hello,

I'd like to generate N PWM shifted of 360/N° to control an interleaved buck converter.

I use PWM1 as reference (master) and generate a SYNCOUT signal when CTR = 0 to feed the others PWM modules (slaves).

When zooming on the edges of slaves PWM i observe a jitter of 20ns which seems to correspond to the note page 1967 of the TRM (jitter of +/-2 clock period).

How can I synchronize the PWM in HR mode without having this jitter ?

Here's my initialization code :

void PWM_configureModule(PWM_moduleConfiguration_s* conf)
{
volatile struct EPWM_REGS * moduleRegs = &EPwm1Regs + conf->module;

PWM_calibrate();

EALLOW;

SyncSocRegs.SYNCSELECT.bit.EPWM4SYNCIN = 0U;
SyncSocRegs.SYNCSELECT.bit.EPWM7SYNCIN = 0U;
SyncSocRegs.SYNCSELECT.bit.EPWM10SYNCIN = 0U;

// Stop PWM synchronization during configuration
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0U;

moduleRegs->TBCTL.bit.PRDLD = 0U; // Period register is shadowed

*((volatile uint32_t*)(&moduleRegs->TBPRDHR)) = (uint32_t)(64000.0F * (float32_t)SYSCTRL_getCpuFreqInMhz() / conf->frequency) << 8U;

if(conf->module == PWM_MODULE_1)
{
moduleRegs->TBCTL.bit.PHSEN = 0U;
moduleRegs->TBCTL.bit.SYNCOSEL = 1U;
}
else
{
moduleRegs->TBCTL.bit.SYNCOSEL = 0U;

if(conf->enablePhaseSynchronisation)
{
if(conf->phase < 180.0F)
{
moduleRegs->TBPHS.all = (uint32_t)(conf->phase / 180.0F * (float32_t)(*((volatile uint32_t*)(&moduleRegs->TBPRDHR))));
moduleRegs->TBCTL.bit.PHSDIR = 0U;
}
else
{
moduleRegs->TBPHS.all = (uint32_t)((360.0F - conf->phase) / 180.0F * (float32_t)(*((volatile uint32_t*)(&moduleRegs->TBPRDHR))));
moduleRegs->TBCTL.bit.PHSDIR = 1U;
}

moduleRegs->TBCTL.bit.PHSEN = 1U;
}
else
{
moduleRegs->TBCTL.bit.PHSEN = 0U;
}
}

moduleRegs->TBCTR = 0U; // Reset timebase counter
moduleRegs->TBCTL.bit.CTRMODE = 2U; // Up-down count mode
moduleRegs->TBCTL.bit.CLKDIV = 0U;
moduleRegs->TBCTL.bit.HSPCLKDIV = 0U;
moduleRegs->TBCTL.bit.FREE_SOFT = 2U;

if(conf->linkDutyCycle)
{
moduleRegs->EPWMXLINK.bit.CMPALINK = conf->linkedModule;
moduleRegs->EPWMXLINK.bit.CMPBLINK = conf->linkedModule;
}
else
{

}

// Enable dead-band half cycle clocking
// to allow high resolution on dead-band
moduleRegs->DBCTL.bit.HALFCYCLE = 1U;
moduleRegs->DBCTL.bit.DEDB_MODE = 0U;
moduleRegs->DBCTL.bit.OUT_MODE = 3U; // Falling and rising edge dead band
moduleRegs->DBCTL.bit.IN_MODE = 2U; // PWMA is the source for rising edge delay, PWMB is the source for falling edge delay
moduleRegs->DBCTL.bit.SHDWDBFEDMODE = 0U; // Dead band registers are shadowed
moduleRegs->DBCTL.bit.SHDWDBREDMODE = 0U;
moduleRegs->DBCTL2.bit.LOADDBCTLMODE = 1U;

switch(conf->mode)
{
case PWM_SINGLE_A:
moduleRegs->DBCTL.bit.POLSEL = 0U; // Non Inverted A
moduleRegs->AQCTLA.bit.CAU = 2U;
moduleRegs->AQCTLA.bit.CAD = 1U;
break;
case PWM_SINGLE_B:
moduleRegs->DBCTL.bit.POLSEL = 0U; // Non Inverted B
moduleRegs->AQCTLB.bit.CBU = 2U;
moduleRegs->AQCTLB.bit.CBD = 1U;
break;
case PWM_COMPLEMENTARY_AB:
moduleRegs->DBCTL.bit.POLSEL = 2U; // Non inverted A, Invert B path
moduleRegs->AQCTLA.bit.CAU = 2U;
moduleRegs->AQCTLA.bit.CAD = 1U;
moduleRegs->AQCTLB.bit.CBU = 2U;
moduleRegs->AQCTLB.bit.CBD = 1U;
break;
case PWM_COMPLEMENTARY_BA:
moduleRegs->DBCTL.bit.POLSEL = 1U; // Inverted A path, Non inverted B
moduleRegs->AQCTLA.bit.CAU = 2U;
moduleRegs->AQCTLA.bit.CAD = 1U;
moduleRegs->AQCTLB.bit.CBU = 2U;
moduleRegs->AQCTLB.bit.CBD = 1U;
break;
}

*((volatile uint32_t*)(&moduleRegs->DBREDHR.all)) = (uint32_t)(conf->risingDeadband / 90.0F * (float32_t)(*((volatile uint32_t*)(&moduleRegs->TBPRDHR))));
*((volatile uint32_t*)(&moduleRegs->DBFEDHR.all)) = (uint32_t)(conf->fallingDeadband / 90.0F * (float32_t)(*((volatile uint32_t*)(&moduleRegs->TBPRDHR))));

moduleRegs->CMPCTL.bit.SHDWAMODE = 0U; // CMPA register is shadowed
moduleRegs->CMPCTL.bit.SHDWBMODE = 0U; // CMPB register is shadowed

moduleRegs->CMPCTL.bit.LOADAMODE = 2U; // Load CMPA of TBCTR = PRD
moduleRegs->CMPCTL.bit.LOADBMODE = 2U; // Load CMPB of TBCTR = PRD

/* Use trip action defined in TZCTL2, TZCTLDCA and TZCTLDCB */
moduleRegs->TZCTL2.all = 0x8FFF;
moduleRegs->TZCTLDCA.all = 0xFFF;
moduleRegs->TZCTLDCA.all = 0xFFF;
moduleRegs->TZCTLDCB.all = 0xFFF;
moduleRegs->TZCTLDCB.all = 0xFFF;

/* Digital compare submodule input is a combination of TRIP inputs */
moduleRegs->DCTRIPSEL.bit.DCAHCOMPSEL = 0xF;
moduleRegs->DCTRIPSEL.bit.DCALCOMPSEL = 0xF;
moduleRegs->DCTRIPSEL.bit.DCBHCOMPSEL = 0xF;
moduleRegs->DCTRIPSEL.bit.DCBLCOMPSEL = 0xF;

moduleRegs->TZDCSEL.bit.DCAEVT1 = 0x2U;
moduleRegs->TZDCSEL.bit.DCAEVT2 = 0x4U;
moduleRegs->TZDCSEL.bit.DCBEVT1 = 0x2U;
moduleRegs->TZDCSEL.bit.DCBEVT2 = 0x4U;

moduleRegs->TBCTL.bit.CTRMODE = 2U; // Up count mode

if(PWM_MODULE_HAS_HR_CAPABILITY(conf->module) && conf->enableHighResolution)
{
moduleRegs->HRCNFG.all = 0x0000U; // Clear register

moduleRegs->HRCNFG.bit.CTLMODE = 0U; // TBPRDHR Register controls the edge position
// (i.e., this is duty or period control mode).
moduleRegs->HRCNFG.bit.CTLMODEB = 0U; //TBPRDHR(8) Register controls the edge position
// (i.e., this is duty or period control mode).
moduleRegs->HRCNFG.bit.HRLOAD = 2U; // Load CMPAHR on either CTR = Zero or CTR = PRD
moduleRegs->HRCNFG.bit.HRLOADB = 2U; // Load CMPBHR on either CTR = Zero or CTR = PRD
moduleRegs->HRCNFG.bit.AUTOCONV = 1U; // Autoconversion ON
moduleRegs->HRCNFG.bit.EDGMODE = 3U; // MEP control of both edges
moduleRegs->HRCNFG.bit.EDGMODEB = 3U; // MEP control of both edges

moduleRegs->HRCNFG2.bit.EDGMODEDB = 3U; // MEP control of both edges (rising edge of DBREDHR or falling
// edge of DBFEDHR )
moduleRegs->HRCNFG2.bit.CTLMODEDBFED = 1U; // Load on either CTR = Zero or CTR = PRD
moduleRegs->HRCNFG2.bit.CTLMODEDBRED = 1U; // Load on either CTR = Zero or CTR = PRD
moduleRegs->HRPCTL.bit.PWMSYNCSEL = 0U;
moduleRegs->HRPCTL.bit.TBPHSHRLOADE = 1U;
moduleRegs->HRPCTL.bit.HRPE = 1U;
moduleRegs->HRPWR.bit.CALPWRON = 1U; // Enable MEP calibration logic
}

CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1U;

forceSynchronization(conf->module);
EDIS;
}

Thank you for your support,

Arthur

  • Hi Arthur,

    As you mentioned, we do have the following note in the TRM:  "NOTE: When high-resolution period mode is enabled, an EPWMxSYNC pulse will introduce +/- 1 - 2
    cycle jitter to the PWM (+/- 1 cycle in up-count mode and +/- 2 cycle in up-down count mode). For this reason, TBCTL[SYNCOSEL] should not be set to 1 (CTR = 0 is EPWMxSYNCO source) or 2 (CTR = CMPB is EPWMxSYNCO source). Otherwise, the jitter will occur on every PWM cycle with the synchronization pulse.

    When TBCTL[SYNCOSEL] = 0 (EPWMxSYNCI is EPWMxSYNCO source), a software synchronization pulse should be issued only once during high-resolution period initialization. If a software sync pulse is applied while the PWM is running, the jitter will appear on the PWM output at the time of the sync pulse."

    SYNCOSEL should not be set to 1 or 2 or else the jitter will occur during every PWM cycle. The only way to remove the jitter is to set SYNCOSEL to 0 and issue a software synchronization pulse during initialization.

    Best Regards,

    Marlyn

  • Hi Marlyn,

    I already tried that but I lost the synchronization between the modules with SYNCOSEL = 0 as there is no common signal to synchronize PWM counters in this configuration. 

    I've spent a LOT of time trying to make the PWM module with high resolution, dead band and phase synchronization work, but every time I solve a problem an other one comes out.

    Can you give me a working code of what I want to do ?

    Thank you,

    Arthur

  • Hi Arthur,

    You can implement a software synchronization pulse every few cycles (4-5), but we recommend that you do not do this at every CTR=0 instance. I would setup an interrupt for when the time-base counter of EPWM1 equals zero, with an interrupt event count of 4-5 events. Within the ISR for this interrupt you can set a software synchronization pulse.

    Best Regards,

    Marlyn

  • Hi Marlyn,

    This solution is not satisfactory for my application. I need a very precise duty cycle on every PWMs.

    However the frequency and phase shift resolution are not so important in my application.

    I tried setting TBPHSHRLOADE and HRPE bits to 0 to disable high resolution on period and/or on phase but I lost the high resolution on the duty cycle also when I do that...

    The HRPWM is very hard to configurate, there are a lot of parameters as if it was very versatile but in the end there are few settings actually allowed.

    Could you please post an initialization code with my requirements ?

    Thank you for your support,

    Arthur

  • Arthur,

    Since it appears all your ePWM are within the same microcontroller, they share the same clock so you would only need to perform synchronization during your initialization. Afterwards you can disable the propagation of sync pulses between modules.

    Hope that helps,

    Pierre

  • Hi Arthur,

    If you have any suggestions for the documentation that you think would help clarify some of the configurations and settings then please let me know and we can work on implementing those changes. 

    The behavior that you are experiencing is defined within our TRM. I wouldn't change your initialization code other than the settings I've already discussed and suggested.

    Best Regards,

    Marlyn

  • Exactly as Pierre mentioned, if you try the solution you will not have an issue. There is no external sync needed, sync once and youre good to go. If you need to change the phase, intialize the values, sync once, then you are good to go.

    Nima

  • Thank you Pierre,

    Your solution seems to fix the problem ! Slight smile

    Best regards,

    Arthur