Skip to content

Commit

Permalink
fix the issue of failure of receiving beacons in modem state caused b…
Browse files Browse the repository at this point in the history
…y enabling light sleep in wifi min/max modem sleep mode
  • Loading branch information
esp-lis authored and espressif-bot committed Apr 7, 2023
1 parent a15c36f commit 94ebda2
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 5 deletions.
7 changes: 7 additions & 0 deletions components/esp_hw_support/include/esp_private/sleep_modem.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ void mac_bb_power_up_cb_execute(void);

#if SOC_PM_SUPPORT_PMU_MODEM_STATE

/**
* @brief The retention action in the modem state of WiFi PHY module
*
* @param restore true for restore the PHY context, false for backup the PHY context
*/
void sleep_modem_wifi_do_phy_retention(bool restore);

/**
* @brief Get WiFi modem state
*
Expand Down
36 changes: 35 additions & 1 deletion components/esp_hw_support/sleep_modem.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "esp_attr.h"
#include "esp_sleep.h"
#include "soc/soc_caps.h"
#include "esp_private/pm_impl.h"
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#include "sdkconfig.h"
Expand All @@ -26,6 +27,7 @@

#if SOC_PM_SUPPORT_PMU_MODEM_STATE
#include "soc/pmu_reg.h"
#include "esp_private/esp_pau.h"
#endif

static __attribute__((unused)) const char *TAG = "sleep_modem";
Expand Down Expand Up @@ -153,10 +155,17 @@ typedef struct {
typedef struct sleep_modem_config {
struct {
void *phy_link;
union {
struct {
uint32_t modem_state_phy_done: 1;
uint32_t reserved: 31;
};
uint32_t flags;
};
} wifi;
} sleep_modem_config_t;

static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL };
static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL, .wifi.flags = 0 };

static __attribute__((unused)) esp_err_t sleep_modem_wifi_modem_state_init(void)
{
Expand Down Expand Up @@ -229,6 +238,7 @@ static __attribute__((unused)) esp_err_t sleep_modem_wifi_modem_state_init(void)
if (err == ESP_OK) {
pau_regdma_set_modem_link_addr(link);
s_sleep_modem.wifi.phy_link = link;
s_sleep_modem.wifi.flags = 0;
}
}
return err;
Expand All @@ -239,6 +249,19 @@ static __attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void)
if (s_sleep_modem.wifi.phy_link) {
regdma_link_destroy(s_sleep_modem.wifi.phy_link, 0);
s_sleep_modem.wifi.phy_link = NULL;
s_sleep_modem.wifi.flags = 0;
}
}

void IRAM_ATTR sleep_modem_wifi_do_phy_retention(bool restore)
{
if (restore) {
if (s_sleep_modem.wifi.modem_state_phy_done == 1) {
pau_regdma_trigger_modem_link_restore();
}
} else {
pau_regdma_trigger_modem_link_backup();
s_sleep_modem.wifi.modem_state_phy_done = 1;
}
}

Expand Down Expand Up @@ -269,16 +292,27 @@ uint32_t IRAM_ATTR sleep_modem_reject_triggers(void)
return reject_triggers;
}

static __attribute__((unused)) bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_light_sleep(void)
{
bool skip = false;
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
skip = (s_sleep_modem.wifi.phy_link != NULL) && (s_sleep_modem.wifi.modem_state_phy_done == 0);
#endif
return skip;
}

esp_err_t sleep_modem_configure(int max_freq_mhz, int min_freq_mhz, bool light_sleep_enable)
{
#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
extern int esp_wifi_internal_mac_sleep_configure(bool, bool);
if (light_sleep_enable) {
if (sleep_modem_wifi_modem_state_init() == ESP_OK) {
esp_pm_register_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep);
esp_wifi_internal_mac_sleep_configure(light_sleep_enable, true); /* require WiFi to enable automatically receives the beacon */
}
} else {
esp_wifi_internal_mac_sleep_configure(light_sleep_enable, false); /* require WiFi to disable automatically receives the beacon */
esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep);
sleep_modem_wifi_modem_state_deinit();
}
#endif
Expand Down
5 changes: 2 additions & 3 deletions components/esp_phy/src/phy_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
#include "soc/dport_reg.h"
#elif CONFIG_IDF_TARGET_ESP32C6
#include "esp_private/sleep_modem.h"
#include "esp_private/esp_pau.h"
#endif
#include "hal/efuse_hal.h"

Expand Down Expand Up @@ -253,7 +252,7 @@ void esp_phy_enable(void)
extern bool pm_mac_modem_rf_already_enabled(void);
if (!pm_mac_modem_rf_already_enabled()) {
if (sleep_modem_wifi_modem_state_enabled()) {
pau_regdma_trigger_modem_link_restore();
sleep_modem_wifi_do_phy_retention(true);
} else {
phy_wakeup_init();
}
Expand Down Expand Up @@ -287,7 +286,7 @@ void esp_phy_disable(void)
#endif
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
if (sleep_modem_wifi_modem_state_enabled()) {
pau_regdma_trigger_modem_link_backup();
sleep_modem_wifi_do_phy_retention(false);
} else
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP */
{
Expand Down
2 changes: 1 addition & 1 deletion components/esp_pm/pm_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ static uint32_t s_mode_mask;

#if CONFIG_FREERTOS_USE_TICKLESS_IDLE

#define PERIPH_SKIP_LIGHT_SLEEP_NO 1
#define PERIPH_SKIP_LIGHT_SLEEP_NO 2

/* Indicates if light sleep shoule be skipped by peripherals. */
static skip_light_sleep_cb_t s_periph_skip_light_sleep_cb[PERIPH_SKIP_LIGHT_SLEEP_NO];
Expand Down

0 comments on commit 94ebda2

Please sign in to comment.