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: ePWM2 producing 1ns wider pulse and SFO lib question

Expert 2530 points

Part Number: TMS320F28377S

Hi

1. We are trying to make 4phase buck. All four ePWMs have CMPA and CMPB registers linked. ePWM7, ePWM8, ePWM6 and ePWM2 should always produce same pulse width, but ePWM2 pulse is about 1ns wider than others. I've double checked all routines, they are almost the same, except different initial TBCTR. Turning HRPWM on or off doesn't change anything. I wonder what could cause this? InitPWM7() and InitPWM2() are below. Two Launchpad boards produce the same PW difference on ePWM2.

2. SFO routine from SFO_v8_fpu_lib_build_c28.lib seems determining MEP_ScaleFactor well, but shouldn't it be done for different ePWM's ? I see HRMSTEP configured for ePWM1 only. All others seem being untouched, HRMSTEP =0. Then what's the purpose of ePWM[] array? No matter, points first element to ePWM1 or ePWM8, still only ePWM1.HRMSTEP is changed.

Thanks

Edward

static void InitPWM7(void)

{

EALLOW;

GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1; // Disable pull-up on GPIO12 (EPWM7A)

GpioCtrlRegs.GPAPUD.bit.GPIO13 = 1; // Disable pull-up on GPIO13 (EPWM7B)

GpioCtrlRegs.GPAGMUX1.bit.GPIO12 = 0; // Configure GPIO2 as EPWM7A

GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 1; // Configure GPIO2 as EPWM7A

GpioCtrlRegs.GPAGMUX1.bit.GPIO13 = 0; // Configure GPIO3 as EPWM7B

GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 1; // Configure GPIO3 as EPWM7B

EPwm7Regs.TBCTL.bit.CTRMODE = TB_FREEZE; // Count up

EPwm7Regs.TBCTL.bit.FREE_SOFT = 2; // free run

 

EPwm7Regs.TBCTR = 0x0000+INIPHOFFSET; // initial ctr

EPwm7Regs.TBPRD = (EPWM_CLOCK / PWM_FREQ)-1; // Set timer period

EPwm7Regs.TBPHS.all = 0x0000; // Phase is 0

 

 

//

// Setup TBCLK

//

EPwm7Regs.TBCTL.bit.PHSDIR = TB_UP;

EPwm7Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading

EPwm7Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT

EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow just to observe on

// the scope

EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO

EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

//

// Setup compare

//

EPwm7Regs.CMPA.bit.CMPA = 0;

//

// Set actions

//

EPwm7Regs.AQCTLA.bit.CAU = AQ_CLEAR;

EPwm7Regs.AQCTLA.bit.ZRO = AQ_SET;

//EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; // optional

//EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // optional

//

// Active Low complementary PWMs - setup the deadband

//

EPwm7Regs.DBCTL.bit.HALFCYCLE = 1;

EPwm7Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

EPwm7Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;

EPwm7Regs.DBCTL.bit.IN_MODE = DBA_ALL;

//EPwm2Regs.DBRED.bit.DBRED = 4;

//EPwm2Regs.DBREDHR.bit.DBREDHR = 100;

//EPwm2Regs.DBFED.bit.DBFED = 4;

//EPwm2Regs.DBFEDHR.bit.DBFEDHR = 100;

 

// SOCA pulse to ADC

EPwm7Regs.ETPS.bit.SOCAPRD = 1;

EPwm7Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // Select INT on Zero event

EPwm7Regs.ETSEL.bit.SOCAEN = 1;

//

// Interrupt where we will modify the deadband

//

// EPwm7Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event

// EPwm7Regs.ETSEL.bit.INTEN = 1; // Enable INT

// EPwm7Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event

 

EPwm7Regs.HRCNFG.all = 0x0;

#if !NOHRPWM

EPwm7Regs.HRCNFG.bit.EDGMODE = HR_FEP;

EPwm7Regs.HRCNFG.bit.CTLMODE = HR_CMP;

EPwm7Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;

EPwm7Regs.HRCNFG.bit.EDGMODEB = HR_REP;

EPwm7Regs.HRCNFG.bit.CTLMODEB = HR_CMP;

EPwm7Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;

EPwm7Regs.HRCNFG2.bit.EDGMODEDB = 3; // both

#endif

EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up

//EPwm7Regs.HRCNFG.bit.AUTOCONV = 1;

//EPwm7Regs.HRMSTEP.all = 0xFFFF;

 

EPwm7Regs.TZSEL.bit.CBC6 = 1; // on CPU stop

EPwm7Regs.TZCTL.bit.TZA = TZ_FORCE_LO;

EPwm7Regs.TZCTL.bit.TZB = TZ_NO_CHANGE;

EDIS;

}

static void InitPWM2(void)

{

EALLOW;

GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1; // Disable pull-up on GPIO12 (EPWM7A)

GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1; // Disable pull-up on GPIO13 (EPWM7B)

GpioCtrlRegs.GPAGMUX1.bit.GPIO2 = 0; // Configure GPIO2 as EPWM7A

GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Configure GPIO2 as EPWM7A

GpioCtrlRegs.GPAGMUX1.bit.GPIO3 = 0; // Configure GPIO3 as EPWM7B

GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // Configure GPIO3 as EPWM7B

if(phbcfg == PHBCFG_4ph)

EPwm2Regs.TBCTL.bit.FREE_SOFT = 2; // free run

else

EPwm2Regs.TBCTL.bit.FREE_SOFT = 1; // stop when whole cycle completes, ~safe for debugger stop

 

EPwm2Regs.TBPRD = (EPWM_CLOCK / PWM_FREQ)-1; // Set timer period

EPwm2Regs.TBPHS.all = 0x0000; // Phase is 0

if(phbcfg == PHBCFG_4ph)

EPwm2Regs.TBCTR = EPWM_CLOCK / PWM_FREQ / 2 -1+INIPHOFFSET;

else

EPwm2Regs.TBCTR = 0; // sync TEC's

//

// Setup TBCLK

//

EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;

EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up

EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading

EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT

EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow just to observe on

// the scope

EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO

EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

//

// Setup compare

//

EPwm2Regs.CMPA.bit.CMPA = 0;

//

// Set actions

//

EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;

//EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; // optional

//EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // optional

//

// Active Low complementary PWMs - setup the deadband

//

EPwm2Regs.DBCTL.bit.HALFCYCLE = 1;

EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;

EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;

//EPwm2Regs.DBRED.bit.DBRED = 4;

//EPwm2Regs.DBREDHR.bit.DBREDHR = 100;

//EPwm2Regs.DBFED.bit.DBFED = 4;

//EPwm2Regs.DBFEDHR.bit.DBFEDHR = 100;

//

// Interrupt where we will modify the deadband

//

// EPwm7Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event

// EPwm7Regs.ETSEL.bit.INTEN = 1; // Enable INT

// EPwm7Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event

 

EPwm2Regs.HRCNFG.all = 0x0;

#if !NOHRPWM

EPwm2Regs.HRCNFG.bit.EDGMODE = HR_FEP;

EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;

EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;

EPwm2Regs.HRCNFG.bit.EDGMODEB = HR_REP;

EPwm2Regs.HRCNFG.bit.CTLMODEB = HR_CMP;

EPwm2Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;

EPwm2Regs.HRCNFG2.bit.EDGMODEDB = 3; // both

#endif

//EPwm2Regs.HRCNFG.bit.AUTOCONV = 1;

//EPwm2Regs.HRMSTEP.all = 0xFFFF;

if(phbcfg == PHBCFG_4ph)

{

#if !BUG1ns

EPwm2Regs.EPWMXLINK.bit.CMPBLINK = 7-1;

EPwm2Regs.EPWMXLINK.bit.CMPALINK = 7-1;

#endif

EPwm2Regs.TZSEL.bit.CBC6 = 1; // on CPU stop

EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO;

EPwm2Regs.TZCTL.bit.TZB = TZ_NO_CHANGE;

}

 

EDIS;

}

  • Hi Edward,

    Just to make sure we understand the issue, are you able to attach a waveform of what you are seeing and what you would expect?

    Regards,
    Kris
  • Hi Kris,

    Thanks for response.

    Colleague didn't pay attention at rising falling times and reported just measured pulse widths. Falling edge on GPIO2 is longer, which is not a problem. Sorry for noise, the first question is solved. Question about SFO() remains: Why does SFO lib calibrate HRMSTEP only for ePWM1 and doesn't calibrate remaining ePWM's .

    Regards,
    Edward