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.

TMS320F280049C: Generating 4 EPWM signals with a quarter period phase shift between them

Part Number: TMS320F280049C
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

Hello, 

I am using the TMS320f280049C to generate 4 EPWM signals. EPWM 1 and 2 are complimentary of each other and so are EPWM 3 and 4. EPWM 1 and 3 should be the same signal, but with a quarter period phase shift between them. The same is true with EPWM 2 and 4. I am struggling understanding the documentation on how to do this. I am using bitfield coding and am not able to use driverlib functions. I see in the TBCTL register there is the PHSEN field and I am not sure if i need to utilize this for the phase shift. There is also the TBPHS which i assume i  need to use to generate the phase shift for the signal, but the syncing the signal with the other epwms is what I am not sure what to do for. Can someone explain this to me and maybe generate a slight bit of code showing how this works? 

Thank you!

  • Hi Kody,

    There is an example in C2000Ware called epwm_ex3_synchronization that demonstrates synchronization between EPWM modules. This example uses SysConfig and driverlib, but should be a good reference on everything needed for synchronization. I'll summarize that here as well:

    For each PWM module that has a phase shift, you will need to write that phase shift to the TBPHS field. You will also need to enable phase shift loading using the PHSEN field as you mentioned. Each EPWM module has a SYINCIN signal feeding into it. When there is a rising edge on this signal and PHSEN is enabled, the TBCTR of that EPWM module will be loaded with the value of TBPHS. For EPWM2 and EPWM3, the SYNCIN signal always comes from the SYNCOUT signal of EPWM1. You can control when EPWM1 generates a SYNCOUT signal via the SYNCOSEL field in TBCTL(you'll want to configure this to be when EPWM1 TBCTR = 0 so that the values in your phase shift registers are an offset relative to EPWM1 TBCTR). For EPWM4 however, the can configure whether the SYNCIN signal comes from EPWM1 or from one of the external sync sources. This is configured through the SYNCSELECT register. This is because EPWM modules are synchronized in groups of 3. For you application you would want to sync it to EPWM1 since EPWM2 and 4 should be in sync.

    Let me know if you have any other questions.

    --Luke

  • Is there any bitfield example codes that I can use for EPWM configuration? I tried setting it up and developed some code and it is not generating any PWM signals and I have no clue where my issue is in the code.

  • Older versions of C2000Ware may include bitfield versions of this example. Later C2000Ware version ported existing examples to use driverlib and SysConfig. Are you disabling your EPWM clock before configuring your EPWM registers and then re-enabling it? Do the values in your registers window reflect the values you're attempting to write in your code? You may need to add the EALLOW command in your code to allow modifying of the EPWM registers.

  • Here  is the code I am running

    //
    // Included Files
    //
    #include "F28x_Project.h"
    #include "math.h"
    
    
    void InitEpwm1Gpio(void);
    void InitEpwm2Gpio(void);
    void InitEpwm4Gpio(void);
    void InitEpwm5Gpio(void);
    void ConfigureEPWM(void);
    void InitEpwm1(void);
    void InitEpwm2(void);
    void InitEpwm4(void);
    void InitEpwm5(void);
    void InitEpwm1Gpio(void);
    
    Uint16 period = 322;//6.45us/2*10ns for 155kHz
    Uint16 dtCount = 20; // dead time on both edges
    
    
    //
    // Main
    //
    void main(void)
    {
        // 1) Initilize System Control
        // PLL, WatchDog, enable Peripheral Clocks
        InitSysCtrl();
    
        // 2) Initilize GPIOs
        // enable PWM1, PWM2, PWM4, PWM5
        // then init Gpio for same PWMs
        InitGpio(); //May need later if code does not work
        CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM4 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM5 = 1;
    
        InitEpwm1Gpio();
        //InitEpwm2Gpio();
        //InitEpwm4Gpio();
        //InitEpwm5Gpio();
    
        // 3) Clear all interrupts and initilize PIE vector table
        // Disaple CPU interrupts
        DINT;
        InitPieCtrl();
        IER = 0x0000;
        IFR = 0x0000;
        InitPieVectTable(); // init pie vect table with points to shell ISR
    
        // Configure EPWM modules
        ConfigureEPWM();
    
        // 4) initialize peripherals (init all EPWM peripherals for now)
        InitEpwm1();
        //InitEpwm2();
        //InitEpwm4();
        //InitEpwm5();
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // SYNCs all active PWM modules to TBCLK
        EDIS;
    
    
        IER = M_INT1;
    
        // Enable Global Interrupt (INTM) and high priority real-time debug events
        EINT; // Enable INTM
        ERTM; // Enable global realtime interrupt DBGM, may or may not be needed.
    }
    
    //
    // ConfigureEPWM - Configure EPWM SOC and compare values confused skip for now
    //
    void ConfigureEPWM(void)
    {
        EALLOW;
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;
        EPwm1Regs.ETSEL.bit.SOCASEL = 4;
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;
        EPwm1Regs.CMPA.bit.CMPA = 105;
        EPwm1Regs.TBPRD = 210;
        EPwm1Regs.TBCTL.bit.CTRMODE = 0;
        EDIS;
    }
    
    
    //
    // EPWM 1 Set up
    //
    void InitEpwm1(void)
    {
    
        //setup counter mode
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // Divide by 1
        EPwm1Regs.TBCTL.bit.CLKDIV = 0; // Divide by 1
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up down count mode
        EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    
        //setup Time base
        EPwm1Regs.TBPRD = period; // Set timer period 155kHz
        EPwm1Regs.TBPHS.bit.TBPHS = 0; // add quarter period phase shift
        EPwm1Regs.TBCTR = 0; // clear counter
    
        //setup compare values
        EPwm1Regs.CMPA.bit.CMPA = period/2;
        EPwm1Regs.CMPB.bit.CMPB = period/2;
    
        //setup shadowing
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; //load on zero
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        //set actions
        EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // set high on event A up count
        EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Set low on event A down count
        EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // set low on event A up count
        EPwm1Regs.AQCTLB.bit.CBD = AQ_SET; // Set high on event A down count
    
        //set deadband
        EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // set rising and falling edge delay
        EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm1Regs.DBRED.bit.DBRED = dtCount; //rising edge delay
        EPwm1Regs.DBFED.bit.DBFED = dtCount; //falling edge delay
    
    }
    
    void InitEpwm1Gpio(void)
    {
        EALLOW;
    
        //Disable internal pull-up resistor for selected output pins for reduced power consumption
        GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1; // Disable Pull up on GPIO0 (EPWM1A)
        GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1; // Disable Pull up on GPIO1 (EPWM1B
    
        //Configure pins to EPWM functionality
        GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A
        GpioCtrlRegs.GPAGMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1B
    
        EDIS;
    }
    
    //
    // End of File
    //

    I have the EALLOW in there where I think  I need to have it. I have not checked the register windows to see if it is being reflected from my code.

  • Try disabling all of your relevant EPWM clocks before configuring any of the EPWM registers. AKA do CpuSysRegs.PCLKCR2.bit.EPWMx = 0 for all EPWMs. Once your configuration is complete, add what's current in lines 36-39 of your code at the end of your configuration.

  • Ok i will give that a try and see if it works. Thanks!

  • No problem, let me know if you need any further help.

  • Ok so i checked in the registers viewer and I am not updating the registers when I run the code so that is why I am not generating any PWMs. What can resolve this issue?

  • I now have the registers updating but still am getting no PWM output on my oscilloscope.

  • Hi Kody,

    Is this the first time you have encountered this issue? Were you able to see PWM outputs on your oscilloscope before attempting to implement phase shift?

  • I figured my issue out! thanks for all of your help through this!