diff --git a/cpu/esp32/periph/pm.c b/cpu/esp32/periph/pm.c index 15c0577993..6d51baa872 100644 --- a/cpu/esp32/periph/pm.c +++ b/cpu/esp32/periph/pm.c @@ -34,6 +34,23 @@ #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" +static inline esp_sleep_wakeup_cause_t pm_get_wakeup_cause(void) +{ + return esp_sleep_get_wakeup_cause(); +} + +/* function that is required by pm_set if esp_now and esp_wifi are not used */ +esp_err_t __attribute__((weak)) esp_wifi_start(void) +{ + return ESP_OK; +} + +/* function that is required by pm_set if esp_now and esp_wifi are not used */ +esp_err_t __attribute__((weak)) esp_wifi_stop(void) +{ + return ESP_OK; +} + static inline void pm_set_lowest_normal(void) { /* reset system watchdog timer */ @@ -65,6 +82,11 @@ void pm_reboot(void) { DEBUG ("%s\n", __func__); + if (IS_USED(MODULE_ESP_WIFI_ANY)) { + /* stop WiFi if necessary */ + esp_wifi_stop(); + } + /* suspend and flush UARTs */ for (int i = 0; i < 3; ++i) { REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); @@ -121,6 +143,10 @@ void pm_set(unsigned mode) UNREACHABLE(); } else if (mode == ESP_PM_LIGHT_SLEEP) { + if (IS_USED(MODULE_ESP_WIFI_ANY)) { + /* stop WiFi if necessary */ + esp_wifi_stop(); + } esp_light_sleep_start(); @@ -130,6 +156,10 @@ void pm_set(unsigned mode) DEBUG ("%s exit from power mode %d @%u with reason %d\n", __func__, mode, system_get_time(), wakeup_reason); + + /* restart WiFi if necessary */ + if (IS_USED(MODULE_ESP_WIFI_ANY) && (esp_wifi_start() != ESP_OK)) { + LOG_ERROR("esp_wifi_start failed\n"); } } } diff --git a/cpu/esp_common/esp-wifi/esp_wifi_netdev.c b/cpu/esp_common/esp-wifi/esp_wifi_netdev.c index 6dedcd5f00..f88e1586eb 100644 --- a/cpu/esp_common/esp-wifi/esp_wifi_netdev.c +++ b/cpu/esp_common/esp-wifi/esp_wifi_netdev.c @@ -398,6 +398,8 @@ static const char *_esp_wifi_disc_reasons [] = { "HANDSHAKE_TIMEOUT" /* 204 */ }; +static unsigned _esp_wifi_started = 0; + /* * Event handler for esp system events. */ @@ -412,6 +414,7 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t * switch(event->event_id) { case SYSTEM_EVENT_STA_START: + _esp_wifi_started = 1; ESP_WIFI_DEBUG("WiFi started"); result = esp_wifi_connect(); if (result != ESP_OK) { @@ -420,6 +423,11 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t * } break; + case SYSTEM_EVENT_STA_STOP: + _esp_wifi_started = 0; + ESP_WIFI_DEBUG("WiFi stopped"); + break; + case SYSTEM_EVENT_SCAN_DONE: ESP_WIFI_DEBUG("WiFi scan done"); break; @@ -457,19 +465,20 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t * _esp_wifi_dev.event_disc++; netdev_trigger_event_isr(&_esp_wifi_dev.netdev); - /* call disconnect to reset internal state */ - result = esp_wifi_disconnect(); - if (result != ESP_OK) { - ESP_WIFI_LOG_ERROR("esp_wifi_disconnect failed with " - "return value %d", result); - return result; - } + if (reason != WIFI_REASON_ASSOC_LEAVE) { + /* call disconnect to reset internal state */ + result = esp_wifi_disconnect(); + if (result != ESP_OK) { + ESP_WIFI_LOG_ERROR("esp_wifi_disconnect failed with " + "return value %d", result); + return result; + } - /* try to reconnect */ - result = esp_wifi_connect(); - if (result != ESP_OK) { - ESP_WIFI_LOG_ERROR("esp_wifi_connect failed with " - "return value %d", result); + /* try to reconnect */ + if (_esp_wifi_started && ((result = esp_wifi_connect()) != ESP_OK)) { + ESP_WIFI_LOG_ERROR("esp_wifi_connect failed with " + "return value %d", result); + } } break;