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.

TMS320F28377S: Issue linking ePWM10 and ePWM11 using EPWMXLINK

Part Number: TMS320F28377S

Hi all,

I have a small issue. I'm using a TMS320F28377S to drive 5 H Bridges. Each bridge requires 4 PWM signals with a bit of dead time and 180° phase shift between the two legs of the H bridge.

I'm linking the CMPA registers (EPWMXLINK.bit.CMPALINK ) of two ePWM modules for each H bridge so that I can just program one ePWM and the change takes effect for both legs.

I'm using the CLA the calculate and update the duty cycle for each of my H bridge and connected ePWM modules.

This works perfectly fine for 4 of my H bridges. These use ePWM1/2, ePWM3/4, ePWM6/7 and ePWM8/9. So no problem here.

But the linking doesn't work for ePWM10/11. CLA updates value the CMPA register of ePWM10 and as for all the other ePWM pairs I expect to reflect the new value in ePWM11 too, but it doesn't.

I have one configuration routine that I use for all PWM modules on startup. I just give it different pointer for each PWM module that needs to be configured. Looking at the EPWM11.EPWMXLINK.bit.CMPALINK register I see that the configuration is as expected and is linked to ePWM10 (= 0x09).

Anybody any idea why it works for all pairs of ePWM but 10/11?

Cheers,

Jens

  • Hi Jens,

    Can you post all of your EPWM configuration code?

    For test purposes, have you tried linking EPWM10 to any PWM that's not 11? And EPWM11 with any PWM other than 10? We have not heard of any issues along these lines, so I suspect it's a configuration issue somewhere.

    Regards,
    Kris
  • Hi Kris,

    thanks for your reply. I haven't tried linking ePWM11 to any other module except 10. It's probably something I should do just to see what happens. In the meantime here is my configuration code:

    #define     EPWM1_LINK      0x00
    #define     EPWM2_LINK      0x01
    #define     EPWM3_LINK      0x02
    #define     EPWM4_LINK      0x03
    #define     EPWM5_LINK      0x04
    #define     EPWM6_LINK      0x05
    #define     EPWM7_LINK      0x06
    #define     EPWM8_LINK      0x07
    #define     EPWM9_LINK      0x08
    #define     EPWM10_LINK     0x09
    #define     EPWM11_LINK     0x0A
    #define     EPWM12_LINK     0x0B
    
    void    pwmInitModules(void)
    {
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        /* all PWM modules use the same init routine, with a few parameters */
        _pwmInitModuleX(&EPwm1Regs, EPWM_PHASE_0DEG, EPWM1_LINK);
        _pwmInitModuleX(&EPwm2Regs, EPWM_PHASE_180DEG, EPWM1_LINK);
    
        _pwmInitModuleX(&EPwm3Regs, EPWM_PHASE_0DEG, EPWM3_LINK);
        _pwmInitModuleX(&EPwm4Regs, EPWM_PHASE_180DEG, EPWM3_LINK);
    
        _pwmInitModuleX(&EPwm6Regs, EPWM_PHASE_0DEG, EPWM6_LINK);
        _pwmInitModuleX(&EPwm7Regs, EPWM_PHASE_180DEG, EPWM6_LINK);
    
        _pwmInitModuleX(&EPwm8Regs, EPWM_PHASE_0DEG, EPWM8_LINK);
        _pwmInitModuleX(&EPwm9Regs, EPWM_PHASE_180DEG, EPWM8_LINK);
    
        _pwmInitModuleX(&EPwm10Regs, EPWM_PHASE_0DEG, EPWM10_LINK);
        _pwmInitModuleX(&EPwm11Regs, EPWM_PHASE_180DEG, EPWM10_LINK);
    
        EPwm2Regs.ETSEL.bit.INTEN = 1;                  // Enable INT for EPWM2
    
        EALLOW;
        /* This starts all configured PWM clocks at once */
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    }
    
    /** @brief Configures function for EPWM modules.
     *
     *  This function is used to configure EPWM modules 1-11. These PWM modules use
     *  the exact same configuration except for very few parameters.
     *  PWM modules with uneven numbers don't have a phase shift, PWM modules with even numbers
     *  have a phase shift of 180° compared to PWM with uneven numbers.
     *  Some PWM modules can be linked to others. Linking PWM modules means that all configuration
     *  data written to one module during run time will automatically be written to the all linked
     *  modules. In conjunction with the 180° phase shift and complementary PWM outputs this
     *  mechanism is used to control a full 4 PWM H Bridge.
     *
     *  @param EPWM_REGS* pwm_regs - pointer to module specific configuration structure
     *  @param Uint16 phaseShift - phase shift in degrees compared to linked module
     *  @param Uint16 linkPwm - PWM module to link
     *  @retval void
     */
    static void     _pwmInitModuleX(volatile struct EPWM_REGS* pwm_regs, Uint16 phaseShift, Uint16 linkPwm)
    {
        // Setup TBCLK
        pwm_regs->TBCTL.bit.CTRMODE     = TB_COUNT_UP;                  // Count up
        pwm_regs->TBPRD                 = EPWM_TIMER_TBPRD - 1;         // Set timer period
    
        pwm_regs->TBCTR                 = 0x0000;                       // Clear counter
        pwm_regs->TBCTL.bit.HSPCLKDIV   = TB_DIV1;                      // Clock divider to SYSCLKOUT for pwm clock for high resolution
        pwm_regs->TBCTL.bit.CLKDIV      = TB_DIV1;                      // Clock divider to SYSCLKOUT for pwm clock
    
        // Setup shadow register load on ZERO
        pwm_regs->CMPCTL.bit.SHDWAMODE  = CC_SHADOW;
        pwm_regs->CMPCTL.bit.SHDWBMODE  = CC_SHADOW;
        pwm_regs->CMPCTL.bit.LOADAMODE  = CC_CTR_ZERO;
        pwm_regs->CMPCTL.bit.LOADBMODE  = CC_CTR_ZERO;
    
        // Set Compare values
        pwm_regs->CMPA.bit.CMPA         = EPWM_INITIAL_CMP;             // Set compare A value
    
        pwm_regs->AQCTL.bit.SHDWAQAMODE = 1;                            // Use shadow registers for action qualifiers EPWMA
        pwm_regs->AQCTL.bit.SHDWAQBMODE = 1;                            // Use shadow registers for action qualifiers EPWMB
    
        pwm_regs->AQCTL.bit.LDAQAMODE   = 1;
        pwm_regs->AQCTL.bit.LDAQBMODE   = 1;
    
        // Set actions
        if (phaseShift == EPWM_PHASE_0DEG )
        {
    
            pwm_regs->TBCTL.bit.PHSEN       = TB_DISABLE;               // Disable phase loading
            pwm_regs->TBCTL.bit.SYNCOSEL    = TB_SYNC_IN;               // Just forward any received SYNC signals
    
            /* Initial configuration after startup is to disable PWM
             * output until a treatment begins.
             *
             * Disable TOP1 leg - cutting off from power supply */
            pwm_regs->AQCTLA.bit.PRD        = AQ_CLEAR;
            pwm_regs->AQCTLA.bit.CAU        = AQ_CLEAR;
    
            /* Enable BOT1 leg - transformers to GND */
            pwm_regs->AQCTLB.bit.PRD        = AQ_SET;
            pwm_regs->AQCTLB.bit.CAU        = AQ_SET;
        }
        else
        {
            pwm_regs->TBCTL.bit.PHSEN       = TB_ENABLE;                // Enable phase loading
            pwm_regs->TBCTL.bit.SYNCOSEL    = TB_SYNC_DISABLE;          // Don't generate SYNC signals on phase shifted EPWM modules
            pwm_regs->TBPHS.bit.TBPHS       = phaseShift;
    
            /* Initial configuration after startup is to disable PWM
             * output until a treatment begins.
             *
             * Disable TOP1 leg - cutting off from power supply */
            pwm_regs->AQCTLA.bit.PRD        = AQ_CLEAR;
            pwm_regs->AQCTLA.bit.CAU        = AQ_CLEAR;
    
            /* Enable BOT1 leg - transformers to GND */
            pwm_regs->AQCTLB.bit.PRD        = AQ_SET;
            pwm_regs->AQCTLB.bit.CAU        = AQ_SET;
        }
    
        // Active Low complementary PWMs - setup the dead band
        pwm_regs->DBCTL.bit.OUT_MODE    = DB_FULL_ENABLE;
        pwm_regs->DBCTL.bit.POLSEL      = DB_ACTV_HIC;
        pwm_regs->DBCTL.bit.IN_MODE     = DBA_ALL;
        pwm_regs->DBRED.bit.DBRED       = EPWM_DBRED;
        pwm_regs->DBFED.bit.DBFED       = EPWM_DBFED;
    
        // Interrupt where we will change the Compare Values
        pwm_regs->ETSEL.bit.INTSEL      = ET_CTR_ZERO;              // Select INT on Zero event
        pwm_regs->ETSEL.bit.INTEN       = 0;                        // Disable INT
    
        pwm_regs->ETPS.bit.INTPSSEL     = 1;
        pwm_regs->ETINTPS.bit.INTPRD2   = PWM_EVENT_RATE;
    
        pwm_regs->EPWMXLINK.bit.CMPALINK    = linkPwm;
    
    }