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 synchronisation

Part Number: TMS320F280049C
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

Hello everyone,

I am using a C2000 microcontroller to generate a HRPWM signal (2-10 MHz, using channels A and B, including deadband control) with a constant 50% duty cycle. This works fine in up-down-count mode with HR period control and HR COMPA and COMPB registers.

Now I want to add a second PWM (ePWM2), synchronized to the first. I want to add a phase shift between these two signals. If I understand correctly, there is no way to do this with high resolution since I am using high resolution for the compare registers. But this is fine for me.
However, even without the high resolution phase shift, I cannot get the synchronization to work correctly: Using sysconfig in CCS, I configured ePWM1 to send a sync-out pulse when the timebase counter equals zero. As I understand it, ePWM2 should now synchronize, but it does not when I enable HRPWM for the HR period control and compare registers.
I have also noticed that PWM2 does not synchronize when I disable the phase shift load. Why does this happen?

I have created a new project based on the example "epwm_ex3_synchronization" from C2000Ware. This minimal test project is attached: In the .syscfg file you can see how I did the configuration that causes the erroneous behavior I described above.  I suspect that I just did a configuration error, but I cannot find the error.

Any help would be appreciated.

Cheers,
Jonathan Kipp

-------------

Sysconfig:

/**
 * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
 * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
 * @cliArgs --device "F28004x" --package "F28004x_100PZ" --part "F28004x_100PZ" --context "system" --product "C2000WARE@5.01.00.00"
 * @versions {"tool":"1.19.0+3426"}
 */

/**
 * Import the modules used in this configuration.
 */
const epwm             = scripting.addModule("/driverlib/epwm.js", {}, false);
const epwm1            = epwm.addInstance();
const epwm2            = epwm.addInstance();
const inputxbar        = scripting.addModule("/driverlib/inputxbar.js", {}, false);
const inputxbar1       = inputxbar.addInstance();
const inputxbar_input  = scripting.addModule("/driverlib/inputxbar_input.js");
const inputxbar_input1 = inputxbar_input.addInstance();
const inputxbar_input2 = inputxbar_input.addInstance();
const sync             = scripting.addModule("/driverlib/sync.js");

/**
 * Write custom configuration values to the imported modules.
 */
epwm1.$name                                                      = "myEPWM1";
epwm1.epwmTimebase_hsClockDiv                                    = "EPWM_HSCLOCK_DIVIDER_1";
epwm1.epwmEventTrigger_enableInterrupt                           = true;
epwm1.epwmEventTrigger_interruptEventCount                       = "1";
epwm1.epwmTimebase_syncOutPulseMode                              = "EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO";
epwm1.epwmTimebase_period                                        = 20;
epwm1.epwmCounterCompare_cmpA                                    = 10;
epwm1.epwmTimebase_counterMode                                   = "EPWM_COUNTER_MODE_UP_DOWN";
epwm1.epwmCounterCompare_cmpB                                    = 10;
epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_UP_CMPA   = "EPWM_AQ_OUTPUT_HIGH";
epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_DOWN_CMPA = "EPWM_AQ_OUTPUT_LOW";
epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_UP_CMPB   = "EPWM_AQ_OUTPUT_HIGH";
epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_DOWN_CMPB = "EPWM_AQ_OUTPUT_LOW";
epwm1.epwmCounterCompare_shadowLoadModeCMPA                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
epwm1.epwmCounterCompare_shadowLoadModeCMPB                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
epwm1.hrpwm_HRLoadA                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
epwm1.hrpwm_HRLoadB                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
epwm1.hrpwm_cmpbHR                                               = 128;
epwm1.hrpwm_cmpaHR                                               = 128;
epwm1.epwmActionQualifier_continousSwForceReloadMode             = "EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO_PERIOD";
epwm1.hrpwm_edgeModeA                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
epwm1.hrpwm_edgeModeB                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
epwm1.hrpwm_periodEnable                                         = true;
epwm1.hrpwm_enable                                               = true;
epwm1.hrpwm_autoConv                                             = true;
epwm1.epwmTimebase_emulationMode                                 = "EPWM_EMULATION_FREE_RUN";
epwm1.epwm.$assign                                               = "EPWM1";

epwm2.epwmEventTrigger_interruptSource                           = "EPWM_INT_TBCTR_ZERO";
epwm2.epwmTimebase_hsClockDiv                                    = "EPWM_HSCLOCK_DIVIDER_1";
epwm2.epwmEventTrigger_enableInterrupt                           = true;
epwm2.epwmEventTrigger_interruptEventCount                       = "1";
epwm2.$name                                                      = "myEPWM2";
epwm2.copyUse                                                    = true;
epwm2.copyFrom                                                   = "myEPWM1";
epwm2.epwmTimebase_period                                        = 20;
epwm2.epwmCounterCompare_cmpA                                    = 10;
epwm2.epwmTimebase_counterMode                                   = "EPWM_COUNTER_MODE_UP_DOWN";
epwm2.epwmCounterCompare_cmpB                                    = 10;
epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_UP_CMPA   = "EPWM_AQ_OUTPUT_HIGH";
epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_DOWN_CMPA = "EPWM_AQ_OUTPUT_LOW";
epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_UP_CMPB   = "EPWM_AQ_OUTPUT_HIGH";
epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_DOWN_CMPB = "EPWM_AQ_OUTPUT_LOW";
epwm2.hrpwm_edgeModeA                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
epwm2.hrpwm_edgeModeB                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
epwm2.epwmCounterCompare_shadowLoadModeCMPB                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
epwm2.epwmCounterCompare_shadowLoadModeCMPA                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
epwm2.hrpwm_HRLoadA                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
epwm2.hrpwm_HRLoadB                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
epwm2.hrpwm_cmpaHR                                               = 128;
epwm2.hrpwm_cmpbHR                                               = 128;
epwm2.hrpwm_phaseLoadEnable                                      = true;
epwm2.epwmTimebase_syncOutPulseMode                              = "EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN";
epwm2.epwmTimebase_periodLink                                    = "EPWM_LINK_WITH_EPWM_1";
epwm2.epwmCounterCompare_cmpALink                                = "EPWM_LINK_WITH_EPWM_1";
epwm2.epwmCounterCompare_cmpBLink                                = "EPWM_LINK_WITH_EPWM_1";
epwm2.hrpwm_enable                                               = true;
epwm2.hrpwm_autoConv                                             = true;
epwm2.epwmTimebase_periodLoadEvent                               = "EPWM_SHADOW_LOAD_MODE_SYNC";
epwm2.epwmTimebase_phaseEnable                                   = true;
epwm2.epwmTimebase_phaseShift                                    = 3;
epwm2.epwm.$assign                                               = "EPWM2";

inputxbar1.$name = "myINPUTXBAR5";

inputxbar_input1.$name          = "myINPUTXBARINPUT0";
inputxbar_input1.inputxbarInput = "XBAR_INPUT5";
inputxbar_input1.inputxbarGpio  = "GPIO56";

inputxbar_input2.$name          = "myINPUTXBARINPUT1";
inputxbar_input2.inputxbarInput = "XBAR_INPUT6";
inputxbar_input2.inputxbarGpio  = "GPIO56";

/**
 * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
 * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
 * re-solve from scratch.
 */
epwm1.epwm.epwm_aPin.$suggestSolution = "GPIO0";
epwm1.epwm.epwm_bPin.$suggestSolution = "GPIO1";
epwm2.epwm.epwm_aPin.$suggestSolution = "GPIO2";
epwm2.epwm.epwm_bPin.$suggestSolution = "GPIO3";

auto generated board.c:

/*
 * Copyright (c) 2020 Texas Instruments Incorporated - http://www.ti.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "board.h"

//*****************************************************************************
//
// Board Configurations
// Initializes the rest of the modules. 
// Call this function in your application if you wish to do all module 
// initialization.
// If you wish to not use some of the initializations, instead of the 
// Board_init use the individual Module_inits
//
//*****************************************************************************
void Board_init()
{
	EALLOW;

	PinMux_init();
	INPUTXBAR_init();
	SYNC_init();
	EPWM_init();

	EDIS;
}

//*****************************************************************************
//
// PINMUX Configurations
//
//*****************************************************************************
void PinMux_init()
{
	//
	// PinMux for modules assigned to CPU1
	//
	
	//
	// EPWM1 -> myEPWM1 Pinmux
	//
	GPIO_setPinConfig(myEPWM1_EPWMA_PIN_CONFIG);
	GPIO_setPadConfig(myEPWM1_EPWMA_GPIO, GPIO_PIN_TYPE_STD);
	GPIO_setQualificationMode(myEPWM1_EPWMA_GPIO, GPIO_QUAL_SYNC);

	GPIO_setPinConfig(myEPWM1_EPWMB_PIN_CONFIG);
	GPIO_setPadConfig(myEPWM1_EPWMB_GPIO, GPIO_PIN_TYPE_STD);
	GPIO_setQualificationMode(myEPWM1_EPWMB_GPIO, GPIO_QUAL_SYNC);

	//
	// EPWM2 -> myEPWM2 Pinmux
	//
	GPIO_setPinConfig(myEPWM2_EPWMA_PIN_CONFIG);
	GPIO_setPadConfig(myEPWM2_EPWMA_GPIO, GPIO_PIN_TYPE_STD);
	GPIO_setQualificationMode(myEPWM2_EPWMA_GPIO, GPIO_QUAL_SYNC);

	GPIO_setPinConfig(myEPWM2_EPWMB_PIN_CONFIG);
	GPIO_setPadConfig(myEPWM2_EPWMB_GPIO, GPIO_PIN_TYPE_STD);
	GPIO_setQualificationMode(myEPWM2_EPWMB_GPIO, GPIO_QUAL_SYNC);


}

//*****************************************************************************
//
// EPWM Configurations
//
//*****************************************************************************
void EPWM_init(){
    HRPWM_setEmulationMode(myEPWM1_BASE, EPWM_EMULATION_FREE_RUN);	
    HRPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);	
    EPWM_setTimeBasePeriod(myEPWM1_BASE, 20);	
    HRPWM_setTimeBaseCounter(myEPWM1_BASE, 0);	
    HRPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);	
    HRPWM_disablePhaseShiftLoad(myEPWM1_BASE);	
    HRPWM_setPhaseShift(myEPWM1_BASE, 0);	
    HRPWM_setSyncOutPulseMode(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO);	
    EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, 10);	
    HRPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
    EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, 10);	
    HRPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
    HRPWM_setActionQualifierContSWForceShadowMode(myEPWM1_BASE, EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO_PERIOD);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    HRPWM_setRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);	
    HRPWM_disableRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);	
    HRPWM_setFallingEdgeDeadBandDelayInput(myEPWM1_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);	
    HRPWM_disableFallingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);	
    HRPWM_enableInterrupt(myEPWM1_BASE);	
    HRPWM_setInterruptEventCount(myEPWM1_BASE, 1);	
    HRPWM_enableAutoConversion(myEPWM1_BASE);	
    HRPWM_setMEPEdgeSelect(myEPWM1_BASE, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
    HRPWM_setHiResCounterCompareValueOnly(myEPWM1_BASE, HRPWM_COUNTER_COMPARE_A, 128);	
    HRPWM_setCounterCompareShadowLoadEvent(myEPWM1_BASE, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
    HRPWM_setMEPEdgeSelect(myEPWM1_BASE, HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
    HRPWM_setHiResCounterCompareValueOnly(myEPWM1_BASE, HRPWM_COUNTER_COMPARE_B, 128);	
    HRPWM_setCounterCompareShadowLoadEvent(myEPWM1_BASE, HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
    HRPWM_enablePeriodControl(myEPWM1_BASE);	
    HRPWM_setClockPrescaler(myEPWM2_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);	
    HRPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC);	
    EPWM_setTimeBasePeriod(myEPWM2_BASE, 20);	
    HRPWM_setupEPWMLinks(myEPWM2_BASE, EPWM_LINK_WITH_EPWM_1, EPWM_LINK_TBPRD);	
    HRPWM_setTimeBaseCounter(myEPWM2_BASE, 0);	
    HRPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP_DOWN);	
    HRPWM_enablePhaseShiftLoad(myEPWM2_BASE);	
    HRPWM_setPhaseShift(myEPWM2_BASE, 3);	
    HRPWM_setSyncOutPulseMode(myEPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);	
    EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, 10);	
    HRPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
    HRPWM_setupEPWMLinks(myEPWM2_BASE, EPWM_LINK_WITH_EPWM_1, EPWM_LINK_COMP_A);	
    EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, 10);	
    HRPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
    EPWM_setupEPWMLinks(myEPWM2_BASE, EPWM_LINK_WITH_EPWM_1, EPWM_LINK_COMP_B);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    HRPWM_setRisingEdgeDelayCountShadowLoadMode(myEPWM2_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);	
    HRPWM_disableRisingEdgeDelayCountShadowLoadMode(myEPWM2_BASE);	
    HRPWM_setFallingEdgeDeadBandDelayInput(myEPWM2_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);	
    HRPWM_disableFallingEdgeDelayCountShadowLoadMode(myEPWM2_BASE);	
    HRPWM_enableInterrupt(myEPWM2_BASE);	
    HRPWM_setInterruptSource(myEPWM2_BASE, EPWM_INT_TBCTR_ZERO);	
    HRPWM_setInterruptEventCount(myEPWM2_BASE, 1);	
    HRPWM_enableAutoConversion(myEPWM2_BASE);	
    HRPWM_enablePhaseShiftLoad(myEPWM2_BASE);	
    HRPWM_setMEPEdgeSelect(myEPWM2_BASE, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
    HRPWM_setHiResCounterCompareValueOnly(myEPWM2_BASE, HRPWM_COUNTER_COMPARE_A, 128);	
    HRPWM_setCounterCompareShadowLoadEvent(myEPWM2_BASE, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
    HRPWM_setMEPEdgeSelect(myEPWM2_BASE, HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
    HRPWM_setHiResCounterCompareValueOnly(myEPWM2_BASE, HRPWM_COUNTER_COMPARE_B, 128);	
    HRPWM_setCounterCompareShadowLoadEvent(myEPWM2_BASE, HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
}

//*****************************************************************************
//
// INPUTXBAR Configurations
//
//*****************************************************************************
void INPUTXBAR_init(){
	myINPUTXBARINPUT0_init();
	myINPUTXBARINPUT1_init();
}

void myINPUTXBARINPUT0_init(){
	XBAR_setInputPin(myINPUTXBARINPUT0_INPUT, myINPUTXBARINPUT0_SOURCE);
}
void myINPUTXBARINPUT1_init(){
	XBAR_setInputPin(myINPUTXBARINPUT1_INPUT, myINPUTXBARINPUT1_SOURCE);
}

//*****************************************************************************
//
// SYNC Scheme Configurations
//
//*****************************************************************************
void SYNC_init(){
	SysCtl_setSyncOutputConfig(SYSCTL_SYNC_OUT_SRC_EPWM1SYNCOUT);
	//
	// For EPWM1, the sync input is: SYSCTL_SYNC_IN_SRC_EXTSYNCIN1
	//
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM7, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP1, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP6, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	//
	// SOCA
	//
	SysCtl_enableExtADCSOCSource(0);
	//
	// SOCB
	//
	SysCtl_enableExtADCSOCSource(0);
}

main.c:

//#############################################################################
//
// FILE:   epwm_ex3_synchronization.c
//
// TITLE:  ePWM Using The Synch Chain and Phase Shift.
//
//! \addtogroup driver_example_list
//! <h1>ePWM Synchronization</h1>
//!
//! This example configures ePWM1, ePWM2, ePWM3 and ePWM4 as follows
//!  - ePWM1 without phase shift as sync source
//!  - ePWM2 with phase shift of 300 TBCLKs
//!  - ePWM3 with phase shift of 600 TBCLKs
//!  - ePWM4 with phase shift of 900 TBCLKs
//!
//! \b External \b Connections \n
//! - GPIO0 EPWM1A
//! - GPIO1 EPWM1B
//! - GPIO2 EPWM2A
//! - GPIO3 EPWM2B
//! - GPIO4 EPWM3A
//! - GPIO5 EPWM3B
//! - GPIO6 EPWM4A
//! - GPIO7 EPWM4B
//!
//! \b Watch \b Variables \n
//! - None.
//
//#############################################################################
//
//
// $Copyright:
// Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"


__interrupt void epwm1ISR(void);
__interrupt void epwm2ISR(void);
//__interrupt void epwm3ISR(void);
//__interrupt void epwm4ISR(void);

//
// Main
//
void main(void)
{
    //
    // 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);


    // Disable sync(Freeze clock to PWM as well). GTBCLKSYNC is applicable
    // only for multiple core devices. Uncomment the below statement if
    // applicable.
    //
    // SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    //

    // Configure GPIO0/1 , GPIO2/3 and GPIO4/5 and GPIO6/7 as
    // ePWM1A/1B, ePWM2A/2B, ePWM3A/3B, ePWM4A/4B pins respectively
    // Configure EPWM Modules
    // 
    Board_init();

    HRPWM_setSyncPulseSource(myEPWM2_BASE, HRPWM_PWMSYNC_SOURCE_ZERO );

    //
    // 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;

    //
    // IDLE loop. Just sit and loop forever (optional):
    //
    for(;;)
    {

    }
}

//
// epwm1ISR - ePWM 1 ISR
//
__interrupt void epwm1ISR(void)
{
    //
    // Clear INT flag for this timer
    //
    EPWM_clearEventTriggerInterruptFlag(myEPWM1_BASE);

    //
    // Acknowledge interrupt group
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
}

//
// epwm2ISR - ePWM 2 ISR
//
__interrupt void epwm2ISR(void)
{
    //
    // Clear INT flag for this timer
    //
    EPWM_clearEventTriggerInterruptFlag(myEPWM2_BASE);

    //
    // Acknowledge interrupt group
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
}

////
//// epwm3ISR - ePWM 3 ISR
////
//__interrupt void epwm3ISR(void)
//{
//    //
//    // Clear INT flag for this timer
//    //
//    EPWM_clearEventTriggerInterruptFlag(myEPWM3_BASE);
//
//    //
//    // Acknowledge interrupt group
//    //
//    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
//}
//
////
//// epwm4ISR - ePWM 4 ISR
////
//__interrupt void epwm4ISR(void)
//{
//    //
//    // Clear INT flag for this timer
//    //
//    EPWM_clearEventTriggerInterruptFlag(myEPWM4_BASE);
//
//    //
//    // Acknowledge interrupt group
//    //
//    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
//}


  • Hi Jonathan,

    Please see the F28004x TRM section 18.15.1.5.4.1 High-Resolution Period Configuration which is helpful for if you are using HR period control. There is an outline of the configuration flow there as well as notes underneath that section which state the recommendation of not continually syncing when using HR period control. This should be avoided to obtain a stable HRPWM signal:

      

    Also, note that the phase shift mechanism functions by loading your TBPHS value to be the new counter whenever a sync event occurs (and the sync event can be configured by you). So when you disable phase shift load, you are effectively disabling phase shift because you are turning off the loading of TBPHS value to the counter. 

    Best Regards,

    Allison

  • Hi Jonathan, 

    I saw you clicked that this response did not answer your questions. Please let me know if you have follow-up questions or if there is still confusion here.

    Best Regards,

    Allison

  • Hi Allison,

    Thanks for your reply! The mentioned section 18.15.1.5.4.1 was very helpful in showing the limits of HR period control in combination with synchronization. I understand it to mean that I cannot synchronize the two PWMs in every period, but I assume that I can do a synchronization with a software pulse, e.g. after changing the period.

    I have tried to implement software pulse synchronization in a simple example with HR period control: ePWM1 is in free run emulation mode while ePWM2 stops during debugging. When I pause the program in debug mode and resume it after a short while, the two PWM signals are randomly shifted.
    Now, I would expect both signals to get synchronized again after one second, since I am generating a software pulse in the main loop every second. But unfortunately the signals do not get synchronized.

    So I am still doing it wrong somehow. If I disable the HR period control, the software pulse synchronization works fine.

    I would really appreciate it if you could take another look at my configuration. Just for your information: I did this basic example without the sfo-lib, but I think this should have no effect on the software sync.

    Cheers,
    Jonathan

    ----------------------

    sysconfig:

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "F28004x" --package "F28004x_100PZ" --part "F28004x_100PZ" --context "system" --product "C2000WARE@5.01.00.00"
     * @versions {"tool":"1.19.0+3426"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const epwm             = scripting.addModule("/driverlib/epwm.js", {}, false);
    const epwm1            = epwm.addInstance();
    const epwm2            = epwm.addInstance();
    const inputxbar        = scripting.addModule("/driverlib/inputxbar.js", {}, false);
    const inputxbar1       = inputxbar.addInstance();
    const inputxbar_input  = scripting.addModule("/driverlib/inputxbar_input.js");
    const inputxbar_input1 = inputxbar_input.addInstance();
    const inputxbar_input2 = inputxbar_input.addInstance();
    const sync             = scripting.addModule("/driverlib/sync.js");
    
    /**
     * Write custom configuration values to the imported modules.
     */
    epwm1.$name                                                      = "myEPWM1";
    epwm1.epwmTimebase_hsClockDiv                                    = "EPWM_HSCLOCK_DIVIDER_1";
    epwm1.epwmEventTrigger_enableInterrupt                           = true;
    epwm1.epwmEventTrigger_interruptEventCount                       = "1";
    epwm1.epwmTimebase_period                                        = 20;
    epwm1.epwmCounterCompare_cmpA                                    = 10;
    epwm1.epwmTimebase_counterMode                                   = "EPWM_COUNTER_MODE_UP_DOWN";
    epwm1.epwmCounterCompare_cmpB                                    = 10;
    epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_UP_CMPA   = "EPWM_AQ_OUTPUT_HIGH";
    epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_DOWN_CMPA = "EPWM_AQ_OUTPUT_LOW";
    epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_UP_CMPB   = "EPWM_AQ_OUTPUT_HIGH";
    epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_DOWN_CMPB = "EPWM_AQ_OUTPUT_LOW";
    epwm1.epwmCounterCompare_shadowLoadModeCMPA                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm1.epwmCounterCompare_shadowLoadModeCMPB                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm1.hrpwm_HRLoadA                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm1.hrpwm_HRLoadB                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm1.hrpwm_cmpbHR                                               = 128;
    epwm1.hrpwm_cmpaHR                                               = 128;
    epwm1.epwmActionQualifier_continousSwForceReloadMode             = "EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm1.hrpwm_edgeModeA                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
    epwm1.hrpwm_edgeModeB                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
    epwm1.epwmTimebase_emulationMode                                 = "EPWM_EMULATION_FREE_RUN";
    epwm1.epwmTimebase_counterModeAfterSync                          = "EPWM_COUNT_MODE_UP_AFTER_SYNC";
    epwm1.epwmTimebase_syncOutPulseMode                              = "EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN";
    epwm1.epwmTimebase_phaseEnable                                   = true;
    epwm1.epwmTimebase_phaseShift                                    = 3;
    epwm1.epwmTimebase_periodLoadEvent                               = "EPWM_SHADOW_LOAD_MODE_COUNTER_SYNC";
    epwm1.hrpwm_enable                                               = true;
    epwm1.hrpwm_periodEnable                                         = true;
    epwm1.hrpwm_autoConv                                             = true;
    epwm1.epwm.$assign                                               = "EPWM1";
    
    epwm2.epwmEventTrigger_interruptSource                           = "EPWM_INT_TBCTR_ZERO";
    epwm2.epwmTimebase_hsClockDiv                                    = "EPWM_HSCLOCK_DIVIDER_1";
    epwm2.epwmEventTrigger_enableInterrupt                           = true;
    epwm2.epwmEventTrigger_interruptEventCount                       = "1";
    epwm2.$name                                                      = "myEPWM2";
    epwm2.copyUse                                                    = true;
    epwm2.copyFrom                                                   = "myEPWM1";
    epwm2.epwmTimebase_period                                        = 20;
    epwm2.epwmCounterCompare_cmpA                                    = 10;
    epwm2.epwmTimebase_counterMode                                   = "EPWM_COUNTER_MODE_UP_DOWN";
    epwm2.epwmCounterCompare_cmpB                                    = 10;
    epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_UP_CMPA   = "EPWM_AQ_OUTPUT_HIGH";
    epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_DOWN_CMPA = "EPWM_AQ_OUTPUT_LOW";
    epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_UP_CMPB   = "EPWM_AQ_OUTPUT_HIGH";
    epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_DOWN_CMPB = "EPWM_AQ_OUTPUT_LOW";
    epwm2.hrpwm_edgeModeA                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
    epwm2.hrpwm_edgeModeB                                            = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
    epwm2.epwmCounterCompare_shadowLoadModeCMPB                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm2.epwmCounterCompare_shadowLoadModeCMPA                      = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm2.hrpwm_HRLoadA                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm2.hrpwm_HRLoadB                                              = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
    epwm2.hrpwm_cmpaHR                                               = 128;
    epwm2.hrpwm_cmpbHR                                               = 128;
    epwm2.hrpwm_phaseLoadEnable                                      = true;
    epwm2.epwmTimebase_periodLink                                    = "EPWM_LINK_WITH_EPWM_1";
    epwm2.epwmCounterCompare_cmpALink                                = "EPWM_LINK_WITH_EPWM_1";
    epwm2.epwmCounterCompare_cmpBLink                                = "EPWM_LINK_WITH_EPWM_1";
    epwm2.epwmTimebase_periodLoadEvent                               = "EPWM_SHADOW_LOAD_MODE_COUNTER_SYNC";
    epwm2.epwmTimebase_counterModeAfterSync                          = "EPWM_COUNT_MODE_UP_AFTER_SYNC";
    epwm2.epwmTimebase_phaseEnable                                   = true;
    epwm2.epwmTimebase_phaseShift                                    = 3;
    epwm2.epwmTimebase_syncOutPulseMode                              = "EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN";
    epwm2.hrpwm_enable                                               = true;
    epwm2.hrpwm_autoConv                                             = true;
    epwm2.hrpwm_periodEnable                                         = true;
    epwm2.epwmTimebase_counterValue                                  = 3;
    epwm2.epwm.$assign                                               = "EPWM2";
    
    inputxbar1.$name = "myINPUTXBAR5";
    
    inputxbar_input1.$name          = "myINPUTXBARINPUT0";
    inputxbar_input1.inputxbarInput = "XBAR_INPUT5";
    inputxbar_input1.inputxbarGpio  = "GPIO56";
    
    inputxbar_input2.$name          = "myINPUTXBARINPUT1";
    inputxbar_input2.inputxbarInput = "XBAR_INPUT6";
    inputxbar_input2.inputxbarGpio  = "GPIO56";
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    epwm1.epwm.epwm_aPin.$suggestSolution = "GPIO0";
    epwm1.epwm.epwm_bPin.$suggestSolution = "GPIO1";
    epwm2.epwm.epwm_aPin.$suggestSolution = "GPIO2";
    epwm2.epwm.epwm_bPin.$suggestSolution = "GPIO3";
    

    auto generated board.c:

    /*
     * Copyright (c) 2020 Texas Instruments Incorporated - http://www.ti.com
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    
    #include "board.h"
    
    //*****************************************************************************
    //
    // Board Configurations
    // Initializes the rest of the modules. 
    // Call this function in your application if you wish to do all module 
    // initialization.
    // If you wish to not use some of the initializations, instead of the 
    // Board_init use the individual Module_inits
    //
    //*****************************************************************************
    void Board_init()
    {
    	EALLOW;
    
    	PinMux_init();
    	INPUTXBAR_init();
    	SYNC_init();
    	EPWM_init();
    
    	EDIS;
    }
    
    //*****************************************************************************
    //
    // PINMUX Configurations
    //
    //*****************************************************************************
    void PinMux_init()
    {
    	//
    	// PinMux for modules assigned to CPU1
    	//
    	
    	//
    	// EPWM1 -> myEPWM1 Pinmux
    	//
    	GPIO_setPinConfig(myEPWM1_EPWMA_PIN_CONFIG);
    	GPIO_setPadConfig(myEPWM1_EPWMA_GPIO, GPIO_PIN_TYPE_STD);
    	GPIO_setQualificationMode(myEPWM1_EPWMA_GPIO, GPIO_QUAL_SYNC);
    
    	GPIO_setPinConfig(myEPWM1_EPWMB_PIN_CONFIG);
    	GPIO_setPadConfig(myEPWM1_EPWMB_GPIO, GPIO_PIN_TYPE_STD);
    	GPIO_setQualificationMode(myEPWM1_EPWMB_GPIO, GPIO_QUAL_SYNC);
    
    	//
    	// EPWM2 -> myEPWM2 Pinmux
    	//
    	GPIO_setPinConfig(myEPWM2_EPWMA_PIN_CONFIG);
    	GPIO_setPadConfig(myEPWM2_EPWMA_GPIO, GPIO_PIN_TYPE_STD);
    	GPIO_setQualificationMode(myEPWM2_EPWMA_GPIO, GPIO_QUAL_SYNC);
    
    	GPIO_setPinConfig(myEPWM2_EPWMB_PIN_CONFIG);
    	GPIO_setPadConfig(myEPWM2_EPWMB_GPIO, GPIO_PIN_TYPE_STD);
    	GPIO_setQualificationMode(myEPWM2_EPWMB_GPIO, GPIO_QUAL_SYNC);
    
    
    }
    
    //*****************************************************************************
    //
    // EPWM Configurations
    //
    //*****************************************************************************
    void EPWM_init(){
        HRPWM_setEmulationMode(myEPWM1_BASE, EPWM_EMULATION_FREE_RUN);	
        HRPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);	
        HRPWM_selectPeriodLoadEvent(myEPWM1_BASE, EPWM_SHADOW_LOAD_MODE_COUNTER_SYNC);	
        EPWM_setTimeBasePeriod(myEPWM1_BASE, 20);	
        HRPWM_setTimeBaseCounter(myEPWM1_BASE, 0);	
        HRPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);	
        HRPWM_setCountModeAfterSync(myEPWM1_BASE, EPWM_COUNT_MODE_UP_AFTER_SYNC);	
        HRPWM_enablePhaseShiftLoad(myEPWM1_BASE);	
        HRPWM_setPhaseShift(myEPWM1_BASE, 3);	
        HRPWM_setSyncOutPulseMode(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);	
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, 10);	
        HRPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, 10);	
        HRPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
        HRPWM_setActionQualifierContSWForceShadowMode(myEPWM1_BASE, EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO_PERIOD);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
        HRPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
        HRPWM_setRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);	
        HRPWM_disableRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);	
        HRPWM_setFallingEdgeDeadBandDelayInput(myEPWM1_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);	
        HRPWM_disableFallingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);	
        HRPWM_enableInterrupt(myEPWM1_BASE);	
        HRPWM_setInterruptEventCount(myEPWM1_BASE, 1);	
        HRPWM_enableAutoConversion(myEPWM1_BASE);	
        HRPWM_setMEPEdgeSelect(myEPWM1_BASE, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
        HRPWM_setHiResCounterCompareValueOnly(myEPWM1_BASE, HRPWM_COUNTER_COMPARE_A, 128);	
        HRPWM_setCounterCompareShadowLoadEvent(myEPWM1_BASE, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
        HRPWM_setMEPEdgeSelect(myEPWM1_BASE, HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
        HRPWM_setHiResCounterCompareValueOnly(myEPWM1_BASE, HRPWM_COUNTER_COMPARE_B, 128);	
        HRPWM_setCounterCompareShadowLoadEvent(myEPWM1_BASE, HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
        HRPWM_enablePeriodControl(myEPWM1_BASE);	
        HRPWM_setClockPrescaler(myEPWM2_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);	
        HRPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_COUNTER_SYNC);	
        EPWM_setTimeBasePeriod(myEPWM2_BASE, 20);	
        HRPWM_setupEPWMLinks(myEPWM2_BASE, EPWM_LINK_WITH_EPWM_1, EPWM_LINK_TBPRD);	
        HRPWM_setTimeBaseCounter(myEPWM2_BASE, 3);	
        HRPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP_DOWN);	
        HRPWM_setCountModeAfterSync(myEPWM2_BASE, EPWM_COUNT_MODE_UP_AFTER_SYNC);	
        HRPWM_enablePhaseShiftLoad(myEPWM2_BASE);	
        HRPWM_setPhaseShift(myEPWM2_BASE, 3);	
        HRPWM_setSyncOutPulseMode(myEPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);	
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, 10);	
        HRPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
        HRPWM_setupEPWMLinks(myEPWM2_BASE, EPWM_LINK_WITH_EPWM_1, EPWM_LINK_COMP_A);	
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, 10);	
        HRPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);	
        EPWM_setupEPWMLinks(myEPWM2_BASE, EPWM_LINK_WITH_EPWM_1, EPWM_LINK_COMP_B);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
        HRPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
        HRPWM_setRisingEdgeDelayCountShadowLoadMode(myEPWM2_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);	
        HRPWM_disableRisingEdgeDelayCountShadowLoadMode(myEPWM2_BASE);	
        HRPWM_setFallingEdgeDeadBandDelayInput(myEPWM2_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);	
        HRPWM_disableFallingEdgeDelayCountShadowLoadMode(myEPWM2_BASE);	
        HRPWM_enableInterrupt(myEPWM2_BASE);	
        HRPWM_setInterruptSource(myEPWM2_BASE, EPWM_INT_TBCTR_ZERO);	
        HRPWM_setInterruptEventCount(myEPWM2_BASE, 1);	
        HRPWM_enableAutoConversion(myEPWM2_BASE);	
        HRPWM_enablePhaseShiftLoad(myEPWM2_BASE);	
        HRPWM_setMEPEdgeSelect(myEPWM2_BASE, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
        HRPWM_setHiResCounterCompareValueOnly(myEPWM2_BASE, HRPWM_COUNTER_COMPARE_A, 128);	
        HRPWM_setCounterCompareShadowLoadEvent(myEPWM2_BASE, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
        HRPWM_setMEPEdgeSelect(myEPWM2_BASE, HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);	
        HRPWM_setHiResCounterCompareValueOnly(myEPWM2_BASE, HRPWM_COUNTER_COMPARE_B, 128);	
        HRPWM_setCounterCompareShadowLoadEvent(myEPWM2_BASE, HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);	
        HRPWM_enablePeriodControl(myEPWM2_BASE);	
    }
    
    //*****************************************************************************
    //
    // INPUTXBAR Configurations
    //
    //*****************************************************************************
    void INPUTXBAR_init(){
    	myINPUTXBARINPUT0_init();
    	myINPUTXBARINPUT1_init();
    }
    
    void myINPUTXBARINPUT0_init(){
    	XBAR_setInputPin(myINPUTXBARINPUT0_INPUT, myINPUTXBARINPUT0_SOURCE);
    }
    void myINPUTXBARINPUT1_init(){
    	XBAR_setInputPin(myINPUTXBARINPUT1_INPUT, myINPUTXBARINPUT1_SOURCE);
    }
    
    //*****************************************************************************
    //
    // SYNC Scheme Configurations
    //
    //*****************************************************************************
    void SYNC_init(){
    	SysCtl_setSyncOutputConfig(SYSCTL_SYNC_OUT_SRC_EPWM1SYNCOUT);
    	//
    	// For EPWM1, the sync input is: SYSCTL_SYNC_IN_SRC_EXTSYNCIN1
    	//
    	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
    	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM7, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
    	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP1, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
    	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
    	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP6, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
    	//
    	// SOCA
    	//
    	SysCtl_enableExtADCSOCSource(0);
    	//
    	// SOCB
    	//
    	SysCtl_enableExtADCSOCSource(0);
    }
    

    main.c:

    //#############################################################################
    //
    // FILE:   epwm_ex3_synchronization.c
    //
    // TITLE:  ePWM Using The Synch Chain and Phase Shift.
    //
    //! \addtogroup driver_example_list
    //! <h1>ePWM Synchronization</h1>
    //!
    //! This example configures ePWM1, ePWM2, ePWM3 and ePWM4 as follows
    //!  - ePWM1 without phase shift as sync source
    //!  - ePWM2 with phase shift of 300 TBCLKs
    //!  - ePWM3 with phase shift of 600 TBCLKs
    //!  - ePWM4 with phase shift of 900 TBCLKs
    //!
    //! \b External \b Connections \n
    //! - GPIO0 EPWM1A
    //! - GPIO1 EPWM1B
    //! - GPIO2 EPWM2A
    //! - GPIO3 EPWM2B
    //! - GPIO4 EPWM3A
    //! - GPIO5 EPWM3B
    //! - GPIO6 EPWM4A
    //! - GPIO7 EPWM4B
    //!
    //! \b Watch \b Variables \n
    //! - None.
    //
    //#############################################################################
    //
    //
    // $Copyright:
    // Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    
    
    __interrupt void epwm1ISR(void);
    __interrupt void epwm2ISR(void);
    //__interrupt void epwm3ISR(void);
    //__interrupt void epwm4ISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // 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);
    
    
        // Disable sync(Freeze clock to PWM as well). GTBCLKSYNC is applicable
        // only for multiple core devices. Uncomment the below statement if
        // applicable.
        //
        // SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        //
    
        // Configure GPIO0/1 , GPIO2/3 and GPIO4/5 and GPIO6/7 as
        // ePWM1A/1B, ePWM2A/2B, ePWM3A/3B, ePWM4A/4B pins respectively
        // Configure EPWM Modules
        // 
        Board_init();
    
    //    HRPWM_setSyncPulseSource(myEPWM2_BASE, HRPWM_PWMSYNC_SOURCE_ZERO );
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        //
        // Enable ePWM interrupts
        //
     //   Interrupt_enable(INT_EPWM1);
     //   Interrupt_enable(INT_EPWM2);
    
    
    
        //
        // IDLE loop. Just sit and loop forever (optional):
        //
        for(;;)
        {
            DEVICE_DELAY_US(1000000);
            EPWM_forceSyncPulse(myEPWM1_BASE);
        }
    }
    
    //
    // epwm1ISR - ePWM 1 ISR
    //
    __interrupt void epwm1ISR(void)
    {
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM1_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm2ISR - ePWM 2 ISR
    //
    __interrupt void epwm2ISR(void)
    {
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM2_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }

  • Hi Jonathan, 

    This was also discussed and answered in another thread (see the link for other context on this thread):

    "HRPWM synchronization requires a very specific process. So you definitely don't want to send a SYNCO from the parent EPWM to the child EPWM on EVERY CTR=ZERO or CTR=PRD event. What you want to do is do ONE SWSYNC pulse at the time of initialization. In doing so ONLY the first cycle of your two in phase EPWM may have a jitter but for the rest of the cycles there won't be jitter.

    IF you need to resync with a new PHASE SHIFT, you will set the new phase shift value, and then ONLY ONCE you SEND a SWSYNC. Again, on the first cycle of the new phase shift you may have jitter, but on all following cycles, you should be good, without jitter and with the new PHASE."

    In terms of your case, the synchronization should still work but as mentioned in the answer above. Have you also already been able to get a non-HR phase shift to work properly? There are examples (such as EPWM driverlib example 3) in the C2000ware SDK that you can try out to reference. Let me know if you are able to do so and compare PWM settings. 

    Best Regards,

    Allison

  • Hi Allison,

    Actually, the code I sent you above was based on the C2000ware example. So I was able to get a non-HR PWM to work properly with a given phase shift.
    And finally I also found the problem when using HRPWM: The "Phase Shift Value" I enter in the syscfg GUI (highlighted in red in the screenshot) is not processed when HRPWM is active. So the entered value is not passed to TBPHS within the auto-generated code. The sysconfig GUI is misleading in this case.

    I solved this problem by using the following driverlib function instead of sysconfig.

    void HRPWM_setPhaseShift(uint32_t base, uint32_t phaseCount)

    Thanks for your support.

    Best regards,
    Jonathan Kipp