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.

LAUNCHXL-F28379D: dual axis drive motor pwm sync issues

Part Number: LAUNCHXL-F28379D

Hi 

We have used the dual axis drive source code to drive our custom inverter Board.

Motor A uses EPWM11, EPWM2, EPWM3

Motor B used EPWM12, EPWM4, EPWM5

When runnig motor B, we see sudden spikes in the Motor Phase currents, probling the MOSFET across source and drain, we see that during the current spike , there is a double pulse event, meaning that the MOSFET is on for a longer duration.

The same is not occuring in Motor A.

I think this is related to the pwm synchronization , which is not happening correctly.

This is my PWM setup function:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void HAL_setupMotorPWMs(HAL_MTR_Handle handle)
{
HAL_MTR_Obj *obj = (HAL_MTR_Obj*) handle;
uint16_t cnt;
uint16_t halfPeriod = 0;
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
// *****************************************
// Inverter PWM configuration - PWM 1, 2, 3
// *****************************************
for (cnt = 0; cnt < 3; cnt++)
{
// Time Base SubModule Registers
// set Immediate load
EPWM_setPeriodLoadMode(obj->pwmHandle[cnt], EPWM_PERIOD_DIRECT_LOAD);
EPWM_setTimeBasePeriod(obj->pwmHandle[cnt], 0);
EPWM_setPhaseShift(obj->pwmHandle[cnt], 0);
EPWM_setTimeBaseCounter(obj->pwmHandle[cnt], 0);
EPWM_setTimeBaseCounterMode(obj->pwmHandle[cnt],
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

You mentioned in the previous thread that we would need to change the sync settings, could you kindly explain what settings exactly need to be changed?

The only change to the function is that i have connected all the EPWM modlues SYNCIN and SYNCOUT signals:

//EPWM1->EWPM4
SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4,
SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
//EPWM1->EWPM7
SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM7,
SYSCTL_SYNC_IN_SRC_EPWM4SYNCOUT);
//EPWM1->EWPM10
SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM10,
SYSCTL_SYNC_IN_SRC_EPWM7SYNCOUT);

  • Adding Motor B oscilloscope images:

    Channel C1 and C2 are probed across Phase U top(Inverted) and bottom MOSFET(Vds), C3 is the DC bus and C4 is Phase U Current.

    You notice the suddent spikes comming in The sine wave

    Here is a zoomed in image, notice the double pulse type event occuring.

  • Any other changes you made? Like PWM frequency? maxModIndex?

  • Switching frequency is 20 KHz, so the maxModIndex changes from 0.98(in SINGLE_SAMPLING) to 0.95.

    We found some success in doing the below changes:

    Instead of disabling phase shift load for PWM11, we have forced it to PWM1 

    if (handle == &halMtr[MTR_1])
    {
    halfPeriod = M1_INV_PWM_TICKS / 2; // 100MHz EPWMCLK

    //EPWM_disablePhaseShiftLoad(obj->pwmHandle[0]); //pwm11
    EPWM_disablePhaseShiftLoad(EPWM1_BASE); -->Changed

    // sync "down-stream"
    //EPWM_setSyncOutPulseMode(obj->pwmHandle[0],EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO);
    EPWM_setSyncOutPulseMode(EPWM1_BASE,EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO);--?Changed

    We had some success, But as the speed was increased this issue was again observed. Our requirment is to reach 10000 RPM running both the motors.

    -Above 7000 RPM, 20 KHz switching frequency: we started observing this issue
    -Then we reduced switching frequency to 15 KHz: we observed this issue at speeds above 9000 RPM
    -Then we further reduced the switching frequency to 12 KHz, we were able to reach 10000 RPM without this event occuring., But if we ramp from 0 to 10000 RPM, because of a small overshoot in speed, at 10000 RPM we catch is issue again.
    But we still don't know the root cause of this and how does changing switching frequecy effect the PWM sync between Motor A and Motor B PWMs.

    One more point, looking at the other reference designs codes(Ex: F2838x, F28002x and F28004x) , we see that the phase shift values between the PWMs are different, so do we need to change the phase shifts values, if so what values do we use?

  • That depends on what EPWM modules for the motor. It's better to use the 3 PWM modules can be easily to synchronized for a motor according to the device, especially on F2838x and F28004x.

    Or you may synchronize the EPWM modules by manual as below if you don't need to change the PWM frequency online.

    // disable the ePWM module time base clock sync signal
    // to synchronize all of the PWMs
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    **Configure all of the PWM modules at here without using the phase shift.

    // enable the ePWM module time base clock sync signal
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

  • That depends on what EPWM modules for the motor. It's better to use the 3 PWM modules can be easily to synchronized for a motor according to the device, especially on F2838x and F28004x.

    We are using PWM11,2,3 for Motor A , and PWM12,4,5 for Motor B. Unfortunately we cannot change the EPWM modules. SO that leaves us witth synchronizing the EPWMs manually..

    Or you may synchronize the EPWM modules by manual as below if you don't need to change the PWM frequency online.

    Yes, we are not changing the switching frequency online, 

    I tried disabling the phase shift for all the PWMs, but at higher speeds again we see this issue...

    This is what i had done, let me know if this is the correct way to disable the phaseshift loading.:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void HAL_setupMotorPWMs(HAL_MTR_Handle handle)
    {
    HAL_MTR_Obj *obj = (HAL_MTR_Obj*) handle;
    uint16_t cnt;
    uint16_t halfPeriod = 0;
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    // *****************************************
    // Inverter PWM configuration - PWM 1, 2, 3
    // *****************************************
    for (cnt = 0; cnt < 3; cnt++)
    {
    // Time Base SubModule Registers
    // set Immediate load
    EPWM_setPeriodLoadMode(obj->pwmHandle[cnt], EPWM_PERIOD_DIRECT_LOAD);
    EPWM_setTimeBasePeriod(obj->pwmHandle[cnt], 0);
    EPWM_setPhaseShift(obj->pwmHandle[cnt], 0);
    EPWM_setTimeBaseCounter(obj->pwmHandle[cnt], 0);
    EPWM_setTimeBaseCounterMode(obj->pwmHandle[cnt],
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


  • Did you call SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC) after the EPWMs are configured?

  • Yes , that is called in the main function , in dual_axis_servo_drive.c

  • Looks good. Please have a try and let's know if have any further questions. Thanks.

  • Hi Yanming, even with the above sollution we get the double pulse issue at 20KHz switching frequency. Is there anything else that we can check?

  • Hi Yanming, I finally got a workable solution, I had to increase the phase shift in Motor B.

    Earlier The phase shift between Motor A and B pwms were 90 degrees. In terms of half period, for a switching frequency of 20 KHz , the half period comes to 2500. So the phase shift in Motor B was 1250(PWM12), 1252(PWM4) and 1254 (PWM5).

    Once i increased the phase difference to 2125, 2127 and 2129, which is approximately 153 degrees, the sudden current spikes have vanished at all desired speeds.

    Here is the code:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void HAL_setupMotorPWMs(HAL_MTR_Handle handle)
    {
    HAL_MTR_Obj *obj = (HAL_MTR_Obj*) handle;
    uint16_t cnt;
    uint16_t halfPeriod = 0;
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    HAL_setupBrCpPWMs(handle);
    // *****************************************
    // Inverter PWM configuration - PWM 1, 2, 3
    // *****************************************
    for (cnt = 0; cnt < 3; cnt++)
    {
    // Time Base SubModule Registers
    // set Immediate load
    EPWM_setPeriodLoadMode(obj->pwmHandle[cnt], EPWM_PERIOD_DIRECT_LOAD);
    EPWM_setTimeBasePeriod(obj->pwmHandle[cnt], 0);
    EPWM_setPhaseShift(obj->pwmHandle[cnt], 0);
    EPWM_setTimeBaseCounter(obj->pwmHandle[cnt], 0);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX