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:
baohongde 2021-01-28 22:28:04 +08:00
parent ee480b7776
commit eef66789d4
15 changed files with 327 additions and 91 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
/**

View File

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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -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;
}

View File

@ -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
*************************************************************************************************************
*/