Skip to main content
paulrbryson
Associate III
Jan 19, 2026 3:17 PM UTC
Solved

nucleo-429zi ethernet Phy Sometimes fails auto-negotiation

I am using a Nucelo-429zi board for development and my custom PCB schematic is based on this board.  I am experiencing a problem where about 10% - 20% of the time after a hardware reset the PHY will fail auto-negotiation.  The green led does not come on and the amber led blinks.  This happens even when on the debugger and the MCU is not allowed to run.  I only have one Nucleo board so I cannot try another to see if the problem is unique to this board.

Is this a known problem? seen before?

What could it be?  Possibly the clock circuit?

paulrbryson
paulrbrysonBest answer
Associate III
Jan 21, 2026 7:35 AM UTC

I am not sure of the cause for the original problem - i.e. a hardware reset leaves the PHY in "bad" state.  I suspect it may have something to do with the internal 25MHz oscillator not stabilizing before auto-negotiation starts?  
In any event I found what looks to be a reliable solution - retstart the auto-negotiation in firmware after the PHY chip has stabilized.  I Inserted the following code in the stm32cubemx generated source, in "ethernet.c".

 

 
/* USER CODE BEGIN PHY_PRE_CONFIG */
 /* Force a PHY Auto-Negotiation -- Hardware Reset Can leave Phy in Bad state*/
 {
 /* PHY Register Definitions */
 const uint32_t NEG_LAN8742A_ADDRESS = 0x00U;
 const uint32_t NEG_PHY_BCR = 0x00U; /* Basic Control Register */
 const uint32_t NEG_PHY_BCR_SOFT_RESET = (1 << 15);
 const uint32_t NEG_PHY_BCR_AUTONEGO_EN = (1 << 12);
 const uint32_t NEG_PHY_BCR_RESTART_AN = (1 << 9);
 
 /* Implementation of the missing function */
 uint32_t phy_reg = 0;
 
 // 1. Send Soft Reset command
 HAL_ETH_WritePHYRegister(&heth, NEG_LAN8742A_ADDRESS, NEG_PHY_BCR, NEG_PHY_BCR_SOFT_RESET);
 
 // 2. Wait for Reset bit to self-clear (indicates PHY is ready)
 uint32_t timeout = HAL_GetTick() + 500;
 do {
 HAL_ETH_ReadPHYRegister(&heth, NEG_LAN8742A_ADDRESS, NEG_PHY_BCR, &phy_reg);
 } while ((phy_reg & NEG_PHY_BCR_SOFT_RESET) && (HAL_GetTick() < timeout));
 
 // 3. Force Auto-Negotiation Enable and Restart
 HAL_ETH_WritePHYRegister(&heth, NEG_LAN8742A_ADDRESS, NEG_PHY_BCR,
 NEG_PHY_BCR_AUTONEGO_EN | NEG_PHY_BCR_RESTART_AN);
 
 }
 
/* USER CODE END PHY_PRE_CONFIG */

3 replies

sergey23
Associate
Jan 20, 2026 1:10 PM UTC

If you can post the ethernet part of the schematic, and your ethernet firmware code snippet, that would help.

You could try to load Mongoose-based test firmware and see if the same happens. Visit https://mongoose.ws/wizard/#/output?board=f429&ide=CubeIDE&rtos=baremetal&file=README.md , select destination directory in the settings tab, click "generate" button on top right, load the project in Cube IDE, start serial console, and build & flash the firmware. Board's IP address should appear in the log, as well as the other debug info like PHY parameters, link speed, etc.

paulrbryson
Associate III
Jan 20, 2026 5:47 PM UTC

I am using the nucleo-429zi development board.  I don't think firmware is involved.  This happens before the firmware even runs.  The phy chip either fails or succeeds at auto-negotiation even if the MCU is completely erased or is prevented from running by the debugger.  Once the phy chip has failed to auto-negotiate it does not recover.  I can repeatedly perform a hardware reset on the phy chip until the auto-negotiation succeeds.  But this seems like a hack rather than a solution and how do I know that board to board variations will not produce some units which never work?

This is the schematic for the nucleo board (also see attached)..

 

paulrbryson_1-1768931106066.png

 

paulrbryson
paulrbrysonAuthorBest answer
Associate III
Jan 21, 2026 7:35 AM UTC

I am not sure of the cause for the original problem - i.e. a hardware reset leaves the PHY in "bad" state.  I suspect it may have something to do with the internal 25MHz oscillator not stabilizing before auto-negotiation starts?  
In any event I found what looks to be a reliable solution - retstart the auto-negotiation in firmware after the PHY chip has stabilized.  I Inserted the following code in the stm32cubemx generated source, in "ethernet.c".

 

 
/* USER CODE BEGIN PHY_PRE_CONFIG */
 /* Force a PHY Auto-Negotiation -- Hardware Reset Can leave Phy in Bad state*/
 {
 /* PHY Register Definitions */
 const uint32_t NEG_LAN8742A_ADDRESS = 0x00U;
 const uint32_t NEG_PHY_BCR = 0x00U; /* Basic Control Register */
 const uint32_t NEG_PHY_BCR_SOFT_RESET = (1 << 15);
 const uint32_t NEG_PHY_BCR_AUTONEGO_EN = (1 << 12);
 const uint32_t NEG_PHY_BCR_RESTART_AN = (1 << 9);
 
 /* Implementation of the missing function */
 uint32_t phy_reg = 0;
 
 // 1. Send Soft Reset command
 HAL_ETH_WritePHYRegister(&heth, NEG_LAN8742A_ADDRESS, NEG_PHY_BCR, NEG_PHY_BCR_SOFT_RESET);
 
 // 2. Wait for Reset bit to self-clear (indicates PHY is ready)
 uint32_t timeout = HAL_GetTick() + 500;
 do {
 HAL_ETH_ReadPHYRegister(&heth, NEG_LAN8742A_ADDRESS, NEG_PHY_BCR, &phy_reg);
 } while ((phy_reg & NEG_PHY_BCR_SOFT_RESET) && (HAL_GetTick() < timeout));
 
 // 3. Force Auto-Negotiation Enable and Restart
 HAL_ETH_WritePHYRegister(&heth, NEG_LAN8742A_ADDRESS, NEG_PHY_BCR,
 NEG_PHY_BCR_AUTONEGO_EN | NEG_PHY_BCR_RESTART_AN);
 
 }
 
/* USER CODE END PHY_PRE_CONFIG */