Skip to content

Commit

Permalink
cpu/esp_common: stop WiFi interface before sleep/reboot
Browse files Browse the repository at this point in the history
The WiFi interface should be stopped before reboot or sleep. But stopping the WiFi interface disconnects an existing connection. Usually, esp_wifi_netdev tries to reconnect on an disconnect event. However, trying reconnect with a stopped WiFi interface may lead to a crash. Therefore, the stop event has to be handled.
  • Loading branch information
gschorcht committed Mar 23, 2020
1 parent 09899e4 commit 4f97731
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 13 deletions.
30 changes: 30 additions & 0 deletions cpu/esp32/periph/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();

Expand All @@ -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");
}
}
}
Expand Down
35 changes: 22 additions & 13 deletions cpu/esp_common/esp-wifi/esp_wifi_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

/* try to reconnect */
result = esp_wifi_connect();
if (result != ESP_OK) {
ESP_WIFI_LOG_ERROR("esp_wifi_connect failed with "
"return value %d", 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 */
if (_esp_wifi_started && ((result = esp_wifi_connect()) != ESP_OK)) {
ESP_WIFI_LOG_ERROR("esp_wifi_connect failed with "
"return value %d", result);
}
}

break;
Expand Down

0 comments on commit 4f97731

Please sign in to comment.