Part Number: LAUNCHXL-F28379D
Hi Yanming Luo
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:
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],
EPWM_COUNTER_MODE_UP_DOWN);
EPWM_setClockPrescaler(obj->pwmHandle[cnt], EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
// Counter Compare Submodule Registers
// set duty 0% initially
EPWM_setCounterCompareValue(obj->pwmHandle[cnt], EPWM_COUNTER_COMPARE_A,
0);
EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[cnt],
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
// Action Qualifier SubModule Registers
EPWM_setActionQualifierActionComplete(
obj->pwmHandle[cnt],
EPWM_AQ_OUTPUT_A,
(EPWM_ActionQualifierEventAction) (EPWM_AQ_OUTPUT_LOW_UP_CMPA
| EPWM_AQ_OUTPUT_HIGH_DOWN_CMPA));
// Active high complementary PWMs - Set up the deadband
EPWM_setRisingEdgeDeadBandDelayInput(obj->pwmHandle[cnt],
EPWM_DB_INPUT_EPWMA);
EPWM_setFallingEdgeDeadBandDelayInput(obj->pwmHandle[cnt],
EPWM_DB_INPUT_EPWMA);
EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_RED, true);
EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_FED, true);
EPWM_setDeadBandDelayPolarity(obj->pwmHandle[cnt], EPWM_DB_RED,
EPWM_DB_POLARITY_ACTIVE_HIGH);
EPWM_setDeadBandDelayPolarity(obj->pwmHandle[cnt], EPWM_DB_FED,
EPWM_DB_POLARITY_ACTIVE_LOW);
/*
* INFO: PWM Dead Time
* Change this to change the pwm dead time.
*/
EPWM_setRisingEdgeDelayCount(obj->pwmHandle[cnt], EPWM_DB_DELAY_RISE);
EPWM_setFallingEdgeDelayCount(obj->pwmHandle[cnt], EPWM_DB_DELAY_FALL);
EPWM_enablePhaseShiftLoad(obj->pwmHandle[cnt]);
EPWM_setCountModeAfterSync(obj->pwmHandle[cnt],
EPWM_COUNT_MODE_UP_AFTER_SYNC);
// configure sync
EPWM_setSyncOutPulseMode(obj->pwmHandle[cnt],
EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);
}
//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);
if (handle == &halMtr[MTR_1])
{
halfPeriod = M1_INV_PWM_TICKS / 2; // 100MHz EPWMCLK
EPWM_disablePhaseShiftLoad(obj->pwmHandle[0]);
// sync "down-stream"
EPWM_setSyncOutPulseMode(obj->pwmHandle[0],
EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO);
// EPWM_setSyncOutPulseMode(obj->pwmHandle[0],
// EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);
EPWM_setPhaseShift(obj->pwmHandle[0], 0);
EPWM_setPhaseShift(obj->pwmHandle[1], 2);
EPWM_setPhaseShift(obj->pwmHandle[2], 4);
EPWM_setTimeBasePeriod(obj->pwmHandle[0], halfPeriod);
EPWM_setTimeBasePeriod(obj->pwmHandle[1], halfPeriod);
EPWM_setTimeBasePeriod(obj->pwmHandle[2], halfPeriod);
}
else if (handle == &halMtr[MTR_2])
{
halfPeriod = M2_INV_PWM_TICKS / 2; // 100MHz EPWMCLK
EPWM_setPhaseShift(obj->pwmHandle[0], ((halfPeriod >> 1) + 0));
EPWM_setPhaseShift(obj->pwmHandle[1], ((halfPeriod >> 1) + 2));
EPWM_setPhaseShift(obj->pwmHandle[2], ((halfPeriod >> 1) + 4));
EPWM_setTimeBasePeriod(obj->pwmHandle[0], halfPeriod);
EPWM_setTimeBasePeriod(obj->pwmHandle[1], halfPeriod);
EPWM_setTimeBasePeriod(obj->pwmHandle[2], halfPeriod);
}
// Setting up link from EPWM to ADC
// EPWM1/EPWM4 - Inverter currents at sampling frequency
// (@ PRD or @ (PRD&ZRO) )
#if(SAMPLING_METHOD == SINGLE_SAMPLING)
// Select SOC from counter at ctr = prd
EPWM_setADCTriggerSource(obj->pwmHandle[0], EPWM_SOC_A,
EPWM_SOC_TBCTR_ZERO);
#elif(SAMPLING_METHOD == DOUBLE_SAMPLING)
// Select SOC from counter at ctr = 0 or ctr = prd
EPWM_setADCTriggerSource(obj->pwmHandle[0], EPWM_SOC_A,
EPWM_SOC_TBCTR_ZERO_OR_PERIOD);
#endif
// Generate pulse on 1st event
EPWM_setADCTriggerEventPrescale(obj->pwmHandle[0], EPWM_SOC_A, 1);
// Enable SOC on A group
EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_A);
return;
}
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);


