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.

Wrong PWM pulse lengths with up/down HRPWM on 28075?

Other Parts Discussed in Thread: CONTROLSUITE

Hi,

we intend to use high resolution pwm with symmetric pwm (up/down counting mode) on the 28075 Piccolo.

I derived a first program from the examples in the controlSUITE (C:\ti\controlSUITE\device_support\F2807x\v190\F2807x_examples_Cpu1\epwm_updown_aq and C:\ti\controlSUITE\device_support\F2807x\v190\F2807x_examples_Cpu1\hrpwm_prdupdown_sfo_v8).

I have the following measurements:

- PWM period = 3 MHz (TBPRD = 10), PWM1A without HRPWM, PWM2A with HRPWM
  EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // clear PWM1A on event A, up count
  EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;   // set PWM1A on event A, down count
  (So high pulse length should be proportional to the compare register value.)


  f_epwm = 60 MHz (1 inc in cmp = 16.6 ns)
  hpwx = high pulse width in ns, compare register value CMPA.CMPAHR = (long)ldexp(cmp, 16);

Results (plus some matlab code to plot)
  cmp = [0 1 3 3.5 4 4.25 4.5 4.75 5 5.5 6 9 10];
  hpw1 = [0 34 100 100 133 133 133 133 167 167 200 300 333];
  hpw2 = [17 50 117 100 151 126 133 142 184 167 217 300 333];
  plot(cmp, hpw1, 'o-', cmp, hpw2, 'd-', [0 10], [0 333.333]); grid;
  legend('w/o HR', 'w HR', 'HR expected', 0);
  xlabel('CMPA.CMPAHR'); ylabel('ns');
  title('EPWM high pulse lengths on 28075 for CAU = CLEAR, CAD = SET');
 


  conclusions
  - with HRPWM the pulse is 1 inc longer if CMPA.CMPAHR == 0
  - with HRPWM the pulse is 1 inc shorter if CMPA.CMPAHR != 0

(PWM1A is as expected)
 
  comparison PWM1A, PWM2A signals on scope for different CMPA.CMPAHR:
  5.00: CAD set 2A ca. 16 ns before CAD set 1A
  5.25: CAD set 2A ca. 16 ns after CAD set 1A
  5.50: CAU clear 2A and CAD set 2A both ca. 8 ns after 1A
  5.75: CAU clear 2A and CAD set 2A ca. 12, 4 ns after 1A

This will give some strange results in the behavior of a control loop if the control algorithm produces accidentially a pwm value with CMPAHR = 0, I think.

As a workaroud I used the following code:

    /* workaround / fix for a good pwm: */
    /* add 0x8000 to get right pulse length, or 0x0100 to avoid CMPxHR = 0 */
    pa_cmpval = (pa_cmpval + 0x8000) | 0x0100;
    EPwm1Regs.CMPA.all = pa_cmpval;


Can anyone (at TI) verify the measurements?

Will the workaround help in any condition or has anyone a better idea?

Thanks,

Frank

(The code is derived from the examples and follows the suggestion given here: )

Some snippets of changes:

    /* Time Base Control Register (TBCTL) - set counter mode, divider */
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // count up
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // disable phase loading
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

    /* Time Base Control Register 2 (TBCTL2) - TODO */

    /* Time Base Counter Register (TBCTR) - clear counter */
    EPwm1Regs.TBCTR = 0x0000;
    /* Time Base Status Register (TBSTS) - clear events */
    EPwm1Regs.TBSTS.bit.CTRMAX = 1;
    EPwm1Regs.TBSTS.bit.SYNCI = 1;

    /* Time Base Phase High (TBPHS) */
    EPwm1Regs.TBPHS.all = 0x00000000;
    /* Time Base Period Register (TBPRD) */
    EPwm1Regs.TBPRD = pwm_period;
    /* Time Base Period High Resolution Register (TBPRDHR) */
    EPwm1Regs.TBPRDHR = 0;

    EPwm1Regs.HRCNFG.all = 0x0;
    EPwm1Regs.HRCNFG2.all = 0x0;
    EPwm1Regs.HRPCTL.all = 0x0;


    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // clear PWM1A on event A, up count
    EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;      // set PWM1A on event A, down count

    EPwm2Regs.HRCNFG.all = 0x0;
    EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP;          // MEP control on both edges
    EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;          // CMPAHR and TBPRDHR HR control
    EPwm2Regs.HRCNFG.bit.HRLOAD  = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
    EPwm2Regs.HRCNFG.bit.EDGMODEB = HR_BEP;          // MEP control on both edges
    EPwm2Regs.HRCNFG.bit.CTLMODEB = HR_CMP;          // CMPBHR and TBPRDHR HR control
    EPwm2Regs.HRCNFG.bit.HRLOADB  = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
    EPwm2Regs.HRCNFG.bit.AUTOCONV = 1;               // Enable autoconversion for HR period


    /* High Resolution Period Control Register (HRPCTL) */

    /* enable TBPHSHR sync (required for updwn count HR control) */
    EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;  // Enable TBPHSHR sync (required for updwn count HR control)
    EPwm2Regs.HRPCTL.bit.HRPE = 1;          // Turn on high-resolution period control.

    EPwm2Regs.HRCNFG2.all = 0x0;


    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // clear PWM1A on event A, up count
    EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;      // set PWM1A on event A, down count


Compare register is set in a timer ISR (cmp is written by CCS debugger):

float cmp;

    pa_cmpval = (long)ldexp(cmp, 16);


    /* workaround / fix for a good pwm: */
    /* add 0x8000 to get right length, or 0x0100 to avoid CMPxHR = 0 */
    // pa_cmpval = (pa_cmpval + 0x8000) | 0x0100;


    EPwm1Regs.CMPA.all = pa_cmpval;
    EPwm2Regs.CMPA.all = pa_cmpval;


  • Hi Frank,

    Do you need hi-res frequency and phase control? If not, please disable [HRPE] and [TBPHSHRLOADE] because the configuration procedure/sequence changes slightly with these enabled. I think this should improve your results.

    Do you also call the SFO HRPWM calibration function? This should be done to make sure a correct MEP value is used by the HRPWM logic.

    Finally, there is a duty cycle range limitation when using hi-res PWM. As documented in the Technical Reference Manual, the CMPA.bit.CMPA value cannot be less than 3 and more than 'TBPRD - 3' in up-down count mode. With a 60 MHz clock this may considerably restrict your achievable hi-res duty cycle steps. If your system allows it, I would try to clock it at a higher speed (up to 100 MHz for the PWM clock).

    I hope this helps.

    Hrishi

  • Hi Hrishi,

    thanks for your reply.

    Hrishi Nene said:
    Do you need hi-res frequency and phase control? If not, please disable [HRPE] and [TBPHSHRLOADE] because the configuration procedure/sequence changes slightly with these enabled. I think this should improve your results.

    If I set HRPE and TBPHSHRLOADE to zero, I do _not_ get HRPWM in up/down mode, the pulse lengths change in 33 ns steps only. That this has to be set on, was mentioned in the post by Lori Heustess I linked to in my first posting, and it is also on in the hrpwm_prdupdown_sfo_v8.c example by TI:

        (*ePWM[j]).HRPCTL.bit.TBPHSHRLOADE = 1;          // Enable TBPHSHR sync (required for updwn count HR control)
        (*ePWM[j]).HRPCTL.bit.HRPE = 1;                  // Turn on high-resolution period control.

    Hrishi Nene said:
    Do you also call the SFO HRPWM calibration function? This should be done to make sure a correct MEP value is used by the HRPWM logic.

    Yes, I get a HRMSTEP of 114 or 115.

    Hrishi Nene said:

    Finally, there is a duty cycle range limitation when using hi-res PWM. As documented in the Technical Reference Manual, the CMPA.bit.CMPA value cannot be less than 3 and more than 'TBPRD - 3' in up-down count mode. With a 60 MHz clock this may considerably restrict your achievable hi-res duty cycle steps. If your system allows it, I would try to clock it at a higher speed (up to 100 MHz for the PWM clock).

    I know that there are the two limitations, but my measurements show that it does not work if I am within the limit (CMPA = 5 for PRD = 10). The 3 MHz are for better measurements only, for the application less than 1 MHz will be enough, so the loss in the duty range will be not that big.

    If I want to set the PWM clock to 100 MHz = SYSCLK / 1, this will reduce CPU and CLA speed from 120 MHz to 100 MHz too, right? I wanted to have both full CPU speed and high resolution pwm.

    Sorry, my questions are still open and I have 2 additional ones:

    Will other CPUs (2837x) with the same ePWM version have the same problem?

    How to solve/workaround the problem with the CLA?

    Thanks,

    Frank

  • Frank,

    HRPE and TBPHSHRLOADE are required only for the case when hi-resolution period and phase control are desired. You should be able to see hi-res duty control at a constant frequency with these bits disabled. Please make sure that HRPWM clock is enabled (PCLKCR0[HRPWM]).

    I understand why you want to clock the PWM at 60MHz and it is a perfectly valid reason.

    Will other CPUs (2837x) with the same ePWM version have the same problem? How to solve/workaround the problem with the CLA?

    The behavior should be the same on these PWMs. The behavior you are seeing is not expected behavior and we need to debug what's going on with your set-up. By the way, are you using shadow load mode for compare registers? When are the active CMP register loaded in a cycle?

    Thanks.

    Hrishi

  • Hi Hrisni,

    thank you for your reply and sorry for my delayed response due to my vacation from office for 3 weeks.

    As already stated in my posting before: No, I DO NOT GET high resolution duty control with HRPE and TBPHSHRLOADE = 0. (By the way, later I'll have to adjust my PWM timings to an external reference clock, and I think it is a good idea to do this with high resolution too.)

    Yes, I use shadow load and the load of the active register is done with the zero event. See the code snippet below.

    Do you have some new discoveries about the unexpected behaviour?

    Thanks,

    Frank

        /*************************************************************************/
        /*                      configure epwm1 registers                        */
        /*************************************************************************/

        EALLOW;

        /************************* pwm time base registers ***********************/

        /* Time Base Control Register (TBCTL) - set counter mode, divider */
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // count up / down
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // disable phase loading
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

        /* Time Base Control Register 2 (TBCTL2) - TODO */

        /* Time Base Counter Register (TBCTR) - clear counter */
        EPwm1Regs.TBCTR = 0x0000;
        /* Time Base Status Register (TBSTS) - clear events */
        EPwm1Regs.TBSTS.bit.CTRMAX = 1;
        EPwm1Regs.TBSTS.bit.SYNCI = 1;

        /* Time Base Phase High (TBPHS) */
        EPwm1Regs.TBPHS.all = 0x00000000;
        /* Time Base Period Register (TBPRD) */
        EPwm1Regs.TBPRD = pwm_period;
        /* Time Base Period High Resolution Register (TBPRDHR) */
        EPwm1Regs.TBPRDHR = 0;

        /********************* high resolution pwm registers *********************/

        /* HRPWM Configuration Register (HRCNFG) */

        EPwm1Regs.HRCNFG.all = 0x0;     /* SWAPAB = SELOUTB = 0 */
        EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP;          // MEP control on both edges
        EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;          // CMPAHR and TBPRDHR HR control
        EPwm1Regs.HRCNFG.bit.HRLOAD  = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
        EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_BEP;          // MEP control on both edges
        EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP;          // CMPBHR and TBPRDHR HR control
        EPwm1Regs.HRCNFG.bit.HRLOADB  = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
        EPwm1Regs.HRCNFG.bit.AUTOCONV = 1;               // Enable autoconversion for HR period

        /* HRPWM Power Register (HRPWR) - is written by SFO software*/
        /* HRPWM MEP Step Register (HRMSTEP) - is written by SFO software */

        /* HRPWM Configuration 2 Register (HRCNFG2) */
        /* sets HR config for dead band, not used */
        EPwm1Regs.HRCNFG2.all = 0;

        /* High Resolution Period Control Register (HRPCTL) */
        /* enable TBPHSHR sync (required for updwn count HR control) */
        EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
        /* turn on high-resolution period control */
        EPwm1Regs.HRPCTL.bit.HRPE = 1;

        /* Global PWM Load Control Register (GLDCTL) */
        /* Global PWM Load Config Register (GLDCFG) */
        /* Global PWM Load Control Register 2 (GLDCTL2) */
        /* EPWMx Link Register (EPWMXLINK) */
        /*
        Writes to the TBPRD:TBPRDHR registers in the ePWM module
        selected by the following bit selections results in a simultaneous
        write to the current ePWM module's TBPRD_TBPRDHR registers.
        */
        /* load epwm2 period with epwm1 period */
        EPwm2Regs.EPWMXLINK.bit.TBPRDLINK = 0;

        /************************** pwm compare registers ************************/

        // set initial compare values
        EPwm1Regs.CMPA.all = pa_cmpnul;
        EPwm1Regs.CMPB.all = pa_cmpnul + pa_cmpdbd;
        /* Counter Compare Control Register (CMPCTL) */
        // LOADASYNC, LOADBSYNC - load conditions Shadow to Active CMPA Register */
        /* 0x01: load both according to LOADAMODE bits and when SYNC occurs */
        EPwm1Regs.CMPCTL.bit.LOADASYNC = 0x01;
        EPwm1Regs.CMPCTL.bit.LOADBSYNC = 0x01;
        // SHDWAFULL, SHDWBFULL fields are read only
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;     // use shadow
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;   // load on zero
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

        /* Counter Compare Control Register 2 (CMPCTL2) */
        /* control events C, D (not used here) */


        /***************** Action-Qualifier Submodule Registers ******************/

        /* Action Qualifier Control Register For Output A (AQCTLA) */
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // clear PWM1A on event A, up count
        EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;      // set PWM1A on event A, down count

        /* Additional Action Qualifier Control Register For Output A (AQCTLA2) */
        /*
        no actions on T1, T2 events: Trigger events based on comparator, trip
        or syncin events, disable all
        */
        EPwm1Regs.AQCTLA2.all = 0;

        /* AQCTLB Action Qualifier Control Register For Output B */
        EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;    // set PWM1B on event B, up count
        EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;  // clear PWM1B on event B, down count
        /* no additional actions */
        EPwm1Regs.AQCTLB2.all = 0;

        /* Action-Qualifier Software Force Register (AQSFRC) - not used here */
        /* Action-qualifier Continuous Software Force Register (AQCSFRC) */

        /******************** Dead-Band Submodule Registers***********************/

        /* do not use dead band module, control dead band using ctrla, ctrlb */

  • Frank,

    If your project requirement is only to enable high-resolution duty cycle, then I recommend reviewing a different example project (hrpwm_duty_sfo_v8). Let us know if this example doesn't help achieve your goal. It can be found at:
    controlSUITE\device_support\F2807x\v200\F2807x_examples_Cpu1\hrpwm_duty_sfo_v8

    The project hrpwm_prdupdown_sfo_v8 is for enabling high-resolution period and the E2E post you’ve linked above is for enabling both HR period and HR duty cycle.

    Elizabeth
  • Elizabeth,

    unfortunately the hrpwm_duty_sfo_v8 example you suggested uses asymmetric pwm (TB_COUNT_UP). We have good experiences with the symmetric pwm mode (on a good old 2407 at lower pwm frequency) and it would be nice if that will work with the new 28075 at higher frequencies.

    Meanwhile I checked that the CLA can do my correction (the MADD32 and MOR32 instructions do the job). It would be nice if you can confirm that my correction will yield a smooth pwm duty cycle function for the (current) controller output in any case.

    Thanks

    Frank
  • Frank,

    The hrpwm_duty_sfo_v8 project can be modified for symmetrical mode by changing the TBCTL/CTRMODE value and changing the CMPA/CMPAHR value for the duty cycle accordingly.

    If the project also requires high-resolution period, then it's good to follow the E2E post you linked and I also suggest reviewing Section 14.2.4.4.1 High-Resolution Period Configuration in the Technical Reference Manual.

    Elizabeth