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.

TMS320F280049C: HR Period Control Enabling

Part Number: TMS320F280049C
Other Parts Discussed in Thread: C2000WARE

Hello,

I have 2 questions regarding HR Period control. First, is it possible to have HR duty control at the same time when HR Period is enabled. I tried to hard code some values to CPAHR register but the duty cycle is not changing. The second question is regarding jitter that I see on the PWM output when HR UPCOUNT control is set. I followed the example in TI support for UPDOWN and changed the setting to UPCOUNT, but I see the jitter. When I enabled dead-time module, the A output comes clean, but B output still has jitter in the falling edge. Below is the initialization code I used with DB:

(*ePWM[j]).TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
(*ePWM[j]).TBPRD = period-1; // PWM frequency = 1/(2*TBPRD)
(*ePWM[j]).CMPA.bit.CMPA = period / 2; // set duty 50% initially
(*ePWM[j]).CMPA.bit.CMPAHR = (1 << 8); // initialize HRPWM extension
(*ePWM[j]).CMPB.bit.CMPB = period / 2; // set duty 50% initially
(*ePWM[j]).CMPB.all |= 1;
(*ePWM[j]).TBPHS.all = 0;
(*ePWM[j]).TBCTR = 0;

(*ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up
// count mode
(*ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
(*ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
(*ePWM[j]).TBCTL.bit.FREE_SOFT = 11;


(*ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_PRD; // LOAD CMPA on CTR =PRD
(*ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_PRD;
(*ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[j]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;

(*ePWM[j]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
(*ePWM[j]).DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
(*ePWM[j]).DBCTL.bit.IN_MODE = DBA_ALL; // EPWM1A is source for both delays
(*ePWM[j]).DBCTL.bit.OUTSWAP = 0;

EPwm1Regs.DBFED.bit.DBFED = 10;
EPwm1Regs.DBRED.bit.DBRED = 10;

(*ePWM[j]).AQCTLA.bit.ZRO = AQ_SET; // PWM toggle high/low
(*ePWM[j]).AQCTLA.bit.CAU = AQ_CLEAR;
(*ePWM[j]).AQCTLB.bit.ZRO = AQ_NO_ACTION;// PWM toggle high/low
(*ePWM[j]).AQCTLB.bit.CBU = AQ_NO_ACTION;

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


// count HR control)
(*ePWM[j]).HRPCTL.bit.HRPE = 1; // Turn on high-resolution
// period control.

CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within
// the EPWM
(*ePWM[j]).TBCTL.bit.SWFSYNC = 1; // Synchronize high
// resolution phase to
// start HR period

This is what I see on the PWM output:

Thanks,

Ahmed

  • To answer your first question, yes, you can have BOTH duty control and period control at the same time using the HIGH RESOLUTION module. But remember that when you do you use HR mode, make sure to not SYNCHRONIZE two ePWM modules on every cycle, that causes jitter usually.

    Up count is definitely supported for HR mode, I will attach some examples with HR mode enabled and in Up count mode.

    Some notes on your code, if using UP-COUNT mode, with HR, I would:

    1. set shadow load event to be CTR=ZERO

    2. Set the output on CTR=ZERO, clear on CTR=CMPA (FOR CHANNEL A)

    3. Use FALLING EDGE control on the HR module.

    4. Remember that you are using DEADBAND, so you have to still HR for Channel B as well, set CMPB to the same value as CMPA.

    5. HR LOAD mode you set to CTR=ZERO.

    Also your image did not go through. Can you resend it?

    Nima

  • Here is some examples for both UP-DOWN and only UP mode.

  • hrpwm_ex3_prd_updown_sfo.syscfg

    6283.hrpwm_ex4_duty_updown_sfo.c
    //#############################################################################
    //
    // FILE:   hrpwm_ex3_prdupdown_sfo.c
    //
    // TITLE:  HRPWM Period Control.
    //
    //#############################################################################
    //
    // FILE:   hrpwm_ex4_duty_updown_sfo.c
    //
    // TITLE:  HRPWM Duty Control with UPDOWN Mode.
    //
    //! \addtogroup driver_example_list
    //! <h1>HRPWM Duty Control with UPDOWN Mode</h1>
    //!
    //! This example calls the following TI's MEP Scale Factor Optimizer (SFO)
    //! software library V8 functions:
    //!
    //! \b int \b SFO(); \n
    //! - updates MEP_ScaleFactor dynamically when HRPWM is in use
    //! - updates HRMSTEP register (exists only in EPwm1Regs register space)
    //!   with MEP_ScaleFactor value
    //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255
    //!   (Auto-conversion may not function properly under this condition)
    //! - returns 1 when complete for the specified channel
    //! - returns 0 if not complete for the specified channel
    //!
    //! This example is intended to explain the HRPWM capabilities. The code can be
    //! optimized for code efficiency. Refer to TI's Digital power application
    //! examples and TI Digital Power Supply software libraries for details.
    //!
    //! \b External \b Connections \n
    //!  - Monitor ePWM1/2/3/4 A/B pins on an oscilloscope.
    //
    //#############################################################################
    // $TI Release: $
    // $Release Date: $
    // $Copyright: $
    //#############################################################################
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "SFO_V8.h"
    
    #define CHANNEL_B_AS_ZRO_PRD_REF    0
    #define EPWM_TIMER_TBPRD            100UL
    #define MIN_HRPWM_DUTY_PERCENT      4.0/((float32_t)EPWM_TIMER_TBPRD)*100.0
    //
    // Defines
    //
    #define LAST_EPWM_INDEX_FOR_EXAMPLE    5
    
    //
    // Globals
    //
    
    float32_t dutyFine = 50.0;
    uint16_t status;
    
    int MEP_ScaleFactor; // Global variable used by the SFO library
                         // Result can be used for all HRPWM channels
                         // This variable is also copied to HRMSTEP
                         // register by SFO() function.
    
    volatile uint32_t ePWM[] =
        {0, myEPWM1_BASE, myEPWM2_BASE, myEPWM3_BASE, myEPWM4_BASE};
    //
    // Function Prototypes
    //
    void initHRPWM(uint32_t period);
    void error(void);
    //__interrupt void epwm1ISR(void);
    //__interrupt void epwm2ISR(void);
    //__interrupt void epwm3ISR(void);
    //__interrupt void epwm4ISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t i = 0;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pull ups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Assign the interrupt service routines to ePWM interrupts
        //
        //Interrupt_register(INT_EPWM1, &epwm1ISR);
        //Interrupt_register(INT_EPWM2, &epwm2ISR);
        //Interrupt_register(INT_EPWM3, &epwm3ISR);
        //Interrupt_register(INT_EPWM4, &epwm4ISR);
    
        //
        // Initialize the EPWM GPIOs and change XBAR inputs from using GPIO0
        //
        Board_init();
    
        //
        // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
        // HRMSTEP must be populated with a scale factor value prior to enabling
        // high resolution period control.
        //
        while(status == SFO_INCOMPLETE)
        {
            status = SFO();
            if(status == SFO_ERROR)
            {
                error();   // SFO function returns 2 if an error occurs & # of MEP
            }              // steps/coarse step exceeds maximum of 255.
        }
    
    
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initHRPWM(EPWM_TIMER_TBPRD);
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
        // Enable ePWM interrupts
        //
        //Interrupt_enable(INT_EPWM1);
        //Interrupt_enable(INT_EPWM2);
        //Interrupt_enable(INT_EPWM3);
        //Interrupt_enable(INT_EPWM4);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
    
        for(;;)
        {
             //
             // Sweep DutyFine
             //
             for(dutyFine = MIN_HRPWM_DUTY_PERCENT; dutyFine < (100.0-MIN_HRPWM_DUTY_PERCENT); dutyFine += 0.01)
             {
                 DEVICE_DELAY_US(1000);
                 for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
                 {
                     float32_t count = ((100.0 - dutyFine) * (float32_t)(EPWM_TIMER_TBPRD << 8))/100.0;
                     uint32_t compCount = (count);
                     uint32_t hrCompCount = (compCount & (0x000000FF));
                     if (hrCompCount == 0)
                     {
                         //
                         // Add 1 to not have CMPxHR = 0
                         //
                         compCount |= 0x00000001;
                     }
                     HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);
    #if CHANNEL_B_AS_ZRO_PRD_REF == 0
                     HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_B, compCount);
    #endif
                 }
    
                 //
                 // Call the scale factor optimizer lib function SFO()
                 // periodically to track for any change due to temp/voltage.
                 // This function generates MEP_ScaleFactor by running the
                 // MEP calibration module in the HRPWM logic. This scale
                 // factor can be used for all HRPWM channels. The SFO()
                 // function also updates the HRMSTEP register with the
                 // scale factor value.
                 //
                 status = SFO(); // in background, MEP calibration module
                                 // continuously updates MEP_ScaleFactor
    
                 if (status == SFO_ERROR)
                 {
                     error();   // SFO function returns 2 if an error occurs & #
                                // of MEP steps/coarse step
                 }              // exceeds maximum of 255.
             }
         }
    }
    
    //
    // epwm1ISR - ePWM 1 ISR
    //
    //__interrupt void epwm1ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm2ISR - ePWM 2 ISR
    //
    //__interrupt void epwm2ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM2_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm3ISR - ePWM 3 ISR
    //
    //__interrupt void epwm3ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM3_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm4ISR - ePWM 4 ISR
    //
    //__interrupt void epwm4ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM4_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    
    void initHRPWM(uint32_t period)
    {
    
        uint16_t j;
    
        //
        // ePWM channel register configuration with HRPWM
        // ePWMxA / ePWMxB toggle low/high with MEP control on Rising and Falling edges
        //
        for (j=1;j<LAST_EPWM_INDEX_FOR_EXAMPLE;j++)
        {
            EPWM_setEmulationMode(ePWM[j], EPWM_EMULATION_FREE_RUN);
    
            //
            // Set-up TBCLK
            //
            EPWM_setTimeBasePeriod(ePWM[j], period-1);
            EPWM_setPhaseShift(ePWM[j], 0U);
            EPWM_setTimeBaseCounter(ePWM[j], 0U);
    
            //
            // set duty 50% initially
            //
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_A, (period/2 << 8) + 1);
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_B, (period/2 << 8) + 1);
    
    
            //
            // Set up counter mode
            //
            EPWM_setTimeBaseCounterMode(ePWM[j], EPWM_COUNTER_MODE_UP_DOWN);
            EPWM_disablePhaseShiftLoad(ePWM[j]);
            EPWM_setClockPrescaler(ePWM[j],
                                   EPWM_CLOCK_DIVIDER_1,
                                   EPWM_HSCLOCK_DIVIDER_1);
            EPWM_setSyncOutPulseMode(ePWM[j], EPWM_SYNC_OUT_PULSE_DISABLED);
    
            //
            // Set up shadowing
            // MUST BE CTR=(ZER & PRD)
            //
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_A,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_B,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
    
            //
            // Set actions
            //
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    
    #if CHANNEL_B_AS_ZRO_PRD_REF == 1
            //
            // Use B channel as the ZERO and PRD reference
            //
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    #else
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    #endif
    
    
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL);
    
            //
            // Set up shadowing
            // MUST BE CTR=(ZER & PRD)
            //
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
    
    #if CHANNEL_B_AS_ZRO_PRD_REF == 0
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL);
    
            //
            // Set up shadowing
            // MUST BE CTR=(ZER & PRD)
            //
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
    #endif
    
            HRPWM_enableAutoConversion(ePWM[j]);
    
            //
            // Turn on high-resolution period control for DUTY to take HR on BOTH EDGEs.
            //
    
            HRPWM_enablePeriodControl(ePWM[j]);
            HRPWM_disablePhaseShiftLoad(ePWM[j]);
    
    
            //
            // Interrupt where we will change the Compare Values
            // Select INT on Time base counter zero event,
            // Enable INT, generate INT on 1st event
            //
            //EPWM_setInterruptSource(ePWM[j], EPWM_INT_TBCTR_ZERO);
            //EPWM_enableInterrupt(ePWM[j]);
            //EPWM_setInterruptEventCount(ePWM[j], 1U);
        }
    
    }
    
    //
    // error - Halt debugger when called
    //
    void error (void)
    {
        ESTOP0;         // Stop here and handle error
    }
    
    hrpwm_ex4_duty_updown_sfo.syscfg
    5270.hrpwm_ex1_duty_sfo.c
    //#############################################################################
    //
    // FILE:   hrpwm_ex1_duty_sfo.c
    //
    // TITLE:  HRPWM Duty Control with SFO.
    //
    //! \addtogroup driver_example_list
    //! <h1>HRPWM Duty Control with SFO</h1>
    //!
    //! This example modifies the MEP control registers to show edge displacement
    //! for high-resolution period with ePWM in Up count mode
    //! due to the HRPWM control extension of the respective ePWM module.
    //!
    //! This example calls the following TI's MEP Scale Factor Optimizer (SFO)
    //! software library V8 functions:
    //!
    //! \b int \b SFO(); \n
    //! - updates MEP_ScaleFactor dynamically when HRPWM is in use
    //! - updates HRMSTEP register (exists only in EPwm1Regs register space)
    //! with MEP_ScaleFactor value
    //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255
    //!   (Auto-conversion may not function properly under this condition)
    //! - returns 1 when complete for the specified channel
    //! - returns 0 if not complete for the specified channel
    //!
    //! This example is intended to explain the HRPWM capabilities. The code can be
    //! optimized for code efficiency. Refer to TI's Digital power application
    //! examples and TI Digital Power Supply software libraries for details.
    //!
    //! \b External \b Connections \n
    //!  - Monitor ePWM1/2/3/4 A/B pins on an oscilloscope.
    //
    //#############################################################################
    // $TI Release: $
    // $Release Date: $
    // $Copyright: $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "SFO_V8.h"
    
    #define EPWM_TIMER_TBPRD            100UL
    #define MIN_HRPWM_DUTY_PERCENT      4.0/((float32_t)EPWM_TIMER_TBPRD)*100.0
    //
    // Defines
    //
    #define LAST_EPWM_INDEX_FOR_EXAMPLE    5
    
    //
    // Globals
    //
    
    float32_t dutyFine = MIN_HRPWM_DUTY_PERCENT;
    uint16_t status;
    
    int MEP_ScaleFactor; // Global variable used by the SFO library
                         // Result can be used for all HRPWM channels
                         // This variable is also copied to HRMSTEP
                         // register by SFO() function.
    
    volatile uint32_t ePWM[] =
        {0, myEPWM1_BASE, myEPWM2_BASE, myEPWM3_BASE, myEPWM4_BASE};
    //
    // Function Prototypes
    //
    void initHRPWM(uint32_t period);
    void error(void);
    //__interrupt void epwm1ISR(void);
    //__interrupt void epwm2ISR(void);
    //__interrupt void epwm3ISR(void);
    //__interrupt void epwm4ISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t i = 0;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pull ups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Assign the interrupt service routines to ePWM interrupts
        //
        //Interrupt_register(INT_EPWM1, &epwm1ISR);
        //Interrupt_register(INT_EPWM2, &epwm2ISR);
        //Interrupt_register(INT_EPWM3, &epwm3ISR);
        //Interrupt_register(INT_EPWM4, &epwm4ISR);
    
        //
        // Initialize the EPWM GPIO Pins and change the XBAR inputs from using GPIO0
        //
        Board_init();
    
    
        //
        // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
        // HRMSTEP must be populated with a scale factor value prior to enabling
        // high resolution period control.
        //
        while(status == SFO_INCOMPLETE)
        {
            status = SFO();
            if(status == SFO_ERROR)
            {
                error();   // SFO function returns 2 if an error occurs & # of MEP
            }              // steps/coarse step exceeds maximum of 255.
        }
    
    
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initHRPWM(EPWM_TIMER_TBPRD);
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
        // Enable ePWM interrupts
        //
        //Interrupt_enable(INT_EPWM1);
        //Interrupt_enable(INT_EPWM2);
        //Interrupt_enable(INT_EPWM3);
        //Interrupt_enable(INT_EPWM4);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
    
        for(;;)
        {
             //
             // Sweep DutyFine
             //
             for(dutyFine = MIN_HRPWM_DUTY_PERCENT; dutyFine < 99.9; dutyFine += 0.01)
             {
                 DEVICE_DELAY_US(1000);
                 for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
                 {
                     float32_t count = (dutyFine * (float32_t)(EPWM_TIMER_TBPRD << 8))/100;
                     uint32_t compCount = (count);
                     HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);
                     HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_B, compCount);
                 }
    
                 //
                 // Call the scale factor optimizer lib function SFO()
                 // periodically to track for any change due to temp/voltage.
                 // This function generates MEP_ScaleFactor by running the
                 // MEP calibration module in the HRPWM logic. This scale
                 // factor can be used for all HRPWM channels. The SFO()
                 // function also updates the HRMSTEP register with the
                 // scale factor value.
                 //
                 status = SFO(); // in background, MEP calibration module
                                 // continuously updates MEP_ScaleFactor
    
                 if (status == SFO_ERROR)
                 {
                     error();   // SFO function returns 2 if an error occurs & #
                                // of MEP steps/coarse step
                 }              // exceeds maximum of 255.
             }
         }
    }
    
    //
    // epwm1ISR - ePWM 1 ISR
    //
    //__interrupt void epwm1ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm2ISR - ePWM 2 ISR
    //
    //__interrupt void epwm2ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM2_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm3ISR - ePWM 3 ISR
    //
    //__interrupt void epwm3ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM3_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm4ISR - ePWM 4 ISR
    //
    //__interrupt void epwm4ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM4_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    
    
    void initHRPWM(uint32_t period)
    {
    
        uint16_t j;
    
        //
        // ePWM channel register configuration with HRPWM
        // ePWMxA / ePWMxB toggle low/high with MEP control on Rising edge
        //
        for (j=1;j<LAST_EPWM_INDEX_FOR_EXAMPLE;j++)
        {
            EPWM_setEmulationMode(ePWM[j], EPWM_EMULATION_FREE_RUN);
    
            //
            // Set-up TBCLK
            //
            EPWM_setTimeBasePeriod(ePWM[j], period-1);
            EPWM_setPhaseShift(ePWM[j], 0U);
            EPWM_setTimeBaseCounter(ePWM[j], 0U);
    
            //
            // set duty 50% initially
            //
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_A, (period/2 << 8));
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_B, (period/2 << 8));
    
    
            //
            // Set up counter mode
            //
            EPWM_setTimeBaseCounterMode(ePWM[j], EPWM_COUNTER_MODE_UP);
            EPWM_disablePhaseShiftLoad(ePWM[j]);
            EPWM_setClockPrescaler(ePWM[j],
                                   EPWM_CLOCK_DIVIDER_1,
                                   EPWM_HSCLOCK_DIVIDER_1);
            EPWM_setSyncOutPulseMode(ePWM[j], EPWM_SYNC_OUT_PULSE_DISABLED);
    
            //
            // Set up shadowing
            //
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_A,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO);
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_B,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
            //
            // Set actions
            //
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
    
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL);
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO);
    
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL);
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO);
    
            HRPWM_enableAutoConversion(ePWM[j]);
    
            //
            // Turn off high-resolution period control.
            //
    
            HRPWM_disablePeriodControl(ePWM[j]);
            HRPWM_disablePhaseShiftLoad(ePWM[j]);
    
    
            //
            // Interrupt where we will change the Compare Values
            // Select INT on Time base counter zero event,
            // Enable INT, generate INT on 1st event
            //
            //EPWM_setInterruptSource(ePWM[j], EPWM_INT_TBCTR_ZERO);
            //EPWM_enableInterrupt(ePWM[j]);
            //EPWM_setInterruptEventCount(ePWM[j], 1U);
        }
    
    }
    
    //
    // error - Halt debugger when called
    //
    void error (void)
    {
        ESTOP0;         // Stop here and handle error
    }
    
    
    hrpwm_ex1_duty_sfo.syscfg
    hrpwm_ex3_prd_updown_sfo.c
    //#############################################################################
    //
    // FILE:   hrpwm_ex3_prdupdown_sfo.c
    //
    // TITLE:  HRPWM Period Control.
    //
    //! \addtogroup driver_example_list
    //! <h1>HRPWM Period Control</h1>
    //!
    //! This example modifies the MEP control registers to show edge displacement
    //! for high-resolution period with ePWM in Up-Down count mode
    //! due to the HRPWM control extension of the respective ePWM module.
    //!
    //! This example calls the following TI's MEP Scale Factor Optimizer (SFO)
    //! software library V8 functions:
    //!
    //! \b int \b SFO(); \n
    //! - updates MEP_ScaleFactor dynamically when HRPWM is in use
    //! - updates HRMSTEP register (exists only in EPwm1Regs register space)
    //!   with MEP_ScaleFactor value
    //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255
    //!   (Auto-conversion may not function properly under this condition)
    //! - returns 1 when complete for the specified channel
    //! - returns 0 if not complete for the specified channel
    //!
    //! This example is intended to explain the HRPWM capabilities. The code can be
    //! optimized for code efficiency. Refer to TI's Digital power application
    //! examples and TI Digital Power Supply software libraries for details.
    //!
    //! \b External \b Connections \n
    //!  - Monitor ePWM1/2/3/4 A/B pins on an oscilloscope.
    //
    //#############################################################################
    // $TI Release: $
    // $Release Date: $
    // $Copyright: $
    //#############################################################################
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "SFO_V8.h"
    
    //
    // Defines
    //
    #define EPWM_TIMER_TBPRD    20UL
    #define LAST_EPWM_INDEX_FOR_EXAMPLE    5
    #define MIN_HRPWM_PRD_PERCENT   0.2
    
    //
    // Globals
    //
    
    float32_t periodFine = MIN_HRPWM_PRD_PERCENT;
    uint16_t status;
    
    int MEP_ScaleFactor; // Global variable used by the SFO library
                         // Result can be used for all HRPWM channels
                         // This variable is also copied to HRMSTEP
                         // register by SFO() function.
    
    volatile uint32_t ePWM[] =
        {0, myEPWM1_BASE, myEPWM2_BASE, myEPWM3_BASE, myEPWM4_BASE};
    //
    // Function Prototypes
    //
    void initHRPWM(uint32_t period);
    void error(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t i = 0;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pull ups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Initialize EPWM GPIOs and change XBAR inputs from using GPIO0
        //
        Board_init();
    
    
        //
        // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
        // HRMSTEP must be populated with a scale factor value prior to enabling
        // high resolution period control.
        //
        while(status == SFO_INCOMPLETE)
        {
            status = SFO();
            if(status == SFO_ERROR)
            {
                error();   // SFO function returns 2 if an error occurs & # of MEP
            }              // steps/coarse step exceeds maximum of 255.
        }
    
    
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initHRPWM(EPWM_TIMER_TBPRD);
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
    
        for(;;)
        {
             //
             // Sweep DutyFine
             //
             for(periodFine = MIN_HRPWM_PRD_PERCENT; periodFine < 0.9; periodFine += 0.01)
             {
                 DEVICE_DELAY_US(1000);
                 for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
                 {
                     float32_t count = ((EPWM_TIMER_TBPRD-1) << 8UL) + (float32_t)(periodFine * 256);
                     uint32_t compCount = count;
                     HRPWM_setTimeBasePeriod(ePWM[i], compCount);
                 }
    
                 //
                 // Call the scale factor optimizer lib function SFO()
                 // periodically to track for any change due to temp/voltage.
                 // This function generates MEP_ScaleFactor by running the
                 // MEP calibration module in the HRPWM logic. This scale
                 // factor can be used for all HRPWM channels. The SFO()
                 // function also updates the HRMSTEP register with the
                 // scale factor value.
                 //
                 status = SFO(); // in background, MEP calibration module
                                 // continuously updates MEP_ScaleFactor
    
                 if (status == SFO_ERROR)
                 {
                     error();   // SFO function returns 2 if an error occurs & #
                                // of MEP steps/coarse step
                 }              // exceeds maximum of 255.
             }
         }
    }
    
    
    void initHRPWM(uint32_t period)
    {
    
        uint16_t j;
    
        //
        // ePWM channel register configuration with HRPWM
        //
        for (j=1;j<LAST_EPWM_INDEX_FOR_EXAMPLE;j++)
        {
            EPWM_setEmulationMode(ePWM[j], EPWM_EMULATION_FREE_RUN);
    
            //
            // Set-up TBCLK
            //
            EPWM_setPeriodLoadMode(ePWM[j], EPWM_PERIOD_SHADOW_LOAD);
            EPWM_setTimeBasePeriod(ePWM[j], period-1);
            EPWM_setPhaseShift(ePWM[j], 0U);
            EPWM_setTimeBaseCounter(ePWM[j], 0U);
    
            //
            // set duty 50% initially
            //
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_A, (period/2 << 8));
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_B, (period/2 << 8));
    
    
            //
            // Set up counter mode
            //
            EPWM_setTimeBaseCounterMode(ePWM[j], EPWM_COUNTER_MODE_UP_DOWN);
            EPWM_disablePhaseShiftLoad(ePWM[j]);
            EPWM_setClockPrescaler(ePWM[j],
                                   EPWM_CLOCK_DIVIDER_1,
                                   EPWM_HSCLOCK_DIVIDER_1);
            EPWM_setSyncOutPulseMode(ePWM[j], EPWM_SYNC_OUT_PULSE_DISABLED);
    
            //
            // Set up shadowing
            //
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_A,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO);
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_B,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
            //
            // Set actions
            //
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
    
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL);
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
    
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL);
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
    
            HRPWM_enableAutoConversion(ePWM[j]);
    
            //
            // Turn on high-resolution period control.
            //
    
            HRPWM_enablePeriodControl(ePWM[j]);
            HRPWM_enablePhaseShiftLoad(ePWM[j]);
    
            EPWM_forceSyncPulse(ePWM[j]);
        }
    
    }
    
    //
    // error - Halt debugger when called
    //
    void error (void)
    {
        ESTOP0;         // Stop here and handle error
    }
    
    

  • Make sure to have downloaded and are using CCS10.x and C2000Ware 3.03.00.00

  • Thanks Nima for your support. When I changed HR Load mode to CTR=Zero, the jitter was removed. However, now I'm trying to synchronize the PWM modules but I'm failing to do so. Here is my code. Can you please check it and give me your feedback? PWM2 is jumping all over the screen and doesn't have a constant phase shift.

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the EPWM
    EDIS;

    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
    EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
    EPwm1Regs.TBPRD = period-1; // PWM frequency = 1/(2*TBPRD)
    EPwm1Regs.CMPA.bit.CMPA = period / 2; // set duty 50% initially
    EPwm1Regs.CMPA.bit.CMPAHR = (1 << 8); // initialize HRPWM extension
    EPwm1Regs.CMPB.bit.CMPB = period / 2; // set duty 50% initially
    EPwm1Regs.CMPB.all |= 1;
    EPwm1Regs.TBPHS.all = 0;
    EPwm1Regs.TBCTR = 0;

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up-down
    // count mode
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    EPwm1Regs.TBCTL.bit.FREE_SOFT = 11;

    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // PWM toggle high/low
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // PWM toggle high/low
    EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;

    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // EPWM1A is source for both delays

    EPwm1Regs.DBFED.bit.DBFED = 10;
    EPwm1Regs.DBRED.bit.DBRED = 10;

    EALLOW;
    EPwm1Regs.HRCNFG.all = 0x0;
    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; // 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; // load on CTR = 0
    // and CTR = TBPRD
    EPwm1Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for
    // HR period

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


    EPwm1Regs.TBCTL.bit.SWFSYNC = 1; // Synchronize high
    // resolution phase to
    // start HR period
    EDIS;

    EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
    EPwm2Regs.TBPRD = period-1; // PWM frequency = 1/(2*TBPRD)
    EPwm2Regs.CMPA.bit.CMPA = period / 2; // set duty 50% initially
    EPwm2Regs.CMPA.bit.CMPAHR = (1 << 8); // initialize HRPWM extension
    EPwm2Regs.CMPB.bit.CMPB = period / 2; // set duty 50% initially
    EPwm2Regs.CMPB.all |= 1;
    EPwm2Regs.TBPHS.all = 0;
    EPwm2Regs.TBCTR = 0;

    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up-down
    // count mode
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    EPwm2Regs.TBCTL.bit.FREE_SOFT = 11;

    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // PWM toggle high/low
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET; // PWM toggle high/low
    EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;

    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL; // EPWM1A is source for both delays

    EPwm2Regs.DBFED.bit.DBFED = 10;
    EPwm2Regs.DBRED.bit.DBRED = 10;

    EALLOW;
    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; // 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; // load on CTR = 0
    // and CTR = TBPRD
    EPwm2Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for
    // HR period

    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.


    EDIS;

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the EPWM
    EDIS;

    Thanks,

    Ahmed

  • What do you want the phase shift between the two PWMs? Do you want to them to be exactly in sync?

    Nima

  • I was writing different values to the TBPRDHR of each PWM and that's why the phase was always changing. But after I fixed that, if I write to the TBPHS of PWM 2 I don't see any phase shift between it and PWM 1. I am trying to add 100ns shift between the modules.

  • Ahmed, 

    When in HR mode, and wanting to use phase shift, you dont want to sync on EVERY CTR=ZRO/PRD/etc.

    What you want to do is set the EPWM2 PHSEN bit, so there is a phase shift enabled, set the value of the TBPHS to equal 100ns. Then finally issue SW sync events to EPWM2 when needed to resync.

    Nima

  • Thanks Nima!

    This solved the issue. However, I placed the phase shift value in the initialization function meaning that I cannot change it dynamically. For full bridge LLC, we need to update the phase shift continuously between the legs. I tried to use SWFSYNC in the main loop but that just screwed up all the signals. Another thing is that I see a 10ns added to the phase shift I request. For example, if I set TBPHS=10, I should get 100ns delay but I get 110ns. Any idea what could be the reason. 

    Thank you very much for your helpful advices.

  • Yes Ahmed 110ns is correct. 2 cycles. You always set the phase shift to be = (desired phase shift - 2) due to the delay in the HW.

    Nima

  • Thanks Nima for your support!