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