Hi everyone,
I am trying to understand of the implementation of HRPWM phase shift in "DAB_calculatePWMDutyPeriodPhaseShiftTicks()" function under"dab.h" file. The function calculates the shift for either "extended phase shift mode" or "single phase shift mode". Here's a copy for the original function in "dab.h" file.
#pragma FUNC_ALWAYS_INLINE(DAB_calculatePWMDutyPeriodPhaseShiftTicks)
static inline void DAB_calculatePWMDutyPeriodPhaseShiftTicks(void)
{
uint32_t temp;
//
// Calculation for the period is done in high resolution
// as it is used by the phase shift variable in high resolution
//
temp = ((uint32_t)(((float32_t)(DAB_pwmPeriod_pu *
DAB_pwmPeriodMax_ticks) *
(float32_t)65536.0)))>> 1;
DAB_pwmPeriod_ticks = temp & 0xFFFFFF00;
//
// In high resolution phase shift,high resolution duty is not available
// when using HRCFG.CTLMODE as 1 but the calculation below calculates the
// CMPAHR value, it's easier to do so as the period ticks are in high
// resolution format
//
DAB_pwmDutyAPrim_ticks = (uint32_t)((float32_t)DAB_pwmPeriod_ticks *
(float32_t)
(1.0f - fabsf(DAB_pwmDutyPrim_pu)));
DAB_pwmDutyASec_ticks = (uint32_t)((float32_t)DAB_pwmPeriod_ticks *
(float32_t)
(1.0f - fabsf(DAB_pwmDutySec_pu)));
//
// the below is to make sure CMPAHR is never 0x00,
//
if((DAB_pwmDutyAPrim_ticks & 0x00FF00) == 0)
{
DAB_pwmDutyAPrim_ticks = DAB_pwmDutyAPrim_ticks | 0x000100;
}
if((DAB_pwmDutyASec_ticks & 0x00FF00) == 0)
{
DAB_pwmDutyASec_ticks = DAB_pwmDutyASec_ticks | 0x000100;
}
//
// If EPS is enabled, subtract half the added delay (alpha p or alpha S) to get the fundamental phase shift.
//
if(DAB_pwmSwState.pwmSwState == pwmSwState_extendedPhaseShiftControl){
float32_t phi_pu = DAB_pwmPhaseShiftPrimSec_pu - ((DAB_pwmEPSAlphaP_pu + DAB_pwmEPSAlphaS_pu) / 2);
DAB_pwmEPSPhaseShift_P1_P2_ns = DAB_pwmEPSAlphaP_pu *
((float32_t)1.0 / DAB_pwmFrequency_Hz) *
(1 / ONE_NANO_SEC);
DAB_pwmEPSPhaseShift_P1_P2_ticks =
(int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_P2_ns *
DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t) 2 << 16);
if(DAB_pwmEPSPhaseShift_P1_P2_ticks >= 0)
{
DAB_phaseSyncP1_P2CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;
//
// DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
//
}
else
{
DAB_phaseSyncP1_P2CountDirection = EPWM_COUNT_MODE_UP_AFTER_SYNC;
DAB_pwmEPSPhaseShift_P1_P2_ticks = DAB_pwmEPSPhaseShift_P1_P2_ticks * -1;
DAB_pwmPhaseShiftP1_P2_HiResticks = ((uint16_t) 0xFF - ((uint16_t)
(DAB_pwmEPSPhaseShift_P1_P2_ticks & 0x0000FFFF) >> 8));
DAB_pwmEPSPhaseShift_P1_P2_ticks =
((DAB_pwmEPSPhaseShift_P1_P2_ticks & 0xFFFF0000) + 0x10000) +
(DAB_pwmPhaseShiftP1_P2_HiResticks << 8);
}
DAB_pwmEPSPhaseShift_P1_S1_ns = (phi_pu + DAB_pwmEPSAlphaP_pu) *
((float32_t)1.0 / DAB_pwmFrequency_Hz) *
(1 / ONE_NANO_SEC);
DAB_pwmEPSPhaseShift_P1_S1_ticks =
(int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_S1_ns *
DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t)2 << 16);
if(DAB_pwmEPSPhaseShift_P1_S1_ticks >= 0)
{
DAB_phaseSyncP1_S1CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;
//
// DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
//
}
else
{
DAB_phaseSyncP1_S1CountDirection = EPWM_COUNT_MODE_UP_AFTER_SYNC;
DAB_pwmEPSPhaseShift_P1_S1_ticks = DAB_pwmEPSPhaseShift_P1_S1_ticks * -1;
DAB_pwmPhaseShiftP1_S1_HiResticks = ((uint16_t) 0xFF - ((uint16_t)
(DAB_pwmEPSPhaseShift_P1_S1_ticks & 0x0000FFFF)>>8));
DAB_pwmEPSPhaseShift_P1_S1_ticks =
((DAB_pwmEPSPhaseShift_P1_S1_ticks & 0xFFFF0000) + 0x10000) +
(DAB_pwmPhaseShiftP1_S1_HiResticks << 8);
}
DAB_pwmEPSPhaseShift_P1_S2_ns = (phi_pu + DAB_pwmEPSAlphaP_pu + DAB_pwmEPSAlphaS_pu) *
((float32_t)1.0 / DAB_pwmFrequency_Hz) *
(1 / ONE_NANO_SEC);
DAB_pwmEPSPhaseShift_P1_S2_ticks =
(int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_S2_ns *
DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t)2 << 16);
if(DAB_pwmEPSPhaseShift_P1_S2_ticks >= 0)
{
DAB_phaseSyncP1_S2CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;
//
// DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
//
}
else
{
DAB_phaseSyncP1_S2CountDirection = EPWM_COUNT_MODE_UP_AFTER_SYNC;
DAB_pwmEPSPhaseShift_P1_S2_ticks = DAB_pwmEPSPhaseShift_P1_S2_ticks * -1;
DAB_pwmPhaseShiftP1_S2_HiResticks = ((uint16_t) 0xFF - ((uint16_t)
(DAB_pwmEPSPhaseShift_P1_S2_ticks & 0x0000FFFF) >> 8));
DAB_pwmEPSPhaseShift_P1_S2_ticks =
((DAB_pwmEPSPhaseShift_P1_S2_ticks & 0xFFFF0000) + 0x10000) +
(DAB_pwmPhaseShiftP1_S2_HiResticks << 8);
}
}
else{
//
// first the phase shift in pu is converter to ns
// this is done for better debug and user friendliness
//
DAB_pwmEPSPhaseShift_P1_S1_ns = DAB_pwmPhaseShiftPrimSec_pu *
((float32_t)1.0 / DAB_pwmFrequency_Hz) *
(1 / ONE_NANO_SEC);
//
// next this ns is simply converted to ticks
//
DAB_pwmEPSPhaseShift_P1_S1_ticks =
(int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_S1_ns *
DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t)2 << 16);
//
// due to the delay line implementation depending on whether it is
// a phase delay or an advance we need to adjust the
// HR phase shift ticks calculations
//
if(DAB_pwmEPSPhaseShift_P1_S1_ticks >= 0)
{
DAB_phaseSyncP1_S1CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;
//
// DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
//
}
else
{
DAB_phaseSyncP1_S1CountDirection = EPWM_COUNT_MODE_UP_AFTER_SYNC;
DAB_pwmEPSPhaseShift_P1_S1_ticks = DAB_pwmEPSPhaseShift_P1_S1_ticks * -1;
DAB_pwmPhaseShiftP1_S1_HiResticks = ((uint16_t) 0xFF - ((uint16_t)
(DAB_pwmEPSPhaseShift_P1_S1_ticks & 0x0000FFFF) >> 8));
DAB_pwmEPSPhaseShift_P1_S1_ticks =
((DAB_pwmEPSPhaseShift_P1_S1_ticks & 0xFFFF0000) + 0x10000) +
(DAB_pwmPhaseShiftP1_S1_HiResticks << 8);
}
DAB_pwmEPSPhaseShift_P1_P2_ticks = 261888; // Hardcoded offset, equivalent to the phase shift in ticks for input of 0.0ns
DAB_phaseSyncP1_P2CountDirection = EPWM_COUNT_MODE_UP_AFTER_SYNC; // Hard coded to correct offset
DAB_pwmEPSPhaseShift_P1_S2_ticks = DAB_pwmEPSPhaseShift_P1_S1_ticks;
DAB_phaseSyncP1_S2CountDirection = DAB_phaseSyncP1_S1CountDirection;
DAB_pwmPhaseShiftPrimSec_ns = DAB_pwmEPSPhaseShift_P1_S1_ns; //just for gui
}
}
My understanding is that the high resolution ticks "DAB_pwmPhaseShiftP1_S1_HiResticks " and "DAB_pwmEPSPhaseShift_P1_S1_ticks" should be calculated for the entire HRPWM phase shift desired, both in positive or negative phase shifts. However, in the code it seems that the calculation only takes place when the phase shift is negative. Is this accurate? Here's a screenshot to what is being implemented.

Thanks for your help!