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.

CCS/LAUNCHXL-F28377S: HRPWM and Deadband Modul

Part Number: LAUNCHXL-F28377S

Tool/software: Code Composer Studio

Hallo,

is it possilbe to creat two PWM signals using HRPWM for the period and the duty cycle and use a fix deadband?

I want do create EPWMxA with a specific period and duty cycle and EPWMxB should be the inverted signal of A with the same deadband. I modified the hrpwm_prdupdown_sfo_cpu01 Project from the controlSUITE examples. But there is always a jitter on channel B.

How can i avoid the jitter?

    //
    // ePWM channel register configuration with HRPWM
    // ePWMxA toggle low/high with MEP control on Rising edge
    //
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // Disable TBCLK within the EPWM
    EDIS;


        EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;  // set Shadow load
        EPwm2Regs.TBPRD = period;               // PWM frequency = 1/(2*TBPRD)
        EPwm2Regs.CMPA.bit.CMPA = period / 2;   // set duty 50% initially
        EPwm2Regs.CMPA.bit.CMPAHR = (1 << 8);   // initialize HRPWM extension
        EPwm2Regs.CMPB.bit.CMPB = period / 2;   // set duty 50% initially
        EPwm2Regs.CMPB.all |= 1;
        EPwm2Regs.TBPHS.all = 0;
        EPwm2Regs.TBCTR = 0;

        EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down
                                                        // count mode
        EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
        EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;          // TBCLK = SYSCLKOUT
        EPwm2Regs.TBCTL.bit.FREE_SOFT = 11;

        EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;  // LOAD CMPA on CTR = 0
        EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
        EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

        EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;             // PWM toggle high/low
        EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
        EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;             // PWM toggle high/low
        EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;

        EALLOW;
        EPwm2Regs.HRCNFG.all = 0x0;
        EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP;          // MEP control on
                                                         // both edges.
        EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;          // CMPAHR and TBPRDHR
  //changed                                                       // HR control.
        EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;  // load on CTR = 0
                                                         // and CTR = TBPRD
        EPwm2Regs.HRCNFG.bit.EDGMODEB = HR_BEP;         // MEP control on
                                                         // both edges
        EPwm2Regs.HRCNFG.bit.CTLMODEB = HR_CMP;         // CMPBHR and TBPRDHR
                                                         // HR control
        EPwm2Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD; // load on CTR = 0
                                                         // and CTR = TBPRD
        EPwm2Regs.HRCNFG.bit.AUTOCONV = 1;        // Enable autoconversion for
                                                   // HR period

        EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;    // Enable TBPHSHR sync
                                                   // (required for updwn
                                                   //  count HR control)
        EPwm2Regs.HRPCTL.bit.HRPE = 1;            // Turn on high-resolution
                                                   // period control.

        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;      // Enable TBCLK within
                                                   // the EPWM
        EPwm2Regs.TBCTL.bit.SWFSYNC = 1;          // Synchronize high
                                                   // resolution phase to
                                                   // start HR period
        EDIS;



        // ohne EPwm2Regs.DBCTL.bit.POLSEL EPwm2Regs.DBRED EPwm2Regs.DBFED PWM2A = PWM2B
        // Setzen der Totzeit
        // Active Low complementary PWMs - setup the deadband

        EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // rising edge delay and falling edge delay enabled
        EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Polarity select Control EPWMxB is inverted || 10: Active high complementary (AHC). EPWMxB is inverted.
        EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;         // Dead-Band Input Mode Control: EPWMxA is source for rising and falling edge
        EPwm2Regs.DBRED = EPWM2_DB;                    // rising edge delay value
        EPwm2Regs.DBFED = EPWM2_DB;                    // falling edge delay value

  • Hi Jonas,

    I'm reviewing your code and will get back to you with suggestions soon.

    Regards,

    Kris

  • Hi Kris,

    have you alreade figured something out?

    Regards,

    Kris
  • Hi Kris,

    do you have any suggestions ?

    Regards,

    Jonas
  • Hi Jonas,

    Can you attach some oscilloscope images highlighting the jitter? I have your code loaded and am looking at it right now but I don't believe I'm seeing the jitter issue.

    Also, can you verify these two lines? What values are you writing?

    EPwm2Regs.DBRED = EPWM2_DB; // rising edge delay value
    EPwm2Regs.DBFED = EPWM2_DB; // falling edge delay value

    One thing you may want to try instead of inverting in the deadband submodule is using HRCNFG[SELOUTB] to invert the B channel and see if that fixes the issue.

    Regards,
    Kris
  • Hi Kris,

    EPWM2_DB = 5;

    Do you mean instead of setting DBCTL[POLSEL] setting SELOUTB = 1;

    Do you know where to place the SELOUTB = 1;

    Here is an example of the jitter:

  • Jonas,

    I suspect that the same thing is happening on the A channel but your trigger settings are masking it. Can we try measuring the pulse widths of the A channel and B channel and also the dead time between them?

    When you started with the original controlSUITE code, were you seeing the issue then or only after adding the deadband code? I'd like to simplify the setup as much as possible to verify where the issue is. Let's start back with the controlSUITE code and check that.

    Regards,
    Kris
  • Hi Kris,


    I am seeing the issue only after adding the deadband code. I tried to modifiy several controlSUITE examples but none of them are without jitter. The Problem is the original code does not fullfill the function i need.
    The files i modified are:
    HRPWM_Duty_SFO_V8.c -> controlSUITE
    HRPWM_PrdUpDown_SFO_V8.c -> controlSUITE
    hrpwm_deadband_sfo_v8.c -> this is out of C2000Ware_1_00_00_00

    I tried a lot of different settings and think the problem can be isolated:
    If i am using the deadband modul to invert the channel A and writing in an interrupt (or in the main-for loop) consistently a arbitrary number e.g. 32000 in the TBPRDHR the jitter occures.

    When using DBCTL[POLSEL] setting SELOUTB = 1 on which position i should place this setting?


    For my application i need the deadband modul and i also need the inverted signal to drive a half bridge. The other thing is i want to control a converter so i need also an interrupt and the ADC modul.

    If you want i can give my code to you so you can also reproduce the jitter.

    Thank you very much for helping,
    Jonas
  • Hi Kris,

    Do you have the same problems if your adding the relevant function to the given examples?

    Regards,
    Jonas
  • Hi Jonas,

    If you are able to post one of the CCS projects I can run these on my device locally to reproduce the issue. Are you able to post it to the forum or does it contain sensitive information?

    Thanks,
    Kris

  • Hi Kris

    It is no Problem to post the CCS project.

    The ADC_PWM_ASSM_LIB_JITTER is my main project.

    I also tried other projects like hrpwm_prdupdown_sfo_cpu01_MODIFIED JITTER but they did not work also

    hrpwm_prdupdown_sfo_cpu01_MODIFIED JITTER.zip

    Regards,

    Jonas

  • ADC_PWM_ASSM_LIB_JITTER_CCS.zip

    Sorry this project did not upload the first time. Try this first on your device please.

  • Hi Jonas,

    I tried loading both of your projects yesterday and ran into compile errors. It seems to just be path issues which were changed to absolute paths for your local machine. I'm still working through them and I don't expect it to be an issue, but I'll let you know if anything else comes up. I hope to have it loaded later today.

    Regards,

    Kris

  • Hi Kris,

    thanks for updating me. Hope you can fix the path problems.

    Regards,
    Jonas
  • Hi Jonas,

    I have the project running and am seeing the jitter as well and investigating the source. Can you confirm that you are also seeing jitter on channel A?

    Regards,
    Kris
  • Jonas,

    Try adding this line to your initialization code:

    EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8); // initialize HRPWM extension

    This fixes the issue on my end. Your setup is configuring HR control on both edges, but the CMPBHR extension is not initialized.

    Regards,
    Kris
  • Hi Kris,

    Which of the projects to you mean. I added EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8); // initialize HRPWM extension to my code but this did not fix the issue. Still seeing jitter on ADC_PWM_ASSM_LIB_JITTER and on the other project after insert this code.

    I can the jitter on channel A too if i am triggering on channel B.

    You don't see jitter after adding EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8); // initialize HRPWM extension to the code ?
    Did you change anything beside this?
    Did you try it with the ADC_PWM_ASSM_LIB_JITTER project?

    Thank you,
    Jonas
  • Hi Jonas,

    I attached the .c file here for your review. The only changes I believe I made were that CMPBHR write and commenting out the SFO calls in the loop (but this shouldn't be causing the issue).

    Can you drop it into your project and see if you have the jitter?

    Regards,

    Kris

    //###########################################################################
    //
    // FILE:    HRPWM_PrdUpDown_SFO_V8.c
    //
    // TITLE:   F2837xS Device HRPWM SFO V8 High-Resolution Period (Up-Down Count)
    //          example
    //
    //! \addtogroup cpu01_example_list
    //! <h1> HRPWM SFO Test (hrpwm_prdupdown_sfo_v8)</h1>
    //!
    //! This program requires the F2837xS header files, which include
    //! the following files required for this example:
    //! SFO_V8.h and SFO_TI_Build_V8_FPU.lib
    //!
    //! Monitor ePWM1-ePWM8 A/B pins on an oscilloscope.
    //! DESCRIPTION:
    //!
    //! This example modifies the MEP control registers to show edge displacement
    //! for high-resolution period with ePWM in Up-Down count mode
    //! due to the HRPWM control extension of the respective ePWM module.
    //!
    //! 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.
    //!
    //! All ePWM1-8 A/B channels will have fine
    //! edge movement due to the HRPWM logic
    //!
    //! =======================================================================
    //! NOTE: For more information on using the SFO software library, see the
    //! F2837xS High-Resolution Pulse Width Modulator (HRPWM) Reference Guide
    //! =======================================================================
    //!
    //! To load and run this example:
    //! -# **!!IMPORTANT!!** - in SFO_V8.h, set PWM_CH to the max number of
    //!    HRPWM channels plus one. For example, for the F2837xS, the
    //!    maximum number of HRPWM channels is 8. 8+1=9, so set
    //!    #define PWM_CH 9 in SFO_V8.h. (Default is 8)
    //! -# Run this example at maximum SYSCLKOUT
    //! -# Activate Real time mode
    //! -# Run the code
    //! -# Watch ePWM A / B channel waveforms on an Oscilloscope
    //! -# In the watch window:
    //!    Set the variable UpdateFine = 1  to observe the ePWMxA & ePWMxB output
    //!    with HRPWM capabilities (default)
    //!    Observe the period/frequency of the waveform changes in fine MEP steps
    //! -# In the watch window:
    //!    Change the variable UpdateFine to 0, to observe the
    //!    ePWMxA & ePWMxB output without HRPWM capabilities
    //!    Observe the period/frequency of the waveform changes in coarse SYSCLKOUT
    //!    cycle steps.
    //!
    //
    //###########################################################################
    // $TI Release: F2837xS Support Library v200 $
    // $Release Date: Tue Jun 21 13:52:16 CDT 2016 $
    // $Copyright: Copyright (C) 2014-2016 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "F28x_Project.h"
    #include "SFO_V8.h"
    
    //
    // Defines
    //
    #define PWM_CH            9        // # of PWM channels
    #define STATUS_SUCCESS    1
    #define STATUS_FAIL       0
    
    //
    // Globals
    //
    float Dutycycle = 0.5;					// Tastgrad | theoretisch von 0-1 | bei uns 0.5
    float PWM_Periodendauer =  100.25;   	// bezogen auf 10ns
    Uint16 UpdateFine, PeriodFine, 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(0) function.
    
    //
    // Array of pointers to EPwm register structures:
    // *ePWM[0] is defined as dummy value not used in the example
    //
    volatile struct EPWM_REGS *ePWM[PWM_CH] =
    {  &EPwm1Regs, &EPwm1Regs, &EPwm2Regs, &EPwm3Regs, &EPwm4Regs, &EPwm5Regs,
       &EPwm6Regs, &EPwm7Regs, &EPwm8Regs};
    
    //
    // Function Prototypes
    //
    void HRPWM_Config(int);
    void error(void);
    void epwm2_isr(void);
    void update_T_PWM(float);
    //
    // Main
    //
    void main(void)
    {
        int i;
    
        EALLOW; // This is needed to write to EALLOW protected registers
    
    //
    // Initialize System Control for Control and Analog Subsystems
    // Enable Peripheral Clocks
    // This example function is found in the F2837xS_SysCtrl.c file.
    //
        InitSysCtrl();
    
        EDIS;
    
    //
    // EPWM1A and EPWM1B through all PWMS
    //
        InitEPwmGpio();
    
        DINT; // Disable CPU interrupts
    
    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    //
    
    //
    // This function is found in the F2837xS_PieCtrl.c file.
    //
        InitPieCtrl();
    
    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
        EALLOW;
        IER = 0x0000;
        IFR = 0x0000;
    
    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xS_DefaultIsr.c.
    // This function is found in F2837xS_PieVect.c.
    //
        InitPieVectTable();
    
        // epwm2_isr mit Interrupt 3.2 verkn�pfen
        EALLOW; // This is needed to write to EALLOW protected registers
        PieVectTable.EPWM2_INT = &epwm2_isr;			// 3.2 - ePWM2 Interrupt
        EDIS;   // This is needed to disable write to EALLOW protected registers
        //
    
    
        //  F�r  Funktion epwm2_isr
        // Enable CPU INT3 which is connected to EPWM1-3 INT:
        IER |= M_INT3; // -> fuer epwm interrupt
        //
    
        // * F�er epwm2_isr
        PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
    
    
    
    
    
    
    
    
    
    
    //
    // Initialize system variables, enable HRPWM
    //
        UpdateFine = 1;
        PeriodFine = 0;
        status = SFO_INCOMPLETE;
    
    //
    // Enable global Interrupts and higher priority real-time debug events:
    //
        EINT;   // Enable Global interrupt INTM
        ERTM;   // Enable Global realtime interrupt DBGM
    
    //
    // 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) // Call until complete
        {
            status = SFO();
            if (status == SFO_ERROR)
            {
                error();    // SFO function returns 2 if an error occurs & # of MEP
            }               // steps/coarse step exceeds maximum of 255.
        }
    
    //
    // ePWM and HRPWM register initialization
    //
        HRPWM_Config(1000);   // ePWMx target
        for(;;)
        {
            //
            // Sweep PeriodFine as a Q16 number from 0.2 - 0.999
            //
            for(PeriodFine = 0x3333; PeriodFine < 0xFFBF; PeriodFine++)
            {
                if(UpdateFine)
                {
                    //
                    // Because auto-conversion is enabled, the desired
                    // fractional period must be written directly to the
                    // TBPRDHR (or TBPRDHRM) register in Q16 format
                    // (lower 8-bits are ignored)
                    //
                    // EPwm1Regs.TBPRDHR = PeriodFine;
                    //
                    // The hardware will automatically scale
                    // the fractional period by the MEP_ScaleFactor
                    // in the HRMSTEP register (which is updated
                    // by the SFO calibration software).
                    //
                    // Hardware conversion:
                    // MEP delay movement = ((TBPRDHR(15:0) >> 8) *  HRMSTEP(7:0) +
                    //                       0x80) >> 8
                    //
                    for(i=1; i<PWM_CH; i++)
                    {
                      //  (*ePWM[i]).TBPRDHR = 0x3333; //In Q16 format
                    }
                }
                else
                {
                    //
                    // No high-resolution movement on TBPRDHR.
                    //
                    for(i=1; i<PWM_CH; i++)
                    {
                      //  (*ePWM[i]).TBPRDHR = 0;
                    }
                }
    
                //
                // Call the scale factor optimizer lib function SFO(0)
                // 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. HRMSTEP
                // register is automatically updated by the SFO function.
                //
    //            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.
            } // end PeriodFine for loop
        } // end infinite for loop
    }
    
    //
    // HRPWM_Config - Configures all ePWM channels and sets up HRPWM
    //                on ePWMxA channels &  ePWMxB channels
    //
    void HRPWM_Config(period)
    {
        Uint16 j;
    
        //
        // ePWM channel register configuration with HRPWM
        // ePWMxA toggle low/high with MEP control on Rising edge
        //
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // Disable TBCLK within the EPWM
        EDIS;
    
    //    for(j=1; j<PWM_CH; j++)
    //    {
            EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;  // set Shadow load
            EPwm2Regs.TBPRD = period;               // PWM frequency = 1/(2*TBPRD)
            EPwm2Regs.CMPA.bit.CMPA = period / 2;   // set duty 50% initially
            EPwm2Regs.CMPA.bit.CMPAHR = (1 << 8);   // initialize HRPWM extension
            EPwm2Regs.CMPB.bit.CMPB = period / 2;   // set duty 50% initially
            EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8);   // initialize HRPWM extension
            EPwm2Regs.CMPB.all |= 1;
            EPwm2Regs.TBPHS.all = 0;
            EPwm2Regs.TBCTR = 0;
    
            EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down
                                                            // count mode
            EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
            EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
            EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;          // TBCLK = SYSCLKOUT
            EPwm2Regs.TBCTL.bit.FREE_SOFT = 11;
    
           // EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // LOAD CMPA on CTR = 0
           // EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
            EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;  // LOAD CMPA on CTR = 0
            EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
            EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
            EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    
            EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;             // PWM toggle high/low
            EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
            EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;             // PWM toggle high/low
            EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;
    
            EALLOW;
            EPwm2Regs.HRCNFG.all = 0x0;
            EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP;          // MEP control on
                                                             // both edges.
            EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;          // CMPAHR and TBPRDHR
                                                             // HR control.
            EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;  // load on CTR = 0
                                                             // and CTR = TBPRD
            EPwm2Regs.HRCNFG.bit.EDGMODEB = HR_BEP;         // MEP control on
                                                             // both edges
            EPwm2Regs.HRCNFG.bit.CTLMODEB = HR_CMP;         // CMPBHR and TBPRDHR
                                                             // HR control
            EPwm2Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD; // load on CTR = 0
                                                             // and CTR = TBPRD
            EPwm2Regs.HRCNFG.bit.AUTOCONV = 1;        // Enable autoconversion for
                                                       // HR period
    
            EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;    // Enable TBPHSHR sync
                                                       // (required for updwn
                                                       //  count HR control)
            EPwm2Regs.HRPCTL.bit.HRPE = 1;            // Turn on high-resolution
                                                       // period control.
    
            CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;      // Enable TBCLK within
                                                       // the EPWM
            EPwm2Regs.TBCTL.bit.SWFSYNC = 1;          // Synchronize high
                                                       // resolution phase to
                                                       // start HR period
            EDIS;
    //    }
    
    
    
    
    
        // ohne EPwm2Regs.DBCTL.bit.POLSEL EPwm2Regs.DBRED EPwm2Regs.DBFED PWM2A = PWM2B
        // Setzen der Totzeit
        // Active Low complementary PWMs - setup the deadband | Figure 13-33 Technical reference manual
        EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // rising edge delay and falling edge delay enabled
        EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Polarity select Control EPWMxB is inverted || 10: Active high complementary (AHC). EPWMxB is inverted.
        EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;         // Dead-Band Input Mode Control: EPWMxA is source for rising and falling edge
        EPwm2Regs.DBRED.all = 10;                    // rising edge delay value
        EPwm2Regs.DBFED.all = 10;                    // falling edge delay value
    
    
        // test shadow deadband
    
    //    EPwm2Regs.DBCTL.bit.LOADFEDMODE = 2;
    //    EPwm2Regs.DBCTL.bit.LOADREDMODE = 2;
    //    EPwm2Regs.DBCTL.bit.SHDWDBFEDMODE = 1;
    //    EPwm2Regs.DBCTL.bit.SHDWDBREDMODE = 1;
    
       // EPwm2Regs.DBCTL2.bit.SHDWDBCTLMODE = 1;
       // EPwm2Regs.DBCTL2.bit.LOADDBCTLMODE = 1;
    
    
        // Interrupt where we will change the Compare Values epwm2_isr
        //EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;  // Select INT on Zero event
        	   	   	   	// Enable event time-base counter equal to zero. TBCTR = 0x00
        EPwm2Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPB;
        EPwm2Regs.ETSEL.bit.INTEN = 1;                  // Enable INT
    	// These bits determine how many selected ETSEL[INTSEL] events
    	//  need to occur before an interrupt is generated
        EPwm2Regs.ETPS.bit.INTPRD = ET_1ST;             // Generate INT on 1st event
    
    
    }
    
    //
    // error - Halt debugger when error occurs
    //
    void error (void)
    {
        ESTOP0;         // Stop here and handle error
    }
    //************************interrupt PWM*********************************
    __interrupt void epwm2_isr(void)
    //interrupt void adca1_isr(void)
    {
    
    	EPwm2Regs.ETSEL.bit.INTEN = 0;
    	GpioDataRegs.GPASET.bit.GPIO12 = 1;
    
    	//while(AdcbRegs.ADCCTL1.bit.ADCBSY);
    
    	EPwm2Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA um nicht permanent neuen abtastwert zu generieren
    
    	// Hochsetzen des GPIO Pins um zu wissen wann man in der Interrupt Funktion ist
    	//GpioDataRegs.GPASET.bit.GPIO12 = 1;  // Load output latch
    
    
    	//EPwm2Regs.TBPRDHR = 0x3333;
        // rufe update_compare  auf
    	//update_T_PWM(PWM_Periodendauer);
        // Clear INT flag for this timer
    
    
    
    
    	//EPwm2Regs.TBPRD = 999;
    	EPwm2Regs.TBPRDHR = 0x3333;
    
        //EPwm2Regs.CMPA.bit.CMPA = 500;
        //EPwm2Regs.CMPA.bit.CMPAHR = 0x3333;
    
    
    
    
    
    
    	EPwm2Regs.ETCLR.bit.INT = 1; // zur�cksetzten n�tig da sonst kein weiterer interrupt erzeugt werden kann
    
        // Acknowledge this interrupt to receive more interrupts from group 3
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    
    
    
        // Clearen des GPIO Pins damit man wei� wann der Interrupt fertig ist
        //GpioDataRegs.GPACLEAR.bit.GPIO12 = 1;  // Writing a 1 will force GPIO0 output data latch to 0
        EPwm2Regs.ETSEL.bit.SOCAEN = 1;  //enable SOC on A Group
    
    	//GpioDataRegs.GPACLEAR.bit.GPIO12 = 1;  // Writing a 1 will force GPIO0 output data latch to 0
    	EPwm2Regs.ETSEL.bit.INTEN = 1;
    
    }
    
    void update_T_PWM(float PWM_T) //
    {
    	// lokale Variablen
    
    	float temp; // -1 wichtig weil 999 im TBPRD Register 100kHz entsprechen
    	temp = PWM_T - 1;
    	Uint16 TBPRD_reg_val, TBPRDHR_reg_val; 	// Register Werte fuer TBPRD, TBPRDHR
    	Uint16 CMPA_reg_val, CMPAHR_reg_val;
    	long temp_1;
    
    
    
    
    	// Setzen der PWM_Periodendauer
    	TBPRD_reg_val = (unsigned int)temp; 	// grober Wert -1 weil 999 100kHz entspricht bei up mode leichter fuer user
    	temp = temp - TBPRD_reg_val;			// (grober+feiner) Wert - grober Wert = feiner Wert in double dezimal
    	temp = temp*65536;						// double auf Register Gr��e bezogen
    	TBPRDHR_reg_val = (unsigned int)temp; 	// feiner Wert auf Registergr��e bezogen
    
    	EPwm2Regs.TBPRD = TBPRD_reg_val;
    	EPwm2Regs.TBPRDHR = TBPRDHR_reg_val;
    
    
    
    
    
    
    	// Anpassen des PWM Duty Cycle zur neuen Periodendauer
    	temp = ((EPwm2Regs.TBPRD*Dutycycle) - (unsigned int)(EPwm2Regs.TBPRD*Dutycycle));
    	temp_1 = temp*65536 + Dutycycle*EPwm2Regs.TBPRDHR; // beide Nachkommastellen zusammen
        if ((temp_1) >= 65536)
        {
        	CMPA_reg_val = (unsigned int)(Dutycycle*EPwm2Regs.TBPRD + 1);
        	CMPAHR_reg_val = (unsigned int)(temp_1-65536);
        }
        else
        {
        	CMPA_reg_val = (unsigned int)(Dutycycle*EPwm2Regs.TBPRD);
        	CMPAHR_reg_val = (unsigned int)(temp_1);
        }
    
    
    
        EPwm2Regs.CMPA.bit.CMPA = CMPA_reg_val;
        EPwm2Regs.CMPA.bit.CMPAHR = CMPAHR_reg_val;
    
    
       return;
    }
    
    
    
    
    
    
    
    //
    // End of file
    //
    

  • Hi Kris,

    there run into an error. But after changing
    EPwm2Regs.DBRED.all = 10; // rising edge delay value
    EPwm2Regs.DBFED.all = 10; // falling edge delay value
    to
    EPwm2Regs.DBRED = 10; // rising edge delay value
    EPwm2Regs.DBFED = 10;
    i can see the PWM signal without jitter.
    I tried the EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8); // initialize HRPWM extension on the other project loaded up as .zip file and there the jitter still occures.
    Can you confirm that you also see jitter on the other project?
    Why did you comment the sfo function out ? Thought the value of the sfo function has to be updated continuously.

    Thank you,
    Jonas
  • Jonas,

    What version of the header files are you using? For example v200 from controlSUITE, etc. You can find this in the path of your project or in the comments at the top of the header file themselves.

    "// $TI Release: F2837xS Support Library v200 $"

    Commenting out the SFO was just part of the debug. In theory, each time you call it you may get a different HRMSTEP which will cause a (very) small shift in the edges- but that's in the hundreds of picoseconds so not what we were seeing. The SFO really only needs to be called periodically when temperature and voltage change as those have the greatest effect on the MEP size. From a cold start you may get a slightly different HRMSTEP than after the device has been running for some time as a result of generated heat so it is good to call it periodically, but unless it's drastic changes is probably not necessary. This is a discussion strictly about picoseconds unless there is a wide temperature or voltage range in your application.

    Regards,
    Kris
  • Hi Kris,

    I am using
    $TI Release: F2837xS Support Library v130 $ in the project ADC_PWM_ASSM_LIB_JITTER
    path is:
    .../controlSUITE/device_support/F2837xS/v130/F2837xS_headers/include


    $TI Release: F2837xS Support Library v200 $ in the other project. The one you fixed with the
    EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8); command
    paht is :
    ...controlSUITE/device_support/F2837xS/v210/F2837xS_common/include

    Regards,
    Jonas
  • Jonas,

    The change in the DBRED/DBFED registers was due to an upgrade in our header file generation after v130. This was a major improvement to provide consistency for the future of C2000 moving forward. In such, there were a few tweaks that had to be made and these registers were one of them. I do strongly recommend moving to the latest versions of all of the header files where possible as they incorporate tweaks and customer feedbacks each release.

    Regards,
    Kris
  • Hi Kris,

    i moved the project to v210. Then i tried the configuration for the EPWM2Regs like in the one you posted here. The only thing i changed was to create another interrupt for the adc conversion.
    EPwm2Regs.ETSEL.bit.SOCAEN = 0; // Disable SOC on A group
    EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // jitter
    EPwm2Regs.ETPS.bit.SOCAPRD = 1;

    But there is still the jitter problem. like before.
    Did you try to run the other project which has an adc interrupt ( .zip file) ? Did you see jitter ?
    What flags have you set while running the project ( C2000 Compiler , C2000 Linker)?

    Thank you very much,
    Jonas
  • Hi Kris,

    i have an update regarding to the file you post here without jitter.
    There is an interrupt named epwm2_isr
    in line 425 there is a comment with
    //update_T_PWM(PWM_Periodendauer);
    Can you please comment it in and the following line out.
    l.432
    EPwm2Regs.TBPRDHR = 0x3333;

    If i am doing this i see jitter on the version you send to me. Can you prove this.

    Thank you very much,
    Jonas
  • Hi Jonas,

    Are you by chance using revision 0 or revision A silicon?  I loaded the project on one of those devices and confirmed I still saw the jitter.

    After reviewing the advisory in the errata, I changed all of the bitwise writes to HRCNFG to one .all write and it seems to have gotten rid of it.  Can you try this on your device?

    The value I calculated was:

    EPwm2Regs.HRCNFG.all = 0x1353;

    Here's the errata for your review (search for HRCNFG):

    I don't have access to a scope with enough resolution to see HR movement today so I'm limited in testing. I can confirm the jitter has gone away, but please verify the HR movement is still proper.

    Regards,

    Kris

  • Hi Kris,

    i have revision code C ( using TMS320 f2877SPZPT YFC-67A616W G4 )

    I delteted every EPwm2Regs.HRCNFG.bit.xxxx and set
    EPwm2Regs.HRCNFG.all = 0x1353;
    but i still see jitter.

    Regards,
    Jonas
  • Jonas,

    Thanks for the information. In update_t_pwm(), can you add the following line after you write to CMPAHR at the end of the function?

    EPwm2Regs.CMPB.bit.CMPBHR = CMPAHR_reg_val;

    Regards,
    Kris
  • Hi Kris,

    i can will try this tomorrow and give you feedback. Why do you want to write the High resolution register of the CMPB register?
    Did you have jitter on a board with revision C too?

    Thank you very much,
    Jonas
  • Jonas,

    I think I had halted the processor execution when I was debugging earlier. When I loaded the program again I did see B channel jitter. I'm pretty confident this is going to resolve your issue.

    Regards,
    Kris
  • Hey Kris,

    I tried it with
    EPwm2Regs.CMPB.bit.CMPBHR = CMPAHR_reg_val;
    and the jitter seems to be gone. I thougth i inverted EPWMA so the CMPB register should have no impact on the EPWMxA or EPWMxB. Can you explain this please?
    I will try it with the other project an give you feedback. Thank you for helping and thank you for your time.

    Regards,
    Jonas
  • Hi Kris,

    Do you have jitter if you try Count up mode? Can you change:
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;

    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; // LOAD CMPA on CTR = 0
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;

    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // PWM toggle high/low
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR;
    EPwm2Regs.AQCTLB.bit.CBU = AQ_SET; // PWM toggle high/low
    EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;

    With updown count mode it seems to run without jitter. Thank you again.

    Regards,
    Jonas
  • Jonas,

    I'll give up count mode a try. I expect there are some other settings to tweak.

    As far as why CMPBHR is required- this is something I've already filed for documentation improvements on. I'll try to give a concise explanation since I don't have any updated diagrams yet. CMPAHR only affects the A channel and is applied between the Chopper and Trip Zone submodules.  CMPBHR only affects the B channel is applied in the same place.  What's important here is that those delays are applied to the channels after the deadband module.  So CMPBHR is still acting on the EPWMxB signal even though it is truly just the inverted A signal from the deadband.  So in your configuration, assuming you want the same delays on each channel, whenever you write to CMPAHR you should also write the same value to CMPBHR.  

    This scenario is probably a good one to turn into example code also.

    Regards,

    Kris

  • Hi Kris,

    Thank you very much for your explanation and for your time. I appreciate it. Can you update me if there are any unexpected problems in up count mode.

    Regards,
    Jonas
  • Jonas,

    No problem- I'm glad to help.

    For up-count your methodology is going to have to change a bit.  The issue here is that you are using CTR=0 as an event which is having a HR edge applied to it.  Remember that in the first 3 and last 3 cycles of the PWM period cannot have HRPWM shifts applied to it.  Again, I apologize for the documentation here, but what's really happening when you set HRCNFG[EDGMODE] to both edges is that the CMPAHR delay is being applied to both edges of Channel A.  When you set HRCNFG[EDGMODEB] to both edges the CMPBHR delay is being applied to both edges of Channel B (after the deadband).

    So instead of just using CMPA, use CMPA and CMPB to make a waveform on Channel A.  Something along these lines:

    EPwm2Regs.CMPA.bit.CMPA = period / 4; // set duty 50% initially
    EPwm2Regs.CMPA.bit.CMPAHR = (1 << 8); // initialize HRPWM extension
    EPwm2Regs.CMPB.bit.CMPB = period*3 / 4; // set duty 50% initially
    EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8); // initialize HRPWM extension

    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // PWM toggle high/low
    EPwm2Regs.AQCTLA.bit.CBU = AQ_CLEAR;

    Of course your ISR calculations are going to have to change a little bit as well.  Let me know if this fixes your issue.

    Regards,

    Kris

  • Hi Kris,

    is there an other possibily without using CMPB for up-count-mode? Because i want to use CMPB to start an ADC conversion.

    Regards,
    Jonas
  • Hi Jonas,

    You'll need to use both CMPA and CMPB for up-count HRPWM mode as those are the only two CMP signals that are used by the Action Qualifier (that aren't 0 or PRD which cannot be used by the HRPWM). However, I believe you can use CMPC or CMPD to generate your SOC conversion.

    Regards,

    Kris