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.

TMS320F28377D: HRPWM Using CMPA and CMPB

Part Number: TMS320F28377D

This has me a bit befuddled, and I will try to keep it concise, if you need any more information let me know. Thanks for your help.

I am using a EPWM in High Resolution Mode. The EPWM is setup in up count and uses CMPA for one trigger and CMPB for the other trigger. I have been comparing one EPWM with another (5&6) and getting some pretty strange results Dead Time is not used here just to make sure something is not getting messed up there. I have looked at the EPWM registers and they look correct. For EPWM1 CALPWRON is set to 1 and the HRMSTEP is 67 (all other EPWM's are 0)  I use EPWM5 as a reference, then compare the rising edge of the B channel (lower switch) controlled by CMPA to the same in EPWM6. This is also done with the falling edge. EPWM clock is 100 MHz. 

As you can see in the following data, the falling delay vs CMPA is as if the High Resolution is not active.

However, the Rising Edge delay vs CPMB looks like it is working fine, but appears there is some interaction with the falling edge, very strange.

I have several screen shots I could share, but not sure how to do that.

Here is the setup code


    //##########  EPWM5
    EALLOW;
    // Assumes ePWM clock is already enabled
    EPwm5Regs.TBPRD                 =   PWM_TBPRD;          // Set period for ePWMx
    EPwm5Regs.TBCTR                 =   0x0000;             // Clear counter
    EPwm5Regs.TBCTL.bit.CLKDIV      =   TB_DIV1;            // Time-base Clock Prescale Bits
    EPwm5Regs.TBCTL.bit.HSPCLKDIV   =   TB_DIV1;            // High-Speed Time-base Clock Prescale Bits
    EPwm5Regs.TBCTL.bit.SYNCOSEL    =   TB_SYNC_IN;         // EPWMx is a "slave", sync flow-through
    EPwm5Regs.TBCTL.bit.PHSEN       =   TB_ENABLE;          // EPWMx is a "slave", Load the time-deg counter from TBPHS at sync
    EPwm5Regs.TBPHS.bit.TBPHS       =   0x0000;             // Initialize Phase Shift
    EPwm5Regs.TBCTL.bit.CTRMODE     =   TB_COUNT_UP;        // Up Count Mode
    EPwm5Regs.CMPA.bit.CMPAHR       =   0;                  // initialize HRPWM extension
    EPwm5Regs.CMPB.bit.CMPBHR       =   0;                  // initialize HRPWM extension
    EPwm5Regs.CMPCTL.bit.SHDWAMODE  =   CC_SHADOW;          //  CmpA Shadow Mode
    EPwm5Regs.CMPCTL.bit.SHDWBMODE  =   CC_SHADOW;          //  CmpB Shadow Mode
    EPwm5Regs.CMPCTL.bit.LOADBMODE  =   CC_CTR_ZERO;        // Load at bottom of the carrier (for up count)
    EPwm5Regs.CMPCTL.bit.LOADAMODE  =   CC_CTR_ZERO;        // Load at bottom of the carrier (for up count)

    // Set up compares for A and B compare registers
    EPwm5Regs.AQCTLA.bit.CAU        =   AQ_SET;             // Turn on upper switch at compare A up
    EPwm5Regs.AQCTLA.bit.CBU        =   AQ_CLEAR;           // Turn off upper switch at compare B up
    EPwm5Regs.AQCTLB.bit.CAU        =   AQ_CLEAR;           // Turn off lower switch at compare A up
    EPwm5Regs.AQCTLB.bit.CBU        =   AQ_SET;             // Turn on  lower switch at compare B up

//    EPwm5Regs.TZSEL.bit.OSHT1       =   0;                  // Disable TZ1 as one one-shot trip source
    EPwm5Regs.TZSEL.bit.OSHT1       =   1;                  // Enable TZ1 as one one-shot trip source
//    EPwm5Regs.TZSEL.bit.OSHT2       =   0;                  // Disable TZ2 as one one-shot trip source
    EPwm5Regs.TZSEL.bit.OSHT2       =   1;                  // Enable TZ2 as one one-shot trip source
//    EPwm5Regs.TZSEL.bit.OSHT3       =   0;                  // Disable TZ3 as one one-shot trip source
    EPwm5Regs.TZSEL.bit.OSHT3       =   1;                  // Enable TZ3 as one one-shot trip source
    EPwm5Regs.TZSEL.bit.OSHT6       =   1;                  // Enable TZ6 as one-shot trip source, to prevent shoot-through during emulation stop (pause,reset, reprogram)
    EPwm5Regs.TZCTL.bit.TZA         =   TZ_FORCE_LO;        // TZ1 forces A output lo
    EPwm5Regs.TZCTL.bit.TZB         =   TZ_FORCE_LO;        // TZ1 forces B output lo
    EPwm5Regs.TZEINT.bit.OST        =   1;                  // Enable TZ interrupt

    EPwm5Regs.HRCNFG.all            = 0x0;                  // Reset HRCNFG
    EPwm5Regs.HRCNFG.bit.EDGMODE    = HR_BEP;   //HR_REP;   //HR_FEP;               // MEP control on falling edge  DAP
    EPwm5Regs.HRCNFG.bit.EDGMODEB   = HR_BEP;   //HR_FEP;   //HR_REP;               // MEP control on rising edge   DAP
    EPwm5Regs.HRCNFG.bit.HRLOAD     = HR_CTR_ZERO;          // Load at bottom of the carrier (for up count)
    EPwm5Regs.HRCNFG.bit.HRLOADB    = HR_CTR_ZERO;          // Load at bottom of the carrier (for up count)
    EPwm5Regs.HRCNFG.bit.AUTOCONV   = 0x1;                  // Enable automatic scaling of CMPAHR based on MEP_ScaleFactor. With this enabled, CMPAHR is simply [0x0000 0xFF00].
    EDIS;

    //##########  EPWM6
    EALLOW;
    // Assumes ePWM clock is already enabled
    EPwm6Regs.TBPRD                 =   PWM_TBPRD;          // Set period for ePWMx
    EPwm6Regs.TBCTR                 =   0x0000;             // Clear counter
    EPwm6Regs.TBCTL.bit.CLKDIV      =   TB_DIV1;            // Time-base Clock Prescale Bits
    EPwm6Regs.TBCTL.bit.HSPCLKDIV   =   TB_DIV1;            // High-Speed Time-base Clock Prescale Bits
    EPwm6Regs.TBCTL.bit.SYNCOSEL    =   TB_SYNC_IN;         // EPWMx is a "slave", sync flow-through
    EPwm6Regs.TBCTL.bit.PHSEN       =   TB_ENABLE;          // EPWMx is a "slave", Load the time-deg counter from TBPHS at sync
    EPwm6Regs.TBPHS.bit.TBPHS       =   0x0000;             //Initialize phase shift
    EPwm6Regs.TBCTL.bit.CTRMODE     =   TB_COUNT_UP;        // Up Count Mode
    EPwm6Regs.CMPA.bit.CMPAHR       =   0;                  // initialize HRPWM extension
    EPwm6Regs.CMPB.bit.CMPBHR       =   0;                  // initialize HRPWM extension
    EPwm6Regs.CMPCTL.bit.SHDWAMODE  =   CC_SHADOW;          //  CmpA Shadow Mode
    EPwm6Regs.CMPCTL.bit.SHDWBMODE  =   CC_SHADOW;          //  CmpB Shadow Mode
    EPwm6Regs.CMPCTL.bit.LOADBMODE  =   CC_CTR_ZERO;        // Load at bottom of the carrier (for up count)
    EPwm6Regs.CMPCTL.bit.LOADAMODE  =   CC_CTR_ZERO;        // Load at bottom of the carrier (for up count)

    // Set up compares for A and B compare register
    EPwm6Regs.AQCTLA.bit.CAU        =   AQ_SET;             // Turn on upper switch at compare A up
    EPwm6Regs.AQCTLA.bit.CBU        =   AQ_CLEAR;           // Turn off upper switch at compare B up
    EPwm6Regs.AQCTLB.bit.CAU        =   AQ_CLEAR;           // Turn off lower switch at compare A up
    EPwm6Regs.AQCTLB.bit.CBU        =   AQ_SET;             // Turn on lower switch at compare B up

//    EPwm6Regs.TZSEL.bit.OSHT1       =   0;                  // Disable TZ1 as one one-shot trip source
    EPwm6Regs.TZSEL.bit.OSHT1       =   1;                  // Enable TZ1 as one one-shot trip source
//    EPwm6Regs.TZSEL.bit.OSHT2       =   0;                  // Disable TZ2 as one one-shot trip source
    EPwm6Regs.TZSEL.bit.OSHT2       =   1;                  // Enable TZ2 as one one-shot trip source
//    EPwm6Regs.TZSEL.bit.OSHT3       =   0;                  // Disable TZ3 as one one-shot trip source
    EPwm6Regs.TZSEL.bit.OSHT3       =   1;                  // Enable TZ3 as one one-shot trip source
    EPwm6Regs.TZSEL.bit.OSHT6       =   1;                  // Enable TZ6 as one-shot trip source, to prevent shoot-through during emulation stop (pause,reset, reprogram)
    EPwm6Regs.TZCTL.bit.TZA         =   TZ_FORCE_LO;        // TZ1 forces A output lo
    EPwm6Regs.TZCTL.bit.TZB         =   TZ_FORCE_LO;        // TZ1 forces B output lo
    EPwm6Regs.TZEINT.bit.OST        =   1;                  // Enable TZ interrupt

    EPwm6Regs.HRCNFG.all            = 0x0;                  // Reset HRCNFG
    EPwm6Regs.HRCNFG.bit.EDGMODE    = HR_BEP;   //HR_REP;   //HR_FEP;               // MEP control on falling edge   DAP
    EPwm6Regs.HRCNFG.bit.EDGMODEB   = HR_BEP;   //HR_FEP;   //HR_REP;               // MEP control on rising edge   DAP
    EPwm6Regs.HRCNFG.bit.HRLOAD     = HR_CTR_ZERO;          // Load at bottom of the carrier (for up count)
    EPwm6Regs.HRCNFG.bit.HRLOADB    = HR_CTR_ZERO;          // Load at bottom of the carrier (for up count)
    EPwm6Regs.HRCNFG.bit.AUTOCONV   = 0x1;                  // Enable automatic scaling of CMPAHR based on MEP_ScaleFactor. With this enabled, CMPAHR is simply [0x0000 0xFF00].
    EDIS;

Here are the results, I tried attaching the graphs but not much luck.

Delay nS Falling Delay nS Rising 5 CMPA 5 CMPB 6 CMPA 6 CMPB
0 0 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E7BF00
0 0 0x04DB4000 0x04E7BF00 0x04DB6000 0x04E7BF00
0 0 0x04DB4000 0x04E7BF00 0x04DBC000 0x04E7BF00
0 0 0x04DB4000 0x04E7BF00 0x04DBE000 0x04E7BF00
0 0 0x04DB4000 0x04E7BF00 0x04DBFF00 0x04E7BF00
10 0 0x04DB4000 0x04E7BF00 0x04DC0000 0x04E7BF00
10 0 0x04DB4000 0x04E7BF00 0x04DC4000 0x04E7BF00
10 0 0x04DB4001 0x04E7BF01 0x04DCFF00 0x04E7BF01
20 0 0x04DB4000 0x04E7BF00 0x04DD0000 0x04E7BF00
Delay nS Falling Delay nS Rising 5 CMPA 5 CMPB 6 CMPA 6 CMPB
0 0 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E7BF00
1 1 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E7DF00
1.5 2 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E7FF00
-2 5 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E83F00
-1.5 6.5 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E85F00
-1 7.5 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E87F00
-0.5 9 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E89F00
0 10 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E8BF00
1 12.5 0x04DB4000 0x04E7BF00 0x04DB4000 0x04E8FF00

  • You are not supposed to configure the CALPWRON register. Why are you enabling it? Also are you not using SFO library?

  • Thanks for the response Nima,

    The CALPWRON is not used anywhere in the code (did a cntrl h search), and yes the SFO routine is called on a regular basis. (although SPRUHM8I indicates it resets to 0, so it must be set somewhere) The "EPWM1 CALPWRON is set to 1 and the HRMSTEP is 67"  statement was from the debugger when I accessed those registers. The data in the table is from the debugger as well. I was trying to get as much data that was software independent as possible.

         Dave

  • I wrote this example to quickly check and I'm getting the same delay on all ePWM modules when I use the HR module.

    Is this correct?

        // Set up compares for A and B compare register
        EPwm6Regs.AQCTLA.bit.CAU        =   AQ_SET;             // Turn on upper switch at compare A up
        EPwm6Regs.AQCTLA.bit.CBU        =   AQ_CLEAR;           // Turn off upper switch at compare B up
        EPwm6Regs.AQCTLB.bit.CAU        =   AQ_CLEAR;           // Turn off lower switch at compare A up
        EPwm6Regs.AQCTLB.bit.CBU        =   AQ_SET;             // Turn on lower switch at compare B up

    Because if you are using HRPWM, you want to:

    1. if using up count, use PRD/ZERO for an action, use CMPA for the other action for CHANNEL A

    or same thing other channel same thing with CMPB.

    You dont want to use CMPA and CMPB on the same channel.

    2. if using UP-DOWN count, use CMPAU and CMPAD for CHANNEL A.

    or the same thing with CMPBU and CMPBD for CHANNEL B.

    Nima

  • Thanks Nima,

    I'm a tad bit confused....

    Did the example you cited actually work? If so, your next comment about CMPA and CMPB on the same channel not working doesn't make sense.

    The way we are doing our phase shift requires using both CMPA and CMPB, if you found a way to make it work that would be great.

      Thanks again

                  Dave

  • One more thing Nima,

    I have tried to find some documentation on how HRPWM is implemented. Out of all the documentation that I have discovered, I keep going back to SPRUHM8I which is specific to this part. It appears that the HRPWM delay is added somewhere in the deadband or tripzone logic, but it is unclear. If there is a document that explains this in more detail that would help my understanding.

              Thanks again Nima,

                      Dave

  • Hi Nima,

    It's been a week, any updates?

       Dave

  • The example I provided uses CMPA U/D events to control CHANNEL A.

    CMPB U/D events to control CHANNEL B.

    You should be able to update your PWM generation algorithm to do the same for HRWPM. 

    CMPAHR will get added to the CMPA on CHANNEL A in this case. Same thing for CMPBHR to CMPB and CHANNEL B.

    As far as where the HR portion is added, it gets added after the ACTION QUALIFIER module and takes into account on the EPWM output the effects of deadband, chopper and tripzone.

    Nima

  • Thanks again for the response Nima,

    I must really be missing something. The code you presented as a fix is exactly the same code that I am using

        // Set up compares for A and B compare registers, complement of EPWM5
        EPwm6Regs.AQCTLA.bit.CAU        =   AQ_SET;             // Turn on upper switch at compare A up
        EPwm6Regs.AQCTLA.bit.CBU        =   AQ_CLEAR;           // Turn off upper switch at compare B up
        EPwm6Regs.AQCTLB.bit.CAU        =   AQ_CLEAR;           // Turn off lower switch at compare A up
        EPwm6Regs.AQCTLB.bit.CBU        =   AQ_SET;             // Turn on lower switch at compare B up

    So will this work if I set the counter register to Up/Down? 

            Dave

  • David,

    This is what you really are looking for:

        EPwm6Regs.AQCTLA.bit.CAU        =   AQ_SET;             // Turn on upper switch at compare A up
        EPwm6Regs.AQCTLA.bit.CAD        =   AQ_CLEAR;           // Turn off upper switch at compare B up
        EPwm6Regs.AQCTLB.bit.CBU        =   AQ_CLEAR;           // Turn off lower switch at compare A up
        EPwm6Regs.AQCTLB.bit.CBD        =   AQ_SET;             // Turn on lower switch at compare B up

    You want to tie your channel to the CHANNELx to CMPx and CMPxHR (x =A or B)

  • Thanks again Nima,

    Sometimes it is the obvious that eludes me. When I figured out that the CMPA and CMPB are compares against the counter, and that the CMPAHR and CMPBHR are delays for the Channels A and B respectively, I was able to get it to work. Basically had to decouple CMPA from CMPAHR and likewise for CMPB/CMPBHR. Since I am using ChA and ChB for the upper/lower switches in a leg, CMPAHR and CMPBHR have to be the same.

         BR

                  Dave