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.

F28069 HRPWM Duty Cycle Limits with HRPE = 0

Hi Everyone!

From spruh18e, it seems that one can bypass the low-end duty cycle range limitation by disabling HR period and setting up the timer in count-down mode.  Here is the relevant section, on page 382:

If the application demands HRPWM operation in the low percent duty cycle region, then the HRPWM can be configured to operate in count-down mode with the rising edge position (REP) controlled by the MEP when high-resolution period is disabled (HRPCTL[HRPE] = 0). This is illustrated in Figure 4-8. In this case, low percent duty limitation is no longer an issue. However, there will be a maximum duty limitation with same percent numbers as given in Table 4-5

There's also an illustration, showing this setup and the duty cycle limit only being at the top of the ramp, but I can't attach that here.

I can't seem to get this to work- has anyone else here done it?  I have other HRPWM channels operating, but I'm missing something about this one.  I'm trying to set it up in ePWM3, as 1 and 2 are otherwise being used.  My setup code is provided below:

EALLOW;

SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Before setting up HRPWM, we need to disable PWM sync

EPwm3Regs.TBCTL.bit.CLKDIV = 0; // ePWM3- Set PWM Frequency to 200kHz, count down mode, set at 0, clear at PRD
EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0;
EPwm3Regs.TBPRD = Command_Period;
EPwm3Regs.TBCTL.bit.CTRMODE = 1;
EPwm3Regs.AQCTLA.bit.ZRO = 1; // Set PWM channel 3A to go hi on falling compare, low on rising
EPwm3Regs.AQCTLA.bit.CAD = 2;

EPwm3Regs.HRCNFG.all = 0x0; // Clear all bits
EPwm3Regs.HRCNFG.bit.AUTOCONV = 1; // Automatically scale HRPWM period to the HRMSTEP that SFO() finds
EPwm3Regs.HRCNFG.bit.SELOUTB = 0; // 3B is not 3A inverted
EPwm3Regs.HRCNFG.bit.HRLOAD = 0; // Load the shadow register on CTR = 0
EPwm3Regs.HRCNFG.bit.CTLMODE = 0; // CMPAHR(8) or TBPRDHR(8) Register controls the edge position (i.e., this is duty or period control mode)
EPwm3Regs.HRCNFG.bit.EDGMODE = 1; // HRPWM precision edge control on rising edge only
EPwm3Regs.HRPCTL.bit.TBPHSHRLOADE = 0; // Disallow HR sync
EPwm3Regs.HRPCTL.bit.HRPE = 0; // Disallow HR Period Control

SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Re-enable PWM sync with system clock
SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK = 1; // Start the HRPWM Clock

EPwm3Regs.TBCTL.bit.PHSEN = 1; // ePWM3 disable synchronization
EPwm3Regs.TBCTL.bit.SYNCOSEL = 0; // ePWM3 passes through sync of ePWM1
EPwm3Regs.TBPHS.half.TBPHS = 0; // ePWM3 goes to counter of this upon sync
EPwm3Regs.TBCTL.bit.PHSDIR = 1; // Start counting up after sync

EDIS;

And this is in the interrupt:

EPwm3Regs.CMPA.all = (long) (V_Command* (float)Command_Period*65536);

Where the command period is my pwm cycle period and vcommand is a 0 to 1 float

The CMPA.all register is being loaded correctly- I'm getting the form 0xYYYYYY00 where the Y's are the command information.

The PWM even works when I go to 0x00010000, but if I drop below, 0x0000FF00 for example, I get nothing.

Can anyone spot what I've done wrong?

Justin

  • Justin,I think i understand what may be happening here.
    You've configured to work in down count mode - set on CMPA down and clear on Zero.
    You also configured rising edge delay in HRCNFG - EDGEMODE bits.
    So, you should have a rising edge and then delay it.
    When you use 0x00010000 then rising occurs at counter value of 1 and that can then be delayed - w.r.t. the value in CMPAHR.
    In the case when you are writing 0x0000FF00 there is no edge occurring - you are already at 100 % (or 0%) duty.
    So, you need to start with 0x00010000... and increase the rising edge delay all the way to 0x0001FF00.
    I hope this is clear.-Bharathi
  • Hi Bharathi!

    Thanks so much! That put me on the right track. It's almost right- adding 1 to the coarse register gives me an offset of one down near zero. Simply inverting the HRPWM compare half-register is what did the trick. So, the lowest value is 0x0000FF00, not 0x0001FF00. As it passes through 0x0001, 0x0000000 provides one HRPWM tick less than 0x0001FF00.

    Justin
  • Justin,

    Great to know it helped.
    I agree with your comment. Also, I would expect 0x0000FF00 or 0x00000000 would both result in continuous low output.
    Correct?

    -Bharathi.
  • Hi Bharathi!

    Not quite- 0x0000FF00 produces continuous low, but 0x00000000 is just shy of 0x00010000.

    Justin