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: Clarification on Documentation

Part Number: TMS320F28377S
In SPRUHX5E Figure 13-5 it shows that the one of the Sync Out Select options is an OR input of SWFSYNC and EPWMxSYNCI.
 
 
In Table 13-2 for EPWMxSYNCO it shows the first selection as only being the EPWMxSYNCI input.
 
In the TBCTL register Table 13-16 for SWFSYNC bit it states that SWFSYNC affects EPWMxSYNCO only when SYNCOSEL is 00 and for SYNCOSEL bits option 00 is EPWMxSYNCI / SWFSYNC.
 
I have tried several configuration and it appears that the SWFSYNC does not connect to the Sync Out Select mux. I cannot get a SWFSYNC to propagate through the EPWMxSYNCO to the next EPWM module.
 
It appear that the connection of SWFSYNC to EPWMxSYNCO is in error.
Is this true?
  • The EPWMxSYNCO, when selecting SYNCOSEL 00, should be the OR of the EPWMxSYNCI and SWFSYNC. The only section of the TRM that needs to be updated is Table 13-2.

    How are you seeing that that the SWFSYNC isn't having an effect?
    Can you describe that to me?
  • Hello Nima,

    I am not able to generate any SYNCO using the SWFSYNC bit. As an example I have the following setup:

    1)      EPWM4 set to SYNCOSEL 00
    2)      EPWM4 EPWM4SYNCIN 000 with EPWM1 not generating any SYNCO
    3)      EPWM5 set to SYNCOSEL 00
    4)      EPWM5 and EPWM6 set TBCTL: PHSEN 1
    5)      EPWM5 and EPWM6 are setup to generate a normal PWM output that are not synced with each other.
    6)      If I set EPWM5 or EPWM6 TBCTL: SWFSYNC 1 I can change the sync of each PWM output individually.
    7)      If I set EPWM1 to generate a SYNCO (SYNCOSEL 01) then both EPWM5 and EPWM6 immediately are in sync.
    8)      If I set EPWM1 to SYNCOSEL 00 (no sync out) and then set EPWM5 and EPWM6 TBCTL: SWFSYNC 1, both PWM output are now out of sync.
    9)      If I set EPWM4 TBCTL: SWFSYNC I will see EPWM4 PWM sync change, but EPWM5 and EPWM6 PWM output will not change and still be out of sync.
     
  • Okay I am writing some code to test this out.
  • PinkCrape,

    I just wrote some code and tested that the SWSYNC DOES infact propagate through.

    So here is what you need to look at and watch out for.

    1. First thing I want to be aware of is EPWM1 SYNCIN. So the sync input for this EPWM is EXTSYNC1 or 2, which come from INPUTXBAR6 and 7. IN THIS DEVICE THE DEFAULT FOR INPUTXBAR6 and 7 are GPIO0, which means  the EPWM1 output on GPIO0 will cause it to SYNC ITSELF. So first step is to change this.

        XBAR_setInputPin(XBAR_INPUT5, 50);
        XBAR_setInputPin(XBAR_INPUT6, 50);

    I chose GPIO 50 becuase I'm not using it. 

    Okay now that thats done, EPWM1 can be synced only through EPWM1.TBCTL.SWSYNC.

    2. If you are using driverlib like I am, make sure to include the line,

        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);

    Before 

        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    If you dont do this, TBCLKSYNC wont have any effect.

    3. Okay now we can check what you are asking about. Lets setup a simple sync between EPWM1 and EWPM2.

        EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
        EPWM_enablePhaseShiftLoad(EPWM1_BASE);
        EPWM_enablePhaseShiftLoad(EPWM2_BASE);

    This makes the SYNCOUT of EPWM1 = SW or SYNCIN.

    Then enable phase shift load for EPWM1 and EPWM2. 

    Now if you execute 

            EPWM_forceSyncPulse(EPWM1_BASE);

    You will see both EPWM1 and EPWM2 restart.

    If you dont want EPWM1 to sync to swsync, just  EPWM_disablePhaseShiftLoad(EPWM1_BASE);

    Now to showcase this to you I have the code below which you can run, I have also attached CCS project.

    pinkCrape.zip

    The code is below. I force SW sync after delays, you can see when the SYNC occurs by scoping GPIO6. You will see EPWM1 and EPWM2 follow each other and the SYNC.

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    #define EPWM_TIMER_TBPRD    2000
    
    //
    // Function Prototypes
    //
    void initEPWM(uint32_t epwm_base);
    
    __interrupt void epwm1ISR(void);
    __interrupt void epwm2ISR(void);
    __interrupt void epwm3ISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pull ups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Assign the interrupt service routines to ePWM interrupts
        //
        Interrupt_register(INT_EPWM1, &epwm1ISR);
        Interrupt_register(INT_EPWM2, &epwm2ISR);
        Interrupt_register(INT_EPWM3, &epwm3ISR);
    
        //
        // Configure GPIO0/1 , GPIO2/3 and GPIO4/5 as ePWM1A/1B, ePWM2A/2B and
        // ePWM3A/3B pins respectively
        //
        GPIO_setPadConfig(0, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_0_EPWM1A);
        GPIO_setPadConfig(1, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_1_EPWM1B);
    
        GPIO_setPadConfig(2, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_2_EPWM2A);
        GPIO_setPadConfig(3, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_3_EPWM2B);
    
        GPIO_setPadConfig(4, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_4_EPWM3A);
        GPIO_setPadConfig(5, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_5_EPWM3B);
    
        GPIO_setPadConfig(6, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_6_GPIO6);
        GPIO_setDirectionMode(6, GPIO_DIR_MODE_OUT);
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
    
        XBAR_setInputPin(XBAR_INPUT5, 50);
        XBAR_setInputPin(XBAR_INPUT6, 50);
    
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
    
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initEPWM(EPWM1_BASE);
        initEPWM(EPWM2_BASE);
        initEPWM(EPWM3_BASE);
    
    
        EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
        EPWM_enablePhaseShiftLoad(EPWM1_BASE);
        EPWM_enablePhaseShiftLoad(EPWM2_BASE);
    
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
        // Enable ePWM interrupts
        //
        Interrupt_enable(INT_EPWM1);
        Interrupt_enable(INT_EPWM2);
        Interrupt_enable(INT_EPWM3);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // IDLE loop. Just sit and loop forever (optional):
        //
    
        for(;;)
        {
            GPIO_writePin(6, 1);
            EPWM_forceSyncPulse(EPWM1_BASE);
            SysCtl_delay(5000);
            GPIO_writePin(6, 0);
            SysCtl_delay(50000);
        }
    }
    
    //
    // epwm1ISR - ePWM 1 ISR
    //
    __interrupt void epwm1ISR(void)
    {
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm2ISR - ePWM 2 ISR
    //
    __interrupt void epwm2ISR(void)
    {
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(EPWM2_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm3ISR - ePWM 3 ISR
    //
    __interrupt void epwm3ISR(void)
    {
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(EPWM3_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    void initEPWM(uint32_t epwm_base)
    {
        //
        // Set-up TBCLK
        //
        EPWM_setTimeBasePeriod(epwm_base, EPWM_TIMER_TBPRD);
        EPWM_setPhaseShift(epwm_base, 0U);
        EPWM_setTimeBaseCounter(epwm_base, 0U);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(epwm_base,
                                    EPWM_COUNTER_COMPARE_A,
                                    EPWM_TIMER_TBPRD/3);
        EPWM_setCounterCompareValue(epwm_base,
                                    EPWM_COUNTER_COMPARE_B,
                                    EPWM_TIMER_TBPRD/2);
    
        //
        // Set up counter mode
        //
        EPWM_setTimeBaseCounterMode(epwm_base, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_disablePhaseShiftLoad(epwm_base);
        EPWM_setClockPrescaler(epwm_base,
                               EPWM_CLOCK_DIVIDER_8,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set up shadowing
        //
        EPWM_setCounterCompareShadowLoadMode(epwm_base,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(epwm_base,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set actions
        //
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
    
        //
        // Interrupt where we will change the Compare Values
        // Select INT on Time base counter zero event,
        // Enable INT, generate INT on 3rd event
        //
        EPWM_setInterruptSource(epwm_base, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(epwm_base);
        EPWM_setInterruptEventCount(epwm_base, 3U);
    }
    

    Thank you,

    Nima Eskandari

  • Hello Nima,

    Here is example code ported to LaunchXL-F28377S that shows that the features doesn’t work and operate differently that the 379D part. The example is only slightly modified to use the PWM pins available on the LaunchXL-F28377S which are different than the example you sent to me.

    //
    // LaunchXL-F28377S
    //

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"

    #define EPWM_TIMER_TBPRD 2000

    //
    // Function Prototypes
    //
    void initEPWM(uint32_t epwm_base);

    __interrupt void epwm7ISR(void);
    __interrupt void epwm8ISR(void);
    __interrupt void epwm9ISR(void);

    //
    // Main
    //
    void main(void)
    {
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pull ups.
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Assign the interrupt service routines to ePWM interrupts
    //
    Interrupt_register(INT_EPWM7, &epwm7ISR);
    Interrupt_register(INT_EPWM8, &epwm8ISR);
    Interrupt_register(INT_EPWM9, &epwm9ISR);

    //
    // Configure GPIO12/13 , GPIO14/15 and GPIO16/17 as ePWM7A/7B, ePWM8A/8B and
    // ePWM9A/9B pins respectively
    //
    GPIO_setPadConfig(12, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_12_EPWM7A);
    GPIO_setPadConfig(13, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_13_EPWM7B);

    GPIO_setPadConfig(14, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_14_EPWM8A);
    GPIO_setPadConfig(15, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_15_EPWM8B);

    GPIO_setPadConfig(16, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_16_EPWM9A);
    GPIO_setPadConfig(17, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_17_EPWM9B);

    GPIO_setPadConfig(2, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_2_GPIO2);
    GPIO_setDirectionMode(2, GPIO_DIR_MODE_OUT);

    //
    // Disable sync(Freeze clock to PWM as well)
    //

    XBAR_setInputPin(XBAR_INPUT5, 50);
    XBAR_setInputPin(XBAR_INPUT6, 50);

    // Not is 377S SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);

    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    initEPWM(EPWM7_BASE);
    initEPWM(EPWM8_BASE);
    initEPWM(EPWM9_BASE);

    SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EXTSYNCIN1);
    SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM7, SYSCTL_SYNC_IN_SRC_EXTSYNCIN1);

    EPWM_setSyncOutPulseMode(EPWM7_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
    EPWM_enablePhaseShiftLoad(EPWM7_BASE);

    EPWM_setSyncOutPulseMode(EPWM8_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
    EPWM_enablePhaseShiftLoad(EPWM8_BASE);

    EPWM_setSyncOutPulseMode(EPWM9_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
    EPWM_enablePhaseShiftLoad(EPWM9_BASE);

    //
    // Enable sync and clock to PWM
    //
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);


    // Enable ePWM interrupts
    //
    Interrupt_enable(INT_EPWM7);
    Interrupt_enable(INT_EPWM8);
    Interrupt_enable(INT_EPWM9);

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // IDLE loop. Just sit and loop forever (optional):
    //

    for(;;)
    {
    GPIO_writePin(2, 1);
    EPWM_forceSyncPulse(EPWM7_BASE);
    SysCtl_delay(5000);
    GPIO_writePin(2, 0);
    SysCtl_delay(50000);
    }
    }

    //
    // epwm1ISR - ePWM 1 ISR
    //
    __interrupt void epwm7ISR(void)
    {

    //
    // Clear INT flag for this timer
    //
    EPWM_clearEventTriggerInterruptFlag(EPWM7_BASE);

    //
    // Acknowledge interrupt group
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }

    //
    // epwm2ISR - ePWM 2 ISR
    //
    __interrupt void epwm8ISR(void)
    {

    //
    // Clear INT flag for this timer
    //
    EPWM_clearEventTriggerInterruptFlag(EPWM8_BASE);

    //
    // Acknowledge interrupt group
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }

    //
    // epwm3ISR - ePWM 3 ISR
    //
    __interrupt void epwm9ISR(void)
    {

    //
    // Clear INT flag for this timer
    //
    EPWM_clearEventTriggerInterruptFlag(EPWM9_BASE);

    //
    // Acknowledge interrupt group
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }

    void initEPWM(uint32_t epwm_base)
    {
    //
    // Set-up TBCLK
    //
    EPWM_setTimeBasePeriod(epwm_base, EPWM_TIMER_TBPRD);
    EPWM_setPhaseShift(epwm_base, 0U);
    EPWM_setTimeBaseCounter(epwm_base, 0U);

    //
    // Set Compare values
    //
    EPWM_setCounterCompareValue(epwm_base,
    EPWM_COUNTER_COMPARE_A,
    EPWM_TIMER_TBPRD/3);
    EPWM_setCounterCompareValue(epwm_base,
    EPWM_COUNTER_COMPARE_B,
    EPWM_TIMER_TBPRD/2);

    //
    // Set up counter mode
    //
    EPWM_setTimeBaseCounterMode(epwm_base, EPWM_COUNTER_MODE_UP_DOWN);
    EPWM_disablePhaseShiftLoad(epwm_base);
    EPWM_setClockPrescaler(epwm_base,
    EPWM_CLOCK_DIVIDER_8,
    EPWM_HSCLOCK_DIVIDER_1);

    //
    // Set up shadowing
    //
    EPWM_setCounterCompareShadowLoadMode(epwm_base,
    EPWM_COUNTER_COMPARE_A,
    EPWM_COMP_LOAD_ON_CNTR_ZERO);
    EPWM_setCounterCompareShadowLoadMode(epwm_base,
    EPWM_COUNTER_COMPARE_B,
    EPWM_COMP_LOAD_ON_CNTR_ZERO);

    //
    // Set actions
    //
    EPWM_setActionQualifierAction(epwm_base,
    EPWM_AQ_OUTPUT_A,
    EPWM_AQ_OUTPUT_HIGH,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(epwm_base,
    EPWM_AQ_OUTPUT_A,
    EPWM_AQ_OUTPUT_LOW,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    EPWM_setActionQualifierAction(epwm_base,
    EPWM_AQ_OUTPUT_B,
    EPWM_AQ_OUTPUT_HIGH,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    EPWM_setActionQualifierAction(epwm_base,
    EPWM_AQ_OUTPUT_B,
    EPWM_AQ_OUTPUT_LOW,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);


    //
    // Interrupt where we will change the Compare Values
    // Select INT on Time base counter zero event,
    // Enable INT, generate INT on 3rd event
    //
    EPWM_setInterruptSource(epwm_base, EPWM_INT_TBCTR_ZERO);
    EPWM_enableInterrupt(epwm_base);
    EPWM_setInterruptEventCount(epwm_base, 3U);
    }
  • Found a Single core launchpad. Im trying this.
  • Okay, I have tested it on the single core launchpad and you are correct. I will need to check with design.
  • Okay found the issue. It is that on dual core we have a GPIO50 pin and know that NOTHING is happening on it. In Single core that is not the case so you need to add the code:

    GPIO_setPadConfig(50, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_50_GPIO50);
    GPIO_setDirectionMode(50, GPIO_DIR_MODE_OUT);
    GPIO_writePin(50, 0);

    I tested and made sure this works on single core launchpad. 

    Here is the final code,

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    #define EPWM_TIMER_TBPRD 2000
    
    //
    // Function Prototypes
    //
    void initEPWM(uint32_t epwm_base);
    
    __interrupt void epwm7ISR(void);
    __interrupt void epwm8ISR(void);
    __interrupt void epwm9ISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pull ups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Assign the interrupt service routines to ePWM interrupts
        //
        Interrupt_register(INT_EPWM7, &epwm7ISR);
        Interrupt_register(INT_EPWM8, &epwm8ISR);
        Interrupt_register(INT_EPWM9, &epwm9ISR);
    
        //
        // Configure GPIO12/13 , GPIO14/15 and GPIO16/17 as ePWM7A/7B, ePWM8A/8B and
        // ePWM9A/9B pins respectively
        //
        GPIO_setPadConfig(12, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_12_EPWM7A);
        GPIO_setPadConfig(13, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_13_EPWM7B);
    
        GPIO_setPadConfig(14, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_14_EPWM8A);
        GPIO_setPadConfig(15, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_15_EPWM8B);
    
        GPIO_setPadConfig(16, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_16_EPWM9A);
        GPIO_setPadConfig(17, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_17_EPWM9B);
    
        GPIO_setPadConfig(2, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_2_GPIO2);
        GPIO_setDirectionMode(2, GPIO_DIR_MODE_OUT);
    
        GPIO_setPadConfig(50, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_50_GPIO50);
        GPIO_setDirectionMode(50, GPIO_DIR_MODE_OUT);
        GPIO_writePin(50, 0);
        //
        // Disable sync(Freeze clock to PWM as well)
        //
    
        XBAR_setInputPin(XBAR_INPUT5, 50);
        XBAR_setInputPin(XBAR_INPUT6, 50);
    
        // Not is 377S SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
    
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        initEPWM(EPWM7_BASE);
        initEPWM(EPWM8_BASE);
        initEPWM(EPWM9_BASE);
    
        SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EXTSYNCIN1);
        SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM7, SYSCTL_SYNC_IN_SRC_EXTSYNCIN1);
    
        EPWM_setSyncOutPulseMode(EPWM7_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
        EPWM_enablePhaseShiftLoad(EPWM7_BASE);
    
        EPWM_setSyncOutPulseMode(EPWM8_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
        EPWM_enablePhaseShiftLoad(EPWM8_BASE);
    
        EPWM_setSyncOutPulseMode(EPWM9_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
        EPWM_enablePhaseShiftLoad(EPWM9_BASE);
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
        // Enable ePWM interrupts
        //
        Interrupt_enable(INT_EPWM7);
        Interrupt_enable(INT_EPWM8);
        Interrupt_enable(INT_EPWM9);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // IDLE loop. Just sit and loop forever (optional):
        //
    
        for(;;)
        {
            GPIO_writePin(2, 1);
            EPWM_forceSyncPulse(EPWM7_BASE);
            SysCtl_delay(5000);
            GPIO_writePin(2, 0);
            SysCtl_delay(50000);
        }
    }
    
    //
    // epwm1ISR - ePWM 1 ISR
    //
    __interrupt void epwm7ISR(void)
    {
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(EPWM7_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm2ISR - ePWM 2 ISR
    //
    __interrupt void epwm8ISR(void)
    {
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(EPWM8_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm3ISR - ePWM 3 ISR
    //
    __interrupt void epwm9ISR(void)
    {
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(EPWM9_BASE);
    
        //
        // Acknowledge interrupt group
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    void initEPWM(uint32_t epwm_base)
    {
        //
        // Set-up TBCLK
        //
        EPWM_setTimeBasePeriod(epwm_base, EPWM_TIMER_TBPRD);
        EPWM_setPhaseShift(epwm_base, 0U);
        EPWM_setTimeBaseCounter(epwm_base, 0U);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(epwm_base,
            EPWM_COUNTER_COMPARE_A,
            EPWM_TIMER_TBPRD/3);
        EPWM_setCounterCompareValue(epwm_base,
            EPWM_COUNTER_COMPARE_B,
            EPWM_TIMER_TBPRD/2);
    
        //
        // Set up counter mode
        //
        EPWM_setTimeBaseCounterMode(epwm_base, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_disablePhaseShiftLoad(epwm_base);
        EPWM_setClockPrescaler(epwm_base,
            EPWM_CLOCK_DIVIDER_8,
            EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set up shadowing
        //
        EPWM_setCounterCompareShadowLoadMode(epwm_base,
            EPWM_COUNTER_COMPARE_A,
            EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(epwm_base,
            EPWM_COUNTER_COMPARE_B,
            EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set actions
        //
        EPWM_setActionQualifierAction(epwm_base,
            EPWM_AQ_OUTPUT_A,
            EPWM_AQ_OUTPUT_HIGH,
            EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(epwm_base,
            EPWM_AQ_OUTPUT_A,
            EPWM_AQ_OUTPUT_LOW,
            EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(epwm_base,
            EPWM_AQ_OUTPUT_B,
            EPWM_AQ_OUTPUT_HIGH,
            EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(epwm_base,
            EPWM_AQ_OUTPUT_B,
            EPWM_AQ_OUTPUT_LOW,
            EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
    
        //
        // Interrupt where we will change the Compare Values
        // Select INT on Time base counter zero event,
        // Enable INT, generate INT on 3rd event
        //
        EPWM_setInterruptSource(epwm_base, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(epwm_base);
        EPWM_setInterruptEventCount(epwm_base, 3U);
    }
    

    This was a tough one to debug.

    Nima

  • Thank you Nima we believe we are now seeing it to work on the 377S.

     

    There still seems to be a problem in the documentation that lead to this problem in the first place and may lead to other implementation problems.

     

    The first is to change the code to leave GPIO50 set to 1.

    GPIO_writePin(50, 1);

    Now when running the example PWM7 will sync up, but PWM8 will not. This now implies that the EPWMxSYNCI input has a pulse generator on it going to the OR gate feeding the PHSEN counter load input. This must be true since the SWFSYNC is able to SYNC PWM7.

     

    Since PWM8 is not getting SYNCed when EPWMxSYNCI is a constant 1 and ORed with SWFSYNC then the SWFSYNC is being blocking from propagating to PWM8. In Figure 13-5 it clearly shows that EPWMxSYNCI into both OR gates is treated as pulsed input and operate the same. The problem looks to be that they are not the same signals into the OR gates.

     

    The fact that SWFSYNC can SYNC PWM7 implies that EPWMxSYNCI is setup correctly for SYNC operations given Figure 13-5, but it isn’t.

     

    Since it seems that EPWMxSYNCI signal operates differently for the PWM7 PHSEN SYNC and EPWMxSYNCO there can be a situation that if the external signal is being used for EPWMxSYNCI and it stays 1 (high) longer that a few clocks and SWFSYNC happens while the external signal is 1 then the SYNC chain would be corrupted and PWM7 would be different from the other PWMs.

     

    Is this how it is intended to operate and is there more detail needed in Figure 13-5?

  • This is how it is intended to operate but I do see how I need to specify this specifically in the TRM.