summaryrefslogtreecommitdiff
path: root/code/esp32/components/eos/power.c
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2020-05-24 00:00:38 +0200
committerUros Majstorovic <majstor@majstor.org>2020-05-24 00:00:38 +0200
commit375ac3b0c7e9ed8b2d2d0fc4d0700a23c8865836 (patch)
tree2b2b53c1b1823a606983061f4d6f61e7478cc611 /code/esp32/components/eos/power.c
parent8cab5fea518d4bf6c680816f8ba8b7b7d9ee7401 (diff)
esp32 deep sleep implemented
Diffstat (limited to 'code/esp32/components/eos/power.c')
-rw-r--r--code/esp32/components/eos/power.c166
1 files changed, 117 insertions, 49 deletions
diff --git a/code/esp32/components/eos/power.c b/code/esp32/components/eos/power.c
index 77f2d05..f07e67b 100644
--- a/code/esp32/components/eos/power.c
+++ b/code/esp32/components/eos/power.c
@@ -13,14 +13,14 @@
#include "cell.h"
#include "power.h"
-#define POWER_GPIO_BTN 0
-#define POWER_GPIO_NET 5
-#define POWER_GPIO_UART 35
+#define POWER_GPIO_BTN 0
+#define POWER_GPIO_NET 5
+#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_BTN 1
+#define POWER_ETYPE_SLEEP 2
+#define POWER_ETYPE_WAKE 3
+#define POWER_ETYPE_NETRDY 4
typedef struct {
uint8_t type;
@@ -38,6 +38,8 @@ static const char *TAG = "EOS POWER";
static QueueHandle_t power_queue;
+static volatile int init_done = 0;
+
static void IRAM_ATTR btn_handler(void *arg) {
power_event_t evt;
@@ -77,51 +79,71 @@ static void IRAM_ATTR uart_wake_handler(void *arg) {
xQueueSendFromISR(power_queue, &evt, NULL);
}
-void power_sleep(void) {
+void power_sleep(uint8_t mode) {
gpio_config_t io_conf;
- eos_modem_sleep();
+ eos_modem_sleep(mode);
+ eos_net_sleep_done(mode);
- 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);
+ 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);
- 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);
- 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);
- eos_net_sleep_done();
+ ESP_LOGD(TAG, "SLEEP");
- ESP_LOGD(TAG, "SLEEP");
+ esp_pm_lock_release(power_lock_apb_freq);
+ esp_pm_lock_release(power_lock_no_sleep);
- esp_pm_lock_release(power_lock_apb_freq);
- esp_pm_lock_release(power_lock_no_sleep);
-}
+ break;
-void power_wake_stage1(uint8_t source) {
- gpio_config_t io_conf;
+ 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_pm_lock_acquire(power_lock_apb_freq);
- esp_pm_lock_acquire(power_lock_no_sleep);
+ ESP_LOGD(TAG, "SLEEP");
- gpio_wakeup_disable(POWER_GPIO_BTN);
- gpio_wakeup_disable(POWER_GPIO_NET);
- gpio_wakeup_disable(POWER_GPIO_UART);
+ esp_deep_sleep_start();
+ break;
- gpio_isr_handler_remove(POWER_GPIO_NET);
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_DISABLE;
- 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);
+ default:
+ break;
+ }
+}
+
+void power_wake_stage1(uint8_t source, uint8_t mode) {
+ gpio_config_t io_conf;
+
+ if (mode == EOS_PWR_SMODE_LIGHT) {
+ 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);
+
+ gpio_isr_handler_remove(POWER_GPIO_NET);
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_DISABLE;
+ 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_intr_disable(POWER_GPIO_BTN);
if ((source != EOS_PWR_WAKE_BTN) && (source != EOS_PWR_WAKE_NET)) {
@@ -130,11 +152,12 @@ void power_wake_stage1(uint8_t source) {
vTaskDelay(200 / portTICK_PERIOD_MS);
gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_INPUT);
}
- eos_net_wake(source);
+
+ eos_net_wake(source, mode);
}
-void power_wake_stage2(uint8_t source) {
- eos_modem_wake(source);
+void power_wake_stage2(uint8_t source, uint8_t mode) {
+ eos_modem_wake(source, mode);
gpio_set_intr_type(POWER_GPIO_BTN, GPIO_INTR_ANYEDGE);
gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL);
@@ -145,15 +168,28 @@ void power_wake_stage2(uint8_t source) {
static void power_event_task(void *pvParameters) {
unsigned char *buf;
power_event_t evt;
- uint8_t source = 0;
- int sleep = 0;
+ uint8_t source;
+ uint8_t wakeup_cause;
+ uint8_t mode;
+ int sleep;
+
+ source = 0;
+ wakeup_cause = eos_power_wakeup_cause();
+ if (wakeup_cause) {
+ mode = EOS_PWR_SMODE_DEEP;
+ sleep = 1;
+ } else {
+ mode = EOS_PWR_SMODE_LIGHT;
+ sleep = 0;
+ }
while (1) {
if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) {
switch (evt.type) {
case POWER_ETYPE_SLEEP:
if (!sleep) {
- power_sleep();
+ mode = EOS_PWR_SMODE_DEEP;
+ power_sleep(mode);
sleep = 1;
}
break;
@@ -161,13 +197,13 @@ static void power_event_task(void *pvParameters) {
case POWER_ETYPE_WAKE:
if (sleep) {
source = evt.source;
- power_wake_stage1(source);
+ power_wake_stage1(source, mode);
}
break;
case POWER_ETYPE_NETRDY:
if (sleep && source) {
- power_wake_stage2(source);
+ power_wake_stage2(source, mode);
sleep = 0;
source = 0;
}
@@ -192,6 +228,7 @@ void eos_power_init(void) {
esp_err_t ret;
gpio_config_t io_conf;
esp_pm_config_esp32_t pwr_conf;
+ uint8_t wakeup_cause;
io_conf.intr_type = GPIO_INTR_ANYEDGE;
io_conf.mode = GPIO_MODE_INPUT;
@@ -201,8 +238,14 @@ void eos_power_init(void) {
gpio_config(&io_conf);
gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL);
- ret = esp_sleep_enable_gpio_wakeup();
+ /*
+ ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
+ assert(ret == ESP_OK);
+ ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_ON);
+ assert(ret == ESP_OK);
+ ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
assert(ret == ESP_OK);
+ */
ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, NULL, &power_lock_cpu_freq);
assert(ret == ESP_OK);
@@ -227,9 +270,34 @@ void eos_power_init(void) {
power_queue = xQueueCreate(4, sizeof(power_event_t));
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);
+
+ init_done = 1;
ESP_LOGI(TAG, "INIT");
}
+void eos_power_wait4init(void) {
+ while (!init_done);
+}
+
+uint8_t eos_power_wakeup_cause(void) {
+ esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
+
+ switch (cause) {
+ case ESP_SLEEP_WAKEUP_EXT0:
+ return EOS_PWR_WAKE_BTN;
+
+ case ESP_SLEEP_WAKEUP_EXT1:
+ return EOS_PWR_WAKE_UART;
+
+ default:
+ case ESP_SLEEP_WAKEUP_UNDEFINED:
+ return EOS_PWR_WAKE_RST;
+ }
+}
+
void eos_power_sleep(void) {
power_event_t evt;