TMS320F28388D: PWM SyncTo question

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

Hi, 

  We have 4 PWMs running 1, 3, 5, 8

  PWM 1 runs at 50 usecs, PWM 8 runs at 100 usecs

  PWM 1 is sunk to PWM 8
  PWM 3 is sunk to PWM 1
  PWM 5 is sunk to PWM 1

  Everything works as expected EXCEPT if we try to change the timeing from 50 usecs to 80/160. What we see is if we change PWM 8 to 160 it also changes PWM 1 TBCR to the same count as PWM 8. 

  Is this normal? Such that when you update the main PWM that the TBCR will be updated on sunk PWM's?

  I added another PWM 7 and sunk it to PWM 8 and when I update PWM 8 TBCR it update the TBCR on both PWM 1 and PWM 7. 

Dorion 

  • Dorion,

    Could you please explain your setting in terms of which ePWM is sending sync out and its associated channel who is taking that as sync in?

    Regards,

    Sumit

  • Hi Sumit, 

      I think this is what you are looking for. 

      We setup ePWM8 (we call BISS_PWM_POS_BASE) Below:

    // FclConfigPWMCommon: Configures a single PWM channel to drive a three phase motor
    // Includes configureation that is common to all channels and should be run for each PWM
    void FocConfigPWM(uint32_t pwmBase, float32_t periodCount)
    {    
         EPWM_setPeriodLoadMode(pwmBase, EPWM_PERIOD_DIRECT_LOAD);

         // Need to subtract 1 since we are in count up mode.
         EPWM_setTimeBasePeriod(BISS_PWM_POS_BASE, (MICROSECONDS_TO_SYSCLK_CYCLES(periodCount) -1));    


         EPWM_setPhaseShift(pwmBase, 0);
         EPWM_setTimeBaseCounter(pwmBase, 0U);

         // example shows enabling this but I am syncing similar to Maglev which disables it
         EPWM_disablePhaseShiftLoad(pwmBase);

         // Initialize PWMs to Freeze until told to Go.
         EPWM_setTimeBaseCounterMode(pwmBase, EPWM_COUNTER_MODE_STOP_FREEZE);

         // after sync count up.
         EPWM_setCountModeAfterSync(pwmBase, EPWM_COUNT_MODE_UP_AFTER_SYNC);

         // Counting up trigger on zero
         EPWM_setTimeBaseCounterMode(pwmBase, EPWM_COUNTER_MODE_UP);

         EPWM_setClockPrescaler(pwmBase, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);

         // Enable sync out pulse on zero.
         EPWM_enableSyncOutPulseSource(pwmBase, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
    }

    We then setup ePWM1 which we cal U_PWM_BASE as follows:
        // PWM Deadband Count
        uint32_t dbPWMCount = MICROSECONDS_TO_SYSCLK_CYCLES(FCL_PWM_DB_USEC);
        
        EPWM_setPeriodLoadMode(pwmBase, EPWM_PERIOD_DIRECT_LOAD);
        EPWM_setTimeBasePeriod(pwmBase, *(pHwConfig->pPwmHalfPeriodCount));
        EPWM_setPhaseShift(pwmBase, 0);
        EPWM_setTimeBaseCounter(pwmBase, 0U);
        // example shows enabling this but I am syncing similar to Maglev which disables it
        EPWM_disablePhaseShiftLoad(pwmBase);
        // Initialize PWMs to Freeze until told to Go.
        EPWM_setTimeBaseCounterMode(pwmBase, EPWM_COUNTER_MODE_STOP_FREEZE);
        // after sync count up. 
        EPWM_setCountModeAfterSync(pwmBase, EPWM_COUNT_MODE_UP_AFTER_SYNC);
       
        // Counting up and down to center all PWM togeter
        EPWM_setTimeBaseCounterMode(pwmBase, EPWM_COUNTER_MODE_UP_DOWN);

        EPWM_setClockPrescaler(pwmBase, EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
        
        // Counter Compare Submodule Registers
        // set duty 0% initially
        // Will load new shadow value on counter = 0
        EPWM_setCounterCompareValue(pwmBase, EPWM_COUNTER_COMPARE_A, 0);
        EPWM_setCounterCompareShadowLoadMode(pwmBase, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        
        // Action Qualifier SubModule Registers
        // Go low when cmpa counting up and high when compa counting down.
        EPWM_setActionQualifierActionComplete(pwmBase, EPWM_AQ_OUTPUT_A,
                                              (EPWM_ActionQualifierEventAction)(EPWM_AQ_OUTPUT_LOW_DOWN_CMPA |
                                                                                EPWM_AQ_OUTPUT_HIGH_UP_CMPA));         

        // set deadband clock to run at TBCK rate
        EPWM_setDeadBandCounterClock(pwmBase, EPWM_DB_COUNTER_CLOCK_FULL_CYCLE);
        
        // Both A and B outputs get input from A (IN_MODE, DEDB_MODE)
        EPWM_setRisingEdgeDeadBandDelayInput(pwmBase,EPWM_DB_INPUT_EPWMA);
        EPWM_setFallingEdgeDeadBandDelayInput(pwmBase,EPWM_DB_INPUT_EPWMA);
        
        // B falling edge output delay is inverted, A rising edge delay is not(POLSEL)
        EPWM_setDeadBandDelayPolarity(pwmBase, EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH);
        EPWM_setDeadBandDelayPolarity(pwmBase, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);

        // A and B are fed from dead band modules (OUT_MODE)
        EPWM_setDeadBandDelayMode(pwmBase, EPWM_DB_RED, true);
        EPWM_setDeadBandDelayMode(pwmBase, EPWM_DB_FED, true);
        
        // No swapping, A gets A and B gets B (OUTSWAP)
        EPWM_setDeadBandOutputSwapMode(pwmBase,EPWM_DB_OUTPUT_A, false);
        EPWM_setDeadBandOutputSwapMode(pwmBase,EPWM_DB_OUTPUT_B, false);

        // For now assign fixed deadband 
        EPWM_setRisingEdgeDelayCount (pwmBase, dbPWMCount);
        EPWM_setFallingEdgeDelayCount(pwmBase,dbPWMCount);

    ==================================================================================

    We then sync them this way: 
            PwmSyncTo(U1_PWM_BASE, BISS_PWM_POS_BASE);

    Then if you set the BISS_PWM_POS_BASE period count like this: 

            SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
            EPWM_setTimeBasePeriod(BISS_PWM_POS_BASE, (MICROSECONDS_TO_SYSCLK_CYCLES(periodCount) -1));

            The above line setTimeBasePeriod will change the U1_PWM_BASE TBCR count to the same periodCount as show above. 

    Easy to reproduce. We just want to know if this is normal behavior? Is there something that we configure that makes it do this?

    Dorion 

  • Forgot to include the pwmSyncTo function
    void PwmSyncTo(uint32_t base, uint32_t syncBase)
    {
        EPWM_enablePhaseShiftLoad(base);
        EPWM_setupEPWMLinks(base, GetLink(syncBase), EPWM_LINK_TBPRD);
        EPWM_setSyncInPulseSource(base, GetPulseSource(syncBase));
        EPWM_enableSyncOutPulseSource(syncBase, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
    }

  • Dorion,

    Are you using sysconfig to configure this. I would suggest to refer to the example synchronization in ePMW in C2000Ware to verify your settings.

    Regards,

    Sumit

  • Sumit, 

      We have used sysconfig in the past to help set things up. I can try to do this again but I need an answer to my original question. Doing a sysconfig config will not give me the answer that I am looking for and take time. 

      My original question is If you have a PWM (A) sunk to another PWM (B) and you change the timeBaseCounter for PWM B does it directly change the TBPRD register for PWM A?

      We have worked around this by configuring PWM B first then PWM A, since the pwm clock is disable this won't hurt anything but we want to make sure we are not fighting something else. 

      There seems to be no documentation on this behavior. 

    Dorion 

  • Synchronization does not change the TBPRD it only loads value from TBPHS to TBCTR when sync event occurs.

    Regards,

    Sumit