diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c index 1ef72672f9..0ec2b16e48 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c @@ -46,6 +46,9 @@ static sys_mutex_t tx_lock_mutex; /* function */ static void _eth_arch_rx_task(void *arg); static void _eth_arch_phy_task(void *arg); +#if defined (TARGET_NUCLEO_F767ZI) +static void _rmii_watchdog(void *arg); +#endif #if LWIP_IPV4 static err_t _eth_arch_netif_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); @@ -372,6 +375,35 @@ static void _eth_arch_phy_task(void *arg) } } +#if defined (TARGET_NUCLEO_F767ZI) +/** + * workaround for the ETH RMII bug in STM32F769 Cut1.0 + * + * \param[in] netif the lwip network interface structure + */ +static void _rmii_watchdog(void *arg) +{ + while(1) { + /* some good packets are received */ + if (EthHandle.Instance->MMCRGUFCR > 0) { + /* RMII Init is OK - would need service to terminate or suspend + * the thread */ + while(1) { + /* don't do anything anymore */ + osDelay(0xFFFFFFFF); + } + } else if (EthHandle.Instance->MMCRFCECR > 10) { + /* ETH received too many packets with CRC errors, resetting RMII */ + SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL; + SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; + EthHandle.Instance->MMCCR |= ETH_MMCCR_CR; + } else { + osDelay(100); + } + } +} +#endif + /** * This function is the ethernet IPv4 packet send function. It calls * etharp_output after checking link status. @@ -465,6 +497,10 @@ err_t eth_arch_enetif_init(struct netif *netif) /* initialize the hardware */ _eth_arch_low_level_init(netif); +#if defined (TARGET_NUCLEO_F767ZI) + sys_thread_new("stm32_rmii_watchdog", _rmii_watchdog, netif, DEFAULT_THREAD_STACKSIZE, osPriorityLow); +#endif + return ERR_OK; }