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