cancel
Showing results for 
Search instead for 
Did you mean: 

nucleo-429zi ethernet Phy Sometimes fails auto-negotiation

paulrbryson
Associate III

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?

1 ACCEPTED SOLUTION

Accepted Solutions
paulrbryson
Associate III

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 */

View solution in original post

3 REPLIES 3
sergey23
Associate II

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.

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
Associate III

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 */