This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 6ce335f xtensa/esp32: Fix some Wi-Fi issues 1. Fix the issue that Wi-Fi can't connect to some special routers occasionally. 2. Update Wi-Fi driver code to fix issue of failure to send pkt. 3. Replace software random with hardware random 6ce335f is described below commit 6ce335fa840fd02a62577324346a8ce08c410a2f Author: ChenWen <chen...@espressif.com> AuthorDate: Tue Nov 30 11:21:39 2021 +0800 xtensa/esp32: Fix some Wi-Fi issues 1. Fix the issue that Wi-Fi can't connect to some special routers occasionally. 2. Update Wi-Fi driver code to fix issue of failure to send pkt. 3. Replace software random with hardware random --- arch/xtensa/src/esp32/esp32_systemreset.c | 96 +++++++++++++++++++ arch/xtensa/src/esp32/esp32_systemreset.h | 105 +++++++++++++++++++++ arch/xtensa/src/esp32/esp32_wifi_adapter.c | 31 +++++- arch/xtensa/src/esp32/esp32_wifi_adapter.h | 16 ++++ arch/xtensa/src/esp32/esp32_wireless.c | 2 +- arch/xtensa/src/esp32/esp32_wlan.c | 48 ++++++++-- .../xtensa/esp32/esp32-devkitc/src/esp32_reset.c | 24 +++++ 7 files changed, 314 insertions(+), 8 deletions(-) diff --git a/arch/xtensa/src/esp32/esp32_systemreset.c b/arch/xtensa/src/esp32/esp32_systemreset.c index c19dfa9..a2ddcb7 100644 --- a/arch/xtensa/src/esp32/esp32_systemreset.c +++ b/arch/xtensa/src/esp32/esp32_systemreset.c @@ -31,12 +31,108 @@ #include "xtensa.h" #include "hardware/esp32_rtccntl.h" +#include "esp32_systemreset.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SHUTDOWN_HANDLERS_NO 4 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static shutdown_handler_t shutdown_handlers[SHUTDOWN_HANDLERS_NO]; /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** + * Name: esp32_register_shutdown_handler + * + * Description: + * This function allows you to register a handler that gets invoked before + * the application is restarted. + * + * Input Parameters: + * handler - Function to execute on restart + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp32_register_shutdown_handler(shutdown_handler_t handler) +{ + for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) + { + if (shutdown_handlers[i] == handler) + { + return -EEXIST; + } + else if (shutdown_handlers[i] == NULL) + { + shutdown_handlers[i] = handler; + return OK; + } + } + + return -ENOMEM; +} + +/**************************************************************************** + * Name: esp32_unregister_shutdown_handler + * + * Description: + * This function allows you to unregister a handler which was previously + * registered using up_register_shutdown_handler function. + * + * Input Parameters: + * handler - Function to execute on restart + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp32_unregister_shutdown_handler(shutdown_handler_t handler) +{ + for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) + { + if (shutdown_handlers[i] == handler) + { + shutdown_handlers[i] = NULL; + return OK; + } + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: up_shutdown_handler + * + * Description: + * Process all registered shutdown callback functions. + * + ****************************************************************************/ + +void up_shutdown_handler(void) +{ + for (int i = SHUTDOWN_HANDLERS_NO - 1; i >= 0; i--) + { + if (shutdown_handlers[i]) + { + shutdown_handlers[i](); + } + } +} + +/**************************************************************************** * Name: up_systemreset * * Description: diff --git a/arch/xtensa/src/esp32/esp32_systemreset.h b/arch/xtensa/src/esp32/esp32_systemreset.h new file mode 100644 index 0000000..c51e78a --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_systemreset.h @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_systemreset.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_SYSTEMRESET_H +#define __ARCH_XTENSA_SRC_ESP32_ESP32_SYSTEMRESET_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdint.h> + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Shutdown handler type */ + +typedef void (*shutdown_handler_t)(void); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_register_shutdown_handler + * + * Description: + * This function allows you to register a handler that gets invoked before + * the application is restarted. + * + * Input Parameters: + * handler - Function to execute on restart + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp32_register_shutdown_handler(shutdown_handler_t handler); + +/**************************************************************************** + * Name: esp32_unregister_shutdown_handler + * + * Description: + * This function allows you to unregister a handler which was previously + * registered using up_register_shutdown_handler function. + * + * Input Parameters: + * handler - Function to execute on restart + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +int esp32_unregister_shutdown_handler(shutdown_handler_t handler); + +/**************************************************************************** + * Name: up_shutdown_handler + * + * Description: + * Process all registered shutdown callback functions. + * + ****************************************************************************/ + +void up_shutdown_handler(void); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_SYSTEMRESET_H */ diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.c b/arch/xtensa/src/esp32/esp32_wifi_adapter.c index 79f446d..c00b41e 100644 --- a/arch/xtensa/src/esp32/esp32_wifi_adapter.c +++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.c @@ -3336,7 +3336,7 @@ void esp_fill_random(void *buf, size_t len) while (len > 0) { - tmp = random(); + tmp = esp_random(); n = len < 4 ? len : 4; memcpy(p, &tmp, n); @@ -6781,3 +6781,32 @@ int esp_wifi_softap_rssi(struct iwreq *iwr, bool set) } #endif + +/**************************************************************************** + * Name: esp_wifi_stop_callback + * + * Description: + * Callback to stop Wi-Fi + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_wifi_stop_callback(void) +{ + wlinfo("INFO: Try to stop Wi-Fi\n"); + + int ret = esp_wifi_stop(); + if (ret) + { + wlerr("ERROR: Failed to stop Wi-Fi ret=%d\n", ret); + } + else + { + nxsig_sleep(1); + } +} diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.h b/arch/xtensa/src/esp32/esp32_wifi_adapter.h index 7116035..e64facb 100644 --- a/arch/xtensa/src/esp32/esp32_wifi_adapter.h +++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.h @@ -852,6 +852,22 @@ int esp32_wifi_bt_coexist_init(void); void coex_dbg_set_log_level(int level); #endif +/**************************************************************************** + * Name: esp_wifi_stop_callback + * + * Description: + * Callback to stop Wi-Fi + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_wifi_stop_callback(void); + #ifdef __cplusplus } #endif diff --git a/arch/xtensa/src/esp32/esp32_wireless.c b/arch/xtensa/src/esp32/esp32_wireless.c index b9803f6..9a08db7 100644 --- a/arch/xtensa/src/esp32/esp32_wireless.c +++ b/arch/xtensa/src/esp32/esp32_wireless.c @@ -261,7 +261,7 @@ void esp32_phy_enable(void) esp32_phy_enable_clock(); if (g_is_phy_calibrated == false) { - register_chipv7_phy(&phy_init_data, cal_data, PHY_RF_CAL_NONE); + register_chipv7_phy(&phy_init_data, cal_data, PHY_RF_CAL_FULL); g_is_phy_calibrated = true; } else diff --git a/arch/xtensa/src/esp32/esp32_wlan.c b/arch/xtensa/src/esp32/esp32_wlan.c index 0e35283..7ef3bc6 100644 --- a/arch/xtensa/src/esp32/esp32_wlan.c +++ b/arch/xtensa/src/esp32/esp32_wlan.c @@ -48,6 +48,7 @@ #include "esp32_wlan.h" #include "esp32_wifi_utils.h" #include "esp32_wifi_adapter.h" +#include "esp32_systemreset.h" /**************************************************************************** * Pre-processor Definitions @@ -182,6 +183,10 @@ struct wlan_priv_s * Private Data ****************************************************************************/ +/* Reference count of register Wi-Fi handler */ + +static uint8_t g_callback_register_ref = 0; + static struct wlan_priv_s g_wlan_priv[ESP32_WLAN_DEVS]; #ifdef ESP32_WLAN_HAS_STA @@ -526,7 +531,7 @@ static void wlan_transmit(struct wlan_priv_s *priv) while ((pktbuf = wlan_txframe(priv))) { ret = priv->ops->send(pktbuf->buffer, pktbuf->len); - if (ret < 0) + if (ret == -ENOMEM) { wlan_add_txpkt_head(priv, pktbuf); wd_start(&priv->txtimeout, WLAN_TXTOUT, @@ -535,6 +540,11 @@ static void wlan_transmit(struct wlan_priv_s *priv) } else { + if (ret < 0) + { + nwarn("WARN: Failed to send pkt, ret: %d\n", ret); + } + wlan_free_buffer(priv, pktbuf->buffer); } } @@ -1066,8 +1076,8 @@ static void wlan_txtimeout_expiry(wdparm_t arg) static void wlan_poll_work(void *arg) { - int32_t delay = WLAN_WDDELAY; - struct wlan_priv_s *priv = (struct wlan_priv_s *)arg; + int32_t delay_tick = WLAN_WDDELAY; + FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)arg; struct net_driver_s *dev = &priv->dev; struct wlan_pktbuf *pktbuf; @@ -1082,7 +1092,14 @@ static void wlan_poll_work(void *arg) pktbuf = wlan_alloc_buffer(priv); if (!pktbuf) { - delay = 1; + /* Delay 10ms */ + + delay_tick = MSEC2TICK(10); + if (delay_tick == 0) + { + delay_tick = 1; + } + goto exit; } @@ -1098,7 +1115,7 @@ static void wlan_poll_work(void *arg) /* Update TCP timing states and poll the network for new XMIT data. */ - devif_timer(&priv->dev, delay, wlan_txpoll); + devif_timer(&priv->dev, delay_tick, wlan_txpoll); if (dev->d_buf) { @@ -1113,7 +1130,7 @@ static void wlan_poll_work(void *arg) wlan_transmit(priv); exit: - wd_start(&priv->txpoll, delay, wlan_poll_expiry, (wdparm_t)priv); + wd_start(&priv->txpoll, delay_tick, wlan_poll_expiry, (wdparm_t)priv); net_unlock(); } @@ -1249,7 +1266,16 @@ static int wlan_ifup(struct net_driver_s *dev) wd_start(&priv->txpoll, WLAN_WDDELAY, wlan_poll_expiry, (wdparm_t)priv); priv->ifup = true; + if (g_callback_register_ref == 0) + { + ret = esp32_register_shutdown_handler(esp_wifi_stop_callback); + if (ret < 0) + { + nwarn("WARN: Failed to register handler ret=%d\n", ret); + } + } + ++g_callback_register_ref; net_unlock(); return OK; @@ -1297,6 +1323,16 @@ static int wlan_ifdown(struct net_driver_s *dev) nerr("ERROR: Failed to stop Wi-Fi ret=%d\n", ret); } + --g_callback_register_ref; + if (g_callback_register_ref == 0) + { + ret = esp32_unregister_shutdown_handler(esp_wifi_stop_callback); + if (ret < 0) + { + nwarn("WARN: Failed to unregister handler ret=%d\n", ret); + } + } + net_unlock(); return OK; diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32_reset.c b/boards/xtensa/esp32/esp32-devkitc/src/esp32_reset.c index bd63ba4..3a0d7b3 100644 --- a/boards/xtensa/esp32/esp32-devkitc/src/esp32_reset.c +++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32_reset.c @@ -24,11 +24,20 @@ #include <nuttx/config.h> +#include <stdlib.h> +#include <debug.h> +#include <assert.h> #include <nuttx/arch.h> #include <nuttx/board.h> +#include "esp32_systemreset.h" + #ifdef CONFIG_BOARDCTL_RESET +#if CONFIG_BOARD_ASSERT_RESET_VALUE == EXIT_SUCCESS +# error "CONFIG_BOARD_ASSERT_RESET_VALUE must not be equal to EXIT_SUCCESS" +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -55,6 +64,21 @@ int board_reset(int status) { + syslog(LOG_INFO, "reboot status=%d\n", status); + + switch (status) + { + case EXIT_SUCCESS: + up_shutdown_handler(); + break; + + case CONFIG_BOARD_ASSERT_RESET_VALUE: + break; + + default: + break; + } + up_systemreset(); return 0;