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.
Tool/software:
Dear TI Experts,
I am encountering an issue while attempting to synchronize the output of two PWM channels using the TBCLKSYNC register.
Could you please provide clarification on why these pulses are missing?
FYI, kindly find the below snapshots of sysconfig and my modification to code.
SYSCONFIG :
EPWM1:
The above configuration is done for both ePWM1 and ePWM2 channels. and to synchronize these two channel outputs i have used below code.
Now im getting output pulses like as below
Pulse outputs ePWM1A and ePWM2A are in sync but you can observe that after some time pulse are missing at regular intervals.
Kindly clarify why these pluses are missing and what is the issue in my configurations?
Regards,
Meetkumar P. Parikh
Hi Meetkumar,
Are you updating any of the CMP / TBPRD values? Do you have phase enabled?
Are you setting the AQ outputs to some state?
Have you tried to run one of our examples?
Best,
Ryan Ma
Hi Ryan Ma,
No only im trying to sync the ePWM1 and ePWM2 by using simple below steps
1. TBCLKSYNC = 0
2. configure PWM
3. TBCLKSYNC = 1
If i try without above method then im getting exact PWM frequency but out of phase. but if i start to use above SYNC mechanism for TBCLKSYNC then its started missing pulse with regular intervals
As you can see in Snapshot AQ output is configured to changed when TBCTR value is equal to CMPA value.
No im not doing any RUN time change for the CMP/ TBPRD values
Hi Meet,
Can you share your syscfg and main code that is causing this issue?
Best,
Ryan Ma
Hi Ryan Ma,
Below is Sysconfig code for ePWM,
void EPWM_init(){
EPWM_setClockPrescaler(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBasePeriod(GP1_GP2_PWM_OBC_Leg_BASE, 356);
EPWM_setTimeBaseCounter(GP1_GP2_PWM_OBC_Leg_BASE, 0);
EPWM_setTimeBaseCounterMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_MODE_UP_DOWN);
EPWM_disablePhaseShiftLoad(GP1_GP2_PWM_OBC_Leg_BASE);
EPWM_setPhaseShift(GP1_GP2_PWM_OBC_Leg_BASE, 0);
EPWM_setSyncInPulseSource(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_SYNC_IN_PULSE_SRC_DISABLE);
EPWM_setCounterCompareValue(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_A, 178);
EPWM_setCounterCompareShadowLoadMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareValue(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_B, 0);
EPWM_setCounterCompareShadowLoadMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
EPWM_setDeadBandDelayPolarity(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
EPWM_setDeadBandDelayMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_DB_RED, true);
EPWM_setDeadBandDelayMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_DB_FED, true);
EPWM_setEmulationMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_EMULATION_FREE_RUN);
EPWM_setClockPrescaler(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBasePeriod(GP5_GP6_PWM_CMN_Leg_BASE, 356);
EPWM_setTimeBaseCounter(GP5_GP6_PWM_CMN_Leg_BASE, 0);
EPWM_setTimeBaseCounterMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_MODE_UP_DOWN);
EPWM_disablePhaseShiftLoad(GP5_GP6_PWM_CMN_Leg_BASE);
EPWM_setPhaseShift(GP5_GP6_PWM_CMN_Leg_BASE, 0);
EPWM_setSyncInPulseSource(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_SYNC_IN_PULSE_SRC_DISABLE);
EPWM_setCounterCompareValue(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_A, 178);
EPWM_setCounterCompareShadowLoadMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareValue(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_B, 0);
EPWM_setCounterCompareShadowLoadMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
EPWM_setDeadBandDelayPolarity(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
EPWM_setDeadBandDelayMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_DB_RED, true);
EPWM_setDeadBandDelayMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_DB_FED, true);
}
Additional code is highlighted below:
void Init_SysPeripheral(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();
//
// PinMux and Peripheral Initialization
//
// Disable the ePWM time base clock before configuring the module
EALLOW;
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // THIS LINE OF ADDITIONAL CODE IS CAUSING ISSUE
EDIS;
Board_init();
// Sync the ePWM time base clock
EALLOW;
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // THIS LINE OF ADDITIONAL CODE IS CAUSING ISSUE
EDIS;
//
// C2000Ware Library initialization
//
C2000Ware_libraries_init();
//
// Enable Global Interrupt (INTM) and real time interrupt (DBGM)
//
EINT;
ERTM;
}
Best Regards,
Meetkumar
Hi Meetkumar,
Apologize for the delay in response, I have not had a chance to test this on my side. I will get to this tomorrow and update you on my results.
Best,
Ryan MA
Hi Ryan Ma,
Sure!
FYI Notes :
1. The CPU clock frequency is 100Mhz.
2. C2000Ware version - C2000Ware_4_03_00_00
3. Use empty project with sysconfig if you try the same.
4. Please do the same configuration as shown in snapshot
Looking forward for your response soon!
Thanks & Regards,
Meetkumar P. Parikh
Hi Ryan Ma,
I have found out one observation here.
I have captured the graph for TBCTR value and found that its retaining constant value as you can see below.
because of that the output pulses is constantly high for certain period as CMPA is not equal to TBCTR value..... you can see in below image of PWM output
======================================================================================================
If i try with any ePWM example project given by TI and remove everything from that project, reconfigure the ePWM module then below is my observation during debugging.
1. TBCTR is incrementing and decrementing correctly
And the output PWM pulses are coming properly as expected.
So can you please clarify where is the issue here? why its not working with imported empty sysconfig project and working with ePWM sysconfig example project ?
Thanks & Regards,
Meetkumar P. Parikh
Hi Meet,
I am unable to reproduce the issue you're seeing.
Here is the exact .syscfg and main.c file I am running.
//########################################################################### // // FILE: epwm_ex13_up_aq.c // // TITLE: Action Qualifier Module - Using up count. // //! \addtogroup driver_example_list //! <h1> EPWM Action Qualifier (epwm_up_aq)</h1> //! //! This example configures ePWM1, ePWM2, ePWM3 to produce an //! waveform with independent modulation on EPWMxA and //! EPWMxB. //! //! The compare values CMPA and CMPB are modified within the ePWM's ISR. //! //! The TB counter is in up count mode for this example. //! //! View the EPWM1A/B(GPIO0 & GPIO1), EPWM2A/B(GPIO2 & GPIO3) //! and EPWM3A/B(GPIO4 & GPIO5) waveforms via an oscilloscope. //! // //########################################################################### // // // $Copyright: // Copyright (C) 2024 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" // // Function Prototypes // void EPWM_initGiven(); // // 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(); // // Disable sync(Freeze clock to PWM as well) // SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // Configure GPIO pins and EPWM Modules // Board_init(); EPWM_initGiven(); // // Enable sync and clock to PWM // SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // // IDLE loop. Just sit and loop forever (optional): // for(;;) { asm (" NOP"); } } void EPWM_initGiven(){ EPWM_setClockPrescaler(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); EPWM_setTimeBasePeriod(GP1_GP2_PWM_OBC_Leg_BASE, 356); EPWM_setTimeBaseCounter(GP1_GP2_PWM_OBC_Leg_BASE, 0); EPWM_setTimeBaseCounterMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_MODE_UP_DOWN); EPWM_disablePhaseShiftLoad(GP1_GP2_PWM_OBC_Leg_BASE); EPWM_setPhaseShift(GP1_GP2_PWM_OBC_Leg_BASE, 0); EPWM_setSyncInPulseSource(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_SYNC_IN_PULSE_SRC_DISABLE); EPWM_setCounterCompareValue(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_A, 178); EPWM_setCounterCompareShadowLoadMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareValue(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_B, 0); EPWM_setCounterCompareShadowLoadMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setDeadBandDelayPolarity(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); EPWM_setDeadBandDelayMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_DB_RED, true); EPWM_setDeadBandDelayMode(GP1_GP2_PWM_OBC_Leg_BASE, EPWM_DB_FED, true); EPWM_setEmulationMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_EMULATION_FREE_RUN); EPWM_setClockPrescaler(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); EPWM_setTimeBasePeriod(GP5_GP6_PWM_CMN_Leg_BASE, 356); EPWM_setTimeBaseCounter(GP5_GP6_PWM_CMN_Leg_BASE, 0); EPWM_setTimeBaseCounterMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_MODE_UP_DOWN); EPWM_disablePhaseShiftLoad(GP5_GP6_PWM_CMN_Leg_BASE); EPWM_setPhaseShift(GP5_GP6_PWM_CMN_Leg_BASE, 0); EPWM_setSyncInPulseSource(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_SYNC_IN_PULSE_SRC_DISABLE); EPWM_setCounterCompareValue(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_A, 178); EPWM_setCounterCompareShadowLoadMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareValue(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_B, 0); EPWM_setCounterCompareShadowLoadMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setDeadBandDelayPolarity(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); EPWM_setDeadBandDelayMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_DB_RED, true); EPWM_setDeadBandDelayMode(GP5_GP6_PWM_CMN_Leg_BASE, EPWM_DB_FED, true); } // // End of file //
/** * 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 "F280015x" --package "80PN" --part "F280015x_80PN" --context "system" --product "C2000WARE@5.03.00.00" * @versions {"tool":"1.20.0+3587"} */ /** * Import the modules used in this configuration. */ const epwm = scripting.addModule("/driverlib/epwm.js", {}, false); const epwm1 = epwm.addInstance(); const epwm2 = epwm.addInstance(); /** * Write custom configuration values to the imported modules. */ epwm1.$name = "GP1_GP2_PWM_OBC_Leg"; epwm1.epwm.$assign = "EPWM1"; epwm1.epwm.epwm_aPin.$assign = "GPIO0"; epwm1.epwm.epwm_bPin.$assign = "GPIO1"; epwm2.$name = "GP5_GP6_PWM_CMN_Leg"; epwm2.epwm.epwm_aPin.$assign = "GPIO2"; epwm2.epwm.epwm_bPin.$assign = "GPIO3"; /** * 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. */ epwm2.epwm.$suggestSolution = "EPWM2";
Best,
Ryan Ma
Hi Rayan Ma,
Thank you for your efforts in trying to reproduce the issue. However, I believe there may be some misunderstandings regarding the actual problem.
Could you confirm if you’ve thoroughly reviewed my previous replies? I suspect that some key details might have been overlooked.
Allow me to quote the relevant part of my earlier response that highlights the core issue:
If i try with any ePWM example project given by TI and remove everything from that project, reconfigure the ePWM module then below is my observation during debugging.
1. TBCTR is incrementing and decrementing correctly
And the output PWM pulses are coming properly as expected.
As you can see, I am able to achieve the correct output in this case, but not when using the "imported empty SysConfig project" from the following C2000Ware version:
C2000Ware_4_03_00_00
The issue occurs specifically with the imported empty SysConfig project in CCS.
Could you confirm if there’s any problem with the SysConfig script or something else that might be causing this below issue ? If you see the below captured Graph, you find out the exact issue with TBCTR counter, it's constant for certain period... Why is TBCTR is constant for certain period when TBCTR>CMPA?
I have found out one observation here.
I have captured the graph for TBCTR value and found that its retaining constant value as you can see below.
because of that the output pulses is constantly high for certain period as CMPA is not equal to TBCTR value..... you can see in below image of PWM output
Note 1: The problem is coming with imported empty sysconfig project!
Hope you have clear picture of my issue now! Kindly let me know if you have any confusion further!
Hopping that you thoroughly go through this reply and give resolution for this issue.
Regards,
Meetkumar
HI Meetkumar,
Please go through the debug process of seeing why the output pulses are being generated.
1. Confirm if TBCLKSYNC is being set after PWM initialization.
2. Confirm in the TBCTL register that you're in the correct count mode.
3. Confirm if TBPRD is loaded properly, and CMPA/CMPB are less than TBPRD.
4. Double check the AQCTLA / AQCTLB registers to see if you're seeing the expected output on the events.
This will generate you the correct waveform. Apologize , I cannot reproduce the issue that you're seeing.
Note 1: The problem is coming with imported empty sysconfig project!
This should not affect the PWM. The example code that we have that use sysconfig simply generate the driverlib functions required to generate the required waveform. The output you're showing seems to be something wrong with the PWM configurations after SysConfig. TBCLKSYNC will start the counts of the PWMs. However in the output you're seeing, looks like the initialization of the PWM is different than the sysoncig project one.
Hi Rayan Ma,
Could you please import the empty sysconfig project from the following path and follow the steps below? I’m very curious to observe the results with the empty project.
Import the project from:
C2000Ware_4_03_00_00\driverlib\f280015x\examples\empty_projects\CCS\empty_driverlib_project.projectspec"
Disable TBCLKSYNC.
Configure the two ePWM modules
Enable TBCLKSYNC
.
Observe and report the results.
I noticed in your previous response that you tried with the epwm_ex13_up_aq.c
example project, but I’m specifically interested in the outcomes from the empty project.
Note: I have tried in multiple different PCs with fresh configurations and the same problem is observed. so, I request you to try with empty project specifically.
Thank you,
Meetkumar P. Parikh
Hi Meetkumar,
Please walk through the debug steps I have outlined.
Like I have mentioned I am unable to reproduce the issue with an empty project. I followed the exact screenshots of your sysconfig configuration. SysConfig will generate the same code for either project.
I am using the latest C2000WARE. Can you try and install the latest C2000WARE to see if you still see the issue?
/** * Import the modules used in this configuration. */ const epwm = scripting.addModule("/driverlib/epwm.js", {}, false); const epwm1 = epwm.addInstance(); const epwm2 = epwm.addInstance(); /** * Write custom configuration values to the imported modules. */ epwm1.$name = "myEPWM0"; epwm1.epwmTimebase_emulationMode = "EPWM_EMULATION_FREE_RUN"; epwm1.epwmTimebase_hsClockDiv = "EPWM_HSCLOCK_DIVIDER_1"; epwm1.epwmTimebase_period = 356; epwm1.epwmTimebase_counterMode = "EPWM_COUNTER_MODE_UP_DOWN"; epwm1.epwmTimebase_syncInPulseSource = "EPWM_SYNC_IN_PULSE_SRC_DISABLE"; epwm1.epwmCounterCompare_cmpA = 36; epwm1.epwmCounterCompare_enableShadowLoadModeCMPA = false; 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.epwm.$assign = "EPWM1"; epwm1.epwm.epwm_aPin.$assign = "GPIO0"; epwm1.epwm.epwm_bPin.$assign = "GPIO1"; epwm2.$name = "myEPWM1"; epwm2.copyUse = true; epwm2.copyFrom = "myEPWM0"; epwm2.epwmTimebase_emulationMode = "EPWM_EMULATION_FREE_RUN"; epwm2.epwmTimebase_hsClockDiv = "EPWM_HSCLOCK_DIVIDER_1"; epwm2.epwmTimebase_period = 356; epwm2.epwmTimebase_counterMode = "EPWM_COUNTER_MODE_UP_DOWN"; epwm2.epwmTimebase_syncInPulseSource = "EPWM_SYNC_IN_PULSE_SRC_DISABLE"; epwm2.epwmCounterCompare_cmpA = 36; epwm2.epwmCounterCompare_enableShadowLoadModeCMPA = false; 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.epwm.$assign = "EPWM2"; epwm2.epwm.epwm_aPin.$assign = "GPIO2"; epwm2.epwm.epwm_bPin.$assign = "GPIO3";
//############################################################################# // // FILE: empty_driverlib_main.c // //! \addtogroup driver_example_list //! <h1>Empty Project Example</h1> //! //! This example is an empty project setup for Driverlib development. //! // //############################################################################# // // // $Copyright: // Copyright (C) 2024 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" #include "c2000ware_libraries.h" // // 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(); SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // PinMux and Peripheral Initialization // Board_init(); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // C2000Ware Library initialization // C2000Ware_libraries_init(); // // Enable Global Interrupt (INTM) and real time interrupt (DBGM) // EINT; ERTM; while(1) { } } // // End of File //
Best,
Ryan Ma
Hi Rayan Ma,
I have checked mentioned debug steps.
My implementation is inline with your debug steps as well.
1. Confirm if TBCLKSYNC is being set after PWM initialization. - Yes TBCLKSYNC is set after PWM config
2. Confirm in the TBCTL register that you're in the correct count mode. - its correct as you can see shared code in my previous response
3. Confirm if TBPRD is loaded properly, and CMPA/CMPB are less than TBPRD - TBPRD loaded properly and CMPA is less than TBPRD
4. Double check the AQCTLA / AQCTLB registers to see if you're seeing the expected output on the events. - Correctly configured
I have checked thoroughly this step before, let me try with latest C2000Ware.
May i know which C2000ware version are you using ?
Thank you for your support!
Thanks,
Meetkumar
Hi Ryan Ma,
Yes, its working with latest versions of C2000 ware 5.03.
Thanks & Regards,
Meetkumar P. Parikh