AnsweredAssumed Answered

Initialize LWIP with Ethernet disconnected

Question asked by Gates on Nov 4, 2016
Latest reply on Apr 3, 2018 by Kolja Waschk
Hello !

The board I am using for this topic is based on the ST STM3220G-EVAL hardware for the Ethernet part.

I have generated a basic code with cubeMx (nice tool!) and Ethernet communication is working well on this board.

The problem is that Ethernet is working only when Ethernet cable is connected at startup (especially when initialization function is run). If I start my board without cable, Ethernet is not working (ping test failed) and will never work even if I connect the cable.

To solve this, I added the following function after LWIP initialization:

netif_set_link_callback(&gnetif, ethernetif_update_config);

The "ethernetif_update_config" function is generated by cubeMx (in ethernetif.c file) to restart auto-negotiation:

/**
  * @brief  Link callback function, this function is called on change of link status
  *         to update low level driver configuration.
* @param  netif: The network interface
  * @retval None
  */
void ethernetif_update_config(struct netif *netif)
{
  __IO uint32_t tickstart = 0;
  uint32_t regvalue = 0;
   
  if(netif_is_link_up(netif))
  {
    /* Restart the auto-negotiation */
    if(heth.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
    {
      /* Enable Auto-Negotiation */
      HAL_ETH_WritePHYRegister(&heth, PHY_BCR, PHY_AUTONEGOTIATION);
       
      /* Get tick */
      tickstart = HAL_GetTick();
       
      /* Wait until the auto-negotiation will be completed */
      do
      {
        HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, ®value);
         
        /* Check for the Timeout ( 1s ) */
        if((HAL_GetTick() - tickstart ) > 1000)
        {    
          /* In case of timeout */
          goto error;
        }  
      } while (((regvalue & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
       
      /* Read the result of the auto-negotiation */
      HAL_ETH_ReadPHYRegister(&heth, PHY_SR, ®value);
       
      /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
      if((regvalue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
      {
        /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
        heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX; 
      }
      else
      {
        /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
        heth.Init.DuplexMode = ETH_MODE_HALFDUPLEX;          
      }
      /* Configure the MAC with the speed fixed by the auto-negotiation process */
      if(regvalue & PHY_SPEED_STATUS)
      
        /* Set Ethernet speed to 10M following the auto-negotiation */
        heth.Init.Speed = ETH_SPEED_10M;
      }
      else
      {  
        /* Set Ethernet speed to 100M following the auto-negotiation */
        heth.Init.Speed = ETH_SPEED_100M;
      }
    }
    else /* AutoNegotiation Disable */
    {
    error :
      /* Check parameters */
      assert_param(IS_ETH_SPEED(heth.Init.Speed));
      assert_param(IS_ETH_DUPLEX_MODE(heth.Init.DuplexMode));
       
      /* Set MAC Speed and Duplex Mode to PHY */
      HAL_ETH_WritePHYRegister(&heth, PHY_BCR, ((uint16_t)(heth.Init.DuplexMode >> 3) |
                                                     (uint16_t)(heth.Init.Speed >> 1)));
    }
 
    /* ETHERNET MAC Re-Configuration */
    HAL_ETH_ConfigMAC(&heth, (ETH_MACInitTypeDef *) NULL);
 
    /* Restart MAC interface */
    HAL_ETH_Start(&heth);  
  }
  else
  {
    /* Stop MAC interface */
    HAL_ETH_Stop(&heth);
  }
 
  ethernetif_notify_conn_changed(netif);
}


Unfortunately, when I manually launch this callback by calling the "netif_set_link_up(&gnetif)" function after connecting the cable, Ethernet is still not working.

Is anybody having an idea on how to make Ethernet working in this configuration?

Thank you for your help

Outcomes