mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Mac BB power down in light sleep
components/bt: Do not use feature: timer support isr dispatch method disable controller after wake up finished. protect critical section of power down choose clk in sleep components/coex: mac bb power down in light sleep components/coex: Macro changed components/os: protect reserved interrupt number update phy to phy_version 300,6e46ba7,Jan 25 2021 some bugfix
This commit is contained in:
parent
ee480b7776
commit
eef66789d4
@ -310,6 +310,21 @@ menu "MODEM SLEEP Options"
|
||||
selected, bluetooth modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, but
|
||||
cannot work when light sleep is enabled. Main crystal has a relatively better performance than
|
||||
other bluetooth low power clock sources.
|
||||
config BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
bool "External 32kHz crystal"
|
||||
depends on ESP32C3_RTC_CLK_SRC_EXT_CRYS
|
||||
help
|
||||
External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency
|
||||
stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth
|
||||
modem sleep to be used with both DFS and light sleep.
|
||||
|
||||
config BT_CTRL_LPCLK_SEL_RTC_SLOW
|
||||
bool "Internal 150kHz RC oscillator"
|
||||
depends on ESP32C3_RTC_CLK_SRC_INT_RC
|
||||
help
|
||||
Internal 150kHz RC oscillator.
|
||||
|
||||
|
||||
endchoice
|
||||
endmenu
|
||||
|
||||
@ -321,6 +336,8 @@ config BT_CTRL_SLEEP_MODE_EFF
|
||||
config BT_CTRL_SLEEP_CLOCK_EFF
|
||||
int
|
||||
default 1 if BT_CTRL_LPCLK_SEL_MAIN_XTAL
|
||||
default 2 if BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
default 3 if BT_CTRL_LPCLK_SEL_RTC_SLOW
|
||||
|
||||
default 0
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "esp_coexist_internal.h"
|
||||
#include "esp32c3/rom/rom_layout.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_sleep.h"
|
||||
|
||||
#if CONFIG_BT_ENABLED
|
||||
|
||||
@ -246,7 +247,7 @@ extern void btdm_deep_sleep_mem_deinit(void);
|
||||
extern void btdm_ble_power_down_dma_copy(bool copy);
|
||||
extern uint8_t btdm_sleep_clock_sync(void);
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB
|
||||
#if CONFIG_MAC_BB_PD
|
||||
extern void esp_mac_bb_power_down(void);
|
||||
extern void esp_mac_bb_power_up(void);
|
||||
extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem);
|
||||
@ -404,9 +405,9 @@ static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
|
||||
static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock;
|
||||
#endif
|
||||
|
||||
void btdm_hw_mac_power_down_wrapper(void)
|
||||
void IRAM_ATTR btdm_hw_mac_power_down_wrapper(void)
|
||||
{
|
||||
#if CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB
|
||||
#if CONFIG_MAC_BB_PD
|
||||
// le module power down
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
|
||||
@ -415,9 +416,9 @@ void btdm_hw_mac_power_down_wrapper(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void btdm_hw_mac_power_up_wrapper(void)
|
||||
void IRAM_ATTR btdm_hw_mac_power_up_wrapper(void)
|
||||
{
|
||||
#if CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB
|
||||
#if CONFIG_MAC_BB_PD
|
||||
// le module power up
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
|
||||
@ -426,9 +427,9 @@ void btdm_hw_mac_power_up_wrapper(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem)
|
||||
void IRAM_ATTR btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem)
|
||||
{
|
||||
#if CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB
|
||||
#if CONFIG_MAC_BB_PD
|
||||
ets_backup_dma_copy(reg, mem_addr, num, to_mem);
|
||||
#endif
|
||||
}
|
||||
@ -688,13 +689,6 @@ static void btdm_sleep_enter_phase2_wrapper(void)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd == 0) {
|
||||
#if (CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB)
|
||||
btdm_ble_power_down_dma_copy(true);
|
||||
#endif
|
||||
s_lp_stat.mac_bb_pd = 1;
|
||||
}
|
||||
|
||||
if (s_lp_stat.pm_lock_released == 0) {
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
@ -706,6 +700,16 @@ static void btdm_sleep_enter_phase2_wrapper(void)
|
||||
|
||||
static void btdm_sleep_exit_phase3_wrapper(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
// If BT wakeup before esp timer coming due to timer task have no chance to run.
|
||||
// Then we will not run into `btdm_sleep_exit_phase0` and acquire PM lock,
|
||||
// Do it again here to fix this issue.
|
||||
if (s_lp_stat.pm_lock_released) {
|
||||
esp_pm_lock_acquire(s_pm_lock);
|
||||
s_lp_stat.pm_lock_released = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(btdm_sleep_clock_sync()) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "sleep eco state err\n");
|
||||
assert(0);
|
||||
@ -716,6 +720,14 @@ static void btdm_sleep_exit_phase3_wrapper(void)
|
||||
s_lp_stat.phy_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If BT wakeup before esp timer coming due to timer task have no chance to run.
|
||||
// Then we will not run into `btdm_sleep_exit_phase0` and stop esp timer,
|
||||
// Do it again here to fix this issue.
|
||||
if (s_lp_cntl.wakeup_timer_required && s_lp_stat.wakeup_timer_started) {
|
||||
esp_timer_stop(s_btdm_slp_tmr);
|
||||
s_lp_stat.wakeup_timer_started = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
|
||||
@ -729,12 +741,6 @@ static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB)
|
||||
if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd) {
|
||||
btdm_ble_power_down_dma_copy(false);
|
||||
s_lp_stat.mac_bb_pd = 0;
|
||||
}
|
||||
#endif
|
||||
btdm_wakeup_request();
|
||||
|
||||
if (s_lp_cntl.wakeup_timer_required && s_lp_stat.wakeup_timer_started) {
|
||||
@ -749,14 +755,9 @@ static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
|
||||
|
||||
static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
|
||||
{
|
||||
#if (defined CONFIG_PM_ENABLE) || (defined CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB)
|
||||
#ifdef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
btdm_vnd_offload_post_from_isr(BTDM_VND_OL_SIG_WAKEUP_TMR, (void *)BTDM_ASYNC_WAKEUP_SRC_TMR, false);
|
||||
esp_timer_isr_dispatch_need_yield();
|
||||
#else
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
btdm_vnd_offload_post(BTDM_VND_OL_SIG_WAKEUP_TMR, (void *)BTDM_ASYNC_WAKEUP_SRC_TMR);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -888,16 +889,27 @@ void esp_release_wifi_and_coex_mem(void)
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region((intptr_t)ets_rom_layout_p->data_start_interface_coexist,(intptr_t)ets_rom_layout_p->bss_end_interface_pp));
|
||||
}
|
||||
|
||||
esp_err_t esp_bluetooth_stop(void)
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
static void IRAM_ATTR btdm_mac_bb_power_down_cb(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB
|
||||
if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd == 0) {
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
btdm_ble_power_down_dma_copy(true);
|
||||
#endif
|
||||
s_lp_stat.mac_bb_pd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR btdm_mac_bb_power_up_cb(void)
|
||||
{
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd) {
|
||||
btdm_hw_mac_power_up_wrapper();
|
||||
btdm_ble_power_down_dma_copy(false);
|
||||
s_lp_stat.mac_bb_pd = 0;
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
@ -941,10 +953,18 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
|
||||
btdm_controller_mem_init();
|
||||
|
||||
if (esp_register_shutdown_handler((shutdown_handler_t)esp_bluetooth_stop) != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
#if CONFIG_MAC_BB_PD
|
||||
if (esp_register_mac_bb_pd_callback(btdm_mac_bb_power_down_cb) != 0) {
|
||||
err = ESP_ERR_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (esp_register_mac_bb_pu_callback(btdm_mac_bb_power_up_cb) != 0) {
|
||||
err = ESP_ERR_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
|
||||
if (osi_funcs_p == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
@ -969,17 +989,17 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
|
||||
// configure and initialize resources
|
||||
s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0;
|
||||
s_lp_cntl.no_light_sleep = 1;
|
||||
s_lp_cntl.no_light_sleep = 0;
|
||||
|
||||
if (s_lp_cntl.enable) {
|
||||
#if (CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB)
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
if (!btdm_deep_sleep_mem_init()) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto error;
|
||||
}
|
||||
s_lp_cntl.mac_bb_pd = 1;
|
||||
#endif
|
||||
#if (defined CONFIG_PM_ENABLE) || (defined CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB)
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
s_lp_cntl.wakeup_timer_required = 1;
|
||||
#endif
|
||||
// async wakeup semaphore for VHCI
|
||||
@ -992,17 +1012,9 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
}
|
||||
|
||||
if (s_lp_cntl.wakeup_timer_required) {
|
||||
#ifndef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
ESP_LOGE(BTDM_LOG_TAG, "ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is required");
|
||||
err = ESP_ERR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
#endif
|
||||
esp_timer_create_args_t create_args = {
|
||||
.callback = btdm_slp_tmr_callback,
|
||||
.arg = NULL,
|
||||
#ifdef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD
|
||||
.dispatch_method = ESP_TIMER_ISR,
|
||||
#endif
|
||||
.name = "btSlp",
|
||||
};
|
||||
if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
|
||||
@ -1014,8 +1026,32 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
|
||||
|
||||
// set default bluetooth sleep clock source
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL;
|
||||
// // set default bluetooth sleep clock source
|
||||
// s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL;
|
||||
#if CONFIG_BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_32K_XTAL) {
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // set default value
|
||||
// #ifdef CONFIG_PM_ENABLE
|
||||
// s_btdm_allow_light_sleep = true;
|
||||
// #endif
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
||||
"light sleep mode will not be able to apply when bluetooth is enabled");
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
}
|
||||
#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW)
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_RTC) {
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // set default value
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "Internal 150kHz RC oscillator not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
||||
"light sleep mode will not be able to apply when bluetooth is enabled");
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
}
|
||||
#else
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
#endif
|
||||
|
||||
bool select_src_ret, set_div_ret;
|
||||
if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
|
||||
@ -1024,9 +1060,22 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
assert(select_src_ret && set_div_ret);
|
||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
|
||||
} else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL32K) {
|
||||
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
|
||||
set_div_ret = btdm_lpclk_set_div(0);
|
||||
assert(select_src_ret && set_div_ret);
|
||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||
btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
|
||||
(1000000 >> (15 - RTC_CLK_CAL_FRACT));
|
||||
assert(btdm_lpcycle_us != 0);
|
||||
} else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_RTC_SLOW) {
|
||||
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
|
||||
set_div_ret = btdm_lpclk_set_div(0);
|
||||
assert(select_src_ret && set_div_ret);
|
||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||
btdm_lpcycle_us = esp_clk_slowclk_cal_get();
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "%s sleep clock not supported", __func__);
|
||||
err = ESP_ERR_NOT_SUPPORTED;
|
||||
err = ESP_ERR_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1052,10 +1101,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
|
||||
periph_module_enable(PERIPH_BT_MODULE);
|
||||
|
||||
#ifdef CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB
|
||||
btdm_hw_mac_power_up_wrapper();
|
||||
#endif
|
||||
|
||||
esp_phy_enable();
|
||||
s_lp_stat.phy_enabled = 1;
|
||||
|
||||
@ -1095,7 +1140,7 @@ error:
|
||||
s_btdm_slp_tmr = NULL;
|
||||
}
|
||||
|
||||
#if (CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB)
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
if (s_lp_cntl.mac_bb_pd) {
|
||||
btdm_deep_sleep_mem_deinit();
|
||||
s_lp_cntl.mac_bb_pd = 0;
|
||||
@ -1110,7 +1155,11 @@ error:
|
||||
}
|
||||
} while (0);
|
||||
|
||||
esp_unregister_shutdown_handler((shutdown_handler_t)esp_bluetooth_stop);
|
||||
#if CONFIG_MAC_BB_PD
|
||||
esp_unregister_mac_bb_pd_callback(btdm_mac_bb_power_down_cb);
|
||||
|
||||
esp_unregister_mac_bb_pu_callback(btdm_mac_bb_power_up_cb);
|
||||
#endif
|
||||
|
||||
if (osi_funcs_p != NULL) {
|
||||
free(osi_funcs_p);
|
||||
@ -1137,12 +1186,10 @@ esp_err_t esp_bt_controller_deinit(void)
|
||||
|
||||
// deinit low power control resources
|
||||
do {
|
||||
#if (CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB)
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
btdm_deep_sleep_mem_deinit();
|
||||
#endif
|
||||
#ifdef CONFIG_PM_POWER_DOWN_WIFI_BT_MAC_BB
|
||||
btdm_hw_mac_power_down_wrapper();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_lp_cntl.no_light_sleep) {
|
||||
esp_pm_lock_delete(s_light_sleep_pm_lock);
|
||||
@ -1170,8 +1217,10 @@ esp_err_t esp_bt_controller_deinit(void)
|
||||
}
|
||||
} while (0);
|
||||
|
||||
esp_unregister_shutdown_handler((shutdown_handler_t)esp_bluetooth_stop);
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
esp_unregister_mac_bb_pd_callback(btdm_mac_bb_power_down_cb);
|
||||
esp_unregister_mac_bb_pu_callback(btdm_mac_bb_power_up_cb);
|
||||
#endif
|
||||
free(osi_funcs_p);
|
||||
osi_funcs_p = NULL;
|
||||
|
||||
@ -1247,7 +1296,7 @@ esp_err_t esp_bt_controller_disable(void)
|
||||
}
|
||||
|
||||
async_wakeup_request(BTDM_ASYNC_WAKEUP_SRC_DISA);
|
||||
|
||||
while (!btdm_power_state_active()){}
|
||||
btdm_controller_disable();
|
||||
|
||||
async_wakeup_request_end(BTDM_ASYNC_WAKEUP_SRC_DISA);
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit cf348db2d264019ac8c2a5c40147f9973f7cf52c
|
||||
Subproject commit 272aaca1f859f87c9694cd441ae68cb3d7829664
|
@ -73,7 +73,8 @@ typedef enum {
|
||||
ESP_BT_SLEEP_CLOCK_NONE = 0, /*!< Sleep clock not configured */
|
||||
ESP_BT_SLEEP_CLOCK_MAIN_XTAL = 1, /*!< SoC main crystal */
|
||||
ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL = 2, /*!< External 32.768kHz crystal */
|
||||
ESP_BT_SLEEP_CLOCK_FPGA_32K = 3, /*!< Hardwired 32KHz clock temporarily used for FPGA */
|
||||
ESP_BT_SLEEP_CLOCK_RTC_SLOW = 3, /*!< Internal 150kHz RC oscillator */
|
||||
ESP_BT_SLEEP_CLOCK_FPGA_32K = 4, /*!< Hardwired 32KHz clock temporarily used for FPGA */
|
||||
} esp_bt_sleep_clock_t;
|
||||
|
||||
/**
|
||||
|
@ -1731,6 +1731,7 @@ ieee80211_set_tx_desc = 0x4000186c;
|
||||
rom_sta_input = 0x40001870;
|
||||
wifi_get_macaddr = 0x40001874;
|
||||
wifi_rf_phy_disable = 0x40001878;
|
||||
wifi_rf_phy_enable = 0x4000187c;
|
||||
ic_ebuf_alloc = 0x40001880;
|
||||
ieee80211_classify = 0x40001884;
|
||||
ieee80211_copy_eb_header = 0x40001888;
|
||||
|
@ -409,6 +409,51 @@ void esp_sleep_gpio_status_init(void);
|
||||
*/
|
||||
void esp_sleep_gpio_status_switch_configure(bool enable);
|
||||
#endif
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
/**
|
||||
* @brief Function type for stub to run mac bb power down.
|
||||
*/
|
||||
typedef void (* mac_bb_power_down_cb_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Function type for stub to run mac bb power up.
|
||||
*/
|
||||
typedef void (* mac_bb_power_up_cb_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Registet mac bb power down callback.
|
||||
* @param cb mac bb power down callback.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_register_mac_bb_pd_callback(mac_bb_power_down_cb_t cb);
|
||||
|
||||
/**
|
||||
* @brief Unregistet mac bb power down callback.
|
||||
* @param cb mac bb power down callback.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_unregister_mac_bb_pd_callback(mac_bb_power_down_cb_t cb);
|
||||
|
||||
/**
|
||||
* @brief Registet mac bb power up callback.
|
||||
* @param cb mac bb power up callback.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_register_mac_bb_pu_callback(mac_bb_power_up_cb_t cb);
|
||||
|
||||
/**
|
||||
* @brief Unregistet mac bb power up callback.
|
||||
* @param cb mac bb power up callback.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_unregister_mac_bb_pu_callback(mac_bb_power_up_cb_t cb);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -176,6 +176,95 @@ static void timer_wakeup_prepare(void);
|
||||
static void touch_wakeup_prepare(void);
|
||||
#endif
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
#define MAC_BB_POWER_DOWN_CB_NO 2
|
||||
#define MAC_BB_POWER_UP_CB_NO 2
|
||||
static DRAM_ATTR mac_bb_power_down_cb_t s_mac_bb_power_down_cb[MAC_BB_POWER_DOWN_CB_NO];
|
||||
static DRAM_ATTR mac_bb_power_up_cb_t s_mac_bb_power_up_cb[MAC_BB_POWER_UP_CB_NO];
|
||||
|
||||
esp_err_t esp_register_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)
|
||||
{
|
||||
int index = MAC_BB_POWER_DOWN_CB_NO;
|
||||
for (int i = MAC_BB_POWER_DOWN_CB_NO -1; i >= 0; i--) {
|
||||
if (s_mac_bb_power_down_cb[i] == cb) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (s_mac_bb_power_down_cb[i] == NULL) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < MAC_BB_POWER_DOWN_CB_NO) {
|
||||
s_mac_bb_power_down_cb[index] = cb;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_unregister_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)
|
||||
{
|
||||
for (int i = MAC_BB_POWER_DOWN_CB_NO -1; i >= 0; i--) {
|
||||
if (s_mac_bb_power_down_cb[i] == cb) {
|
||||
s_mac_bb_power_down_cb[i] = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void mac_bb_power_down_cb_execute(void)
|
||||
{
|
||||
for (int i = 0; i < MAC_BB_POWER_DOWN_CB_NO; i++) {
|
||||
if (s_mac_bb_power_down_cb[i]) {
|
||||
s_mac_bb_power_down_cb[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_register_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)
|
||||
{
|
||||
int index = MAC_BB_POWER_UP_CB_NO;
|
||||
for (int i = MAC_BB_POWER_UP_CB_NO -1; i >= 0; i--) {
|
||||
if (s_mac_bb_power_up_cb[i] == cb) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (s_mac_bb_power_up_cb[i] == NULL) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < MAC_BB_POWER_UP_CB_NO) {
|
||||
s_mac_bb_power_up_cb[index] = cb;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_unregister_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)
|
||||
{
|
||||
for (int i = MAC_BB_POWER_UP_CB_NO -1; i >= 0; i--) {
|
||||
if (s_mac_bb_power_up_cb[i] == cb) {
|
||||
s_mac_bb_power_up_cb[i] = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void mac_bb_power_up_cb_execute(void)
|
||||
{
|
||||
for (int i = 0; i < MAC_BB_POWER_UP_CB_NO; i++) {
|
||||
if (s_mac_bb_power_up_cb[i]) {
|
||||
s_mac_bb_power_up_cb[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif ///CONFIG_MAC_BB_PD
|
||||
|
||||
/* Wake from deep sleep stub
|
||||
See esp_deepsleep.h esp_wake_deep_sleep() comments for details.
|
||||
*/
|
||||
@ -342,6 +431,7 @@ void esp_sleep_gpio_status_switch_configure(bool enable)
|
||||
}
|
||||
#endif // SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
|
||||
|
||||
static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
{
|
||||
// Stop UART output so that output is not lost due to APB frequency change.
|
||||
@ -364,6 +454,10 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
suspend_uarts();
|
||||
}
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
mac_bb_power_down_cb_execute();
|
||||
#endif
|
||||
|
||||
// Save current frequency and switch to XTAL
|
||||
rtc_cpu_freq_config_t cpu_freq_config;
|
||||
rtc_clk_cpu_freq_get_config(&cpu_freq_config);
|
||||
@ -474,6 +568,9 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
gpio_sleep_mode_config_unapply();
|
||||
#endif
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
mac_bb_power_up_cb_execute();
|
||||
#endif
|
||||
// re-enable UART output
|
||||
resume_uarts();
|
||||
|
||||
|
@ -446,7 +446,7 @@ menu "PHY"
|
||||
|
||||
config ESP32_PHY_MAC_BB_PD
|
||||
bool "Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled"
|
||||
depends on IDF_TARGET_ESP32C3
|
||||
depends on (IDF_TARGET_ESP32C3 && FREERTOS_USE_TICKLESS_IDLE)
|
||||
default n
|
||||
help
|
||||
If enabled, the MAC and baseband of Wi-Fi and Bluetooth will be powered
|
||||
|
@ -219,6 +219,7 @@ int64_t esp_phy_rf_get_on_ts(void);
|
||||
*/
|
||||
esp_err_t esp_phy_update_country_info(const char *country);
|
||||
|
||||
|
||||
#if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
|
||||
/**
|
||||
* @brief Apply PHY init bin to PHY
|
||||
|
@ -526,6 +526,16 @@ void esp_wifi_internal_update_light_sleep_wake_ahead_time(uint32_t);
|
||||
* - ESP_OK: succeed
|
||||
*/
|
||||
esp_err_t esp_wifi_internal_set_mac_sleep(bool enable);
|
||||
|
||||
/**
|
||||
* @brief mac bb sleep.
|
||||
*/
|
||||
void pm_mac_sleep(void);
|
||||
|
||||
/**
|
||||
* @brief mac bb wakeup.
|
||||
*/
|
||||
void pm_mac_wakeup(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 56d0911c8a27bd97e7939057bf82c61e82a689e6
|
||||
Subproject commit ba5b0ff41f052c8e1e66c92be577a503fcd46674
|
@ -271,8 +271,6 @@ void esp_mac_bb_pd_mem_init(void)
|
||||
|
||||
IRAM_ATTR void esp_mac_bb_power_up(void)
|
||||
{
|
||||
uint32_t level = phy_enter_critical();
|
||||
|
||||
if (s_mac_bb_pd_mem != NULL && s_mac_bb_pd_ref == 0) {
|
||||
esp_phy_common_clock_enable();
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
|
||||
@ -283,13 +281,13 @@ IRAM_ATTR void esp_mac_bb_power_up(void)
|
||||
esp_phy_common_clock_disable();
|
||||
}
|
||||
s_mac_bb_pd_ref++;
|
||||
|
||||
phy_exit_critical(level);
|
||||
}
|
||||
|
||||
IRAM_ATTR void esp_mac_bb_power_down(void)
|
||||
{
|
||||
uint32_t level = phy_enter_critical();
|
||||
if (s_mac_bb_pd_ref == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_mac_bb_pd_ref--;
|
||||
if (s_mac_bb_pd_mem != NULL && s_mac_bb_pd_ref == 0) {
|
||||
@ -299,8 +297,6 @@ IRAM_ATTR void esp_mac_bb_power_down(void)
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
|
||||
esp_phy_common_clock_disable();
|
||||
}
|
||||
|
||||
phy_exit_critical(level);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -152,7 +152,10 @@ esp_err_t esp_wifi_deinit(void)
|
||||
esp_pm_unregister_inform_out_light_sleep_overhead_callback(esp_wifi_internal_update_light_sleep_wake_ahead_time);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
|
||||
esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -207,11 +210,26 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#if CONFIG_MAC_BB_PD
|
||||
if (esp_register_mac_bb_pd_callback(pm_mac_sleep) != ESP_OK
|
||||
|| esp_register_mac_bb_pu_callback(pm_mac_wakeup) != ESP_OK) {
|
||||
|
||||
esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
|
||||
esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_WIFI_HW_TSF
|
||||
esp_err_t ret = esp_pm_register_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to register skip light sleep callback (0x%x)", ret);
|
||||
#if CONFIG_MAC_BB_PD
|
||||
esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
|
||||
esp_unregister_mac_bb_pu_callback(pm_mac_wakeup);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
ret = esp_pm_register_inform_out_light_sleep_overhead_callback(esp_wifi_internal_update_light_sleep_wake_ahead_time);
|
||||
@ -222,10 +240,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
|
||||
esp_sleep_enable_wifi_wakeup();
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_MAC_BB_PD
|
||||
esp_mac_bb_pd_mem_init();
|
||||
esp_wifi_internal_set_mac_sleep(true);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
|
||||
esp_err_t err = tcpip_adapter_set_default_wifi_handlers();
|
||||
if (err != ESP_OK) {
|
||||
@ -237,6 +252,10 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
|
||||
#endif
|
||||
esp_err_t result = esp_wifi_init_internal(config);
|
||||
if (result == ESP_OK) {
|
||||
#if CONFIG_MAC_BB_PD
|
||||
esp_mac_bb_pd_mem_init();
|
||||
esp_wifi_internal_set_mac_sleep(true);
|
||||
#endif
|
||||
esp_wifi_set_debug_log();
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time;
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
static bool is_interrupt_number_reserved(int interrupt_number)
|
||||
{
|
||||
//TODO. Workaround to reserve interrupt number 0 for Wi-Fi.
|
||||
if (interrupt_number == 1) {
|
||||
//TODO. Workaround to reserve interrupt number 1 for Wi-Fi and 5&8 for Bluetooth.
|
||||
if (interrupt_number == 1 || interrupt_number == 5 || interrupt_number == 8) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -270,23 +270,23 @@
|
||||
|
||||
//interrupt cpu using table, Please see the core-isa.h
|
||||
/*************************************************************************************************************
|
||||
* Intr num Level Type PRO CPU usage APP CPU uasge
|
||||
* 0 1 extern level WMAC Reserved
|
||||
* 1 1 extern level BT/BLE Host HCI DMA BT/BLE Host HCI DMA
|
||||
* Intr num Level Type PRO CPU usage
|
||||
* 0 1 extern level Panic
|
||||
* 1 1 extern level WMAC
|
||||
* 2 1 extern level
|
||||
* 3 1 extern level
|
||||
* 4 1 extern level WBB
|
||||
* 5 1 extern level BT/BLE Controller BT/BLE Controller
|
||||
* 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1)
|
||||
* 7 1 software BT/BLE VHCI BT/BLE VHCI
|
||||
* 8 1 extern level BT/BLE BB(RX/TX) BT/BLE BB(RX/TX)
|
||||
* 5 1 extern level BT/BLE Controller
|
||||
* 6 1 timer FreeRTOS Tick(L1)
|
||||
* 7 1 software
|
||||
* 8 1 extern level BT/BLE BB(RX/TX)
|
||||
* 9 1 extern level
|
||||
* 10 1 extern edge
|
||||
* 11 3 profiling
|
||||
* 12 1 extern level
|
||||
* 13 1 extern level
|
||||
* 14 7 nmi Reserved Reserved
|
||||
* 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3)
|
||||
* 14 7 nmi Reserved
|
||||
* 15 3 timer FreeRTOS Tick(L3)
|
||||
* 16 5 timer
|
||||
* 17 1 extern level
|
||||
* 18 1 extern level
|
||||
@ -298,10 +298,10 @@
|
||||
* 24 4 extern level TG1_WDT
|
||||
* 25 4 extern level CACHEERR
|
||||
* 26 5 extern level
|
||||
* 27 3 extern level Reserved Reserved
|
||||
* 28 4 extern edge DPORT ACCESS DPORT ACCESS
|
||||
* 29 3 software Reserved Reserved
|
||||
* 30 4 extern edge Reserved Reserved
|
||||
* 27 3 extern level Reserved
|
||||
* 28 4 extern edge Reserved
|
||||
* 29 3 software Reserved
|
||||
* 30 4 extern edge Reserved
|
||||
* 31 5 extern level
|
||||
*************************************************************************************************************
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user