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.

TMS320F28376S: create complementary High resoultion PWM singlags

Part Number: TMS320F28376S
Other Parts Discussed in Thread: C2000WARE

Dear sir ,

1.We are developing Motor Controler based on C2000  28376S  , we need to  create Complementary PWMs singlas Per Phase (total of 3 phases)

2. each Phase will connect to PWM module (1,2,3) , signal A will be used for high side MOSFET  , signal B will be used for low side MOSFET  (the signlas are connected trough proper gate drivers )

3. PWMXA  and PWMXB should be complementary signals with proper dead time , which we able to successfully configure 

the issue we have is to make thhse signals as high resoultion PWM complementary signals 

my question , is it possible to achive such configuration (Complementary high resoultion PWM signals ) ?

below is snippet code for tyring to make high resoultion PWM signnals

EALLOW;

EPwmRegHandle->TBPRD = EPWM_TIMER_TBPRD; // Set timer period
EPwmRegHandle->TBCTL.bit.PHSEN =TB_ENABLE; // Enable phase loading

EPwmRegHandle->TBCTL.bit.PHSDIR = TB_UP; // count up after SYNC
EPwmRegHandle->TBCTL.bit.PRDLD = TB_SHADOW;
EPwmRegHandle->TBCTL2.bit.PRDLDSYNC = 0; //PRD on CTR=0 and SYNC
EPwmRegHandle->TBPHS.bit.TBPHS = 0; // Phase is always 0°
EPwmRegHandle->TBCTR = 0x0; // Clear counter
EPwmRegHandle->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count down
EPwmRegHandle->TBCTL.bit.HSPCLKDIV = TB_DIV1; // High Speed Clock ratio to SYSCLKOUT
EPwmRegHandle->TBCTL.bit.CLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwmRegHandle->TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Output sync is connected to input sync
EPwmRegHandle->CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Use shadow mode
EPwmRegHandle->CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Use shadow mode

EPwmRegHandle->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // Load registers every ZERO or PERIOD
EPwmRegHandle->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; // Load registers every ZERO or PERIOD

/*High resolution PWM */

EPwmRegHandle->CMPA.bit.CMPAHR = 0;
EPwmRegHandle->CMPB.bit.CMPBHR = 0;
EPwmRegHandle->TBPHS.bit.TBPHSHR = 0x0;

/*Clear High Resolution Configuration*/
EPwmRegHandle->HRCNFG.all = 0x0;

/*Enable High Res. CH-A */
EPwmRegHandle->HRCNFG.bit.EDGMODE = HR_REP;
EPwmRegHandle->HRCNFG.bit.CTLMODE = HR_CMP;
EPwmRegHandle->HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;

//* Enable High Res. CH-B (if using Deadband)
EPwmRegHandle->HRCNFG.bit.EDGMODEB = HR_FEP;
EPwmRegHandle->HRCNFG.bit.CTLMODEB = HR_CMP;
EPwmRegHandle->HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD;

EPwmRegHandle->HRPCTL.bit.TBPHSHRLOADE = 1;
EPwmRegHandle->HRPCTL.bit.HRPE = 0; //must be disable of duty cycle control
EPwmRegHandle->HRMSTEP.bit.HRMSTEP = 32;


/* Action Qualifer */
EPwmRegHandle->AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on CAU
EPwmRegHandle->AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on CAD
EPwmRegHandle->AQCTLB.bit.CBU = AQ_SET; // Set PWM1B on event B, up count
EPwmRegHandle->AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B, down count

/* Disable Dead-band */
EPwmRegHandle->DBCTL.bit.OUT_MODE = DB_DISABLE;

/* Clear Trip Zone configuration*/
EPwmRegHandle->TZCTL.all=0;
EPwmRegHandle->TZSEL.all=0;
EPwmRegHandle->TZDCSEL.all=0;
EPwmRegHandle->DCTRIPSEL.all=0;

/*Confiure Dead Band module if Enable (Dead time+ Polarity of OUTA/OUTB relative to ePWMxA) */
/*High Resolution Dead time */
EPwmRegHandle->DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //FED+RED
EPwmRegHandle->DBCTL.bit.POLSEL = dead_band_polarity; // A same as CMD B is inverted
EPwmRegHandle->DBCTL.bit.IN_MODE = DBA_ALL; //A is Source for Falling and rising Edge
EPwmRegHandle->DBCTL.bit.SHDWDBREDMODE = 1;
EPwmRegHandle->DBCTL.bit.SHDWDBFEDMODE = 1;
EPwmRegHandle->DBCTL.bit.LOADREDMODE = 0; // Load on Counter == 0
EPwmRegHandle->DBCTL.bit.LOADFEDMODE = 0; // Load on Counter == 0
EPwmRegHandle->DBCTL.bit.HALFCYCLE = 1; //Need for High resolution Dead band
EPwmRegHandle->DBRED.bit.DBRED = EPWM_DB_RED_DLY; //RE delay DBRED*TCLK/2
EPwmRegHandle->DBREDHR.bit.DBREDHR = 0x0; //val *256 (where val is number of steps)
EPwmRegHandle->DBFED.bit.DBFED = EPWM_DB_FED_DLY; //FE delay DBFED*TCLK/2
EPwmRegHandle->DBFEDHR.bit.DBFEDHR = 0x0;//val *256 (where val is number of steps)
EPwmRegHandle->HRCNFG2.bit.EDGMODEDB = HR_BEP;//HR_BEP; // DBREDHR and DBFEDHR
EPwmRegHandle->HRCNFG2.bit.CTLMODEDBRED = 0; // Load on ZRO
EPwmRegHandle->HRCNFG2.bit.CTLMODEDBFED = 0; // Load on ZRO

EDIS;

in various testing , i have partly succeeded to achive high resoultion complementary PWM signlas only if 

1. set Edge mode for channle A to Rising Edge (e.g. MEP mechansim)

2.set Edge mode for channel B to Falling Edge 

.....

when i am updating pwm command( if i am not updating EPwm1Regs.CMPB.bit.CMPBHR   , i see difference of the high resoultion)

 EPwm1Regs.CMPA.bit.CMPA          <= coarse resoultion 

EPwm1Regs.CMPA.bit.CMPAHR     <= fine resoultion 

EPwm1Regs.CMPB.bit.CMPBHR     <= fine resoultion

even tough it's partaly working , on some value i see jitter , and strange behavior 

can you please advise on this matter ?

  • Yes, but you have to add the high-resolution part of the complimentary signal in through CMPxHR and DEAD BAND HR registers.

    If the deadband is in complimentary mode for the EPWMxA output, making EPWMxB the inverted version with deadband, make sure to add the CMPBHR to the same value as CMPAHR. 

    Nima

  • Meaning CMPBHR = CMPAHR

  • hi Nima 

    thanks for you quick response , this is what  i was doing 

    Command to be update 

     EPwm1Regs.CMPA.bit.CMPA          <= coarse resoultion 

    EPwm1Regs.CMPA.bit.CMPAHR     <= fine resoultion 

    EPwm1Regs.CMPB.bit.CMPBHR     <= fine resoultion

    this will result in CMPAHR     = CMPBHR     , in addtion the configuration for MEP (edge postion ) is configure 

    Channel A  - Faling Edge 

    Channel B  - Rising Edge 

    only this configuration achive Partly working 

    1. on DC of 50%  + some sub resoultion  - working

    2.changing deae time  + DC of 40%  +some high resoulton working   (include the MEP propely aligned A , B)

    but the issue is on some value of command the PWM  is jittering 

  • You are using Up/Down mode, correct? I see that in your code.

    For your actions, please set the actions to be Set on CMPAU, clear on CMPAD. Then the high resolution on both edges. Load shadow to active event to be CNTR_PRD_ZERO both.

    Nima

  • Hi Nima  ,

    yes PWM working in UP down counter 

    Action Qualifer 

    EPwmRegHandle->AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on CAU
    EPwmRegHandle->AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on CAD
    EPwmRegHandle->AQCTLB.bit.CBU = AQ_SET; // Set PWM1B on event B, up count
    EPwmRegHandle->AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B, down count

    as you can see for Channel A  ( Set on UP CMP match , Clear on Down Compare Match ) , channel B action quilfer are not relevant 

    load shadow  


    load both on 0 and PRD

    EPwmRegHandle->HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;

    EPwmRegHandle->HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD;

    EPwmRegHandle->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // Load registers every ZERO or PERIOD
    EPwmRegHandle->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; // Load registers every ZERO or PERIOD

    will change this to load on period and zero (maybe this is the issue)

    EPwmRegHandle->DBCTL.bit.LOADREDMODE = 0; // Load on Counter == 0
    EPwmRegHandle->DBCTL.bit.LOADFEDMODE = 0; // Load on Counter == 0

    EPwmRegHandle->HRCNFG2.bit.CTLMODEDBRED = 0; // Load on ZRO
    EPwmRegHandle->HRCNFG2.bit.CTLMODEDBFED = 0; // Load on ZRO

    MEP

    changeing MEP to both edge   ? i think i have tried it and it look more like phase shift  , this is also mention in datasheet

  • Both edges is different than phase shift. When in duty control mode, both edges causes both rising edge and falling edge to move closer to the PRD event,

    While in phase control mode, both edges shift right.

    In this scenario you want duty control mode with both edges controlled by the MEP.

    Nima

  • Hi Nima ,

    i have tried it in the past  , and ask about it in this form (maybe i dint understand correclty ) , but the MEP  is delay based  , meaning it can  only delay the edge  (thus for up dowm  PWM  , setting both edge wont make the edge closer to the PRD)... it could be that i didnt undertand it well , but i will give it try.

    also from data sheet 

    Edge Mode — The MEP can be programmed to provide precise position control on the rising edge (RE),
    falling edge (FE) or both edges (BE) at the same time. FE and RE are used for power topologies
    requiring duty cycle control(CMPA or CMPB high-resolution control), while BE is used for topologies
    requiring phase shifting, for example, phase shifted full bridge (TBPHS or TBPRD high-resolution
    control).


    Control Mode — The MEP is programmed to be controlled either from the CMPAHR / CMPBHR register
    in case of duty cycle control or the TBPHSHR register (phase control). RE or FE control mode
    should be used with CMPAHR or CMPBHR register. BE control mode should be used with
    TBPHSHR register. When the MEP is controlled from the TBPRDHR register (period control) the
    duty cycle and phase can also be controlled via their respective high-resolution registers.

  • I understand the confusion but that's not correct. The BE although mainly used with TBPSHHR, it is used in UP-DOWN mode with DUTY Control mode.

    MEP is delay based but here is what happens in both edge mode for DUTY control.

    Counting up: CMPA + CMPAHR -> closer to PRD

    Counting down: CMPA + CMPAHR -> closer to PRD

    Therefore the duty is shortened.

    Nima

  • Hi Nima,

    i have tried you suggestiones  

    changing Edge mode to both edge

    EPwm3Regs.HRCNFG.bit.EDGMODE = HR_BEP;
    EPwm3Regs.HRCNFG.bit.EDGMODEB = HR_BEP;

    seting DC to 50%   , and just changeing  fraction 

    EPwm3Regs.CMPA.bit.CMPAHR  =(dc_frc*local_sfo)<<8 +0x080;

    EPwm3Regs.CMPA.bit.CMPBHR = (dc_frc*local_sfo)<<8 +0x080;

    looking with scope , i didnt see any change   (i have change the dc_frc  so it will change ~6-7ns)

    while working in this configuration

    EPwm3Regs.HRCNFG.bit.EDGMODE = HR_REP;
    EPwm3Regs.HRCNFG.bit.EDGMODEB = HR_FEP;

    looking with scope , setting DC to 50%   and changing fraction , i was able to see change (on signle edge ) , but in complementary mode

    EPwm3Regs.CMPA.bit.CMPAHR  =(dc_frc*local_sfo)<<8 +0x080;

    EPwm3Regs.CMPA.bit.CMPBHR = (dc_frc*local_sfo)<<8 +0x080;

    so why when seeting to Both edge didnt work  ?

  • This has been verified. An example for EPWM up-down count with BOTH edge control to do duty control is below. Can you try it out?

    //#############################################################################
    //
    // FILE:   hrpwm_ex3_prdupdown_sfo.c
    //
    // TITLE:  HRPWM Period Control.
    //
    //#############################################################################
    //
    // FILE:   hrpwm_ex4_duty_updown_sfo.c
    //
    // TITLE:  HRPWM Duty Control with UPDOWN Mode.
    //
    //! \addtogroup driver_example_list
    //! <h1>HRPWM Duty Control with UPDOWN Mode</h1>
    //!
    //! This example calls the following TI's MEP Scale Factor Optimizer (SFO)
    //! software library V8 functions:
    //!
    //! \b int \b SFO(); \n
    //! - updates MEP_ScaleFactor dynamically when HRPWM is in use
    //! - updates HRMSTEP register (exists only in EPwm1Regs register space)
    //!   with MEP_ScaleFactor value
    //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255
    //!   (Auto-conversion may not function properly under this condition)
    //! - returns 1 when complete for the specified channel
    //! - returns 0 if not complete for the specified channel
    //!
    //! This example is intended to explain the HRPWM capabilities. The code can be
    //! optimized for code efficiency. Refer to TI's Digital power application
    //! examples and TI Digital Power Supply software libraries for details.
    //!
    //! \b External \b Connections \n
    //!  - Monitor ePWM1/2/3/4 A/B pins on an oscilloscope.
    //
    //###########################################################################
    // $TI Release: F2837xD Support Library v3.10.00.00 $
    // $Release Date: Tue May 26 17:13:46 IST 2020 $
    // $Copyright:
    // Copyright (C) 2013-2020 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 "SFO_V8.h"
    
    #define CHANNEL_B_AS_ZRO_PRD_REF    0
    #define EPWM_TIMER_TBPRD            100UL
    #define MIN_HRPWM_DUTY_PERCENT      4.0/((float32_t)EPWM_TIMER_TBPRD)*100.0
    //
    // Defines
    //
    #define LAST_EPWM_INDEX_FOR_EXAMPLE    5
    
    //
    // Globals
    //
    
    float32_t dutyFine = 50.0;
    uint16_t status;
    
    int MEP_ScaleFactor; // Global variable used by the SFO library
                         // Result can be used for all HRPWM channels
                         // This variable is also copied to HRMSTEP
                         // register by SFO() function.
    
    volatile uint32_t ePWM[] =
        {0, myEPWM1_BASE, myEPWM2_BASE, myEPWM3_BASE, myEPWM4_BASE};
    //
    // Function Prototypes
    //
    void initHRPWM(uint32_t period);
    void error(void);
    //__interrupt void epwm1ISR(void);
    //__interrupt void epwm2ISR(void);
    //__interrupt void epwm3ISR(void);
    //__interrupt void epwm4ISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t i = 0;
    
        //
        // 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);
    
        //
        // Initialize the EPWM GPIOs and change XBAR inputs from using GPIO0
        //
        Board_init();
    
        //
        // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
        // HRMSTEP must be populated with a scale factor value prior to enabling
        // high resolution period control.
        //
        while(status == SFO_INCOMPLETE)
        {
            status = SFO();
            if(status == SFO_ERROR)
            {
                error();   // SFO function returns 2 if an error occurs & # of MEP
            }              // steps/coarse step exceeds maximum of 255.
        }
    
    
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initHRPWM(EPWM_TIMER_TBPRD);
    
        //
        // 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;
    
    
        for(;;)
        {
             //
             // Sweep DutyFine
             //
             for(dutyFine = MIN_HRPWM_DUTY_PERCENT; dutyFine < (100.0-MIN_HRPWM_DUTY_PERCENT); dutyFine += 0.01)
             {
                 DEVICE_DELAY_US(1000);
                 for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
                 {
                     float32_t count = ((100.0 - dutyFine) * (float32_t)(EPWM_TIMER_TBPRD << 8))/100.0;
                     uint32_t compCount = (count);
                     uint32_t hrCompCount = (compCount & (0x000000FF));
                     if (hrCompCount == 0)
                     {
                         //
                         // Add 1 to not have CMPxHR = 0
                         //
                         compCount |= 0x00000001;
                     }
                     HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);
    #if CHANNEL_B_AS_ZRO_PRD_REF == 0
                     HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_B, compCount);
    #endif
                 }
    
                 //
                 // Call the scale factor optimizer lib function SFO()
                 // periodically to track for any change due to temp/voltage.
                 // This function generates MEP_ScaleFactor by running the
                 // MEP calibration module in the HRPWM logic. This scale
                 // factor can be used for all HRPWM channels. The SFO()
                 // function also updates the HRMSTEP register with the
                 // scale factor value.
                 //
                 status = SFO(); // in background, MEP calibration module
                                 // continuously updates MEP_ScaleFactor
    
                 if (status == SFO_ERROR)
                 {
                     error();   // SFO function returns 2 if an error occurs & #
                                // of MEP steps/coarse step
                 }              // exceeds maximum of 255.
             }
         }
    }
    
    //
    // epwm1ISR - ePWM 1 ISR
    //
    //__interrupt void epwm1ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm2ISR - ePWM 2 ISR
    //
    //__interrupt void epwm2ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM2_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm3ISR - ePWM 3 ISR
    //
    //__interrupt void epwm3ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM3_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    //
    // epwm4ISR - ePWM 4 ISR
    //
    //__interrupt void epwm4ISR(void)
    //{
    //    EPWM_clearEventTriggerInterruptFlag(EPWM4_BASE);
    //    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    //}
    
    
    void initHRPWM(uint32_t period)
    {
    
        uint16_t j;
    
        //
        // ePWM channel register configuration with HRPWM
        // ePWMxA / ePWMxB toggle low/high with MEP control on Rising and Falling edges
        //
        for (j=1;j<LAST_EPWM_INDEX_FOR_EXAMPLE;j++)
        {
            EPWM_setEmulationMode(ePWM[j], EPWM_EMULATION_FREE_RUN);
    
            //
            // Set-up TBCLK
            //
            EPWM_setTimeBasePeriod(ePWM[j], period-1);
            EPWM_setPhaseShift(ePWM[j], 0U);
            EPWM_setTimeBaseCounter(ePWM[j], 0U);
    
            //
            // set duty 50% initially
            //
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_A, (period/2 << 8) + 1);
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_B, (period/2 << 8) + 1);
    
    
            //
            // Set up counter mode
            //
            EPWM_setTimeBaseCounterMode(ePWM[j], EPWM_COUNTER_MODE_UP_DOWN);
            EPWM_disablePhaseShiftLoad(ePWM[j]);
            EPWM_setClockPrescaler(ePWM[j],
                                   EPWM_CLOCK_DIVIDER_1,
                                   EPWM_HSCLOCK_DIVIDER_1);
            EPWM_setSyncOutPulseMode(ePWM[j], EPWM_SYNC_OUT_PULSE_DISABLED);
    
            //
            // Set up shadowing
            // MUST BE CTR=(ZER & PRD)
            //
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_A,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_B,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
    
            //
            // Set actions
            //
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    
    #if CHANNEL_B_AS_ZRO_PRD_REF == 1
            //
            // Use B channel as the ZERO and PRD reference
            //
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    #else
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    #endif
    
    
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL);
    
            //
            // Set up shadowing
            // MUST BE CTR=(ZER & PRD)
            //
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
    
    #if CHANNEL_B_AS_ZRO_PRD_REF == 0
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL);
    
            //
            // Set up shadowing
            // MUST BE CTR=(ZER & PRD)
            //
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
    #endif
    
            HRPWM_enableAutoConversion(ePWM[j]);
    
            //
            // Turn on high-resolution period control for DUTY to take HR on BOTH EDGEs.
            //
    
            HRPWM_enablePeriodControl(ePWM[j]);
            HRPWM_disablePhaseShiftLoad(ePWM[j]);
    
    
            //
            // Interrupt where we will change the Compare Values
            // Select INT on Time base counter zero event,
            // Enable INT, generate INT on 1st event
            //
            //EPWM_setInterruptSource(ePWM[j], EPWM_INT_TBCTR_ZERO);
            //EPWM_enableInterrupt(ePWM[j]);
            //EPWM_setInterruptEventCount(ePWM[j], 1U);
        }
    
    }
    
    //
    // error - Halt debugger when called
    //
    void error (void)
    {
        ESTOP0;         // Stop here and handle error
    }
    

    Nima

  • What actually happens is this:

    You set shadow to active load for all registers to be ZERO AND PERIOD.

    Set CMPA/CMPAHR = for example 22.5

    PRD = 40

    At CTR=ZERO event, CMPA/CMPAHR is set to 22.5, so the rising edge has to be delayed 0.5 after 22 towards the PRD=40.

    AT CTR=PRD event, CMPA/CMPAHR is set to 22.5, internally HRPWM does a calculation and KNOWS, it has to advance the falling edge since 22.5 is closer to 40 than just 22. So it will make the falling edge occur earlier than if the CMPA/CMPAHR = 22. 

    Hence, shrinking the duty, and NOT doing a phase shift. If you are not seeing this on your scope either the scope's resolution is not showing the small HR changes, or there is another setting that is not correct.

    The example above does exactly that and we will be releasing it to C2000Ware in the upcoming february release.

    Nima

  • Hi Nima ,

    Thank you for the example , and your  patient , but in the example Channel A and Channel B doesn't work as complemetary mode  

    they work individualy to each other  (you could set the proper action qulifer  to work as complementary).

    in my implementaion they work as complemntary using the dead band mechansim , which  route ePWMA  to output A  and the inverted to output B

    plus proper FED an RED time, maybe this is the reason ?

    i will try the example you suggested

    Thanks.

  • You should be able to do Channel B with CMPAU to clear and CMPAD to SET and it should all work with BOTH edges and DUTY Contorl.