diff options
Diffstat (limited to 'fw/esp32/components/eos/power.c')
| -rw-r--r-- | fw/esp32/components/eos/power.c | 185 |
1 files changed, 117 insertions, 68 deletions
diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c index 27c44a5..1f58f77 100644 --- a/fw/esp32/components/eos/power.c +++ b/fw/esp32/components/eos/power.c @@ -18,14 +18,14 @@ #include "cell.h" #include "power.h" -#define PWR_ETYPE_SLEEP_REQ 1 -#define PWR_ETYPE_SLEEP_RDY 2 -#define PWR_ETYPE_WAKE 3 +#define PWR_ETYPE_SET_MODE 1 +#define PWR_ETYPE_SLEEP_REQ 2 +#define PWR_ETYPE_SLEEP_RDY 3 +#define PWR_ETYPE_WAKE 4 typedef struct { uint8_t type; - uint8_t mode; - uint32_t dev; + uint32_t param; } power_event_t; static esp_pm_lock_handle_t power_lock_cpu_freq; @@ -40,7 +40,7 @@ static void IRAM_ATTR net_wake_handler(void *arg) { power_event_t evt; evt.type = PWR_ETYPE_WAKE; - evt.dev = EOS_PWR_DEV_NET; + evt.param = EOS_PWR_DEV_NET; xQueueSendFromISR(power_queue, &evt, NULL); } @@ -48,7 +48,7 @@ static void IRAM_ATTR app_wake_handler(void *arg) { power_event_t evt; evt.type = PWR_ETYPE_WAKE; - evt.dev = EOS_PWR_DEV_APP; + evt.param = EOS_PWR_DEV_APP; xQueueSendFromISR(power_queue, &evt, NULL); } @@ -56,65 +56,112 @@ static void IRAM_ATTR modem_wake_handler(void *arg) { power_event_t evt; evt.type = PWR_ETYPE_WAKE; - evt.dev = EOS_PWR_DEV_MODEM; + evt.param = EOS_PWR_DEV_MODEM; xQueueSendFromISR(power_queue, &evt, NULL); } +static void power_sleep_req(uint32_t dev) { + if (dev & EOS_PWR_DEV_NET) { + eos_net_sleep_req(); + } + if (dev & EOS_PWR_DEV_APP) { + eos_app_sleep_req(); + } + if (dev & EOS_PWR_DEV_MODEM) { + eos_modem_sleep_req(); + } +} + +static void power_sleep_rdy(uint32_t dev) { + gpio_config_t io_conf = { + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_NEGEDGE, + .pull_up_en = 1, + .pull_down_en = 0, + }; + + if (dev & EOS_PWR_DEV_NET) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_NET); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_NET, net_wake_handler, NULL); + } + if (dev & EOS_PWR_DEV_APP) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_APP); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_APP, app_wake_handler, NULL); + } + if (dev & EOS_PWR_DEV_MODEM) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_MODEM); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_MODEM, modem_wake_handler, NULL); + } +} + +static void power_wake(uint32_t dev) { + if (dev & EOS_PWR_DEV_NET) { + gpio_isr_handler_remove(EOS_PWR_GPIO_NET); + gpio_reset_pin(EOS_PWR_GPIO_NET); + eos_net_wake(); + } + if (dev & EOS_PWR_DEV_APP) { + gpio_isr_handler_remove(EOS_PWR_GPIO_APP); + gpio_reset_pin(EOS_PWR_GPIO_APP); + eos_app_wake(); + } + if (dev & EOS_PWR_DEV_MODEM) { + gpio_isr_handler_remove(EOS_PWR_GPIO_MODEM); + gpio_reset_pin(EOS_PWR_GPIO_MODEM); + eos_modem_wake(); + } +} + static void power_event_task(void *pvParameters) { power_event_t evt; uint8_t mode; uint32_t sleep_req, sleep_rdy; int sys_sleep; + mode = 0; sys_sleep = 0; sleep_req = 0; sleep_rdy = 0; + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + mode = EOS_PWR_SMODE_DEEP; + sys_sleep = 1; + sleep_rdy = EOS_PWR_DEV_ALL; + power_sleep_rdy(sleep_rdy); + } + while (1) { if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) { switch (evt.type) { - case PWR_ETYPE_SLEEP_REQ: { - if (evt.mode) mode = evt.mode; - if ((evt.dev & EOS_PWR_DEV_NET) && !(sleep_req & EOS_PWR_DEV_NET)) { - eos_net_sleep_req(); - } - if ((evt.dev & EOS_PWR_DEV_APP) && !(sleep_req & EOS_PWR_DEV_APP)) { - eos_app_sleep_req(); - } - if ((evt.dev & EOS_PWR_DEV_MODEM) && !(sleep_req & EOS_PWR_DEV_MODEM)) { - eos_modem_sleep_req(); - } - sleep_req |= evt.dev; + case PWR_ETYPE_SET_MODE: { + mode = evt.param; if (sleep_rdy == EOS_PWR_DEV_ALL) { eos_power_sleep_rdy(0); } break; } + case PWR_ETYPE_SLEEP_REQ: { + evt.param &= ~sleep_req; + evt.param &= ~sleep_rdy; + + power_sleep_req(evt.param); + + sleep_req |= evt.param; + break; + } + case PWR_ETYPE_SLEEP_RDY: { - gpio_config_t io_conf = { - .mode = GPIO_MODE_INPUT, - .intr_type = GPIO_INTR_NEGEDGE, - .pull_up_en = 1, - .pull_down_en = 0, - }; - - if (evt.dev & EOS_PWR_DEV_NET) { - io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_NET); - gpio_config(&io_conf); - gpio_isr_handler_add(EOS_PWR_GPIO_NET, net_wake_handler, NULL); - } - if (evt.dev & EOS_PWR_DEV_APP) { - io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_APP); - gpio_config(&io_conf); - gpio_isr_handler_add(EOS_PWR_GPIO_APP, app_wake_handler, NULL); - } - if (evt.dev & EOS_PWR_DEV_MODEM) { - io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_MODEM); - gpio_config(&io_conf); - gpio_isr_handler_add(EOS_PWR_GPIO_MODEM, modem_wake_handler, NULL); - } - sleep_rdy |= evt.dev; + evt.param &= sleep_req; + evt.param &= ~sleep_rdy; + + power_sleep_rdy(evt.param); + + sleep_req &= ~evt.param; + sleep_rdy |= evt.param; if (!sys_sleep && mode && (sleep_rdy == EOS_PWR_DEV_ALL)) { sys_sleep = 1; eos_power_sys_sleep(mode); @@ -123,30 +170,18 @@ static void power_event_task(void *pvParameters) { } case PWR_ETYPE_WAKE: { - ESP_LOGI(TAG, "WAKE:0x%.8lX", evt.dev); + evt.param &= ~sleep_req; + evt.param &= sleep_rdy; + if (sys_sleep) { eos_power_sys_wake(mode); sys_sleep = 0; mode = 0; } - if ((evt.dev & EOS_PWR_DEV_NET) && (sleep_rdy & EOS_PWR_DEV_NET)) { - gpio_isr_handler_remove(EOS_PWR_GPIO_NET); - gpio_reset_pin(EOS_PWR_GPIO_NET); - eos_net_wake(); - } - if ((evt.dev & EOS_PWR_DEV_APP) && (sleep_rdy & EOS_PWR_DEV_APP)) { - gpio_isr_handler_remove(EOS_PWR_GPIO_APP); - gpio_reset_pin(EOS_PWR_GPIO_APP); - eos_app_wake(); - } - if ((evt.dev & EOS_PWR_DEV_MODEM) && (sleep_rdy & EOS_PWR_DEV_MODEM)) { - gpio_isr_handler_remove(EOS_PWR_GPIO_MODEM); - gpio_reset_pin(EOS_PWR_GPIO_MODEM); - eos_modem_wake(); - } - sleep_req &= ~evt.dev; - sleep_rdy &= ~evt.dev; - ESP_LOGI(TAG, "WAKE DONE:0x%.8lX", evt.dev); + + power_wake(evt.param); + + sleep_rdy &= ~evt.param; break; } } @@ -186,7 +221,6 @@ void eos_power_init(void) { rtc_gpio_deinit(EOS_PWR_GPIO_NET); rtc_gpio_deinit(EOS_PWR_GPIO_APP); rtc_gpio_deinit(EOS_PWR_GPIO_MODEM); - eos_power_sys_wake(EOS_PWR_SMODE_DEEP); } power_queue = xQueueCreate(4, sizeof(power_event_t)); @@ -201,6 +235,10 @@ void eos_power_run(void) { rv = xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL); assert(rv == pdPASS); + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + eos_power_wake(eos_power_wakeup_source()); + } + ESP_LOGI(TAG, "RUN"); } @@ -221,6 +259,10 @@ void eos_power_sys_sleep(uint8_t mode) { rtc_gpio_pullup_en(EOS_PWR_GPIO_MODEM); esp_sleep_enable_ext1_wakeup_io(EOS_PWR_DEV_ALL, ESP_EXT1_WAKEUP_ANY_LOW); if (mode == EOS_PWR_SMODE_DEEP) { + eos_net_deep_sleep(); + eos_app_deep_sleep(); + eos_modem_deep_sleep(); + gpio_deep_sleep_hold_en(); esp_deep_sleep_start(); } else { @@ -270,12 +312,19 @@ uint32_t eos_power_wakeup_source(void) { return dev; } -void eos_power_sleep_req(uint8_t mode, uint32_t dev) { +void eos_power_set_mode(uint8_t mode) { + power_event_t evt; + + evt.type = PWR_ETYPE_SET_MODE; + evt.param = mode; + xQueueSend(power_queue, &evt, portMAX_DELAY); +} + +void eos_power_sleep_req(uint32_t dev) { power_event_t evt; evt.type = PWR_ETYPE_SLEEP_REQ; - evt.mode = mode; - evt.dev = dev; + evt.param = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } @@ -283,7 +332,7 @@ void eos_power_sleep_rdy(uint32_t dev) { power_event_t evt; evt.type = PWR_ETYPE_SLEEP_RDY; - evt.dev = dev; + evt.param = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } @@ -292,6 +341,6 @@ void eos_power_wake(uint32_t dev) { ESP_LOGI(TAG, "WAKE SENT"); evt.type = PWR_ETYPE_WAKE; - evt.dev = dev; + evt.param = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } |
