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.

LAUNCHXL-F28379D: clock frequency of ePWM module

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: C2000WARE

Hi Team,

Can you please help with the inquiry below?

I was trying to generate PWM signals using the ePWM module in the launchpad using the example code in C2000ware. I was able to generate the PWM signals however the frequency of the PWM comes out to be the half of what I calculated, I have already searched the E2E forum and could not find a satisfactory solution. I have checked the code as well and I don't think I am missing anything but I'll still attach some screenshots of my code.
The TBPRD value I defined is 1500 so as to get a duty cycle of 50%, according to me the frequency should be 33.33 kHz but it is coming out to be 16.67 kHz.

Let me know if you need more information.

Regards,

Marvin

  • Hi Marvin,

    Which PWM C2000Ware are you referring to? There is EPWMCLK and TBCLK, what is your EPWMCLK? Does changing the dividers to all be 1 except the ClkCfgRegs.PERCLKDIVSEL[EPWMCLKDIV] = 2 solve your issue? Verify your SYSCLK frequency as well.  

    Best,

    Ryan Ma

  • Hi Ryan,

    Here is the screenshot for the complete clock diagram related to the PWM generation:

    Does changing the dividers to all be 1 except the ClkCfgRegs.PERCLKDIVSEL[EPWMCLKDIV] = 2 solve your issue? Verify your SYSCLK frequency as well.  

    The customer is not changing ClkCfgRegs.PERCLKDIVSEL[EPWMCLKDIV] as it is given in the datasheet that by default the EPWMCLKDIV prescalar is /2. 

    Let me know if you need more information.

    Regards,

    Marvin

  • Hi Marvin,

    Thank you for verifying the clock configurations. Could you screenshot me the TBPRD register within the CCS's register view.

    I am unable to replicate this issue with an imported ex2 epwm example project. Here is the code I used.

    //#############################################################################
    //
    // FILE:   epwm_ex2_updown_aq.c
    //
    // TITLE:  ePWM Action Qualifier Module - Using up/down count.
    //
    //! \addtogroup driver_example_list
    //! <h1> ePWM Up Down Count Action Qualifier</h1>
    //!
    //! This example configures ePWM1, ePWM2, ePWM3 to produce a 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/down count mode for this example.
    //!
    //! View the ePWM1A/B(GPIO0 & GPIO1), ePWM2A/B(GPIO2 &GPIO3)
    //! and ePWM3A/B(GPIO4 & GPIO5) waveforms on oscilloscope.
    //
    //#############################################################################
    //
    // $Release Date: $
    // $Copyright:
    // Copyright (C) 2013-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"
    
    //
    // Defines
    //
    #define EPWM1_TIMER_TBPRD  1500U
    #define EPWM1_MAX_CMPA     750U
    #define EPWM1_MIN_CMPA     750U
    #define EPWM1_MAX_CMPB     750U
    #define EPWM1_MIN_CMPB     750U
    
    #define EPWM2_TIMER_TBPRD  2000U
    #define EPWM2_MAX_CMPA     1950U
    #define EPWM2_MIN_CMPA       50U
    #define EPWM2_MAX_CMPB     1950U
    #define EPWM2_MIN_CMPB       50U
    
    #define EPWM3_TIMER_TBPRD  2000U
    #define EPWM3_MAX_CMPA      950U
    #define EPWM3_MIN_CMPA       50U
    #define EPWM3_MAX_CMPB     1950U
    #define EPWM3_MIN_CMPB     1050U
    
    #define EPWM_CMP_UP           1U
    #define EPWM_CMP_DOWN         0U
    
    //
    // Globals
    //
    typedef struct
    {
        uint32_t epwmModule;
        uint16_t epwmCompADirection;
        uint16_t epwmCompBDirection;
        uint16_t epwmTimerIntCount;
        uint16_t epwmMaxCompA;
        uint16_t epwmMinCompA;
        uint16_t epwmMaxCompB;
        uint16_t epwmMinCompB;
    }epwmInformation;
    
    //
    // Globals to hold the ePWM information used in this example
    //
    epwmInformation epwm1Info;
    epwmInformation epwm2Info;
    epwmInformation epwm3Info;
    
    //
    // Function Prototypes
    //
    void initEPWM1(void);
    void initEPWM2(void);
    void initEPWM3(void);
    __interrupt void epwm1ISR(void);
    __interrupt void epwm2ISR(void);
    __interrupt void epwm3ISR(void);
    void updateCompare(epwmInformation *epwmInfo);
    
    //
    // 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);
    
        //
        // Configure GPIO0/1 , GPIO2/3 and GPIO4/5 as ePWM1A/1B, ePWM2A/2B and
        // ePWM3A/3B pins respectively
        //
        Board_init();
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initEPWM1();
        initEPWM2();
        initEPWM3();
    
        //
        // 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);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // IDLE loop. Just sit and loop forever (optional):
        //
        for(;;)
        {
            NOP;
        }
    }
    
    //
    // epwm1ISR - ePWM 1 ISR
    //
    __interrupt void epwm1ISR(void)
    {
        //
        // Update the CMPA and CMPB values
        //
    //    updateCompare(&epwm1Info);
    
        //
        // 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)
    {
        //
        // Update the CMPA and CMPB values
        //
    //    updateCompare(&epwm2Info);
    
        //
        // 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)
    {
        //
        // Update the CMPA and CMPB values
        //
    //    updateCompare(&epwm3Info);
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM3_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // initEPWM1 - Configure ePWM1
    //
    void initEPWM1()
    {
        //
        // Set-up TBCLK
        //
        EPWM_setTimeBasePeriod(myEPWM1_BASE, EPWM1_TIMER_TBPRD);
        EPWM_setPhaseShift(myEPWM1_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM1_BASE, 0U);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM1_BASE,
                                    EPWM_COUNTER_COMPARE_A,
                                    EPWM1_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM1_BASE,
                                    EPWM_COUNTER_COMPARE_B,
                                    EPWM1_MAX_CMPB);
    
        //
        // Set up counter mode
        //
        EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
        EPWM_setClockPrescaler(myEPWM1_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set up shadowing
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set actions
        //
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
        //
        // Interrupt where we will change the Compare Values
        // Select INT on Time base counter zero event,
        // Enable INT, generate INT on 3rd event
        //
        EPWM_setInterruptSource(myEPWM1_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM1_BASE);
        EPWM_setInterruptEventCount(myEPWM1_BASE, 3U);
    
        //
        // Information this example uses to keep track of the direction the
        // CMPA/CMPB values are moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm1Info.epwmCompADirection = EPWM_CMP_UP;
        epwm1Info.epwmCompBDirection = EPWM_CMP_DOWN;
        epwm1Info.epwmTimerIntCount = 0U;
        epwm1Info.epwmModule = myEPWM1_BASE;
        epwm1Info.epwmMaxCompA = EPWM1_MAX_CMPA;
        epwm1Info.epwmMinCompA = EPWM1_MIN_CMPA;
        epwm1Info.epwmMaxCompB = EPWM1_MAX_CMPB;
        epwm1Info.epwmMinCompB = EPWM1_MIN_CMPB;
    }
    
    //
    // initEPWM2 - Configure ePWM2
    //
    void initEPWM2()
    {
        //
        // Set-up TBCLK
        //
        EPWM_setTimeBasePeriod(myEPWM2_BASE, EPWM2_TIMER_TBPRD);
        EPWM_setPhaseShift(myEPWM2_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM2_BASE, 0U);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM2_BASE,
                                    EPWM_COUNTER_COMPARE_A,
                                    EPWM2_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM2_BASE,
                                    EPWM_COUNTER_COMPARE_B,
                                    EPWM2_MIN_CMPB);
    
        //
        // Set-up counter mode
        //
        EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_disablePhaseShiftLoad(myEPWM2_BASE);
        EPWM_setClockPrescaler(myEPWM2_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set-up shadowing
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Action qualifier
        //
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    
        //
        // Interrupt where we will change the Compare Values
        // Select INT on Time base counter zero event,
        // Enable INT, generate INT on 3rd event
        //
        EPWM_setInterruptSource(myEPWM2_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM2_BASE);
        EPWM_setInterruptEventCount(myEPWM2_BASE, 3U);
    
        //
        // Information this example uses to keep track of the direction the
        // CMPA/CMPB values are moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm2Info.epwmCompADirection = EPWM_CMP_UP;
        epwm2Info.epwmCompBDirection = EPWM_CMP_UP;
        epwm2Info.epwmTimerIntCount = 0U;
        epwm2Info.epwmModule = myEPWM2_BASE;
        epwm2Info.epwmMaxCompA = EPWM2_MAX_CMPA;
        epwm2Info.epwmMinCompA = EPWM2_MIN_CMPA;
        epwm2Info.epwmMaxCompB = EPWM2_MAX_CMPB;
        epwm2Info.epwmMinCompB = EPWM2_MIN_CMPB;
    }
    
    //
    // initEPWM3 - Configure ePWM3
    //
    void initEPWM3(void)
    {
        //
        // Set-up TBCLK
        //
        EPWM_setTimeBaseCounterMode(myEPWM3_BASE, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_setTimeBasePeriod(myEPWM3_BASE, EPWM3_TIMER_TBPRD);
        EPWM_disablePhaseShiftLoad(myEPWM3_BASE);
        EPWM_setPhaseShift(myEPWM3_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM3_BASE, 0U);
        EPWM_setClockPrescaler(myEPWM3_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set up shadowing
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM3_BASE,
                                    EPWM_COUNTER_COMPARE_A,
                                    EPWM3_MIN_CMPA);
    
        EPWM_setCounterCompareValue(myEPWM3_BASE,
                                    EPWM_COUNTER_COMPARE_B,
                                    EPWM3_MAX_CMPB);
    
        //
        // Set actions
        //
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        //
        // Interrupt where we will change the Compare Values
        // Select INT on Time base counter zero event,
        // Enable INT, generate INT on 3rd event
        //
        EPWM_setInterruptSource(myEPWM3_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM3_BASE);
        EPWM_setInterruptEventCount(myEPWM3_BASE, 3U);
    
        //
        // Information this example uses to keep track of the direction the
        // CMPA/CMPB values are moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
        epwm3Info.epwmCompADirection = EPWM_CMP_UP;
        epwm3Info.epwmCompBDirection = EPWM_CMP_DOWN;
        epwm3Info.epwmTimerIntCount = 0U;
        epwm3Info.epwmModule = myEPWM3_BASE;
        epwm3Info.epwmMaxCompA = EPWM3_MAX_CMPA;
        epwm3Info.epwmMinCompA = EPWM3_MIN_CMPA;
        epwm3Info.epwmMaxCompB = EPWM3_MAX_CMPB;
        epwm3Info.epwmMinCompB = EPWM3_MIN_CMPB;
    }
    
    //
    // updateCompare - Function to update the frequency
    //
    void updateCompare(epwmInformation *epwmInfo)
    {
        uint16_t compAValue;
        uint16_t compBValue;
    
        compAValue = EPWM_getCounterCompareValue(epwmInfo->epwmModule,
                                                 EPWM_COUNTER_COMPARE_A);
    
        compBValue = EPWM_getCounterCompareValue(epwmInfo->epwmModule,
                                                 EPWM_COUNTER_COMPARE_B);
    
        //
        //  Change the CMPA/CMPB values every 10th interrupt.
        //
        if(epwmInfo->epwmTimerIntCount == 10U)
        {
            epwmInfo->epwmTimerIntCount = 0U;
    
            //
            // If we were increasing CMPA, check to see if we reached the max
            // value. If not, increase CMPA else, change directions and decrease
            // CMPA
            //
            if(epwmInfo->epwmCompADirection == EPWM_CMP_UP)
            {
                if(compAValue < (epwmInfo->epwmMaxCompA))
                {
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_A,
                                                ++compAValue);
                }
                else
                {
                    epwmInfo->epwmCompADirection = EPWM_CMP_DOWN;
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_A,
                                                --compAValue);
                }
            }
            //
            // If we were decreasing CMPA, check to see if we reached the min
            // value. If not, decrease CMPA else, change directions and increase
            // CMPA
            //
            else
            {
                if( compAValue == (epwmInfo->epwmMinCompA))
                {
                    epwmInfo->epwmCompADirection = EPWM_CMP_UP;
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_A,
                                                ++compAValue);
                }
                else
                {
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_A,
                                                --compAValue);
                }
            }
    
            //
            // If we were increasing CMPB, check to see if we reached the max
            // value. If not, increase CMPB else, change directions and decrease
            // CMPB
            //
            if(epwmInfo->epwmCompBDirection == EPWM_CMP_UP)
            {
                if(compBValue < (epwmInfo->epwmMaxCompB))
                {
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_B,
                                                ++compBValue);
                }
                else
                {
                    epwmInfo->epwmCompBDirection = EPWM_CMP_DOWN;
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_B,
                                                --compBValue);
                }
            }
            //
            // If we were decreasing CMPB, check to see if we reached the min
            // value. If not, decrease CMPB else, change directions and increase
            // CMPB
            //
            else
            {
                if(compBValue == (epwmInfo->epwmMinCompB))
                {
                    epwmInfo->epwmCompBDirection = EPWM_CMP_UP;
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_B,
                                                ++compBValue);
                }
                else
                {
                    EPWM_setCounterCompareValue(epwmInfo->epwmModule,
                                                EPWM_COUNTER_COMPARE_B,
                                                --compBValue);
                }
            }
        }
        else
        {
            epwmInfo->epwmTimerIntCount++;
        }
    }
    

  • Hi Ryan,

    Thank you. Please refer to the response below:

    In the screenshots, I have defined a macro EPWM1_TIMER_TBPRD as 1500U hence to make the duty cycle 50%, and according to the formula, the frequency should be( I am using up-down counter) -- frequency of TBCLK/(2* TBPRD)= 100 MHz/(3000)=33.34 KHz. But on looking at the oscilloscope it is coming out to be 16.67 KHz.

    The customer project file is also attached for further reference

    dsp_tms320f28379d_pwm_generation-master (1).zip

    Let me know if you need more information

    Regards,

    Marvin

  • Hi Marvin, 

    Your calculations are correct, let me see if I can replicate this issue. 

    Update: I copied the customer's configurations and still am unable to reproduce this issue. Here are my scope shots. I would again verify that you're expected clock is running at TBCLK = 100Mhz. 

    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    
    //
    // Defines
    //
    #define EPWM1_TIMER_TBPRD  1500U
    
    
    #define EPWM2_TIMER_TBPRD  1500U
    
    
    #define EPWM3_TIMER_TBPRD  1500U
    
    
    #define EPWM_CMP_UP           1U
    #define EPWM_CMP_DOWN         0U
    
    //
    // Globals
    //
    
    void initEPWM1(void);
    void initEPWM2(void);
    void initEPWM3(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();
    
    
        //
        // Configure GPIO0/1 , GPIO2/3 and GPIO4/5 as ePWM1A/1B, ePWM2A/2B and
        // ePWM3A/3B pins respectively
        //
        Board_init();
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initEPWM1();
        initEPWM2();
        initEPWM3();
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // IDLE loop. Just sit and loop forever (optional):
        //
        for(;;)
        {
            NOP;
        }
    }
    
    
    //
    // initEPWM1 - Configure ePWM1
    //
    void initEPWM1()
    {
        //
        // Set-up TBCLK
        //
        EPWM_setTimeBasePeriod(myEPWM1_BASE, EPWM1_TIMER_TBPRD);
        EPWM_setPhaseShift(myEPWM1_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM1_BASE, 0U);
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM1_BASE,
                                    EPWM_COUNTER_COMPARE_A,
                                    750);
        EPWM_setCounterCompareValue(myEPWM1_BASE,
                                    EPWM_COUNTER_COMPARE_B,
                                    750);
    
        //
        // Set up counter mode
        //
        EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
        EPWM_setClockPrescaler(myEPWM1_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set up shadowing
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set actions
        //
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_TOGGLE,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
    }
    
    //
    // initEPWM2 - Configure ePWM2
    //
    void initEPWM2()
    {
        //
        // Set-up TBCLK
        //
        EPWM_setTimeBasePeriod(myEPWM2_BASE, EPWM2_TIMER_TBPRD);
        EPWM_setPhaseShift(myEPWM2_BASE, EPWM2_TIMER_TBPRD/6);
        EPWM_setTimeBaseCounter(myEPWM2_BASE, 0U);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM2_BASE,
                                    EPWM_COUNTER_COMPARE_A,
                                    750);
        EPWM_setCounterCompareValue(myEPWM2_BASE,
                                    EPWM_COUNTER_COMPARE_B,
                                    750);
    
        //
        // Set-up counter mode
        //
        EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_enablePhaseShiftLoad(myEPWM2_BASE);
        EPWM_setClockPrescaler(myEPWM2_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set-up shadowing
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Action qualifier
        //
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    
    }
    //
    // initEPWM3 - Configure ePWM3
    //
    void initEPWM3(void)
    {
        //
           // Set-up TBCLK
           //
           EPWM_setTimeBasePeriod(myEPWM3_BASE, EPWM2_TIMER_TBPRD);
           EPWM_setPhaseShift(myEPWM3_BASE, EPWM2_TIMER_TBPRD/1.2);
           EPWM_setTimeBaseCounter(myEPWM3_BASE, 0U);
    
           //
           // Set Compare values
           //
           EPWM_setCounterCompareValue(myEPWM3_BASE,
                                       EPWM_COUNTER_COMPARE_A,
                                       750);
           EPWM_setCounterCompareValue(myEPWM3_BASE,
                                       EPWM_COUNTER_COMPARE_B,
                                       750);
    
           //
           // Set-up counter mode
           //
           EPWM_setTimeBaseCounterMode(myEPWM3_BASE, EPWM_COUNTER_MODE_UP_DOWN);
           EPWM_enablePhaseShiftLoad(myEPWM3_BASE);
           EPWM_setClockPrescaler(myEPWM3_BASE,
                                  EPWM_CLOCK_DIVIDER_1,
                                  EPWM_HSCLOCK_DIVIDER_1);
    
           //
           // Set-up shadowing
           //
           EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                                EPWM_COUNTER_COMPARE_A,
                                                EPWM_COMP_LOAD_ON_CNTR_ZERO);
           EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                                EPWM_COUNTER_COMPARE_B,
                                                EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
           //
           // Set Action qualifier
           //
           EPWM_setActionQualifierAction(myEPWM3_BASE,
                                         EPWM_AQ_OUTPUT_A,
                                         EPWM_AQ_OUTPUT_HIGH,
                                         EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
           EPWM_setActionQualifierAction(myEPWM3_BASE,
                                         EPWM_AQ_OUTPUT_A,
                                         EPWM_AQ_OUTPUT_LOW,
                                         EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
           EPWM_setActionQualifierAction(myEPWM3_BASE,
                                         EPWM_AQ_OUTPUT_B,
                                         EPWM_AQ_OUTPUT_LOW,
                                         EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
           EPWM_setActionQualifierAction(myEPWM3_BASE,
                                         EPWM_AQ_OUTPUT_B,
                                         EPWM_AQ_OUTPUT_HIGH,
                                         EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    
    }
    

    Best,

    Ryan Ma

  • Hi Ryan,

    The customer checked on another oscilloscope and the result is correct