Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

HRPWM MEP Scale Factor Half of Expected

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?

  • It sounds like the confusion is coming from you system running at 150 MHz and your EPWM running at 75 MHz.  The MEP scale factor is calibrated with respect to SYSCLK, not your EPWM clock.  So if you are receiving a value of 51 from the SFO(), this implies that each step is about 130 ps on the device you're using.  This is very reasonable- here is how I calculated it:

    (1/150 MHz) / 51 ~= 130 ps

    So when you are programming the CMPAHR register with 51 steps, you are seeing a shift of approximately one SYSCLK (130 ps * 51 ~= 6.7 ns) because the MEP steps are clocked off of SYSCLK.  However, when you step the CMPA register, this is running off of your PWM clock which is being clocked at 75 MHz, so effectively stepping two SYSCLKs.

    Let me know if this answers your question.

    Kris

  • Thanks, that makes me feel a lot better that everything is correct.  I see now that the documentation specifies with respect to SYSCLKOUT.  This just confused me because I tend to think of the coarse steps with respect to the peripheral clock, since that's what is ultimately clocking the PWM module.  Since the minimum clock divisor between the two clocks is 2, I now see that's where the factor comes from.