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.

TMS320F280049C: Is there any relevant code of HRPWM application in TMS320F280049C?

Part Number: TMS320F280049C
Other Parts Discussed in Thread: TMS320F280049, C2000WARE

Hello All,

I am trying to apply HRPWM in my example code epwm_ex13_up_aq.c for TMS320F280049.

I have added the sample code here for your reference

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//###########################################################################
//
// FILE: epwm_ex13_up_aq.c
//
// TITLE: Action Qualifier Module - Using up count.
//
//! \addtogroup driver_example_list
//! <h1> EPWM Action Qualifier (epwm_up_aq)</h1>
//!
//! This example configures ePWM1, ePWM2, ePWM3 to produce an
//! waveform with independent modulation on EPWMxA and
//! EPWMxB.
//!
//! The compare values CMPA and CMPB are modified within the ePWM's ISR.
//!
//! The TB counter is in up count mode for this example.
//!
//! View the EPWM1A/B(GPIO0 & GPIO1), EPWM2A/B(GPIO2 & GPIO3)
//! and EPWM3A/B(GPIO4 & GPIO5) waveforms via an oscilloscope.
//!
//
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi Ashik,

    The HRPWM examples are located driverlib/[DEVICE]/examples/hrpwm in C2000Ware. Apologies if you had trouble locating these.

    Let me know if you have issues understanding these examples.

    Thank you,

    Luke

  • Hi Luke,

    Thanks for your reply.

    For HRPWM I am using a template quote hrpwm_ex1_duty_sfo.c. 

    I am pretty new with HRPWM. My objective is to have PWM1 and PWM2 to start from zero and stop at 50% duty cycle. I am not considering PWM 3 and 4 now.

    After attaining 50% duty cycle PWM1 and PWM2 should get a phase shift of 10 degree. 

    I am facing problems to keep the duty cycle fix at 50%. In the existing code (attached) after reaching 50% it again goes to initial value.

    Can you suggest a smarter way to apply the phase shift in hrpwm_ex1_duty_sfo.c?

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //#############################################################################
    //
    // FILE: hrpwm_ex1_duty_sfo.c
    //
    // TITLE: HRPWM Duty Control with SFO.
    //
    //! \addtogroup driver_example_list
    //! <h1>HRPWM Duty Control with SFO</h1>
    //!
    //! This example modifies the MEP control registers to show edge displacement
    //! for high-resolution period with ePWM in Up count mode
    //! due to the HRPWM control extension of the respective ePWM module.
    //!
    //! This example calls the following TI's MEP Scale Factor Optimizer (SFO)
    //! software library V8 functions:
    //!
    //! \b int \b SFO(); \n
    //! - updates MEP_ScaleFactor dynamically when HRPWM is in use
    //! - updates HRMSTEP register (exists only in EPwm1Regs register space)
    //! with MEP_ScaleFactor value
    //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Ashik 

  • I tried using EPWM_EMULATION_STOP_AFTER_FULL_CYCLE in EPWM_setEmulationMode.

    But it seems not working. The PWM changes back and forth from minimum to 50%.

  • Hi Luke,

    Hope you are doing fine.

    Is there any suggestion for above issue?

    Ashik

  • Hi Ashik,

    Apologies for the delayed response, I will provide you an update by the end of the day.

    Thank you,

    Luke

  • Hi Ashik, EPWM_EMULATION_STOP_AFTER_FULL_CYCLE in EPWM_setEmulationMode just determines the behavior of the EPWM when the debugger halts the CPU.

    What exactly do you mean by PWM changes back and forth between 50% and the minimum? Is the minimum 0%? Could you send a scope shot of what this looks like?

    Thank you,

    Luke

  • Minimum PWM is probably 4%. I meant that it starts from a minimum (4%) then goes to 50% and again reduces to 4% and it repeats. But I want to stop the repetition after it attains 50% duty cycle. 

    My objective is to start the PWM with a minimum duty cycle and reach maximum 50% slowly and after attaining the 50% duty cycle PWM2 get a 10 degree shift from PWM1. 

    I can send you a scope snapshot tomorrow.

    Ashik

  • Good morning Luke,

    Hope you are doing alright. I have uploaded a short video to make you understand.

    Click here to play this video

    Below is a snapshot when the PWM is 50% duty. (It is PWM1 and PWM2).

    Below is a snapshot when the PWM is minimum duty. (It is PWM1 and PWM2).

    Thanks for your consideration.

    Ashik

  • Ashik,

    Apologies, but the video you sent doesn't seem to be working on my side.

    In your code, you have a for loop inside of a while loop. When the for loop completes, it will restart because it is inside of a while loop. I suspect this is causing your duty cycle to reset to the minimum after it reaches 50%.

    Your code contains the following snippet:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    for(;;)
    {
    //
    // Sweep DutyFine
    //
    for(dutyFine = MIN_HRPWM_DUTY_PERCENT; dutyFine < 50; dutyFine += 0.01) //dutyFine < 99.9
    {
    DEVICE_DELAY_US(1000);
    for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
    {
    float32_t count = (dutyFine * (float32_t)(EPWM_TIMER_TBPRD << 8))/100;
    uint32_t compCount = (count);
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_B, compCount);
    }
    //
    // Call the scale factor optimizer lib function SFO()
    // periodically to track for any change due to temp/voltage.
    // This function generates MEP_ScaleFactor by running the
    // MEP calibration module in the HRPWM logic. This scale
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    But to meet your use-case where the duty cycle stays stuck at 50%, the while loop should come AFTER the for-loop, like this:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //
    // Sweep DutyFine
    //
    for(dutyFine = MIN_HRPWM_DUTY_PERCENT; dutyFine < 50; dutyFine += 0.01) //dutyFine < 99.9
    {
    DEVICE_DELAY_US(1000);
    for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
    {
    float32_t count = (dutyFine * (float32_t)(EPWM_TIMER_TBPRD << 8))/100;
    uint32_t compCount = (count);
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_B, compCount);
    }
    //
    // Call the scale factor optimizer lib function SFO()
    // periodically to track for any change due to temp/voltage.
    // This function generates MEP_ScaleFactor by running the
    // MEP calibration module in the HRPWM logic. This scale
    // factor can be used for all HRPWM channels. The SFO()
    // function also updates the HRMSTEP register with the
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Let me know if this is actually the issue.

    Thank you,

    Luke

  • Great!!! Luke,

    It worked.... Now the PWM stops at 50%.

    Le me try the phase shift now.

    Thanks again.

    Ashik

  • Hi Luke,

    Now I am trying to give phase shift after the PWM stops at 50% duty cycle. I have added another for loop to that will apply only to PWM2 and rest.

    But  it seems not working. Do you have any suggestion for this how to proceed?

    Thank you.

    Ashik

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //
    // Sweep DutyFine
    //
    for(dutyFine = MIN_HRPWM_DUTY_PERCENT; dutyFine < 50; dutyFine += 0.01) //dutyFine < 99.9
    {
    DEVICE_DELAY_US(1000);
    for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
    {
    float32_t count = (dutyFine * (float32_t)(EPWM_TIMER_TBPRD << 8))/100;
    uint32_t compCount = (count);
    //uint32_t compCount = 1;
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_B, compCount);
    }
    //Add Phase
    for(k=2; i<LAST_EPWM_INDEX_FOR_EXAMPLE; k++)
    {
    EPWM_selectPeriodLoadEvent(ePWM[k], EPWM_SHADOW_LOAD_MODE_SYNC);
    EPWM_setPhaseShift(ePWM[k], 50UL);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
     

  • Ashik,

    You have this code:

    for(k=2; i<LAST_EPWM_INDEX_FOR_EXAMPLE; k++)

    Should this change to:

    'for(k=2; k<LAST_EPWM_INDEX_FOR_EXAMPLE; k++)

    I swapped the i with a k

  • Thanks Luke, for pointing this out.

    I have changed the k to i. But it seems not shifting the PWM yet.

    Fo your convenience I have uploaded the whole code again. The void initHRPWM(uint32_t period) function contains all the HRPWM information. I am not sure if i need to change it here or not. This function is called before the for loop we are discussing in earlier reply. So the PWM duty change is happening after calling the function initHRPWM(uint32_t period). So in my understanding the PWM phase change should also be done after sweeping the duty cycle.

    For your information, all the interrupt registers and interrupt enable functions are commented out as they are not used so far.

    Your suggestions will be appreciated.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "SFO_V8.h"
    #define EPWM_TIMER_TBPRD 100UL
    #define MIN_HRPWM_DUTY_PERCENT 1.0/((float32_t)EPWM_TIMER_TBPRD)*100.0 //4.0/((float32_t)EPWM_TIMER_TBPRD)*100.0
    //
    // Defines
    //
    #define LAST_EPWM_INDEX_FOR_EXAMPLE 5
    //
    // Globals
    //
    float32_t dutyFine = MIN_HRPWM_DUTY_PERCENT;
    uint16_t status;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
     

    Ashik

  • Hi Luke,

    Thanks for helping me out.

    If you have any suggestion regarding this you can let me know.

    Ashik

  • Hello Luke,

    Any help on this will be appriceiated.

    Ashik

  • Hi Ashik,

    Apologies for the delayed response.

    Are you enabling PHSEN in your EPWM by using the EPWM_enablePhaseShiftLoad function? I don't see this in your code.

    PHSEN must be set to 1 for a phase shift to take effect when a sync pulse is generated.

    Thank you,

    Luke

  • Hello Luke,

    Thanks for your reply.

    I have enabled the EPWM_enablePhaseShiftLoad function before initiating the loop regarding phase shift.

    It seems have no effect.

    Any suggestion will be appreciated.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
    {
    float32_t count = (dutyFine * (float32_t)(EPWM_TIMER_TBPRD << 8))/100;
    uint32_t compCount = (count);
    //uint32_t compCount = 1;
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);
    HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_B, compCount);
    }
    //Add Phase
    EPWM_enablePhaseShiftLoad(ePWM[i]);//Ashik Added
    for(k=2; k<LAST_EPWM_INDEX_FOR_EXAMPLE; k++)
    {
    EPWM_selectPeriodLoadEvent(ePWM[k], EPWM_SHADOW_LOAD_MODE_SYNC);
    EPWM_setPhaseShift(ePWM[k], 50UL);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Ashik,

    Can you confirm whether this same application code was working correctly before you implemented HRPWM support? It will be difficult to check your entire code to find a potential mistake.

    If this code was working before implementing HRPWM, and you can identify the code changes that you made to incorporate HRPWM support that will make it easier to identify the problem in your code.

    Thank you,

    Luke