I'm using an F28335 at 150 MHz clock, and this is the first time I've seriously pursued getting a high-resolution pulse-width modulator working (HRPWM). My issue is the MEP scale factor returned from the calibration routine is giving me a value half of what is needed to span the coarse step (51 instead of 102 steps).
I've based my code on the Example_2833xHRPWM_SFO_V5 example. I used the routine HRPWM6_Config(48); to set the carrier frequency to about 1.55 MHz. The code for that routine is:
void HRPWM6_Config(Uint16 period)
{
// EPwm6 register configuration with HRPWM
// EPwm6A toggle high/low with MEP control on falling edge
EPwm6Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; // set Immediate load
EPwm6Regs.TBPRD = period-1; // PWM frequency = 1 / period
EPwm6Regs.CMPA.half.CMPA = period / 2; // set duty 50% initially
EPwm6Regs.CMPA.half.CMPAHR = (1 << 8); // initialize HRPWM extension
EPwm6Regs.CMPB = period / 2; // set duty 50% initially
EPwm6Regs.TBPHS.all = 0;
EPwm6Regs.TBCTR = 0;
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; // EPwm6 is the Master
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV2;
EPwm6Regs.TBCTL.bit.FREE_SOFT = 0x00; // Behavior during emulation,
// 00 = off, 11 = free run during pause
EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET; // PWM toggle low/high
EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm6Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm6Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EALLOW;
EPwm6Regs.HRCNFG.all = 0x0;
EPwm6Regs.HRCNFG.bit.EDGMODE = HR_FEP; //MEP control on falling edge
EPwm6Regs.HRCNFG.bit.CTLMODE = HR_CMP;
EPwm6Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
EDIS;
}
My scale factor is defined globally as:
// Global array used by the SFO library
// For n HRPWM channels + 1 for MEP_ScaleFactor[0]
int MEP_ScaleFactor[PWM_CH] = {0, 0, 0, 0, 0, 0, 0};
and finally my call to the calibration routine is:
int i;
EALLOW;
for(i=1;i<PWM_CH;i++)
{
(*ePWM[i]).HRCNFG.bit.EDGMODE = 1; // Enable HRPWM logic for channel prior to calibration
while ( SFO_MepDis_V5(i) == SFO_INCOMPLETE ); //returns "0" when cal. incomplete for channel
}
EDIS;
I then run a program that goes into an infinite loop with the duty cycle initially set at 50%.
To exclude the possibility of a math error in my duty cycle to step/MEP step conversion, I am pausing the program and changing the CMPA and CMPAHR registers manually. I set my oscilloscope to have the high-to-low transition at the middle of the screen. If I change the CMPAHR register to the value of the calibration routine (51 steps => 0x3300) then the transition shifts about 7ns forward in time (seems reasonable as 51*150 ps (typ) = 7.65 ns). However, if I zero the CMPAHR register again and increment the CMPA register by 1 (from 23 to 24) then the transition changes by about 14 ns, double the value obtained by putting CMPAHR at the calibration value. This value makes sense in that 1/75MHz is 13.3 ns, the coarse step resolution.
I can mark this point with the oscilloscope cursor and set CMPA back to 23 and set CMPAHR to double the calibration value, 102. Lo and behold, the transition matches exactly on the oscilloscope cursor, despite the value in CMPAHR seemingly double what the calibration routine tells me it should be!
My forum search on this topic only seemed to turn up one hit in the thread HRPWM MEP step size clarification. The "solution" was to change the line:
HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
to
HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;
Now, this seems to be a problem in 3 ways.
- First, if "HR_CTR_ZERO_PRD" is not defined in DSP2833x_EPwm_defines.h, there are only defintions for HR_CTR_ZERO (0x0) and HR_CTR_PRD (0x1).
- Second, if "HR_CTR_ZERO_PRD" is meant to be "Load on either CTR = Zero or CTR = PRD," then the TMS320x2833x, 2823x High Resolution Pulse Width Modulator (HRPWM) Reference Guide says it "should not be used with HRPWM."
- Third, just for kicks, I tried setting HRLOAD to 0x2, and nothing seemed to change. The calibration routine still reports 51 MEP steps.
So what's going on? Is the MEP Scale factor intended for use with the "Both edge" mode and do we need to double the value if we're in "rising edge" or "falling edge" mode?