You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/12/29 05:48:30 UTC

[incubator-nuttx] branch master updated: 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

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 <ch...@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;