cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet driver initialization fails when no link is present at start-up

Daniel Glasser
Associate III
Posted on October 12, 2017 at 02:45

Details: STM32CubeMX v4.22.1, firmware library for the STM32F7xxx family v1.8.0.

Created project for SW4STM32 using (nearly) default pin configuration for the Nucleo-144 with STM32F767ZI (rev Z).

If it matters, the project is configured to generate files for AC6 (sw4stm32).

The code generated in 'Src/main.c' has some problems:

  1. USART3 is initialized after the Ethernet MAC or USB devices (minor problem)
  2. The generated function 'MX_ETH_Init()' calls 'HAL_ETH_Init()'.  If 'HAL_ETH_Init()' returns status other than 'HAL_OK', 'MX_ETH_Init()' calls '_Error_Handler()', which (of course) does not return. 
  3. If there is no Ethernet link present when 'HAL_ETH_Init()' is called, it returns the status 'HAL_TIMEOUT', and does so without fully configuring the PHY for auto-negotiation per the configuration passed in.
  4. Because USART3 has not yet been initialized, attempts to print failure over USART3 fail for things like the Ethernet and USB initialization.

&sharp1, &sharp2, and &sharp4 are just annoying.  It would be less of a problem if the code for those things was not in the 'immutable' sections of the code generated by STM32CubeMX -- every time the project is updated, any changes to the order of driver initialization or the result of the initialization gets overwritten because those changes don't appear between '/* USER CODE BEGIN xxx */' and '/* USER CODE END xxx */' markers.  The new vs. old file have to be manually merged, which is somewhat error prone.  I can live with it, just don't like it.

Issue &sharp3 is the real problem, and it's in the HAL driver code for the STM32F7xx MAC ('stm32f7xx_hal_eth.c').  Througout the code in 'HAL_ETH_Init()', there are loops that look like the following:

tickstart = HAL_GetTick();

do

{

   HAL_ETH_ReadPHYRegister(eth, PHY_BSR, &phyreg);

   if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_LINKED_STATE)

   {

      err = ETH_ERROR;

     ETH_MACDMAConfig(heth, err);

      heth->State = HAL_ETH_STATE_READY;

      __HAL_UNLOCK(heth);

      return HAL_TIMEOUT;

   }

} while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));

This is being done for operations where the current link status should not matter.  Initializing the Ethernet driver should not require that a link can be established at that time.  There are callbacks and other means of notifying user software when a link is established, but configuring the PHY itself should not expect a link to exist.

A timeout reading/writing one of the PHY registers is an error that can cause the driver init to fail, but please, not the Ethernet link itself.

The only workaround I can come up with is to edit the driver code, since I cannot guarentee that I will have a link at start-up (and can pretty much guarentee that it won't 90% of the time).

I've attached my STM32CubeMX project file for anyone who wants to reproduce the problem.

#stm32cubemx #hal-drivers #hal_eth_init #ethernet #stm32f7
5 REPLIES 5
Jeanne Joly
Senior III
Posted on February 13, 2018 at 15:48

Hello

Glasser.Daniel

,

Thanks to highlight this issue and sorry for my late answer.

This issue would be fixed in the next FW_F7 release.

I will keep you informed.

BR. Jeanne

sedlons
Associate II

Same problem with STM32F217VE and STMCUBE 4.27.0 with package 1.7.0.

I just set AutoNegotiation to ETH_AUTONEGOTIATION_DISABLE and do changes in my code instead in driver.

Akio Nakamura
Associate II

Thank you for this valuable infomation.

This is the first time I use Nucleo STM32F767ZI board, bought in Novermber, and hit the same problem.

Using Eclipse, I set up basic functions of USART1& 3 and DMA, with default USB_OTG and ETH ​and run.First run, hung.

Checked the error location and found MX_ETH_Init() is the problem. Commented out this then LD2 & LD3, UART3 works just normal like STM32F303RE Nucleo board. I am just trying to transfer GPS data from UART1 to UART3, the latter connected to TeraTerm.

Since I am still in premitive stages of Nucleo study, I will not use ETH soon, but I will keep this information in my folder for future use.

CKauf
Associate III

Hello Jeanne,

I have the same problem on the STM32F746G-Discovery board with STM32Cube_FW_F7_V1.15.0.

The init-code in 'HAL_ETH_Init()' still looks the same as Daniel described it.

Is there any update available for the driver or a workaround for this issue?

Best regards

Christoph

NPato
Associate II

Hi,

Still not fixed, at least not in the latest firmware for NUCLEO-F207ZG.

A simple workaround ST could implement would be to change:

#define ETH_TIMEOUT_LINKED_STATE           5000U

to be:

#if !defined (ETH_TIMEOUT_LINKED_STATE)
#define ETH_TIMEOUT_LINKED_STATE           5000U
#endif

This would allow the timeout to be reduced at compile time, setting to a low number would allow a quick check at startup while not blocking for 5 seconds.

Thanks

Nigel