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.

ePWM TBPRD register is resetting to 0xFFFF- Delfino

Other Parts Discussed in Thread: TMS320F28377D

Hi,

We are using TMS320F28377D, delfino DSP controller in our project. We are controlling around 12 stepper motor using ePMWs. They are configured to generate interrupt for every pulse. In ePWM ISR, we are changing the TBPRD and CMPA/CMPB registers to implement ramp up and ramp down for smooth motor start and stop. After the desired pulses are over, we are stopping the ePWM.

Now, the problem we are facing is, after certain sequence of motor start and stop, we found out that one or two ePWM TBPRD & CMPA/CMPB registers are resetting to 0xFFFF and 0x00 respectively even though we are loading a proper period and duty cycle.

Below code is used for configuring the ePWM,

(*ePWM[Channel]).TBCTL.bit.PRDLD = TB_SHADOW; 
(*ePWM[Channel]).TBPRD = period-1;
(*ePWM[Channel]).CMPA.bit.CMPA = 0;

(*ePWM[Channel]).TBPHS.all = 0;
(*ePWM[Channel]).TBCTR = 0;

(*ePWM[Channel]).TBCTL.bit.CTRMODE = TB_COUNT_UP; 
(*ePWM[Channel]).TBCTL.bit.PHSEN = TB_DISABLE;
(*ePWM[Channel]).TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

(*ePWM[Channel]).TBCTL.bit.HSPCLKDIV = 7; //PWM_TB_DIV10;
(*ePWM[Channel]).TBCTL.bit.CLKDIV = 7; // PWM_TB_DIV8;
(*ePWM[Channel]).TBCTL.bit.FREE_SOFT = 3;

(*ePWM[Channel]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
(*ePWM[Channel]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
(*ePWM[Channel]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[Channel]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;

(*ePWM[Channel]).AQCTLA.bit.ZRO = AQ_CLEAR;

(*ePWM[Channel]).AQCTLA.bit.CAU = AQ_CLEAR;

// Interrupt where we will change the Compare Values
(*ePWM[Channel]).ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
(*ePWM[Channel]).ETSEL.bit.INTEN = 1; // Enable INT
(*ePWM[Channel]).ETPS.bit.INTPRD = ET_1ST; //ET_3RD; 0->fist event, 1-> second event, 2-> third event // Generate INT on 3rd event

Following code is used for starting and stopping of ePWM,

if(State == START)
{
(*ePWM[Channel]).TBPRD = period-1;
(*ePWM[Channel]).CMPA.bit.CMPA = (Uint16)(period*0.5); // set duty 50%
(*ePWM[Channel]).AQCTLA.bit.ZRO = AQ_SET; // PWM toggle high/low
(*ePWM[Channel]).AQCTLA.bit.CAU = AQ_CLEAR;
(*ePWM[Channel]).ETSEL.bit.INTEN = 1; // Enable INT
}
else
{
(*ePWM[Channel]).ETSEL.bit.INTEN = 0; // Disable INT
(*ePWM[Channel]).CMPA.bit.CMPA = 0; //DUTY_PERCENT_0; // set duty 0%
(*ePWM[Channel]).AQCTLA.bit.ZRO = AQ_CLEAR; // PWM toggle high/low
(*ePWM[Channel]).AQCTLA.bit.CAU = AQ_CLEAR;
}

We have cross verified our code and nowhere we are loading 0xFFFF to TBPRD. What could be the cause for the registers value resetting.

  • Hi,

    This is really strange behavior. I do not expect the values of TBPRD and CMPA to change unless the values are explicitly written to.
    I've the following questions/suggestions -

    1. ePWM TBPRD & CMPA/CMPB registers resetting to 0xFFFF and 0x0000 is happening consistently? I mean, is this behavior reproduced repeatedly on multiple devices?

    2. Can you try using different values of the following clock divide registers - just for debug purposes?

    (*ePWM[Channel]).TBCTL.bit.HSPCLKDIV = 7; //PWM_TB_DIV10;
    (*ePWM[Channel]).TBCTL.bit.CLKDIV = 7; // PWM_TB_DIV8;

    3. What is the system clock frequency? and what is the ePWM clock frequency?

    -Bharathi.

  • Hi Bharathi,

    Thanks for the reply.

    1. Its consistant & repetitive. We tried with different control card(TMDSCNCD28377D). Still same behavior

    2. Not yet tried since we have not suspected anything from that. But will try out and update you in a day or two

    3. System clock frequency : 200 MHz
    ePWM frequency: 55.803 KHz
  • Hi,

    While you work on the above - i have an additional question.
    What is the value configured for EPWMCLKDIV in PERCLKDIVSEL register?

    -Bharathi

  • Hi,

    EPWMCLKDIV = 1; //Default Value

    Also we have tested with different division value. Still the problem persist

    -Mohan
  • what is the value of period variable? Is it a global variable?
    how is this value being changed in the code?
    Is it possible that the period variable is getting corrupted in the code?

  • The following piece of code is used for updating the frequency and duty cycle. This function is called in PWM ISR. "period" is a passing parameter and we are getting the value from a constant table. We have cross verified the value many times and nowhere we are loading erroneous value. Is there any chance of corrupting TBPRD register if it is updated on the run and in PWM ISR?

    void Pwm1FreqControl(Uint16 period)
    {
    (*ePWM[0]).TBPRD = period-1;
    (*ePWM[0]).CMPA.bit.CMPA = (Uint16)(period*0.5); // set duty 50%
    }

    void Pwm1FreqControlB(Uint16 period)
    {
    (*ePWM[0]).TBPRD = period-1;
    (*ePWM[0]).CMPB.bit.CMPB = (Uint16)(period*0.5); // set duty 50%
    }
  • Mohan,

    I would not expect the value written to TBPRD/CMPA to be corrupted.
    Can you try the following to narrow down the issue, and make sure s/w is not corrupting these regs?

    - Place a check in the s/w whenever there is an update to TBPRD/CMPA registers
    - Check for the value before writing to TBPRD/CMPA and after the updates?
    - Also, check for the value of period before writing to these regs.

    It would also help to know when the value is being corrupted, and when it happens what is the status of rest of the EPWM regs? are they getting corrupted too?

    -Bharathi