cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429 + LAN8742A - reinitialize LWIP/network after ESD shock

jp9
Associate II

EDIT: 

After doing some more research and testing, I've discovered that doing a software reset of the STM32 actually pulls the nRST pin itself low briefly. I did not realize this.  I assumed a software reset was purely internal.

In my previous testing, I noticed that the LAN8742A PHY was recovering after resetting only the STM32, so I thought it was something in the startup initialization sequence that was pulling the PHY out.  However, I now realize that the PHY is also being hard reset.  

(more details about this in latest reply below).

ORIGINAL MESSAGE:

Hello.  We have a controller using an STM32F429 with a LAN8742A ethernet phy.  That part of the design is roughly based on the STM32F429 discovery board.  Long story short - what is the correct process/procedure for reinitializing everything related to ethernet and LWIP?  We are experience ethernet lockups associated with electrical noise.  Resetting the STM32 without resetting the PHY seems to recover communication, but since this is running a piece of equipment, we are not able to fully reset while running.  

Details:

We are running FreeRTOS with LWIP, with a communication protocol using a single UDP socket.  This runs great, but occasionally a controller will stop responding to UDP requests.  We have done extensive bench testing of leaving controllers running for days and they never lose communication.  However, these controllers are in HVAC units, so there is some electrical noise from contactors and other equipment.

I have been able to reproduce the issue with ESD discharges to a board.  About 1 out of 10 times, a light ESD shock to the board in the area of the ethernet jack and PHY is enough to lock up the ethernet so that it no longer responds.  Everything else on the controller is still running and otherwise working - the ethernet simply stops responding.

We do not have a separate hardware reset line for the PHY - it is tied to the global reset - so we are not able to hard reset the PHY.  Doing a software reset of the PHY does not help.

One clue is that I *was* able to recover communication by triggering a chip reset of the STM32.  In this case, the LAN8742A is *not* hard reset, but the STM32 obviously goes through it's startup and initialization.  After this, the ethernet works.  So I'm convinced that I should be able to re-initialize the ethernet-related stuff and be able to recover without doing a full reset.  However, this isn't quite working.  I've done what I though is needed to bring down and reinitialize everything ethernet-related, but after that process. the MACCR register is all 0s, so nothing is enabled.  I suspect something is not in a state to be able to be configured when I'm trying to configure it - either something doesn't have a clock when it needs to, or *does* have a clock when it shouldn't.  

What is the correct sequence to fully re-initialize ethernet and LWIP as it would be after startup?  Here is what I have now:

void ethernet_phy_reset_thread(void const * argument)
{

  uint32_t oldRxCount = 0;
  ETH_MACConfigTypeDef MACConf = {0};
  for(;;)
  {

    phyResetTimer++;
    // FIXME: this is probably *not* the ideal way to determine if we are down
    if(getRxUnicastGoodFrameCount() != oldRxCount){
      oldRxCount = getRxUnicastGoodFrameCount();
      phyResetTimer = 0;
    }

    // if(phyResetTimer > PHY_RESET_INTERVAL * 60){
    // FIXME: short timer for testing
    if(phyResetTimer >10){
      phyResetInProgress = true;
      phyResetTimer = 0;
      phyResetCount++;
// FIXME: FIXME: FIXME: take out!!! - testing CPU reset(without hard resetting the PHY) to see if it is the CPU or the PHY that is locked
      // NVIC_SystemReset();
      // while(1);
     
     
      // Bring netif down
      netif_set_down(&gnetif);
      netif_set_link_down(&gnetif);

      // Deinit ETH peripheral
      HAL_ETH_DeInit(&heth);

      osDelay(2);
      HAL_ETH_MspDeInit(&heth);
      osDelay(2);
      // Optionally re-init ETH GPIO pins
      HAL_ETH_MspInit(&heth);
      osDelay(2);
      LAN8742_DeInit(&LAN8742);
      osDelay(2);
     
      // Toggle RMII interface
      SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL;
      osDelay(2);
      SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
      osDelay(2);
      LAN8742_Init(&LAN8742);
      osDelay(2);



      // Reinitialize DMA descriptors(must be done after de-initializing ETH peripheral)
      heth.Init.RxDesc = DMARxDscrTab;
      heth.Init.TxDesc = DMATxDscrTab;
      heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;

      // Reinit ETH peripheral
      HAL_ETH_Init(&heth);

      // Reinit MAC config if needed
      HAL_ETH_GetMACConfig(&heth, &MACConf);
      MACConf.DuplexMode = ETH_FULLDUPLEX_MODE; // or as detected
      MACConf.Speed = ETH_SPEED_100M;           // or as detected
      HAL_ETH_SetMACConfig(&heth, &MACConf);

      // Start ETH interrupts
      HAL_ETH_Start_IT(&heth);

      // Bring netif up
      netif_set_up(&gnetif);
      netif_set_link_up(&gnetif);
     

      phyResetInProgress = false;
    }

    osDelay(1000);
  }
}

 

10 REPLIES 10

Thanks, I've posted to Microchip's form also, specifically about the LAN8742A.  

From the STM32F429 side, is there a way to detect if it is not receiving the 50MHz REF_CLK input?  Some sort of status bit in a register or something?  

If I end up having to reset the whole controller in order to recover the LAN8742A, I want to make sure to only do that if I have to.  I don't want to end up resetting the controller simply because it hasn't received any packets in a while, as this could happen during normal operation and isn't necessarily an indication of a lockup of the PHY.

If the STM32 could detect if it has or doesn't have the REF_CLK signal, then I'd be much more comfortable resetting if I knew I lost that.

 

Thanks!