This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit a18b7186a622952bbd68e84cc2f4418612bb1c89
Author: Eren Terzioglu <[email protected]>
AuthorDate: Tue Apr 21 12:27:21 2026 +0200

    arch/risc-v/espressif: Add BLE sleep
    
    Add BLE sleep for esp32[-c3]
    
    Signed-off-by: Eren Terzioglu <[email protected]>
---
 arch/risc-v/src/common/espressif/CMakeLists.txt |   2 +-
 arch/risc-v/src/common/espressif/Make.defs      |   2 +-
 arch/risc-v/src/esp32c3/esp_ble_adapter.c       | 110 +++++++++++++++++++-----
 3 files changed, 90 insertions(+), 24 deletions(-)

diff --git a/arch/risc-v/src/common/espressif/CMakeLists.txt 
b/arch/risc-v/src/common/espressif/CMakeLists.txt
index 47b1bbeffbc..3141406868e 100644
--- a/arch/risc-v/src/common/espressif/CMakeLists.txt
+++ b/arch/risc-v/src/common/espressif/CMakeLists.txt
@@ -213,7 +213,7 @@ if(DEFINED ENV{ESP_HAL_3RDPARTY_VERSION})
       CACHE STRING "ESP HAL 3rdparty version")
 else()
   set(ESP_HAL_3RDPARTY_VERSION
-      c32f1ad13f4ce8312de494e8b79c88fda10fe9ed
+      e10e44f52e41aee7a617b4d144982a1998a17fc5
       CACHE STRING "ESP HAL 3rdparty version")
 endif()
 
diff --git a/arch/risc-v/src/common/espressif/Make.defs 
b/arch/risc-v/src/common/espressif/Make.defs
index 43b7090d208..d9b4560e0d9 100644
--- a/arch/risc-v/src/common/espressif/Make.defs
+++ b/arch/risc-v/src/common/espressif/Make.defs
@@ -221,7 +221,7 @@ endif
 
 ESP_HAL_3RDPARTY_REPO   = esp-hal-3rdparty
 ifndef ESP_HAL_3RDPARTY_VERSION
-       ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed
+       ESP_HAL_3RDPARTY_VERSION = e10e44f52e41aee7a617b4d144982a1998a17fc5
 endif
 
 ifndef ESP_HAL_3RDPARTY_URL
diff --git a/arch/risc-v/src/esp32c3/esp_ble_adapter.c 
b/arch/risc-v/src/esp32c3/esp_ble_adapter.c
index de5b451e9ff..6ebc6dacec5 100644
--- a/arch/risc-v/src/esp32c3/esp_ble_adapter.c
+++ b/arch/risc-v/src/esp32c3/esp_ble_adapter.c
@@ -85,6 +85,10 @@
 #endif
 #include "esp_intr_alloc.h"
 #include "esp_ble_adapter.h"
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#  include "esp_sleep.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -92,6 +96,8 @@
 
 #define BTDM_MIN_TIMER_UNCERTAINTY_US    (1800)
 
+#define BTDM_RTC_SLOW_CLK_RC_DRIFT_PERCENT  (7)
+
 /* Sleep and wakeup interval control */
 
 #define BTDM_MIN_SLEEP_DURATION          (24) /* Threshold of interval in half 
slots to allow to fall into sleep mode */
@@ -603,13 +609,14 @@ static DRAM_ATTR void * g_wakeup_req_sem = NULL;
 
 /* wakeup timer */
 
-static DRAM_ATTR esp_timer_handle_t g_btdm_slp_tmr;
+static DRAM_ATTR esp_timer_handle_t g_btdm_slp_tmr = NULL;
 
 #ifdef CONFIG_PM
+static DRAM_ATTR esp_pm_lock_handle_t g_pm_lock;
 
 /* pm_lock to prevent light sleep due to incompatibility currently */
 
-static DRAM_ATTR void * g_light_sleep_pm_lock;
+static DRAM_ATTR esp_pm_lock_handle_t g_light_sleep_pm_lock;
 #endif
 
 /* BT interrupt private data */
@@ -1677,6 +1684,17 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t 
lpcycles)
   DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
   uncertainty = (us_to_sleep >> 11);
 
+#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
+  /* Recalculate clock drift when Bluetooth keeps
+   * main XTAL on during light sleep
+   */
+
+  if (rtc_clk_slow_freq_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW)
+    {
+      uncertainty = us_to_sleep * BTDM_RTC_SLOW_CLK_RC_DRIFT_PERCENT / 100;
+    }
+#endif
+
   if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US)
     {
       uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US;
@@ -1684,9 +1702,8 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t 
lpcycles)
 
   DEBUGASSERT(g_lp_stat.wakeup_timer_started == 0);
 
-  ets_timer_arm_us((void *)&g_btdm_slp_tmr,
-                   us_to_sleep - uncertainty,
-                   false);
+  esp_timer_start_once(g_btdm_slp_tmr,
+                       us_to_sleep - uncertainty);
   g_lp_stat.wakeup_timer_started = true;
 }
 
@@ -1721,6 +1738,7 @@ static void btdm_sleep_enter_phase2_wrapper(void)
 #ifdef CONFIG_PM
       if (g_lp_stat.pm_lock_released == 0)
         {
+          esp_pm_lock_release(g_pm_lock);
           g_lp_stat.pm_lock_released = 1;
         }
 #endif
@@ -1746,6 +1764,7 @@ static void btdm_sleep_exit_phase3_wrapper(void)
 #ifdef CONFIG_PM
   if (g_lp_stat.pm_lock_released)
     {
+      esp_pm_lock_acquire(g_pm_lock);
       g_lp_stat.pm_lock_released = 0;
     }
 #endif
@@ -1761,7 +1780,7 @@ static void btdm_sleep_exit_phase3_wrapper(void)
 
   if (g_lp_cntl.wakeup_timer_required && g_lp_stat.wakeup_timer_started)
     {
-      ets_timer_disarm((void *)&g_btdm_slp_tmr);
+      esp_timer_stop(g_btdm_slp_tmr);
       g_lp_stat.wakeup_timer_started = 0;
     }
 
@@ -2211,8 +2230,8 @@ static void esp_update_time(struct timespec *timespec, 
uint32_t ticks)
 static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
 {
 #ifdef CONFIG_PM
-  btdm_vnd_offload_post(BTDM_VND_OL_SIG_WAKEUP_TMR,
-                        (void *)BTDM_ASYNC_WAKEUP_SRC_TMR);
+  r_btdm_vnd_offload_post(BTDM_VND_OL_SIG_WAKEUP_TMR,
+                          (void *)BTDM_ASYNC_WAKEUP_SRC_TMR);
 #endif
 }
 
@@ -2265,6 +2284,7 @@ static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
 #ifdef CONFIG_PM
   if (g_lp_stat.pm_lock_released)
     {
+      esp_pm_lock_acquire(g_pm_lock);
       g_lp_stat.pm_lock_released = 0;
     }
 #endif
@@ -2279,7 +2299,7 @@ static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
 
   if (g_lp_cntl.wakeup_timer_required && g_lp_stat.wakeup_timer_started)
     {
-      ets_timer_disarm((void *)&g_btdm_slp_tmr);
+      esp_timer_stop(g_btdm_slp_tmr);
       g_lp_stat.wakeup_timer_started = 0;
     }
 
@@ -2406,9 +2426,7 @@ static esp_err_t 
btdm_low_power_mode_init(esp_bt_controller_config_t *cfg)
                   .name = "btSlp",
                 };
 
-              ets_timer_setfn((void *)&g_btdm_slp_tmr,
-                              (void *)btdm_slp_tmr_callback,
-                              &create_args);
+              esp_timer_create(&create_args, &g_btdm_slp_tmr);
             }
 
           /* set default bluetooth sleep clock cycle and its
@@ -2470,7 +2488,7 @@ static esp_err_t 
btdm_low_power_mode_init(esp_bt_controller_config_t *cfg)
       if (g_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL)
         {
 #ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
-          ASSERT(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON));
+          esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
           g_lp_cntl.main_xtal_pu = 1;
 #endif
           select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
@@ -2511,7 +2529,28 @@ static esp_err_t 
btdm_low_power_mode_init(esp_bt_controller_config_t *cfg)
 #endif
 
 #ifdef CONFIG_PM
-      g_lp_stat.pm_lock_released = 1;
+      if (g_lp_cntl.no_light_sleep)
+        {
+          err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0,
+                                   "ble", &g_light_sleep_pm_lock);
+          if (err != OK)
+            {
+              break;
+            }
+
+          wlwarn("Light sleep mode will not be able to"
+                  "apply when bluetooth is enabled.");
+        }
+
+      err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "ble", &g_pm_lock);
+      if (err != OK)
+        {
+          break;
+        }
+      else
+        {
+          g_lp_stat.pm_lock_released = 1;
+        }
 #endif
     }
   while (0);
@@ -2607,20 +2646,28 @@ static void btdm_low_power_mode_deinit(void)
     {
       if (g_light_sleep_pm_lock != NULL)
         {
+          esp_pm_lock_delete(g_light_sleep_pm_lock);
           g_light_sleep_pm_lock = NULL;
         }
     }
+
+  if (g_pm_lock != NULL)
+    {
+      esp_pm_lock_delete(g_pm_lock);
+      g_pm_lock = NULL;
+      g_lp_stat.pm_lock_released = 0;
+    }
 #endif
 
   if (g_lp_cntl.wakeup_timer_required && g_btdm_slp_tmr != NULL)
     {
       if (g_lp_stat.wakeup_timer_started)
         {
-          ets_timer_disarm((void *)&g_btdm_slp_tmr);
+          esp_timer_stop(g_btdm_slp_tmr);
         }
 
       g_lp_stat.wakeup_timer_started = 0;
-      ets_timer_done((void *)&g_btdm_slp_tmr);
+      esp_timer_delete(g_btdm_slp_tmr);
       g_btdm_slp_tmr = NULL;
     }
 
@@ -2639,7 +2686,7 @@ static void btdm_low_power_mode_deinit(void)
 #ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
       if (g_lp_cntl.main_xtal_pu)
         {
-          ASSERT(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF));
+          esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
           g_lp_cntl.main_xtal_pu = 0;
         }
 #endif
@@ -2695,9 +2742,10 @@ static bool async_wakeup_request(int event)
         if (!btdm_power_state_active())
           {
             do_wakeup_request = true;
-#if CONFIG_PM
+#ifdef CONFIG_PM
             if (g_lp_stat.pm_lock_released)
               {
+                esp_pm_lock_acquire(g_pm_lock);
                 g_lp_stat.pm_lock_released = 0;
               }
 #endif
@@ -2707,7 +2755,7 @@ static bool async_wakeup_request(int event)
             if (g_lp_cntl.wakeup_timer_required &&
                 g_lp_stat.wakeup_timer_started)
               {
-                ets_timer_disarm((void *)&g_btdm_slp_tmr);
+                esp_timer_stop(g_btdm_slp_tmr);
                 g_lp_stat.wakeup_timer_started = 0;
               }
           }
@@ -3194,26 +3242,32 @@ int esp_bt_controller_enable(esp_bt_mode_t mode)
 #ifdef CONFIG_PM
   /* enable low power mode */
 
+  if (g_lp_cntl.no_light_sleep)
+    {
+      esp_pm_lock_acquire(g_light_sleep_pm_lock);
+    }
+
+  esp_pm_lock_acquire(g_pm_lock);
   g_lp_stat.pm_lock_released = 0;
 #endif
 
 #if CONFIG_MAC_BB_PD
   if (esp_register_mac_bb_pd_callback(btdm_mac_bb_power_down_cb) != 0)
     {
-      err = -EINVAL;
+      ret = -EINVAL;
       goto error;
     }
 
   if (esp_register_mac_bb_pu_callback(btdm_mac_bb_power_up_cb) != 0)
     {
-      err = -EINVAL;
+      ret = -EINVAL;
       goto error;
     }
 #endif
 
   if (g_lp_cntl.enable)
     {
-        btdm_controller_enable_sleep(true);
+      btdm_controller_enable_sleep(true);
     }
 
   /* Disable pll track by default in BLE controller on ESP32-C3 and
@@ -3246,8 +3300,14 @@ error:
   btdm_controller_enable_sleep(false);
 
 #ifdef CONFIG_PM
+  if (g_lp_cntl.no_light_sleep)
+    {
+      esp_pm_lock_release(g_light_sleep_pm_lock);
+    }
+
   if (g_lp_stat.pm_lock_released == 0)
     {
+      esp_pm_lock_release(g_pm_lock);
       g_lp_stat.pm_lock_released = 1;
     }
 #endif
@@ -3316,8 +3376,14 @@ int esp_bt_controller_disable(void)
 #endif
 
 #ifdef CONFIG_PM
+  if (g_lp_cntl.no_light_sleep)
+    {
+      esp_pm_lock_release(g_light_sleep_pm_lock);
+    }
+
   if (g_lp_stat.pm_lock_released == 0)
     {
+      esp_pm_lock_release(g_pm_lock);
       g_lp_stat.pm_lock_released = 1;
     }
   else

Reply via email to