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.

TMS320F2808: ESD events causes operating frequency to change

Part Number: TMS320F2808

We have discovered that ESD events causes the frequency of the TMS320F2808 chip on our PCB interface to change. The DSP restarts correctly most of the time according to the WD settings. However, sometimes the interface freezes and becomes fully or partially unresponsive.

The ESD event is created by discharging from a human body through a screwdriver and to the GND of the interface (or the chassis).

The chip runs at 100MHz with an external crystal of 20MHz and during an ESD event, XCLKOUT is changed to 2.5MHz during the reset. Most of the time XCLKOUT correctly returns to 100MHz and normal operation continues. Unfortunately, sometimes it gets stuck at 2.5MHz or other frequencies such as 0Mhz (XCLKOUT stays high), 5MHz, 17.5MHz, 50MHz and even 200MHz (!). Frequencies under 100MHz cause the DSP to freeze as can be seen from a stripped-down FW where almost only a GPIO is toggling. At 200MHz the GPIO continues to toggle however at double the rate. Debugging is seemingly still possible sometimes at some frequencies (seen at 200MHz and 50MHz). Connecting JTAG, COM, and CAN interfaces to the PCB greatly increases the sensitivity to the ESD events. Also enabling more of our modules in main.c seems to increase the rate at which these freezing events happen. Modules consist of timer interrupts, EEPROM, GPIO, SPI, UART, FLASH, RTC, CAN, PWM, and some of our own modules.

These findings prompted monitoring XCLK, PLLSTS, PLLCR, and WD of the SYSCTRL register. Before going into the details of the registers, it is important to note that no glitches have been seen with the oscilloscope (Siglent SDS1204X-E) on the Vdd(1.8V), VddIO(3.3V), and X2 (external 20MHz crystal) pins during the ESD event. This might be because the voltage spikes are too fast to observe/trigger on. The /XRS pin also seems unchanged during an ESD event. For now, the focus has been on the internal DSP registers.

main.c:

int main( void )
{

#if USE_PORT_CANOPEN
#else
    is_programming = false;
#endif

    _copy_code_from_flash_to_ram();

    InitSysCtrl();
    //modules_init();

    EnableInterrupts();

    SetDog();

    EALLOW;
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 1; // pullup off
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // G16/EQEP1A/SPISIMOC/CANTXB
    GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; // 1:output, 0:input
    GpioDataRegs.GPASET.bit.GPIO16 = 0; // Load output latch
    EDIS;

    for( ; ; )
    {

        RTASSERT_RESET(main_loop_active);

        //ServiceDog();

        GpioDataRegs.GPASET.bit.GPIO16 = 1;
        delay(100);
        GpioDataRegs.GPACLEAR.bit.GPIO16 = 1;
        delay(100);

#if USE_PORT_CANOPEN
#else
        if (is_programming) {   //Exit loop if the start programming message was received
            break;
        }
#endif
        //stackutils_check();
        ServiceDog();

        RTASSERT_IS_LESS(main_loop_active, 15000000);

    }   //End of the main loop


    return 0;
}

InitPll(DSP28_PLLCR,DSP28_CLKINDIV) in InitSysCtrl() where DSP28_PLLCR=10 and DSP28_CLKINDIV=0:

void InitPll(Uint16 val, Uint16 clkindiv)
{
   volatile Uint16 iVol;
   test++;

   // Make sure the PLL is not running in limp mode
   if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
   {
      // Missing external clock has been detected (running in limp mode)
      // Replace this line with a call to an appropriate
      // SystemShutdown(); function. 
       //ResetProc();

//       EALLOW;
//       SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
//       EDIS;
      asm("        ESTOP0");
       //asm(" RPT #20 || NOP");
   }

   // CLKINDIV MUST be 0 before PLLCR can be changed from
   // 0x0000. It is set to 0 by an external reset XRSn
   if (SysCtrlRegs.PLLSTS.bit.CLKINDIV != 0)
   {
       SysCtrlRegs.PLLSTS.bit.CLKINDIV = 0;
   }
   
   // Change the PLLCR
   if (SysCtrlRegs.PLLCR.bit.DIV != val)
   {
       
	   //thread_enter_critical_registers();
       EALLOW;
      // Before setting PLLCR turn off missing clock detect logic
      SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
      SysCtrlRegs.PLLCR.bit.DIV = val;
      EDIS;
      //thread_leave_critical_registers();
   
      // Optional: Wait for PLL to lock.
      // During this time the CPU will switch to OSCCLK/2 until
      // the PLL is stable.  Once the PLL is stable the CPU will 
      // switch to the new PLL value. 
      //
      // This time-to-lock is monitored by a PLL lock counter.   
      //   
      // Code is not required to sit and wait for the PLL to lock.   
      // However, if the code does anything that is timing critical, 
      // and requires the correct clock be locked, then it is best to 
      // wait until this switching has completed.  
  
      // Wait for the PLL lock bit to be set.  
      // Note this bit is not available on 281x devices.  For those devices
      // use a software loop to perform the required count. 

      // The watchdog should be disabled before this loop, or fed within 
      // the loop via ServiceDog().   
      
	  // Uncomment to disable the watchdog
      DisableDog();
   
      while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1) 
      {
	      // Uncomment to service the watchdog
          // ServiceDog();
      }

      //thread_enter_critical_registers();
      EALLOW;
      SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
      SysCtrlRegs.PLLSTS.bit.CLKINDIV != clkindiv;      // Disable CLKIN divide by 2
      EDIS;
      //thread_leave_critical_registers();
    }
}

SYSCTRL during normal 100MHz operation:

SYSCTRL after ESD event where XCLKOUT eventually becomes 200MHz:

SYSCTRL after shorting X2 while XCLKOUT=200MHz. Here XCLK becomes 50MHz while the missing clock flag is set (PLLSTS[MCLKSTS]=1) and the WD is not operating (no changes):

Since PLLSTS[MCLKSTS] is set I assumed XCLKOUT would be in the range of 1-5Mhz, not 50Mhz?

Conducting a SW reset by writing a faulty pattern to WDCR[WDCHK] while debugging during normal operation (XCLKOUT=100MHZ) also freezes the DSP (no GPIO is toggling). XCLKOUT becomes stuck at 2.5MHz while WDCR[WDFLAG] is toggling. The PLLSTS[MCLKSTS] bit is not set, so I am not sure if the is “limp mode” or something else. As for the PLL and XCLK during this test, the following changes are observed:

  • PLLSTS[CLKINDIV] = 0
  • PLLCR[DIV] = 1010b --> PLLCR[DIV] = 0000b (default)
  • PLLSTS[PLLLOCKS] = 1b --> Unchanged
  • XCLK[XCLKDIV] = 10b --> XCLK[XCLKDIV] = 00b

Now the question is if there is any way to reset the DSP so that it resumes normal operation (it goes back to 100Mhz consistently) after resetting from an ESD event? The event does not seem to break the DSP, but the WD is unable to reset somehow and XCLKOUT is stuck at seemingly arbitrary multiples of OSCCLK or it even 0 (staying high). JTAG connection is unfortunately lost during most of the ESD events so reading the registers is not possible making debugging difficult. The goal here is to reset the DSP back to normal operation in order to comply with certification requirements with regards to Electrical Fast Transient Test Failure.

  • ESD/EMI events are capable of inducing all sorts of bizarre behavior in the device. While a WD reset (or an external “warm reset by way of activating the -XRS pin) generally pulls the device out of this indeterminate state, sometimes cycling power is the only way to get the device to function normally again. The solution lies in beefing up the circuit design to make it immune to the disturbance. The challenge lies in determining precisely how the disturbance impacts the circuit. i.e. in identifying exactly how noise couples into the circuit. In other words, what is the conduit for this noise to get into the circuit and cause the malfunction. Once this is identified, it is relatively easy to come up with the protection solution. Unfortunately, often times, the shortcomings are discovered after the board is made and hence make the redesign of the board necessary. 

    Many books have been written on this topic and many papers published. The actual circuit design, the components used, the geometry of the components, the board layout, the board stack-up, the shielding employed , all play a role in the immunity strength of the design. Debugging such problems is an iterative process and warrant hands-on debug. It is extremely difficult to debug issues like this remotely. I’d be happy to take a look at your schematics for any possible improvements. You could share it with me privately without having to post it on the forum. You can do this by requesting my friendship.

  • I have requested your friendship and will provide the DSP and power schematics.

  • Closing the thread since it is being handled offline.