From 6a4b3ef0e72ee134b81a523ce41fd4c45f3b4429 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Sun, 4 Sep 2022 18:43:50 +0200 Subject: fixed wifi and cell --- fw/esp32/components/eos/power.c | 190 ++++++++++++++++++++++++++-------------- 1 file changed, 126 insertions(+), 64 deletions(-) (limited to 'fw/esp32/components/eos/power.c') diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c index 0cbb4e0..c659481 100644 --- a/fw/esp32/components/eos/power.c +++ b/fw/esp32/components/eos/power.c @@ -5,8 +5,10 @@ #include #include #include +#include #include #include +#include #include "eos.h" #include "net.h" @@ -18,9 +20,10 @@ #define POWER_GPIO_UART 35 #define POWER_ETYPE_BTN 1 -#define POWER_ETYPE_SLEEP 2 -#define POWER_ETYPE_WAKE 3 -#define POWER_ETYPE_NETRDY 4 +#define POWER_ETYPE_SLEEP1 2 +#define POWER_ETYPE_SLEEP2 3 +#define POWER_ETYPE_WAKE 4 +#define POWER_ETYPE_NETRDY 5 typedef struct { uint8_t type; @@ -30,6 +33,8 @@ typedef struct { }; } power_event_t; +static esp_timer_handle_t timer; + static esp_pm_lock_handle_t power_lock_cpu_freq; static esp_pm_lock_handle_t power_lock_apb_freq; static esp_pm_lock_handle_t power_lock_no_sleep; @@ -39,6 +44,7 @@ static const char *TAG = "EOS POWER"; static QueueHandle_t power_queue; static volatile int init_done = 0; +static volatile int wake_done = 0; static void IRAM_ATTR btn_handler(void *arg) { power_event_t evt; @@ -79,62 +85,79 @@ static void IRAM_ATTR uart_wake_handler(void *arg) { xQueueSendFromISR(power_queue, &evt, NULL); } -void power_sleep(uint8_t mode) { - gpio_config_t io_conf; +static void timer_handler(void *arg) { + power_event_t evt; - eos_modem_sleep(mode); - eos_net_sleep_done(mode); + evt.type = POWER_ETYPE_SLEEP2; + xQueueSendFromISR(power_queue, &evt, NULL); +} - switch (mode) { - case EOS_PWR_SMODE_LIGHT: - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); +void power_sleep_stage1(void) { + gpio_config_t io_conf = {}; + + eos_modem_sleep(); + eos_net_sleep(); + + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET); + io_conf.pull_up_en = 0; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); - gpio_isr_handler_add(POWER_GPIO_BTN, btn_wake_handler, NULL); - gpio_isr_handler_add(POWER_GPIO_NET, net_wake_handler, NULL); - gpio_isr_handler_add(POWER_GPIO_UART, uart_wake_handler, NULL); + gpio_isr_handler_add(POWER_GPIO_BTN, btn_wake_handler, NULL); + gpio_isr_handler_add(POWER_GPIO_NET, net_wake_handler, NULL); + gpio_isr_handler_add(POWER_GPIO_UART, uart_wake_handler, NULL); - esp_sleep_enable_gpio_wakeup(); - gpio_wakeup_enable(POWER_GPIO_BTN, GPIO_INTR_LOW_LEVEL); - gpio_wakeup_enable(POWER_GPIO_NET, GPIO_INTR_LOW_LEVEL); - gpio_wakeup_enable(POWER_GPIO_UART, GPIO_INTR_LOW_LEVEL); + esp_sleep_enable_gpio_wakeup(); + gpio_wakeup_enable(POWER_GPIO_BTN, GPIO_INTR_LOW_LEVEL); + gpio_wakeup_enable(POWER_GPIO_NET, GPIO_INTR_LOW_LEVEL); + gpio_wakeup_enable(POWER_GPIO_UART, GPIO_INTR_LOW_LEVEL); - ESP_LOGI(TAG, "SLEEP"); + esp_timer_start_once(timer, 10 * 1000000); - esp_pm_lock_release(power_lock_apb_freq); - esp_pm_lock_release(power_lock_no_sleep); + esp_pm_lock_release(power_lock_cpu_freq); + esp_pm_lock_release(power_lock_apb_freq); + esp_pm_lock_release(power_lock_no_sleep); +} +void power_sleep_stage2(uint8_t mode) { + switch (mode) { + case EOS_PWR_SMODE_LIGHT: { + ESP_LOGI(TAG, "LIGHT SLEEP"); + + esp_light_sleep_start(); break; + } + + case EOS_PWR_SMODE_DEEP: { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); - case EOS_PWR_SMODE_DEEP: gpio_deep_sleep_hold_en(); esp_sleep_enable_ext0_wakeup(POWER_GPIO_BTN, 0); - esp_sleep_enable_ext1_wakeup((uint64_t)1 << POWER_GPIO_UART, ESP_EXT1_WAKEUP_ALL_LOW); + // esp_sleep_enable_ext1_wakeup((uint64_t)1 << POWER_GPIO_UART, ESP_EXT1_WAKEUP_ALL_LOW); - ESP_LOGI(TAG, "SLEEP"); + ESP_LOGI(TAG, "DEEP SLEEP"); + eos_modem_deep_sleep(); esp_deep_sleep_start(); break; - - default: - break; + } } } void power_wake_stage1(uint8_t source, uint8_t mode) { - gpio_config_t io_conf; - if (mode == EOS_PWR_SMODE_LIGHT) { + gpio_config_t io_conf = {}; + + esp_pm_lock_acquire(power_lock_cpu_freq); esp_pm_lock_acquire(power_lock_apb_freq); esp_pm_lock_acquire(power_lock_no_sleep); gpio_wakeup_disable(POWER_GPIO_BTN); gpio_wakeup_disable(POWER_GPIO_NET); gpio_wakeup_disable(POWER_GPIO_UART); + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); gpio_isr_handler_remove(POWER_GPIO_NET); io_conf.intr_type = GPIO_INTR_DISABLE; @@ -147,8 +170,8 @@ void power_wake_stage1(uint8_t source, uint8_t mode) { gpio_intr_disable(POWER_GPIO_BTN); if ((source != EOS_PWR_WAKE_BTN) && (source != EOS_PWR_WAKE_NET)) { - gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_OUTPUT); gpio_set_level(POWER_GPIO_BTN, 0); + gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_OUTPUT); vTaskDelay(200 / portTICK_PERIOD_MS); gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_INPUT); } @@ -163,58 +186,77 @@ void power_wake_stage2(uint8_t source, uint8_t mode) { gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); ESP_LOGI(TAG, "WAKE"); + wake_done = 1; } static void power_event_task(void *pvParameters) { - unsigned char *buf; power_event_t evt; uint8_t source; uint8_t wakeup_cause; uint8_t mode; - int sleep; + int sleep1, sleep2; + mode = 0; source = 0; wakeup_cause = eos_power_wakeup_cause(); - if (wakeup_cause) { + if (wakeup_cause != EOS_PWR_WAKE_RST) { mode = EOS_PWR_SMODE_DEEP; - sleep = 1; + sleep1 = 1; } else { - mode = EOS_PWR_SMODE_LIGHT; - sleep = 0; + sleep1 = 0; } + sleep2 = 0; while (1) { if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) { switch (evt.type) { - case POWER_ETYPE_SLEEP: - if (!sleep) { + case POWER_ETYPE_SLEEP1: { + if (!sleep1) { + mode = EOS_PWR_SMODE_LIGHT; + power_sleep_stage1(); + sleep1 = 1; + sleep2 = 1; + } + break; + } + + case POWER_ETYPE_SLEEP2: { + if (sleep2) { mode = EOS_PWR_SMODE_DEEP; - power_sleep(mode); - sleep = 1; + power_sleep_stage2(mode); + sleep2 = 0; } break; + } - case POWER_ETYPE_WAKE: - if (sleep) { + case POWER_ETYPE_WAKE: { + if (sleep1) { source = evt.source; power_wake_stage1(source, mode); + if (sleep2) { + esp_timer_stop(timer); + sleep2 = 0; + } } break; + } - case POWER_ETYPE_NETRDY: - if (sleep && source) { - power_wake_stage2(source, mode); - sleep = 0; - source = 0; - } + case POWER_ETYPE_NETRDY: { + power_wake_stage2(source, mode); + sleep1 = 0; + source = 0; break; + } + + case POWER_ETYPE_BTN: { + unsigned char *buf; - case POWER_ETYPE_BTN: buf = eos_net_alloc(); buf[0] = EOS_PWR_MTYPE_BUTTON; buf[1] = evt.level; eos_net_send(EOS_NET_MTYPE_POWER, buf, 2); break; + } default: break; @@ -226,7 +268,8 @@ static void power_event_task(void *pvParameters) { void eos_power_init(void) { esp_err_t ret; - gpio_config_t io_conf; + gpio_config_t io_conf = {}; + esp_timer_create_args_t timer_args = {}; esp_pm_config_esp32_t pwr_conf; uint8_t wakeup_cause; @@ -238,6 +281,13 @@ void eos_power_init(void) { gpio_config(&io_conf); gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); + timer_args.callback = timer_handler, + timer_args.arg = NULL; + timer_args.name = "sleep"; + + ret = esp_timer_create(&timer_args, &timer); + assert(ret == ESP_OK); + /* ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); assert(ret == ESP_OK); @@ -272,7 +322,9 @@ void eos_power_init(void) { xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL); wakeup_cause = eos_power_wakeup_cause(); - if (wakeup_cause) eos_power_wake(wakeup_cause); + if (wakeup_cause != EOS_PWR_WAKE_RST) { + eos_power_wake(wakeup_cause); + } init_done = 1; ESP_LOGI(TAG, "INIT"); @@ -282,25 +334,35 @@ void eos_power_wait4init(void) { while (!init_done); } +void eos_power_wait4wake(void) { + if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) return; + while (!wake_done); +} + uint8_t eos_power_wakeup_cause(void) { - esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + esp_reset_reason_t reset_cause = esp_reset_reason(); + esp_sleep_wakeup_cause_t wakeup_cause = esp_sleep_get_wakeup_cause(); - switch (cause) { - case ESP_SLEEP_WAKEUP_EXT0: - return EOS_PWR_WAKE_BTN; + if (reset_cause == ESP_RST_DEEPSLEEP) { + switch (wakeup_cause) { + case ESP_SLEEP_WAKEUP_EXT0: + return EOS_PWR_WAKE_BTN; - case ESP_SLEEP_WAKEUP_EXT1: - return EOS_PWR_WAKE_UART; + case ESP_SLEEP_WAKEUP_EXT1: + return EOS_PWR_WAKE_UART; - default: - return EOS_PWR_WAKE_RST; + default: + return EOS_PWR_WAKE_UNDEF; + } + } else { + return EOS_PWR_WAKE_RST; } } void eos_power_sleep(void) { power_event_t evt; - evt.type = POWER_ETYPE_SLEEP; + evt.type = POWER_ETYPE_SLEEP1; evt.source = 0; xQueueSend(power_queue, &evt, portMAX_DELAY); } -- cgit v1.2.3