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.
Hello,
I want to generate a high resolution active high complementary PWM with dead-band.
I have a problem setting the dead-band, when settting DBRED and DBFED to value 0 or 1, the high resolution seems to work fine.
But when setting DBRED and DBFED to different values, the PWM behave as a standard PWM (no high resolution).
Here's my initialization code :
void PWM_configureModule(PWM_moduleConfiguration_s * conf)
{
volatile struct EPWM_REGS * moduleRegs = &EPwm1Regs + conf->module;
PWM_calibrate();
EALLOW;
// Stop PWM synchronization during configuration
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0U;
moduleRegs->TBCTL.bit.PRDLD = 0U; // Period register is shadowed
moduleRegs->TBCTL.bit.CTRMODE = 3U; // Freeze counter for initialization
moduleRegs->TBCTR = 0U; // Reset timebase counter
moduleRegs->TBCTL.bit.SYNCOSEL = 0U; // Software sync
moduleRegs->TBCTL2.bit.SYNCOSELX = 0U;
moduleRegs->TBCTL.bit.CLKDIV = 0U; // Clock prescaler of 1
moduleRegs->TBCTL.bit.HSPCLKDIV = 0U; // High speed clock prescaler of 1
moduleRegs->TBCTL.bit.FREE_SOFT = 2U; // Free run emulation mode
moduleRegs->AQCTLA.bit.ZRO = 2U; // Set PWMA on TBCTR = 0
moduleRegs->AQCTLA.bit.CAU = 1U; // Clear PWMA on TBCTR = CMPA
moduleRegs->AQCTLB.bit.ZRO = 2U; // Set PWMB on TBCTR = 0
moduleRegs->AQCTLB.bit.CBU = 1U; // Clear PWMB on TBCTR = CMPB
timebasePeriod[conf->module] = (uint32_t)(128000.0F * (float32_t)SYSCTRL_getCpuFreqInMhz() / conf->frequency);
*((volatile uint32_t*)(&moduleRegs->TBPRDHR)) = (timebasePeriod[conf->module] - 256) << 8UL;
// Enable dead-band half cycle clocking
// to allow high resolution on dead-band
moduleRegs->DBCTL.bit.OUT_MODE = 3U; // Falling and rising edge dead band
moduleRegs->DBCTL.bit.DEDB_MODE = 0U;
moduleRegs->DBCTL.bit.HALFCYCLE = 1U;
moduleRegs->DBCTL.bit.POLSEL = 2U; // Invert B path
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 = 1U; // Dead band registers are shadowed
moduleRegs->DBCTL.bit.SHDWDBREDMODE = 1U;
moduleRegs->DBCTL2.bit.LOADDBCTLMODE = 1U;
*((volatile uint32_t*)(&moduleRegs->DBREDHR.all)) = (uint32_t)(conf->risingDeadband / 360.0F * (float32_t)timebasePeriod[conf->module]) << 9UL;
*((volatile uint32_t*)(&moduleRegs->DBFEDHR.all)) = (uint32_t)(conf->fallingDeadband / 360.0F * (float32_t)timebasePeriod[conf->module]) << 9UL;
moduleRegs->CMPCTL.bit.SHDWAMODE = 0U; // CMPA register is shadowed
moduleRegs->CMPCTL.bit.SHDWBMODE = 0U; // CMPB register is shadowed
moduleRegs->CMPCTL.bit.LOADAMODE = 1U; // Load CMPA of TBCTR = PRD
moduleRegs->CMPCTL.bit.LOADBMODE = 1U; // 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 = 0U; // Up count mode
moduleRegs->TBPHS.all = 0U; // No phase shift
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 = 0U;
moduleRegs->HRPCTL.bit.HRPE = 1U;
moduleRegs->HRPWR.bit.CALPWRON = 1U; // Enable MEP calibration logic
}
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1U;
moduleRegs->TBCTL.bit.SWFSYNC = 1U; // Force synchronization
EDIS;
}
Do you have any idea why it behaves like that ?
Thank you for the support.
Arthur
Hi Arthur,
Are you setting values for both CMPAHR and CMPBHR?
Best Regards,
Marlyn
Hi Marlyn,
Yes, I'am setting both compare registers A and B when setting the duty cycle :
void PWM_setDutyCycle(PWM_module_e mod, float32_t dc)
{
volatile struct EPWM_REGS * moduleRegs = &EPwm1Regs + mod;
uint32_t compare;
compare = (uint32_t)((float32_t)timebasePeriod[mod] * dc) << 8U;
moduleRegs->CMPA.all = compare;
moduleRegs->CMPB.all = compare;
}
Thank you,
Arthur
In HR mode, if CTRMODE = up count mode, the deadband module is not supported.
Please switch to CTRMODE = UP/DOWN.
Thank you Nima for your answer,
I didn't see this restriction on the TRM, could you please tell me on which page is it mentioned ?
With UP/DOWN count mode it seems to work almost fine, but I now see some glitches on the duty cycle when I make some small variations on the duty cycle.
It seems to happen when the high resolution part of the compare registers (CMPAHR and CMPBHR) is equal to zero.
1)
CMPA/B = 0x01F4
CMPA/BHR = 0xFF00
CMPA/B = 0x01F5
CMPA/BHR = 0x0000
CMPA/B = 0x01F5
CMPA/BHR = 0x0100
Thank you for the support.
Best Regards,
Arthur
Yes the value of ZERO is not a valid value. I have an example for HRPWM in the C2000WARE and I show case how:
if (CMPAHR == 0)
{
CMPAHR = 1; //offset to skip 0.
}
Thank you, it seems to solve the problem...
But again, as mentioned before I don't find any information about that in the TRM nor in the datasheet.
It's a recurrent issue with your documentations, the information is whether spread on multiple paragraphs or simply not there.
Best Regards,
Arthur
A variant of the note above is in the TRM but I have updated it for the next TRM revision to clearly specify it.
Nima