2025-09-18 2:23 PM
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);
}
}
Solved! Go to Solution.
2025-09-18 6:06 PM
Why do you reset the PHY if you found that it is alive and only the STM32 should be reset? Reset of the PHY can take several seconds (with auto link detection) so avoid it if possible. Try to re-initialize the MAC like when the link goes down and up again: stop the ETH then start again. Check the PHY to ensure that it still senses the link.
2025-09-18 6:06 PM
Why do you reset the PHY if you found that it is alive and only the STM32 should be reset? Reset of the PHY can take several seconds (with auto link detection) so avoid it if possible. Try to re-initialize the MAC like when the link goes down and up again: stop the ETH then start again. Check the PHY to ensure that it still senses the link.