From 7204508fa1740247a49654ed96c9f4b531a5f2c6 Mon Sep 17 00:00:00 2001 From: maidnl Date: Fri, 5 Jul 2024 15:28:29 +0200 Subject: [PATCH] fix that restart interface in case of error (DEBUG LOG TO BE REMOVED) --- .../drivers/emac/TARGET_STM/stm32xx_emac.cpp | 27 +++++++++++++++++++ .../drivers/emac/TARGET_STM/stm32xx_emac.h | 7 +++++ .../lwipstack/source/LWIPInterface.cpp | 4 --- .../lwipstack/source/LWIPInterfaceEMAC.cpp | 17 ++++++++++-- .../netsocket/include/netsocket/EMAC.h | 4 +++ .../STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c | 4 +++ .../STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h | 1 + 7 files changed, 58 insertions(+), 6 deletions(-) diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp index 0230a90665c..ce62b91294f 100644 --- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp +++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp @@ -402,6 +402,33 @@ bool STM32_EMAC::low_level_init_successful() } #endif // ETH_IP_VERSION_V2 +/** + * This function get the state of emac interface + */ +int STM32_EMAC::get_interface_status() { + return HAL_ETH_GetStateOnly(&EthHandle); +} + +/** + * This function returns true if the status of the interface is in the + * correct state for the trasmission + */ +bool STM32_EMAC::is_ready_to_tx() { + return (HAL_ETH_GetStateOnly(&EthHandle) == HAL_ETH_STATE_READY); +} + +/** + * This function reset the emac interface in case the status is in error + * Apparently there was not anything to recover from an error state + */ +void STM32_EMAC::restart() { + if(HAL_ETH_STATE_ERROR == HAL_ETH_GetStateOnly(&EthHandle)){ + HAL_ETH_Stop(&EthHandle); + HAL_ETH_Start(&EthHandle); + } +} + + /** * This function should do the actual transmission of the packet. The packet is * contained in the memory buffer chain that is passed to the function. diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h index cfa67521774..ecc280b2f84 100644 --- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h +++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h @@ -148,6 +148,13 @@ class STM32_EMAC : public EMAC { */ virtual void set_memory_manager(EMACMemoryManager &mem_mngr); + /* return the status of the interface as integer */ + int get_interface_status() override; + /* return true if the interface is in the correct state to transmit */ + bool is_ready_to_tx() override; + /* restart only if the interface is in error state */ + void restart() override; + // Called from driver functions ETH_HandleTypeDef EthHandle; osThreadId_t thread; /**< Processing thread */ diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp index 4cc6d303e07..dfefebcb8bd 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -175,7 +175,6 @@ nsapi_error_t LWIP::Interface::set_dhcp() } err_t err = dhcp_start(&netif); - dhcp_has_to_be_set = false; if (err) { connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { @@ -204,9 +203,6 @@ void LWIP::Interface::netif_link_irq(struct netif *netif) netif_set_down(&interface->netif); } } else { - if(interface->dhcp_started) { - interface->dhcp_has_to_be_set = true; - } osSemaphoreRelease(interface->unlinked); if (netif_is_up(&interface->netif)) { interface->connected = NSAPI_STATUS_CONNECTING; diff --git a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp index 56fbcc0d904..e372fe2b379 100644 --- a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp +++ b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp @@ -27,15 +27,28 @@ #if LWIP_ETHERNET +extern "C" void log_add(const char *fmt, ...); + err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p) { + bool ret = false; /* Increase reference counter since lwip stores handle to pbuf and frees it after output */ pbuf_ref(p); LWIP::Interface *mbed_if = static_cast(netif->state); - bool ret = mbed_if->emac->link_out(p); - return ret ? ERR_OK : ERR_IF; + + if(mbed_if->emac->is_ready_to_tx()) { + ret = mbed_if->emac->link_out(p); + } + else { + log_add("!!!! emac is NOT OK ---> RESTART!!!"); + mbed_if->emac->restart(); + ret = mbed_if->emac->link_out(p); + } + + err_t rv = ret ? ERR_OK : ERR_IF; + return rv; } void LWIP::Interface::emac_input(emac_mem_buf_t *buf) diff --git a/connectivity/netsocket/include/netsocket/EMAC.h b/connectivity/netsocket/include/netsocket/EMAC.h index 515629b5a61..bbbc42f4a73 100644 --- a/connectivity/netsocket/include/netsocket/EMAC.h +++ b/connectivity/netsocket/include/netsocket/EMAC.h @@ -176,6 +176,10 @@ class EMAC { * @param mem_mngr Pointer to memory manager */ virtual void set_memory_manager(EMACMemoryManager &mem_mngr) = 0; + + virtual bool is_ready_to_tx() { return false;} + virtual void restart() {} + virtual int get_interface_status() { return -1; } }; diff --git a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c index decff79455a..ec45d0e6af9 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c +++ b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c @@ -2333,6 +2333,10 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi * @{ */ +HAL_ETH_StateTypeDef HAL_ETH_GetStateOnly(ETH_HandleTypeDef *heth) { + return heth->gState; +} + /** * @brief Returns the ETH state. * @param heth: pointer to a ETH_HandleTypeDef structure that contains diff --git a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h index 354ce3f5f8b..33310f6b5b9 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h +++ b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h @@ -1654,6 +1654,7 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi */ /* Peripheral State functions **************************************************/ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth); +HAL_ETH_StateTypeDef HAL_ETH_GetStateOnly(ETH_HandleTypeDef *heth); uint32_t HAL_ETH_GetError(ETH_HandleTypeDef *heth); uint32_t HAL_ETH_GetDMAError(ETH_HandleTypeDef *heth); uint32_t HAL_ETH_GetMACError(ETH_HandleTypeDef *heth);