Sfoglia il codice sorgente

components/bt: Make sleep avaliable in hli(for future use)

baohongde 5 anni fa
parent
commit
fcbaa63c4e
2 ha cambiato i file con 88 aggiunte e 91 eliminazioni
  1. 88 69
      components/bt/bt.c
  2. 0 22
      components/bt/include/esp_bt.h

+ 88 - 69
components/bt/bt.c

@@ -178,6 +178,7 @@ struct osi_funcs_t {
     uint32_t _magic;
     uint32_t _magic;
 };
 };
 
 
+typedef void (*workitem_handler_t)(void* arg);
 
 
 /* External functions or values
 /* External functions or values
  ************************************************************************
  ************************************************************************
@@ -194,13 +195,14 @@ extern void btdm_controller_disable(void);
 extern uint8_t btdm_controller_get_mode(void);
 extern uint8_t btdm_controller_get_mode(void);
 extern const char *btdm_controller_get_compile_version(void);
 extern const char *btdm_controller_get_compile_version(void);
 extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
 extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
+extern int btdm_dispatch_work_to_controller(workitem_handler_t callback, void *arg, bool blocking);
 /* Sleep */
 /* Sleep */
 extern void btdm_controller_enable_sleep(bool enable);
 extern void btdm_controller_enable_sleep(bool enable);
 extern void btdm_controller_set_sleep_mode(uint8_t mode);
 extern void btdm_controller_set_sleep_mode(uint8_t mode);
 extern uint8_t btdm_controller_get_sleep_mode(void);
 extern uint8_t btdm_controller_get_sleep_mode(void);
 extern bool btdm_power_state_active(void);
 extern bool btdm_power_state_active(void);
-extern void btdm_wakeup_request(bool request_lock);
-extern void btdm_wakeup_request_end(void);
+extern void btdm_wakeup_request(void);
+extern void btdm_in_wakeup_requesting_set(bool in_wakeup_requesting);
 /* Low Power Clock */
 /* Low Power Clock */
 extern bool btdm_lpclk_select_src(uint32_t sel);
 extern bool btdm_lpclk_select_src(uint32_t sel);
 extern bool btdm_lpclk_set_div(uint32_t div);
 extern bool btdm_lpclk_set_div(uint32_t div);
@@ -279,7 +281,6 @@ static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us);
 static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt);
 static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt);
 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
 static void btdm_sleep_enter_phase2_wrapper(void);
 static void btdm_sleep_enter_phase2_wrapper(void);
-static void IRAM_ATTR btdm_sleep_exit_phase1_wrapper(void);
 static void btdm_sleep_exit_phase3_wrapper(void);
 static void btdm_sleep_exit_phase3_wrapper(void);
 static bool coex_bt_wakeup_request(void);
 static bool coex_bt_wakeup_request(void);
 static void coex_bt_wakeup_request_end(void);
 static void coex_bt_wakeup_request_end(void);
@@ -327,7 +328,7 @@ static const struct osi_funcs_t osi_funcs_ro = {
     ._btdm_sleep_check_duration = btdm_sleep_check_duration,
     ._btdm_sleep_check_duration = btdm_sleep_check_duration,
     ._btdm_sleep_enter_phase1 = btdm_sleep_enter_phase1_wrapper,
     ._btdm_sleep_enter_phase1 = btdm_sleep_enter_phase1_wrapper,
     ._btdm_sleep_enter_phase2 = btdm_sleep_enter_phase2_wrapper,
     ._btdm_sleep_enter_phase2 = btdm_sleep_enter_phase2_wrapper,
-    ._btdm_sleep_exit_phase1 = btdm_sleep_exit_phase1_wrapper,
+    ._btdm_sleep_exit_phase1 = NULL,
     ._btdm_sleep_exit_phase2 = NULL,
     ._btdm_sleep_exit_phase2 = NULL,
     ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
     ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
     ._coex_bt_wakeup_request = coex_bt_wakeup_request,
     ._coex_bt_wakeup_request = coex_bt_wakeup_request,
@@ -384,11 +385,12 @@ static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit f
 static DRAM_ATTR uint8_t btdm_lpclk_sel;
 static DRAM_ATTR uint8_t btdm_lpclk_sel;
 #endif /* #ifdef CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG */
 #endif /* #ifdef CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG */
 
 
+static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL;
 #ifdef CONFIG_PM_ENABLE
 #ifdef CONFIG_PM_ENABLE
 static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
 static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
 static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
 static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
 static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock; // pm_lock to prevent light sleep due to incompatibility currently
 static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock; // pm_lock to prevent light sleep due to incompatibility currently
-static DRAM_ATTR QueueHandle_t s_pm_lock_sem = NULL;
+static bool s_pm_lock_acquired = true;
 static void btdm_slp_tmr_callback(void *arg);
 static void btdm_slp_tmr_callback(void *arg);
 #endif
 #endif
 
 
@@ -845,8 +847,10 @@ static void btdm_sleep_enter_phase2_wrapper(void)
         esp_modem_sleep_enter(MODEM_BLE_MODULE);
         esp_modem_sleep_enter(MODEM_BLE_MODULE);
         esp_modem_sleep_enter(MODEM_CLASSIC_BT_MODULE);
         esp_modem_sleep_enter(MODEM_CLASSIC_BT_MODULE);
 #ifdef CONFIG_PM_ENABLE
 #ifdef CONFIG_PM_ENABLE
-        esp_pm_lock_release(s_pm_lock);
-        semphr_give_wrapper(s_pm_lock_sem);
+        if (s_pm_lock_acquired) {
+            esp_pm_lock_release(s_pm_lock);
+            s_pm_lock_acquired = false;
+        }
 #endif
 #endif
     } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
     } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
         esp_modem_sleep_enter(MODEM_BLE_MODULE);
         esp_modem_sleep_enter(MODEM_BLE_MODULE);
@@ -855,17 +859,15 @@ static void btdm_sleep_enter_phase2_wrapper(void)
     }
     }
 }
 }
 
 
-static void IRAM_ATTR btdm_sleep_exit_phase1_wrapper(void)
+static void btdm_sleep_exit_phase3_wrapper(void)
 {
 {
 #ifdef CONFIG_PM_ENABLE
 #ifdef CONFIG_PM_ENABLE
-    if (semphr_take_from_isr_wrapper(s_pm_lock_sem, NULL) == pdTRUE) {
+    if (!s_pm_lock_acquired) {
+        s_pm_lock_acquired = true;
         esp_pm_lock_acquire(s_pm_lock);
         esp_pm_lock_acquire(s_pm_lock);
     }
     }
 #endif
 #endif
-}
 
 
-static void btdm_sleep_exit_phase3_wrapper(void)
-{
     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
         esp_modem_sleep_exit(MODEM_BLE_MODULE);
         esp_modem_sleep_exit(MODEM_BLE_MODULE);
         esp_modem_sleep_exit(MODEM_CLASSIC_BT_MODULE);
         esp_modem_sleep_exit(MODEM_CLASSIC_BT_MODULE);
@@ -881,45 +883,81 @@ static void btdm_sleep_exit_phase3_wrapper(void)
 }
 }
 
 
 #ifdef CONFIG_PM_ENABLE
 #ifdef CONFIG_PM_ENABLE
-static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
+static void btdm_slp_tmr_customer_callback(void * arg)
 {
 {
-    if (semphr_take_wrapper(s_pm_lock_sem, 0) == pdTRUE) {
+    (void)(arg);
+
+    if (!s_pm_lock_acquired) {
+        s_pm_lock_acquired = true;
         esp_pm_lock_acquire(s_pm_lock);
         esp_pm_lock_acquire(s_pm_lock);
     }
     }
 }
 }
+
+static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
+{
+    (void)(arg);
+    btdm_dispatch_work_to_controller(btdm_slp_tmr_customer_callback, NULL, true);
+}
+#endif
+
+#define BTDM_ASYNC_WAKEUP_REQ_HCI       0
+#define BTDM_ASYNC_WAKEUP_REQ_COEX      1
+#define BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA 2
+#define BTDM_ASYNC_WAKEUP_REQMAX        3
+
+static void btdm_wakeup_request_callback(void * arg)
+{
+    (void)(arg);
+
+#if CONFIG_PM_ENABLE
+    if (!s_pm_lock_acquired) {
+        s_pm_lock_acquired = true;
+        esp_pm_lock_acquire(s_pm_lock);
+    }
+    esp_timer_stop(s_btdm_slp_tmr);
 #endif
 #endif
+    btdm_wakeup_request();
 
 
-#define BTDM_ASYNC_WAKEUP_REQ_HCI   0
-#define BTDM_ASYNC_WAKEUP_REQ_COEX   1
-#define BTDM_ASYNC_WAKEUP_REQMAX    2
+    semphr_give_wrapper(s_wakeup_req_sem);
+}
 
 
 static bool async_wakeup_request(int event)
 static bool async_wakeup_request(int event)
 {
 {
     bool request_lock = false;
     bool request_lock = false;
+    bool do_wakeup_request = false;
+
     switch (event) {
     switch (event) {
         case BTDM_ASYNC_WAKEUP_REQ_HCI:
         case BTDM_ASYNC_WAKEUP_REQ_HCI:
             request_lock = true;
             request_lock = true;
+            // NO break
+        case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA:
+            if (!btdm_power_state_active()) {
+                do_wakeup_request = true;
+                if (request_lock) {
+                    btdm_in_wakeup_requesting_set(true);
+                }
+
+                btdm_dispatch_work_to_controller(btdm_wakeup_request_callback, NULL, true);
+                semphr_take_wrapper(s_wakeup_req_sem, OSI_FUNCS_TIME_BLOCKING);
+            }
             break;
             break;
         case BTDM_ASYNC_WAKEUP_REQ_COEX:
         case BTDM_ASYNC_WAKEUP_REQ_COEX:
-            request_lock = false;
+            if (!btdm_power_state_active()) {
+                do_wakeup_request = true;
+#if CONFIG_PM_ENABLE
+                if (!s_pm_lock_acquired) {
+                    s_pm_lock_acquired = true;
+                    esp_pm_lock_acquire(s_pm_lock);
+                }
+                esp_timer_stop(s_btdm_slp_tmr);
+#endif
+                btdm_wakeup_request();
+            }
             break;
             break;
         default:
         default:
             return false;
             return false;
     }
     }
 
 
-    bool do_wakeup_request = false;
-
-    if (!btdm_power_state_active()) {
-#if CONFIG_PM_ENABLE
-        if (semphr_take_wrapper(s_pm_lock_sem, 0)) {
-            esp_pm_lock_acquire(s_pm_lock);
-        }
-        esp_timer_stop(s_btdm_slp_tmr);
-#endif
-        do_wakeup_request = true;
-        btdm_wakeup_request(request_lock);
-    }
-
     return do_wakeup_request;
     return do_wakeup_request;
 }
 }
 
 
@@ -931,6 +969,7 @@ static void async_wakeup_request_end(int event)
             request_lock = true;
             request_lock = true;
             break;
             break;
         case BTDM_ASYNC_WAKEUP_REQ_COEX:
         case BTDM_ASYNC_WAKEUP_REQ_COEX:
+        case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA:
             request_lock = false;
             request_lock = false;
             break;
             break;
         default:
         default:
@@ -938,7 +977,7 @@ static void async_wakeup_request_end(int event)
     }
     }
 
 
     if (request_lock) {
     if (request_lock) {
-        btdm_wakeup_request_end();
+        btdm_in_wakeup_requesting_set(false);
     }
     }
 
 
     return;
     return;
@@ -1128,7 +1167,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
     if (btdm_dram_available_region[0].mode == ESP_BT_MODE_IDLE) {
     if (btdm_dram_available_region[0].mode == ESP_BT_MODE_IDLE) {
         return ESP_ERR_INVALID_STATE;
         return ESP_ERR_INVALID_STATE;
     }
     }
-    
+
     osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
     osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
     if (osi_funcs_p == NULL) {
     if (osi_funcs_p == NULL) {
         return ESP_ERR_NO_MEM;
         return ESP_ERR_NO_MEM;
@@ -1172,6 +1211,12 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
     memset(btdm_queue_table, 0, sizeof(btdm_queue_item_t) * BTDM_MAX_QUEUE_NUM);
     memset(btdm_queue_table, 0, sizeof(btdm_queue_item_t) * BTDM_MAX_QUEUE_NUM);
 #endif
 #endif
 
 
+    s_wakeup_req_sem = semphr_create_wrapper(1, 0);
+    if (s_wakeup_req_sem == NULL) {
+        err = ESP_ERR_NO_MEM;
+        goto error;
+    }
+
 #ifdef CONFIG_PM_ENABLE
 #ifdef CONFIG_PM_ENABLE
     if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
     if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
         goto error;
         goto error;
@@ -1188,11 +1233,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
         goto error;
         goto error;
     }
     }
 
 
-    s_pm_lock_sem = semphr_create_wrapper(1, 0);
-    if (s_pm_lock_sem == NULL) {
-        err = ESP_ERR_NO_MEM;
-        goto error;
-    }
+    s_pm_lock_acquired = true;
 #endif
 #endif
 
 
     btdm_controller_mem_init();
     btdm_controller_mem_init();
@@ -1272,11 +1313,12 @@ error:
         esp_timer_delete(s_btdm_slp_tmr);
         esp_timer_delete(s_btdm_slp_tmr);
         s_btdm_slp_tmr = NULL;
         s_btdm_slp_tmr = NULL;
     }
     }
-    if (s_pm_lock_sem) {
-        semphr_delete_wrapper(s_pm_lock_sem);
-        s_pm_lock_sem = NULL;
-    }
+
 #endif
 #endif
+    if (s_wakeup_req_sem) {
+        semphr_delete_wrapper(s_wakeup_req_sem);
+        s_wakeup_req_sem = NULL;
+    }
     return err;
     return err;
 }
 }
 
 
@@ -1293,14 +1335,13 @@ esp_err_t esp_bt_controller_deinit(void)
 #ifdef CONFIG_PM_ENABLE
 #ifdef CONFIG_PM_ENABLE
     esp_pm_lock_delete(s_light_sleep_pm_lock);
     esp_pm_lock_delete(s_light_sleep_pm_lock);
     s_light_sleep_pm_lock = NULL;
     s_light_sleep_pm_lock = NULL;
-    esp_pm_lock_delete(s_pm_lock);
-    s_pm_lock = NULL;
     esp_timer_stop(s_btdm_slp_tmr);
     esp_timer_stop(s_btdm_slp_tmr);
     esp_timer_delete(s_btdm_slp_tmr);
     esp_timer_delete(s_btdm_slp_tmr);
     s_btdm_slp_tmr = NULL;
     s_btdm_slp_tmr = NULL;
-    semphr_delete_wrapper(s_pm_lock_sem);
-    s_pm_lock_sem = NULL;
+    s_pm_lock_acquired = false;
 #endif
 #endif
+    semphr_delete_wrapper(s_wakeup_req_sem);
+    s_wakeup_req_sem = NULL;
 
 
 #if CONFIG_SPIRAM_USE_MALLOC
 #if CONFIG_SPIRAM_USE_MALLOC
     vSemaphoreDelete(btdm_queue_table_mux);
     vSemaphoreDelete(btdm_queue_table_mux);
@@ -1391,9 +1432,7 @@ esp_err_t esp_bt_controller_disable(void)
     // disable modem sleep and wake up from sleep mode
     // disable modem sleep and wake up from sleep mode
     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
         btdm_controller_enable_sleep(false);
         btdm_controller_enable_sleep(false);
-        if (!btdm_power_state_active()) {
-            btdm_wakeup_request(false);
-        }
+        async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA);
         while (!btdm_power_state_active()) {
         while (!btdm_power_state_active()) {
             ets_delay_us(1000);
             ets_delay_us(1000);
         }
         }
@@ -1511,26 +1550,6 @@ esp_err_t esp_bt_sleep_disable (void)
     return status;
     return status;
 }
 }
 
 
-bool esp_bt_controller_is_sleeping(void)
-{
-    if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED ||
-        btdm_controller_get_sleep_mode() != BTDM_MODEM_SLEEP_MODE_ORIG) {
-        return false;
-    }
-
-    return !btdm_power_state_active();
-}
-
-void esp_bt_controller_wakeup_request(void)
-{
-    if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED ||
-        btdm_controller_get_sleep_mode() != BTDM_MODEM_SLEEP_MODE_ORIG) {
-        return;
-    }
-
-    btdm_wakeup_request(false);
-}
-
 esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path)
 esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path)
 {
 {
     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {

+ 0 - 22
components/bt/include/esp_bt.h

@@ -454,28 +454,6 @@ esp_err_t esp_bt_sleep_enable(void);
  */
  */
 esp_err_t esp_bt_sleep_disable(void);
 esp_err_t esp_bt_sleep_disable(void);
 
 
-/**
- * @brief to check whether bluetooth controller is sleeping at the instant, if modem sleep is enabled
- *
- * Note that this function shall not be invoked before esp_bt_controller_enable()
- * This function is supposed to be used ORIG mode of modem sleep
- *
- * @return  true if in modem sleep state, false otherwise
- */
-bool esp_bt_controller_is_sleeping(void);
-
-/**
- * @brief request controller to wakeup from sleeping state during sleep mode
- *
- * Note that this function shall not be invoked before esp_bt_controller_enable()
- * Note that this function is supposed to be used ORIG mode of modem sleep
- * Note that after this request, bluetooth controller may again enter sleep as long as the modem sleep is enabled
- *
- * Profiling shows that it takes several milliseconds to wakeup from modem sleep after this request.
- * Generally it takes longer if 32kHz XTAL is used than the main XTAL, due to the lower frequency of the former as the bluetooth low power clock source.
- */
-void esp_bt_controller_wakeup_request(void);
-
 /**
 /**
  * @brief Manually clear scan duplicate list
  * @brief Manually clear scan duplicate list
  *
  *