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.

TMS320F28379D: Jdjd

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hi,

we have an application where we use TMA320F28379D processor.

we are having a trouble that sometime the epwm TBCTRL register gets initialised and sometime does not.

clock speed for epwm is 100MHz. The chances of getting it initialised are 50%.

During the trouble shooting, I found that of I use epwm clock speed of 50 MHz then i dont see this problem.

anyone has any idea why this could happen? Thanks in advance.

/Usman

  • Hi Usman,

    A few questions - can you clarify what you mean by this?

    sometime the epwm TBCTRL register gets initialised and sometime does not.

    I'd like to know what symptoms you are seeing that imply that the TBCTL register is not getting initialized? Are you stepping through the code in CCS while watching the registers to see that register values change as expected? 

    What values are you changing when you instead use 50MHz EPWM clock 

    Best Regards,

    Allison

  • HI,

    I have following code for initialization of epwm.

    void InitPWM()
    {
    // Disable EPWM clocks
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    // Configure primary IGBT control
    IgbtCtrl_Init(&EPwm1Regs, IGBT_OUTPUT_A); // U1 primary and U3 complementary
    IgbtCtrl_Init(&EPwm2Regs, IGBT_OUTPUT_A); // V1 primary and V3 complementary
    IgbtCtrl_Init(&EPwm3Regs, IGBT_OUTPUT_A); // W1 primary and W3 complementary
    IgbtCtrl_Init(&EPwm10Regs, IGBT_OUTPUT_A); // U2 primary and U4 complementary
    IgbtCtrl_Init(&EPwm11Regs, IGBT_OUTPUT_A); // V2 primary and V4 complementary
    IgbtCtrl_Init(&EPwm12Regs, IGBT_OUTPUT_A); // W2 primary and W4 complementary

    IgbtCtrl_SetPeriod(DTC_T1PR);
    IgbtCtrl_SetMode(IGBT_DTC);

    // Activate interrupt
    EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on each event

    // Start of conversion (SOC)
    EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_PRD; // Trigger SOC-A on Period event
    EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC-A
    EPwm1Regs.ETPS.bit.SOCAPRD = ET_1ST; // Generate pulse on 1st event

    // Configure relay control
    RelayCtrl_Init(&EPwm4Regs); // DC-relay
    RelayCtrl_Init(&EPwm7Regs); // Inverter relay
    RelayCtrl_Init(&EPwm9Regs); // Grid relay

    // Configure fan control
    FanCtrl_Init(&EPwm8Regs);

    // Configure external WD interrupt
    EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV2; // Use 50 MHz counter
    EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Counting up/down
    EPwm5Regs.TBCTR = 0x0000; // Clear counter
    EPwm5Regs.TBPRD = 31250; // 50 MHz / 2 / 31250 = 800 Hz. Divide by two as counting up/down.
    EPwm5Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm5Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on each event
    EPwm5Regs.ETSEL.bit.INTSEL = ET_CTR_PRDZERO; // Interrupts at period and zero events => 1600 Hz ~ 625 us
    }

    function IgbtCtrl_Init() is given below here.

    void IgbtCtrl_Init(volatile struct EPWM_REGS *EPwmRegs_p, enum __IGBT_OUTPUT_UPPER igbt_output_upper)
    {
    // Setup time-base to use a 100 MHz counter (maximum allowed)
    // PLLSYSCLK / EPWMCLKDIV / HSPCLKDIV / CLKDIV = 200 MHz / 2 / 1 / 1 = 100 MHz
    EPwmRegs_p->TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwmRegs_p->TBCTL.bit.CLKDIV = TB_DIV1;
    EPwmRegs_p->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down
    EPwmRegs_p->TBCTR = 0x0000; // Clear counter

    // Link all individual PWMx timebase periods (TBPRD) to PWM1
    EPwmRegs_p->EPWMXLINK.bit.TBPRDLINK = 0; // PWMx period linked to U (PWM1)

    // Configuration of compare control
    EPwmRegs_p->CMPCTL.bit.SHDWAMODE = 0; // Use shadow register
    EPwmRegs_p->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // Load of duty cycle at both zero and period events

    // Configuration of compare actions for PWMxA
    // Output A should be high when the counter is above the compare value and vice versa.
    // Output A needs to be cleared at Zero as no count down event can occur.
    // Output A needs to be set at Period as no count up event can occur.
    EPwmRegs_p->AQCTLA.bit.ZRO = AQ_CLEAR; // Clear A at zero. Needed when the old compare value is period.
    EPwmRegs_p->AQCTLA.bit.CAU = AQ_SET; // Set A on count up
    EPwmRegs_p->AQCTLA.bit.PRD = AQ_SET; // Set A at period. Needed when the old compare value is period.
    EPwmRegs_p->AQCTLA.bit.CAD = AQ_CLEAR; // Clear A on count down

    // Configuration of dead-band submodule
    EPwmRegs_p->DBCTL.bit.IN_MODE = DBA_ALL; // Rising edge delay and falling edge delay controlled by PWMxA
    EPwmRegs_p->DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Both output paths controlled by the dead-band module

    // Initialize dead-band values - conservative default values (reconfigured later)
    EPwmRegs_p->DBRED.bit.DBRED = 75; // Rising edge dead-band = 3us
    EPwmRegs_p->DBFED.bit.DBFED = 75; // Falling edge dead-band = 3us

    // Initialize the polarity settings - standard default values (reconfigured later)
    EPwmRegs_p->DBCTL.bit.POLSEL = DB_ACTV_HIC; // Upper IGBT active high, Lower IGBT active high

    // Configure which output pin of the PWM module that is used for the Upper IGBT and Lower IGBT
    if (igbt_output_upper == IGBT_OUTPUT_A)
    {
    EPwmRegs_p->DBCTL.bit.OUTSWAP = 0; // Pin A controls the Upper IGBT, Pin B controls the Lower IGBT
    }
    else // Swap outputs A and B
    {
    EPwmRegs_p->DBCTL.bit.OUTSWAP = 1; // Pin B controls the Upper IGBT, Pin A controls the lower IGBT
    }
    }

  • Symptoms are that sometime when we start (power-up) our application we do not get the interrupt that is based on epwm1 and hence the code in that interrupt is not executed. and sometime when we start (power-up) the application it works fine. I would say a 50% chance.

    Another strange thing is that we have this product running for last 1.5 years without this problem and all of sudden we are getting this issue.

    what I observe that when we  have the not working start (power-up) then following epwm registers do not show the value for which they are initialized.

    EPwmXRegs.TBCTL.bit.CTRMODE =  TB_FREEZE  instead of TB_COUNT_UPDOWN

    EPwmXRegs.AQCTLA.bit.ZRO = 0 instead of AQ_CLEAR; // Clear A at zero. Needed when the old compare value is period.
    EPwmXRegs.AQCTLA.bit.CAU = 0 instead of AQ_SET; // Set A on count up
    EPwmXRegs.AQCTLA.bit.PRD = 0 instead of AQ_SET; // Set A at period. Needed when the old compare value is period.
    EPwmXRegs.AQCTLA.bit.CAD = 0 instead of AQ_CLEAR; // Clear A on count down

    EPwmXRegs.DBRED.bit.DBRED = 0 instead of 75;
    EPwmXRegs.DBFED.bit.DBFED = 0 instead of 75;

    Now, as said earlier, as the CTRMODE is changed to Freeze or it was perhaps not initialized therefore we do not get the epwm1 interrupt.

  • while playing around with the code, I have noticed that if I place asm(" NOP"); in start and end of IgbtCtrl_Init then I get all the start ups (power-up) working fine.

  • Hello,

    Thanks for sharing the information. A few more questions:

    1. Does this still happen when you step through the code with debugger connected and monitor the registers? Or only in standalone mode? Or both?
    2. Has anything changed in the system setup/hardware or other EPWM initializations recently? 
    3. Do you have any other issues with other ISRs occurring?
    4. Can you please describe all cases you have tried that resolve the issue? Is it just the altering of the EPWM clock and the asm NOP? Or are there other parameters you have changed that resolve the issue?
    5. I also wanted to ask if you are using any of our C2000Ware examples as reference here? These examples are typically a good starting point or comparison to be sure you are initializing and starting up your PWMs in best practice. 

    Best Regards,

    Allison

  • 1. it happens both with and without debugger,

    2. Not that we are aware of. Perhaps we are on the edge earlier also and the new hardware maybe on the extreme end of tolerances making it more vulnerbale.

    3. No. What we observed is that we get the WDRsn flag high when we have this program. This indicates that we had reset of micro-processor due to some reason?

    4.Lowering the Epwm clock to 50MHz instead of 100MHz solved the issue. Inserting asm NOP also helped.

    5. We looked on the examples while writting but have our own code as posted earlier.

    Regards

    Usman

  • Hi Usman,

    When you are connected to the debugger have you tried stepping through the code while monitoring the registers already?

    Are you saying you step over EPWM initializations without seeing the registers change in the registers window? Can you try setting breakpoints within those init functions or perhaps hardware watchpoints for those register locations to confirm that the code is running without the registers changing?

    To confirm, the issue only occurs when you see the WDRsn flag set? After a watchdog reset, the WDRSn bit will be set. Do you disable the watchdog in your device initialization? If you refer to our DriverLib C2000Ware examples as I mentioned, you can see this is done in DeviceInit().

    Have you been scoping the device power lines and EPWM outputs to watch if/when the device resets as well as monitor the PWM output?

    Best Regards,

    Allison