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: HRPWM up-down with dead-time

Part Number: TMS320F28377S
Other Parts Discussed in Thread: C2000WARE

Hallo,

I need to extend already existing ePWM configuration. We have implemented FOC based on 3 ePWMs which are synchronized.

Period and dead-time are set once and never change, CMPAx is used for duty cycle. Output EPWMxB is inverted EPWMxA.

Shadow registers of CMPAx are loaded globally in single shot mode.

Additionally the SOC_A is triggered from PWM2:CMPB. This timing is constant.

The problem:

CAMPHR is properly updated what can be seen in debugger view. Unfortunately, no result is seen in output signal (oscilloscope). It works still as ePWM without HR extension.

As I add HRPWM configuration functions the dead-time seems to disappear. If I remove completely dead-time support then HRPWM works correctly.

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2);
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3);
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_HRPWM); //sourced from ePWM1 clock source

    while  (m_sfo_status == SFO_INCOMPLETE) // Call until complete
    {
        m_sfo_status = SFO();
        if (m_sfo_status == SFO_ERROR)
        {
            ESTOP0;    // SFO function returns 2 if an error occurs and number of MEP steps/coarse step exceeds maximum of 255.
        }
    }

    // Disable sync(Freeze clock to PWM as well)
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    // ePWM1 - master
    GPIO_setPadConfig(145, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_145_EPWM1A); // phase UH
    GPIO_setPadConfig(146, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_146_EPWM1B);
   // ePWM2
    GPIO_setPadConfig(147, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_147_EPWM2A); // phase VH
    GPIO_setPadConfig(148, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_148_EPWM2B);
    // ePWM3
    GPIO_setPadConfig(149, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_149_EPWM3A);
    GPIO_setPadConfig(150, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_150_EPWM3B);

    // master PWM gets no phase shift
    set_ePWM_config( EPWM1_BASE, m_period, 0, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
    // slave PWMs get always phase shift 2
    set_ePWM_config( EPWM2_BASE, m_period, 2, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
    set_ePWM_config( EPWM3_BASE, m_period, 2, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );

    EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); // EPWM 1 is master and olny sync generator
    EPWM_setSyncOutPulseMode(EPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // slave
    EPWM_setSyncOutPulseMode(EPWM3_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // slave

    // ADC trigger offset (EPWM_COUNTER_COMPARE_B)
    EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_B, ( adc_trigger_pmwcount ));
    EPWM_setADCTriggerSource(EPWM2_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPB);
    EPWM_setADCTriggerEventPrescale(EPWM2_BASE, EPWM_SOC_A, 1);
    EPWM_enableADCTrigger(EPWM2_BASE, EPWM_SOC_A);
    EPWM_setCounterCompareShadowLoadMode( EPWM2_BASE,
                                          EPWM_COUNTER_COMPARE_B,
                                          EPWM_COMP_LOAD_ON_CNTR_ZERO);

    // Enable global shadow to active load for CMPA registers. See TRM 13.4.7.2 "One-Shot Load Mode"
    EPWM_enableGlobalLoad(EPWM1_BASE);  //GLDCTL[GLD]=1, individual shadowing is ignored
    EPWM_enableGlobalLoadOneShotMode(EPWM1_BASE); // GLDCTL[OSHTMODE] enable one-shot
    EPWM_enableGlobalLoadRegisters(EPWM1_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR); // GLDCFG - register to be shadow-loaded
    EPWM_setGlobalLoadTrigger(EPWM1_BASE, EPWM_GL_LOAD_PULSE_CNTR_PERIOD); //load on CNT_ZERO - GLDCTL[GLDMODE]
    EPWM_setupEPWMLinks(EPWM1_BASE, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_GLDCTL2); //writing to ePWM3 (one shot trigger) causes writing trigger (the same value of GLDCTL2) to ePWM1

    EPWM_enableGlobalLoad(EPWM2_BASE);
    EPWM_enableGlobalLoadOneShotMode(EPWM2_BASE);
    EPWM_enableGlobalLoadRegisters(EPWM2_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR);
    EPWM_setGlobalLoadTrigger(EPWM2_BASE, EPWM_GL_LOAD_PULSE_CNTR_PERIOD);
    EPWM_setupEPWMLinks(EPWM2_BASE, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_GLDCTL2); //writing to ePWM3 (one shot trigger) causes writing trigger to ePWM1

    EPWM_enableGlobalLoad(EPWM3_BASE);
    EPWM_enableGlobalLoadOneShotMode(EPWM3_BASE);
    EPWM_enableGlobalLoadRegisters(EPWM3_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR);
    EPWM_setGlobalLoadTrigger(EPWM3_BASE, EPWM_GL_LOAD_PULSE_CNTR_PERIOD);

    // see Technical Reference page 1566: should be enabled after all ePWMs are initialized
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
	
	
	
	
	
void set_ePWM_config(uint32_t epwm_base, uint16_t period, uint16_t offset, uint16_t deadband_delay_rising_edge, uint16_t deadband_delay_falling_edge)
{
    // Set-up TBCLK
    EPWM_setPeriodLoadMode(epwm_base, EPWM_PERIOD_DIRECT_LOAD); //direct load and never change, shadow is not used for period
    EPWM_setTimeBasePeriod(epwm_base, period);
    EPWM_setPhaseShift(epwm_base, offset);
    EPWM_setTimeBaseCounter(epwm_base, offset);
    EPWM_setEmulationMode(epwm_base, EPWM_EMULATION_FREE_RUN);

    // Set up counter mode
    EPWM_setTimeBaseCounterMode(epwm_base, EPWM_COUNTER_MODE_UP_DOWN);

    EPWM_setClockPrescaler(epwm_base,EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);

    // if offset == 0 then there is master ePWM
    if( 0 == offset )
    {
        EPWM_disablePhaseShiftLoad(epwm_base);
//        HRPWM_disablePhaseShiftLoad(epwm_base);
    }
    else
    {
        EPWM_enablePhaseShiftLoad(epwm_base);
        EPWM_setCountModeAfterSync(epwm_base, EPWM_COUNT_MODE_UP_AFTER_SYNC);
    }
//    HRPWM_selectPeriodLoadEvent(epwm_base, EPWM_SHADOW_LOAD_MODE_SYNC); //load shadow when sync happens, TODO: no one wants to reload period register
//    HRPWM_setCounterCompareShadowLoadEvent(epwm_base, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_PERIOD); //slaves do not reach CNTR==0 because of phase shift --check it!
    // Set actions
    EPWM_setActionQualifierAction(epwm_base,
                                  EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_HIGH,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    // down counting: Output A low
    EPWM_setActionQualifierAction(epwm_base,
                                  EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_LOW,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);

    // enable rising and falling edge delay (S0, S1)
    EPWM_setDeadBandDelayMode(epwm_base, EPWM_DB_RED, true);
    EPWM_setDeadBandDelayMode(epwm_base, EPWM_DB_FED, true);
    // set EPWM_A as "lead" signal (S4, S5)
    EPWM_setRisingEdgeDeadBandDelayInput(epwm_base, EPWM_DB_INPUT_EPWMA);
    EPWM_setFallingEdgeDeadBandDelayInput(epwm_base, EPWM_DB_INPUT_EPWMA);
    // invert output logic of B, don't invert A (S2, S3)
    EPWM_setDeadBandDelayPolarity(epwm_base, EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH);
    EPWM_setDeadBandDelayPolarity(epwm_base, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
    // set output swapping of out_A/out_B (S6, S7)
    EPWM_setDeadBandOutputSwapMode(epwm_base, EPWM_DB_OUTPUT_A, true);
    EPWM_setDeadBandOutputSwapMode(epwm_base, EPWM_DB_OUTPUT_B, true);
    // set delay counts
    EPWM_setFallingEdgeDelayCount(epwm_base, deadband_delay_falling_edge);
    EPWM_setRisingEdgeDelayCount(epwm_base, deadband_delay_rising_edge);

//    HRPWM_disablePeriodControl(epwm_base);
    HRPWM_setMEPControlMode(epwm_base, HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL); //MEP controlled by value of CMPA
    HRPWM_setMEPEdgeSelect(epwm_base, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);

    HRPWM_setDeadbandMEPEdgeSelect(epwm_base, HRPWM_DB_MEP_CTRL_RED_FED);
//    HRPWM_setChannelBOutputPath(epwm_base, HRPWM_OUTPUT_ON_B_INV_A); //dead time is overwritten?
}

  • Hi,

    Give me some time to look into this and get back to you at the earliest. Expect a reply after the weekend.

    Thanks,

    Aditya

  • Hi,

    I don't see the CMPAHR register getting updated in your code. Did you miss to put it in the snippet? That is necessary for the HR to work.

    The upper 8 bits in the 24-bit CMPAHR register only constitutes the HR configuration, so the update that you might be seeing in the expressions window would probably be just for the lower 16 bits. You can refer to any of the available HRPWM examples in C2000Ware for brief understanding about HRPWM configuration.

    Thanks,

    Aditya

  • Hi,

    You are right, i didn't post complete code.

    Here the function which sets duty cycle for 3 ePWM asynchronously from PWM base timer but at once (one shot).

    set_ratio( float uvw_from_0to1[] )
    {
        for (uint16_t i=0; i < 3; i++)
        {
            float ratio = uvw_from_0to1[i] * m_period;
            uint16_t ratio_in_ticks = static_cast<uint16_t>(ratio);
            uint16_t mep_ticks = static_cast<uint16_t>(0.5f + (ratio - (float)(ratio_in_ticks))*(float)MEP_ScaleFactor*2);
    		
            // don't allow 0 ticks (see technical reference manual page 1584)
            if (ratio_in_ticks == 0) 
    		    { ratio_in_ticks = 1; }
            if ((ratio_in_ticks < 3)||(ratio_in_ticks > m_period-3))  //TRM 14.3.1: If HRPCTL[HRPE=0]) and CMPA value is less than three cycles, then its CMPAHR must be cleared to zero.
    		    { mep_ticks = 0; }
            if (i == 0) {
                EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, ratio_in_ticks);
                HRPWM_setHiResCounterCompareValueOnly(EPWM1_BASE, HRPWM_COUNTER_COMPARE_A, mep_ticks);
            }
            else if(i == 1) {
                EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_A, ratio_in_ticks);
                HRPWM_setHiResCounterCompareValueOnly(EPWM2_BASE, HRPWM_COUNTER_COMPARE_A, mep_ticks);
            }
            else if(i == 2) {
                EPWM_setCounterCompareValue(EPWM3_BASE, EPWM_COUNTER_COMPARE_A, ratio_in_ticks);
                HRPWM_setHiResCounterCompareValueOnly(EPWM3_BASE, HRPWM_COUNTER_COMPARE_A, mep_ticks);
                EPWM_setGlobalLoadOneShotLatch( EPWM3_BASE ); //one-shot update for already linked ePWM1 and ePWM2 on the next CNTR_ZERO event (once)
            }
        }
    }

    As mentioned I can observe CMPAHR changes with the help of debugger.

    There is also code for SFO() function called every 5 seconds. It seems to work. The MEP_ScaleFactor global variable is initially 0x40. As the temperature of my board reach 65 Celsius MEP_ScaleFactor is updated to 0x41.

    I assume I should recall not finished SFO() until completed.

    update_millisecond()
    {
        if(( millisecond_counter % 5000 == 0)||(m_sfo_status == SFO_INCOMPLETE)) //5s guard
        {
            m_sfo_status = SFO(); //m_sfo_status is global
            if (m_sfo_status == SFO_ERROR)
            {
                ESTOP0;    // SFO function returns 2 if an error occurs
            }
        }
        millisecond_counter++;
    }

    However, the problem is that with the following line with the deadtime disappear:

    HRPWM_setChannelBOutputPath(epwm_base, HRPWM_OUTPUT_ON_B_INV_A);

  • Hi,

    In addition to the configurations that you've made, you need to enable the bit 'HRPE' from the register HRPCTL for enabling the high resolution period. For that you can use the below mentioned line in your code appropriately.

            HRPWM_enablePeriodControl(EPWM_BASE);

    Let me know if this helps.

    In addition to this, just for information, you don't need to disable and enable both GTBCLKSYNC and TBCLKSYNC. Only one needs to be worked with depending on the application. Global Sync works beyond CPU1 which isn't the case for TBCLKSYNC. You can remove the global sync in your case.

    Thanks,

    Aditya

  • Hi Aditya,

    how should I understand it? I don't want to control period. I just want to controll duty.

    I have tried the command and it doesn't work for me.

  • Hi,

    I need to look into this further more. I cannot see any direct initialization related issue in the code. Let me check back with other experts and get back to you. By the time, can you try and check the initialization configurations with the reference code available in C2000Ware? Also, if you can share the source code?

    Aditya

  • Hi,

    Were you able to resolve the issue? I think the issue could be in global load related configuration. I see that you have enable one-shot mode for this. I am looking into the provided code, let me know if you can share your full code so that I can check it from my end for any issues?

    Thanks

    Vasudha

  • Hello,

    i didn't solve my problem until now. I have still no dead time if using MEP. To clarify I post code files to eaisly compare them line to line. First file configures ePWM solution which works functionaly correct. The second file includes HRPWM as extension of first one, what works with issue "no dead time anymore".
    One shot mode provides all three PWM update at once in runtime. PWM channels integrity is very important. The ::set_ratio() mehod is called from another thread, can be also interrupted. The only sollution semms to be one shot.

    ePWM:

    // Configure ePWM module as master (period == 0) or slave synchronized block.
    void F2837x_Three_Phase_Power_Stage::set_ePWM_config(uint32_t epwm_base,
                                                             uint16_t period,
                                                             uint16_t offset,
                                                             bool invert_high_side_output_logic,
                                                             bool invert_low_side_output_logic,
                                                             uint16_t deadband_delay_rising_edge,
                                                             uint16_t deadband_delay_falling_edge)
    {
        // Set-up TBCLK
        EPWM_setTimeBasePeriod(epwm_base, period);
        EPWM_setPhaseShift(epwm_base, offset);
        EPWM_setTimeBaseCounter(epwm_base, offset);
    
        // Set up counter mode
        EPWM_setTimeBaseCounterMode(epwm_base, EPWM_COUNTER_MODE_UP_DOWN);
    
        EPWM_setClockPrescaler(epwm_base,EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    
        // Set up shadowing
        if( 0 != offset )
        {
            EPWM_setCounterCompareShadowLoadMode(epwm_base,
                                                 EPWM_COUNTER_COMPARE_A,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO);
        }
        // if offset == 0 then there is master ePWM
        if( 0 == offset )
        {
            EPWM_disablePhaseShiftLoad(epwm_base);
            EPWM_selectPeriodLoadEvent(epwm_base, EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO); //TODO: no one wants to reload period register
        }
        else
        {
            EPWM_enablePhaseShiftLoad(epwm_base);
            EPWM_setCountModeAfterSync(epwm_base, EPWM_COUNT_MODE_UP_AFTER_SYNC);
            EPWM_selectPeriodLoadEvent(epwm_base, EPWM_SHADOW_LOAD_MODE_SYNC); //TODO: no one wants to reload period register
        }
    
        // Set actions
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        // down counting: Output A low
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
        // enable rising and falling edge delay (S0, S1)
        EPWM_setDeadBandDelayMode(epwm_base, EPWM_DB_RED, true);
        EPWM_setDeadBandDelayMode(epwm_base, EPWM_DB_FED, true);
        // set EPWM_A as "lead" signal (S4, S5)
        EPWM_setRisingEdgeDeadBandDelayInput(epwm_base, EPWM_DB_INPUT_EPWMA);
        EPWM_setFallingEdgeDeadBandDelayInput(epwm_base, EPWM_DB_INPUT_EPWMA);
        // invert output logic of B, don't invert A (S2, S3)
        EPWM_setDeadBandDelayPolarity(epwm_base, EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH);
        EPWM_setDeadBandDelayPolarity(epwm_base, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
        // set output swapping of out_A/out_B (S6, S7)
        EPWM_setDeadBandOutputSwapMode(epwm_base, EPWM_DB_OUTPUT_A, invert_high_side_output_logic);
        EPWM_setDeadBandOutputSwapMode(epwm_base, EPWM_DB_OUTPUT_B, invert_low_side_output_logic);
        // set delay counts
        EPWM_setFallingEdgeDelayCount(epwm_base, deadband_delay_falling_edge);
        EPWM_setRisingEdgeDelayCount(epwm_base, deadband_delay_rising_edge);
    
    
    }
    
    
    F2837x_Three_Phase_Power_Stage::F2837x_Three_Phase_Power_Stage( float dc_link_voltage_in_V,
                                                                    uint32_t frequency_in_Hz,
                                                                    bool invert_high_side_output_logic,
                                                                    bool invert_low_side_output_logic,
                                                                    uint16_t deadband_delay_rising_edge_in_ticks,
                                                                    uint16_t deadband_delay_falling_edge_in_ticks,
                                                                    uint16_t adc_trigger_pmwcount) :
            Three_Phase_Power_Stage<float>(),
            m_period( ( system::get_cpu_clock_speed() / frequency_in_Hz ) / 4 ), // for up down count mode
            m_invert_high_side_output_logic(invert_high_side_output_logic),
            m_invert_low_side_output_logic(invert_low_side_output_logic),
            m_state(SWITCHES_OPEN),
            m_dc_link_voltage(dc_link_voltage_in_V)
    {
        debugprintf("F2837x_Three_Phase_Power_Stage %lu Hz\r\n", frequency_in_Hz);
    
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3);
    
        // Disable sync(Freeze clock to PWM as well)
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // ePWM1 - master
        GPIO_setPadConfig(145, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_145_EPWM1A); // phase UH
        GPIO_setPadConfig(146, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_146_EPWM1B);
    
       // ePWM2
        GPIO_setPadConfig(147, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_147_EPWM2A); // phase VH
        GPIO_setPadConfig(148, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_148_EPWM2B);
    
        // ePWM3
        GPIO_setPadConfig(149, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_149_EPWM3A);
        GPIO_setPadConfig(150, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_150_EPWM3B);
    
        // master PWM gets no phase shift
        set_ePWM_config( EPWM1_BASE, m_period, 0, m_invert_high_side_output_logic, m_invert_low_side_output_logic, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
        // slave PWMs get always phase shift 2
        set_ePWM_config( EPWM2_BASE, m_period, 2, m_invert_high_side_output_logic, m_invert_low_side_output_logic, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
        set_ePWM_config( EPWM3_BASE, m_period, 2, m_invert_high_side_output_logic, m_invert_low_side_output_logic, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
    
        EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); // EPWM 1 is master and olny sync generator
        EPWM_setSyncOutPulseMode(EPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // slave
        EPWM_setSyncOutPulseMode(EPWM3_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // slave
    
        // Configure the SOC to occur on the first up-count event, doesn't work if PWM1 is the AD trigger, works with PWM2 without further investigation why
        // The chain of SOC conversions must be so triggered that the last SOC (u/v/w-current) meets PWM center. Calculations in excel sheet.
        EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_A, ( adc_trigger_pmwcount ));
        EPWM_setADCTriggerSource(EPWM2_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
        EPWM_setADCTriggerEventPrescale(EPWM2_BASE, EPWM_SOC_A, 1);
        EPWM_enableADCTrigger(EPWM2_BASE, EPWM_SOC_A);
    
        // Enable global shadow to active load for CMPB registers. See TRM 13.4.7.2 "One-Shot Load Mode"
        EPWM_enableGlobalLoad(EPWM1_BASE);  //GLDCTL[GLD]=1, individual shadowing is ignored
        EPWM_enableGlobalLoadOneShotMode(EPWM1_BASE); // GLDCTL[OSHTMODE] enable one-shot
        EPWM_enableGlobalLoadRegisters(EPWM1_BASE, EPWM_GL_REGISTER_CMPB_CMPBHR); // GLDCFG - register to be shadow-loaded
        EPWM_setGlobalLoadTrigger(EPWM1_BASE, EPWM_GL_LOAD_PULSE_CNTR_ZERO); //load on CNT_ZERO - GLDCTL[GLDMODE]
        EPWM_setupEPWMLinks(EPWM1_BASE, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_GLDCTL2); //writing to ePWM3 (one shot trigger) causes writing trigger to ePWM1
    
        EPWM_enableGlobalLoad(EPWM2_BASE);
        EPWM_enableGlobalLoadOneShotMode(EPWM2_BASE);
        EPWM_enableGlobalLoadRegisters(EPWM2_BASE, EPWM_GL_REGISTER_CMPB_CMPBHR);
        EPWM_setGlobalLoadTrigger(EPWM2_BASE, EPWM_GL_LOAD_PULSE_CNTR_ZERO);
        EPWM_setupEPWMLinks(EPWM2_BASE, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_GLDCTL2);
    
        EPWM_enableGlobalLoad(EPWM3_BASE);
        EPWM_enableGlobalLoadOneShotMode(EPWM3_BASE);
        EPWM_enableGlobalLoadRegisters(EPWM3_BASE, EPWM_GL_REGISTER_CMPB_CMPBHR);
        EPWM_setGlobalLoadTrigger(EPWM3_BASE, EPWM_GL_LOAD_PULSE_CNTR_ZERO);
    
        // see Technical Reference page 1566: should be enabled after all ePWMs are initialized
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // if all half bridges are phase synchron and are set to 50% duty cycle, the two zero voltage vectors are set in alternated
        set_ratio(Three_Component_Vector<float>(0.5, 0.5, 0.5));
    
        // switch off at first
        open_switches();
    }
    
    //updating PWM duty works correct
    void F2837x_Three_Phase_Power_Stage::set_ratio( Three_Component_Vector<float> uvw_from_0to1 )
    {
        for (uint16_t i=0; i < 3; i++)
        {
    //      assert( uvw_from_0to1.access_component_by_index(i) <= 1.0f );
    //      assert( uvw_from_0to1.access_component_by_index(i) >= 0.0f );
    
            // saturate
            if( uvw_from_0to1.access_component_by_index(i) > 1.0f ) { uvw_from_0to1.access_component_by_index(i) = 1.0f; }
            if( uvw_from_0to1.access_component_by_index(i) < 0.0f ) { uvw_from_0to1.access_component_by_index(i) = 0.0f; }
            uint16_t ratio_in_ticks = static_cast<uint16_t>(uvw_from_0to1.access_component_by_index(i) * m_period);
    
            // don't allow 0 ticks (see technical reference manual page 1584)
            if (ratio_in_ticks == 0) { ratio_in_ticks = 1; }
    
            if (i == 0) {
                EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, ratio_in_ticks);
            }
            else if(i == 1) {
                EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_B, ratio_in_ticks);
            }
            else if(i == 2) {
                EPWM_setCounterCompareValue(EPWM3_BASE, EPWM_COUNTER_COMPARE_B, ratio_in_ticks);
                EPWM_setGlobalLoadOneShotLatch( EPWM3_BASE ); //one-shot update for already linked ePWM1 and ePWM2 on the next CNTR_ZERO event (once)
            }
        }
    }
    
    
    
    void F2837x_Three_Phase_Power_Stage::enable_pwm_generation(void)
    {
        uint32_t base(EPWM1_BASE);
        for ( uint16_t i = 0; i < 3; i++ )
        {
            switch(i)
            {
                case 0: default: break;
                case 1: base = EPWM2_BASE; break;
                case 2: base = EPWM3_BASE; break;
            }
            EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_SW_DISABLED);
            EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_SW_DISABLED);
    
            //(re)enable deadband unit
            EPWM_setDeadBandDelayMode(base, EPWM_DB_RED, true);
            EPWM_setDeadBandDelayMode(base, EPWM_DB_FED, true);
        }
    
        m_state = OPERATING;
    }
    
    
    void F2837x_Three_Phase_Power_Stage::open_switches(void)
    {
        uint32_t base(EPWM1_BASE);
        for ( uint16_t i = 0; i < 3; i++ )
        {
            switch(i)
            {
                case 1: base = EPWM2_BASE; break;
                case 2: base = EPWM3_BASE; break;
                case 0:
                default:
                    break;
            }
            EPWM_setActionQualifierContSWForceAction( base, EPWM_AQ_OUTPUT_A, (m_invert_high_side_output_logic ? EPWM_AQ_SW_OUTPUT_HIGH : EPWM_AQ_SW_OUTPUT_LOW) );
            EPWM_setActionQualifierContSWForceAction( base, EPWM_AQ_OUTPUT_B, (m_invert_low_side_output_logic ? EPWM_AQ_SW_OUTPUT_HIGH : EPWM_AQ_SW_OUTPUT_LOW) );
    
            // disable rising and falling edge delay (S0, S1): activate bypassing of deadband unit
            EPWM_setDeadBandDelayMode(base, EPWM_DB_RED, false);
            EPWM_setDeadBandDelayMode(base, EPWM_DB_FED, false);
        }
    
        m_state = SWITCHES_OPEN;
    }
    
    float F2837x_Three_Phase_Power_Stage::get_pwm_frequency_in_Hz(void)
    {
        return ( system::get_cpu_clock_speed() / (m_period * 4) );
    }
    
    

    hrPWM:

    extern uint32_t MEP_ScaleFactor = 0; // Global variable used by teh SFO library
    
    #define myEPWM1_BASE EPWM1_BASE
    #define myEPWM2_BASE EPWM2_BASE
    #define myEPWM3_BASE EPWM3_BASE
    
    extern volatile uint32_t ePWM[] = { 0, myEPWM1_BASE, myEPWM2_BASE, myEPWM3_BASE };
    
    // Configure ePWM module as master (period == 0) or slave synchronized block.
    void F2837x_Three_Phase_Power_Stage::set_ePWM_config(uint32_t epwm_base,
                                                             uint16_t period,
                                                             uint16_t offset,
                                                             bool invert_high_side_output_logic,
                                                             bool invert_low_side_output_logic,
                                                             uint16_t deadband_delay_rising_edge,
                                                             uint16_t deadband_delay_falling_edge)
    {
        // Set-up TBCLK
        EPWM_setPeriodLoadMode(epwm_base, EPWM_PERIOD_DIRECT_LOAD); //direct load and never change, shadow is not used for period
        EPWM_setTimeBasePeriod(epwm_base, period);
        EPWM_setPhaseShift(epwm_base, offset);
        EPWM_setTimeBaseCounter(epwm_base, offset);
        EPWM_setEmulationMode(epwm_base, EPWM_EMULATION_FREE_RUN);
    
        // Set up counter mode
        EPWM_setTimeBaseCounterMode(epwm_base, EPWM_COUNTER_MODE_UP_DOWN);
    
        EPWM_setClockPrescaler(epwm_base,EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    
        // if offset == 0 then there is master ePWM
        if( 0 == offset )
        {
            EPWM_disablePhaseShiftLoad(epwm_base);
            HRPWM_disablePhaseShiftLoad(epwm_base);
        }
        else
        {
            EPWM_enablePhaseShiftLoad(epwm_base);
            EPWM_setCountModeAfterSync(epwm_base, EPWM_COUNT_MODE_UP_AFTER_SYNC);
        }
    
        HRPWM_setCounterCompareShadowLoadEvent(epwm_base, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO); //slaves do not reach CNTR==0 because of phase shift --check it!
        EPWM_setCounterCompareShadowLoadMode( epwm_base,
                                              EPWM_COUNTER_COMPARE_A,
                                              EPWM_COMP_LOAD_ON_CNTR_ZERO); //ADC SOC, exactly only for ePWM2
        // Set actions
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        // down counting: Output A low
        EPWM_setActionQualifierAction(epwm_base,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    
        // enable rising and falling edge delay (S0, S1)
        EPWM_setDeadBandDelayMode(epwm_base, EPWM_DB_RED, true);
        EPWM_setDeadBandDelayMode(epwm_base, EPWM_DB_FED, true);
        // set EPWM_A as "lead" signal (S4, S5)
        EPWM_setRisingEdgeDeadBandDelayInput(epwm_base, EPWM_DB_INPUT_EPWMA);
        EPWM_setFallingEdgeDeadBandDelayInput(epwm_base, EPWM_DB_INPUT_EPWMA);
        // invert output logic of B, don't invert A (S2, S3)
        EPWM_setDeadBandDelayPolarity(epwm_base, EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH);
        EPWM_setDeadBandDelayPolarity(epwm_base, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
        // set output swapping of out_A/out_B (S6, S7)
        EPWM_setDeadBandOutputSwapMode(epwm_base, EPWM_DB_OUTPUT_A, invert_high_side_output_logic);
        EPWM_setDeadBandOutputSwapMode(epwm_base, EPWM_DB_OUTPUT_B, invert_low_side_output_logic);
        // set delay counts
        EPWM_setFallingEdgeDelayCount(epwm_base, deadband_delay_falling_edge);
        EPWM_setRisingEdgeDelayCount(epwm_base, deadband_delay_rising_edge);
    
        HRPWM_disablePeriodControl(epwm_base);
        HRPWM_setMEPControlMode(epwm_base, HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL); //MEP controlled by value of CMPA
        HRPWM_setMEPEdgeSelect(epwm_base, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_FALLING_EDGE);
        HRPWM_setChannelBOutputPath(epwm_base, HRPWM_OUTPUT_ON_B_INV_A); //dead time is overwritten, destructed!!!
        HRPWM_setSyncPulseSource(epwm_base, HRPWM_PWMSYNC_SOURCE_PERIOD); //?
    
        HRPWM_setDeadbandMEPEdgeSelect(epwm_base, HRPWM_DB_MEP_CTRL_RED); //no effect of this call
    }
    
    
    F2837x_Three_Phase_Power_Stage::F2837x_Three_Phase_Power_Stage( float dc_link_voltage_in_V,
                                                                    uint32_t frequency_in_Hz,
                                                                    bool invert_high_side_output_logic,
                                                                    bool invert_low_side_output_logic,
                                                                    uint16_t deadband_delay_rising_edge_in_ticks,
                                                                    uint16_t deadband_delay_falling_edge_in_ticks,
                                                                    uint16_t adc_trigger_pmwcount,
                                                                    F2837x_CPU_Timer_0& hw_timer) :
            Three_Phase_Power_Stage<float>(),
            m_period( ( system::get_cpu_clock_speed() / frequency_in_Hz ) / 4 ), // for up down count mode
            m_invert_high_side_output_logic(invert_high_side_output_logic),
            m_invert_low_side_output_logic(invert_low_side_output_logic),
            m_state(SWITCHES_OPEN),
            m_dc_link_voltage(dc_link_voltage_in_V),
            m_ms_cpu_timer(hw_timer),
            m_ms_counter(0),
            m_sfo_status(SFO_INCOMPLETE)
    {
        debugprintf("F2837x_Three_Phase_Power_Stage %lu Hz\r\n", frequency_in_Hz);
    
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_HRPWM); //sourced from ePWM1 clock source
    
        while  (m_sfo_status == SFO_INCOMPLETE) // Call until complete
        {
            m_sfo_status = SFO();
            if (m_sfo_status == SFO_ERROR)
            {
                ESTOP0;    // SFO function returns 2 if an error occurs and number of MEP steps/coarse step exceeds maximum of 255.
            }
        }
    
        // Disable sync(Freeze clock to PWM as well)
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
        // ePWM1 - master
        GPIO_setPadConfig(145, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_145_EPWM1A); // phase UH
        GPIO_setPadConfig(146, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_146_EPWM1B);
    
       // ePWM2
        GPIO_setPadConfig(147, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_147_EPWM2A); // phase VH
        GPIO_setPadConfig(148, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_148_EPWM2B);
    
        // ePWM3
        GPIO_setPadConfig(149, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_149_EPWM3A);
        GPIO_setPadConfig(150, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_150_EPWM3B);
    
        // master PWM gets no phase shift
        set_ePWM_config( EPWM1_BASE, m_period, 0, m_invert_high_side_output_logic, m_invert_low_side_output_logic, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
        // slave PWMs get always phase shift 2
        set_ePWM_config( EPWM2_BASE, m_period, 2, m_invert_high_side_output_logic, m_invert_low_side_output_logic, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
        set_ePWM_config( EPWM3_BASE, m_period, 2, m_invert_high_side_output_logic, m_invert_low_side_output_logic, deadband_delay_rising_edge_in_ticks, deadband_delay_falling_edge_in_ticks );
    
        EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); // EPWM 1 is master and olny sync generator
        EPWM_setSyncOutPulseMode(EPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // slave
        EPWM_setSyncOutPulseMode(EPWM3_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // slave
    
        // Configure the SOC to occur on the first up-count event, doesn't work if PWM1 is the AD trigger, works with PWM2 without further investigation why
        // The chain of SOC conversions must be so triggered that the last SOC (u/v/w-current) meets PWM center. Calculations in excel sheet.
        EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_B, ( adc_trigger_pmwcount ));
        EPWM_setADCTriggerSource(EPWM2_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPB);
        EPWM_setADCTriggerEventPrescale(EPWM2_BASE, EPWM_SOC_A, 1);
        EPWM_enableADCTrigger(EPWM2_BASE, EPWM_SOC_A);
        EPWM_setCounterCompareShadowLoadMode( EPWM2_BASE,
                                              EPWM_COUNTER_COMPARE_B,
                                              EPWM_COMP_LOAD_ON_CNTR_ZERO); //ADC SOC, exactly only for ePWM2
    
        // Enable global shadow to active load for CMPA registers. See TRM 13.4.7.2 "One-Shot Load Mode"
        EPWM_enableGlobalLoad(EPWM1_BASE);  //GLDCTL[GLD]=1, individual shadowing is ignored
        EPWM_enableGlobalLoadOneShotMode(EPWM1_BASE); // GLDCTL[OSHTMODE] enable one-shot
        EPWM_enableGlobalLoadRegisters(EPWM1_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR); // GLDCFG - register to be shadow-loaded
        EPWM_setGlobalLoadTrigger(EPWM1_BASE, EPWM_GL_LOAD_PULSE_CNTR_PERIOD); //load on CNT_ZERO - GLDCTL[GLDMODE]
        EPWM_setupEPWMLinks(EPWM1_BASE, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_GLDCTL2); //writing to ePWM3 (one shot trigger) causes writing trigger (the same value of GLDCTL2) to ePWM1
    
        EPWM_enableGlobalLoad(EPWM2_BASE);
        EPWM_enableGlobalLoadOneShotMode(EPWM2_BASE);
        EPWM_enableGlobalLoadRegisters(EPWM2_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR);
        EPWM_setGlobalLoadTrigger(EPWM2_BASE, EPWM_GL_LOAD_PULSE_CNTR_PERIOD);
        EPWM_setupEPWMLinks(EPWM2_BASE, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_GLDCTL2); //writing to ePWM3 (one shot trigger) causes writing trigger to ePWM1
    
        EPWM_enableGlobalLoad(EPWM3_BASE);
        EPWM_enableGlobalLoadOneShotMode(EPWM3_BASE);
        EPWM_enableGlobalLoadRegisters(EPWM3_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR);
        EPWM_setGlobalLoadTrigger(EPWM3_BASE, EPWM_GL_LOAD_PULSE_CNTR_PERIOD);
    
        // see Technical Reference page 1566: should be enabled after all ePWMs are initialized
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_GTBCLKSYNC);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // if all half bridges are phase synchron and are set to 50% duty cycle, the two zero voltage vectors are set in alternated
        set_ratio(Three_Component_Vector<float>(0.5, 0.5, 0.5));
    
        // switch off at first
        open_switches();
    }
    
    //updating PWM duty works correct
    void F2837x_Three_Phase_Power_Stage::set_ratio( Three_Component_Vector<float> uvw_from_0to1 )
    {
        for (uint16_t i=0; i < 3; i++)
        {
    //      assert( uvw_from_0to1.access_component_by_index(i) <= 1.0f );
    //      assert( uvw_from_0to1.access_component_by_index(i) >= 0.0f );
    
            // saturate
            if( uvw_from_0to1.access_component_by_index(i) > 1.0f ) { uvw_from_0to1.access_component_by_index(i) = 1.0f; }
            if( uvw_from_0to1.access_component_by_index(i) < 0.0f ) { uvw_from_0to1.access_component_by_index(i) = 0.0f; }
    
            float ratio = uvw_from_0to1.access_component_by_index(i) * m_period;
            uint16_t ratio_in_ticks = static_cast<uint16_t>(ratio);
            uint16_t mep_ticks = static_cast<uint16_t>(0.5f + (ratio - (float)(ratio_in_ticks))*(float)MEP_ScaleFactor*2); //MEP scaling factor ca. 66
            // don't allow 0 ticks (see technical reference manual page 1584)
            if (ratio_in_ticks == 0) { ratio_in_ticks = 1; }
            if ((ratio_in_ticks < 3)||(ratio_in_ticks > m_period-3)) { mep_ticks = 0; } //TRM 14.3.1: If HRPCTL[HRPE=0]) and CMPA value is less than three cycles, then its CMPAHR must be cleared to zero.
    
            if (i == 0) {
                EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, ratio_in_ticks);
                HRPWM_setHiResCounterCompareValueOnly(EPWM1_BASE, HRPWM_COUNTER_COMPARE_A, mep_ticks);
            }
            else if(i == 1) {
                EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_A, ratio_in_ticks);
                HRPWM_setHiResCounterCompareValueOnly(EPWM2_BASE, HRPWM_COUNTER_COMPARE_A, mep_ticks);
            }
            else if(i == 2) {
                EPWM_setCounterCompareValue(EPWM3_BASE, EPWM_COUNTER_COMPARE_A, ratio_in_ticks);
                HRPWM_setHiResCounterCompareValueOnly(EPWM3_BASE, HRPWM_COUNTER_COMPARE_A, mep_ticks);
                EPWM_setGlobalLoadOneShotLatch( EPWM3_BASE ); //one-shot update for already linked ePWM1 and ePWM2 on the next CNTR_ZERO event (once)
            }
        }
    }
    
    
    
    void F2837x_Three_Phase_Power_Stage::enable_pwm_generation(void)
    {
        uint32_t base(EPWM1_BASE);
        for ( uint16_t i = 0; i < 3; i++ )
        {
            switch(i)
            {
                case 0: default: break;
                case 1: base = EPWM2_BASE; break;
                case 2: base = EPWM3_BASE; break;
            }
            EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_SW_DISABLED);
            EPWM_setActionQualifierContSWForceAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_SW_DISABLED);
            //(re)enable deadband unit
            EPWM_setDeadBandDelayMode(base, EPWM_DB_RED, true);
            EPWM_setDeadBandDelayMode(base, EPWM_DB_FED, true);
        }
    
        m_state = OPERATING;
    }
    
    
    void F2837x_Three_Phase_Power_Stage::open_switches(void)
    {
        uint32_t base(EPWM1_BASE);
        for ( uint16_t i = 0; i < 3; i++ )
        {
            switch(i)
            {
                case 1: base = EPWM2_BASE; break;
                case 2: base = EPWM3_BASE; break;
                case 0:
                default:
                    break;
            }
            EPWM_setActionQualifierContSWForceAction( base, EPWM_AQ_OUTPUT_A, (m_invert_high_side_output_logic ? EPWM_AQ_SW_OUTPUT_HIGH : EPWM_AQ_SW_OUTPUT_LOW) );
            EPWM_setActionQualifierContSWForceAction( base, EPWM_AQ_OUTPUT_B, (m_invert_low_side_output_logic ? EPWM_AQ_SW_OUTPUT_HIGH : EPWM_AQ_SW_OUTPUT_LOW) );
            // disable rising and falling edge delay (S0, S1): activate bypassing of deadband unit
            EPWM_setDeadBandDelayMode(base, EPWM_DB_RED, false);
            EPWM_setDeadBandDelayMode(base, EPWM_DB_FED, false);
        }
    
        m_state = SWITCHES_OPEN;
    }
    
    float F2837x_Three_Phase_Power_Stage::get_pwm_frequency_in_Hz(void)
    {
        return ( system::get_cpu_clock_speed() / (m_period * 4) );
    }
    
    //called every 60 seconds to update MEP
    void F2837x_Three_Phase_Power_Stage::update(Timer* subject ATTRIBUTE_UNUSED)
    {
        if(( m_ms_counter % 5000 == 0)||(m_sfo_status == SFO_INCOMPLETE)) //0,5s..5s
        {
            m_sfo_status = SFO();
            if (m_sfo_status == SFO_ERROR)
            {
                ESTOP0;    // SFO function returns 2 if an error occurs & # of MEP steps/coarse step
            }              // exceeds maximum of 255.
        }
        m_ms_counter++;
    }
    
    

    Greetings

    Maciej Drozd

  • Hi,

    I think the HRPE bit needs to be set for controlling both period and duty. PFB the description from the TRM.

  • Hi,

    it is hard to understand what happens under HRPE.

    1. When I hange HPRE in run-time with already working PWM (oscilloscope supervision) from 0 to 1 using debugger, then it stops to generate PWM signal.

    2. When I revert HRPE 1 -> 0 after beformentioned, then it will not work again. I have to restart programm.

    Setting HRPE with help of sourcecode and function HRPWM_enablePeriodControl() will cause that PWM will not start at all.

    Why I do observe high resolution PWM with HRPE bit reset (as 0)?

  • HRPE bit needs to be set for controlling both period and duty

    If youre using up-down mode, turn on high-resolution period control for DUTY to take HR on BOTH EDGEs

  • I can close this issue as I have completely rewriten the code. Suggested changes don't help with published above code.