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/TMS320F28377S: Problem with PWM

Part Number: TMS320F28377S
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hi,

I configured ePWM2 using the example from C:\ti\c2000\C2000Ware_1_00_03_00\device_support\f2837xs\examples\cpu1\epwm_deadband and I have a problem. When I connected ePWM2A to the osciloscope I didn't see waveform.  ePWM2A  is always high on osciloscope.

#include "F28x_Project.h"


#define EPWM1_MAX_DB   0x03FF
#define EPWM2_MAX_DB   0x03FF
#define EPWM3_MAX_DB   0x03FF
#define EPWM1_MIN_DB   0
#define EPWM2_MIN_DB   0
#define EPWM3_MIN_DB   0
#define DB_UP          1
#define DB_DOWN        0

Uint32 EPwm2TimerIntCount;
Uint16 EPwm2_DB_Direction;

void InitEPwm2Example(void);
__interrupt void epwm2_isr(void);

void main(void)
{

    InitSysCtrl();


    CpuSysRegs.PCLKCR2.bit.EPWM2=1;


    InitEPwm2Gpio();


    DINT;

    InitPieCtrl();


    IER = 0x0000;
    IFR = 0x0000;

    InitPieVectTable();

    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.EPWM2_INT = &epwm2_isr;

    EDIS;

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
    EDIS;

    InitEPwm2Example();

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1;
    EDIS;

    EPwm2TimerIntCount = 0;

    IER |= M_INT3;

    PieCtrlRegs.PIEIER3.bit.INTx2 = 1;

    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

    for(;;)
    {
        asm ("          NOP");
    }
}

// epwm2_isr - EPWM2 ISR

__interrupt void epwm2_isr(void)
{
    if(EPwm2_DB_Direction == DB_UP)
    {
        if(EPwm2Regs.DBFED.bit.DBFED < EPWM2_MAX_DB)
        {
            EPwm2Regs.DBFED.bit.DBFED++;
            EPwm2Regs.DBRED.bit.DBRED++;
        }
        else
        {
            EPwm2_DB_Direction = DB_DOWN;
            EPwm2Regs.DBFED.bit.DBFED--;
            EPwm2Regs.DBRED.bit.DBRED--;
        }
    }
    else
    {
        if(EPwm2Regs.DBFED.bit.DBFED == EPWM2_MIN_DB)
        {
            EPwm2_DB_Direction = DB_UP;
            EPwm2Regs.DBFED.bit.DBFED++;
            EPwm2Regs.DBRED.bit.DBRED++;
        }
        else
        {
            EPwm2Regs.DBFED.bit.DBFED--;
            EPwm2Regs.DBRED.bit.DBRED--;
        }
    }

    EPwm2TimerIntCount++;
    EPwm2Regs.ETCLR.bit.INT = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}

void InitEPwm2Example()
{
    EPwm2Regs.TBPRD = 6000;                       // Set timer period
    EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
    EPwm2Regs.TBCTR = 0x0000;                     // Clear counter

    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4;       // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV4;          // Slow just to observe on
                                                   // the scope
    EPwm2Regs.CMPA.bit.CMPA = 3000;

    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM2A on Zero
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;

    EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR;          // Set PWM2A on Zero
    EPwm2Regs.AQCTLB.bit.CAD = AQ_SET;

    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_LOC;
    EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm2Regs.DBRED.bit.DBRED = EPWM2_MIN_DB;
    EPwm2Regs.DBFED.bit.DBFED = EPWM2_MIN_DB;
    EPwm2_DB_Direction = DB_UP;

    EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
    EPwm2Regs.ETSEL.bit.INTEN = 1;                // Enable INT
    EPwm2Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
}


Thank you in advance for your help

Best regards

Szymon


  • Did you set the GPIO pin mux registers?

     GpioCtrlRegs.GPAGMUX1.bit.GPIO2 = 0;  // 0|0=GPIO  0|1=EPWM2A       0|2=rsvd         0|3=rsvd
     GpioCtrlRegs.GPAMUX1.bit.GPIO2  = 1;  // 1|0=GPIO  1|1=OUTPUTXBAR1  1|2=SDAB         1|3=rsvd
                                           // 2|0=GPIO  2|1=rsvd         2|2=rsvd         2|3=rsvd
                                           // 3|0=GPIO  3|1=rsvd         3|2=rsvd         3|3=rsvd

    Regards,

    David

  • Hi Szymon,

    I think David probably has the right suggestion here. If that doesn't work (don't forget EALLOW), do you receive your interrupts? If you add the TBCTR to the watch window, do you see it counting?

    Regards,
    Kris
  • Hi,

    I've added MUX settings but all the time I have the same problem. Yes I receive interrupts and TBCTR is counting.

    Maybe do you have simple code with changing PWM duty cycle ?

    Best regards

    Szymon

    
    

    #include "F28x_Project.h"
    
    
    #define EPWM1_MAX_DB   0x03FF
    #define EPWM2_MAX_DB   0x03FF
    #define EPWM3_MAX_DB   0x03FF
    #define EPWM1_MIN_DB   0
    #define EPWM2_MIN_DB   0
    #define EPWM3_MIN_DB   0
    #define DB_UP          1
    #define DB_DOWN        0
    
    Uint32 EPwm2TimerIntCount;
    Uint16 EPwm2_DB_Direction;
    
    void InitEPwm2Example(void);
    __interrupt void epwm2_isr(void);
    
    void main(void)
    {
    
        InitSysCtrl();
    
        EALLOW;
    
        CpuSysRegs.PCLKCR2.bit.EPWM2=1;
    
    
        GpioCtrlRegs.GPAGMUX1.bit.GPIO2 = 0;
        GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;
    
    
        DINT;
    
        InitPieCtrl();
    
    
        IER = 0x0000;
        IFR = 0x0000;
    
        InitPieVectTable();
    
        EALLOW; // This is needed to write to EALLOW protected registers
        PieVectTable.EPWM2_INT = &epwm2_isr;
    
        EDIS;
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
        EDIS;
    
        InitEPwm2Example();
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1;
        EDIS;
    
        EPwm2TimerIntCount = 0;
    
        IER |= M_INT3;
    
        PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
    
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
        for(;;)
        {
            asm ("          NOP");
        }
    }
    
    // epwm2_isr - EPWM2 ISR
    
    __interrupt void epwm2_isr(void)
    {
        if(EPwm2_DB_Direction == DB_UP)
        {
            if(EPwm2Regs.DBFED.bit.DBFED < EPWM2_MAX_DB)
            {
                EPwm2Regs.DBFED.bit.DBFED++;
                EPwm2Regs.DBRED.bit.DBRED++;
            }
            else
            {
                EPwm2_DB_Direction = DB_DOWN;
                EPwm2Regs.DBFED.bit.DBFED--;
                EPwm2Regs.DBRED.bit.DBRED--;
            }
        }
        else
        {
            if(EPwm2Regs.DBFED.bit.DBFED == EPWM2_MIN_DB)
            {
                EPwm2_DB_Direction = DB_UP;
                EPwm2Regs.DBFED.bit.DBFED++;
                EPwm2Regs.DBRED.bit.DBRED++;
            }
            else
            {
                EPwm2Regs.DBFED.bit.DBFED--;
                EPwm2Regs.DBRED.bit.DBRED--;
            }
        }
    
        EPwm2TimerIntCount++;
        EPwm2Regs.ETCLR.bit.INT = 1;
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    void InitEPwm2Example()
    {
        EPwm2Regs.TBPRD = 6000;                       // Set timer period
        EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm2Regs.TBCTR = 0x0000;                     // Clear counter
    
        EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
        EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4;       // Clock ratio to SYSCLKOUT
        EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV4;          // Slow just to observe on
                                                       // the scope
        EPwm2Regs.CMPA.bit.CMPA = 3000;
    
        EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM2A on Zero
        EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    
        EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR;          // Set PWM2A on Zero
        EPwm2Regs.AQCTLB.bit.CAD = AQ_SET;
    
        EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_LOC;
        EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm2Regs.DBRED.bit.DBRED = EPWM2_MIN_DB;
        EPwm2Regs.DBFED.bit.DBFED = EPWM2_MIN_DB;
        EPwm2_DB_Direction = DB_UP;
    
        EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm2Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm2Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
    }

  • I think it would help if you copy-past the Registers values for the ePWM2 module here.

    Also, paste the values for GPIO.

    Also, exactly what pin do you have your scope connected to? (GPIO number)

    For example:

    ePWM2 Registers 
     TBCTL 0x4181 Time Base Control Register [Memory Mapped] 
     TBSTS 0x0002 Time Base Status Register [Memory Mapped] 
     TBPHS 0x00000000 Union of TBPHS:TBPHSHR [Memory Mapped] 
     TBCTR 0x0000 Time Base Counter [Memory Mapped] 
     TBPRD 0x007F Time Base Period register set [Memory Mapped] 
     TBPRDHR 0x0000 Time Base Period High Res Register [Memory Mapped] 
     CMPCTL 0x0000 Compare control [Memory Mapped] 
     CMPA 0x00000000 Union of CMPA:CMPAHR [Memory Mapped] 
     CMPB 0x0000 Compare B reg [Memory Mapped] 
     AQCTLA 0x0003 Action qual output A [Memory Mapped] 
     AQCTLB 0x0000 Action qual output B [Memory Mapped] 
     AQSFRC 0x0000 Action qual SW force [Memory Mapped] 
     AQCSFRC 0x0000 Action qualifier continuous SW force [Memory Mapped] 
     DBCTL 0x0000 Dead-band control [Memory Mapped] 
     DBRED 0x0000 Dead-band rising edge delay [Memory Mapped] 
     DBFED 0x0000 Dead-band falling edge delay [Memory Mapped] 
     ... CUT OFF a BUNCH MORE LINES ...

  • Szy,

    >> Maybe do you have simple code with changing PWM duty cycle ?

    Attached is a simple example with fixed duty PWM on ePWM2A.  Since your issue is with getting any output on the ePWM2A, this should be sufficient to solve that problem.  I tested this code on the F28377S Launchpad.  It works.

    Regards,

    David

    /cfs-file/__key/communityserver-discussions-components-files/171/F28377S_5F00_PWM2A.zip

  • Hi,

    David thank you for code. It works prefectly. My code also works. I've connected wrong GPIO to the scope.

    Thank you for help

    Best regards
    Szymon