From 5d157b4f7ecea4793c9da5c33a890d4ea4afc545 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Sun, 17 May 2020 04:03:16 +0200 Subject: power management implemented; net protocol change --- code/esp32/components/eos/at_cmd.c | 158 ++++++++++++++++ code/esp32/components/eos/at_urc.c | 109 ------------ code/esp32/components/eos/cell.c | 2 +- code/esp32/components/eos/cell_modem.c | 277 ++++++++++++++++++++--------- code/esp32/components/eos/cell_pcm.c | 4 +- code/esp32/components/eos/include/at_cmd.h | 19 ++ code/esp32/components/eos/include/at_urc.h | 17 -- code/esp32/components/eos/include/cell.h | 17 +- code/esp32/components/eos/include/eos.h | 9 +- code/esp32/components/eos/include/net.h | 13 +- code/esp32/components/eos/include/power.h | 13 ++ code/esp32/components/eos/net.c | 190 +++++++++++++------- code/esp32/components/eos/power.c | 257 ++++++++++++++++++++++++++ code/esp32/components/eos/wifi.c | 8 +- code/esp32/main/app_main.c | 7 +- 15 files changed, 802 insertions(+), 298 deletions(-) create mode 100644 code/esp32/components/eos/at_cmd.c delete mode 100644 code/esp32/components/eos/at_urc.c create mode 100644 code/esp32/components/eos/include/at_cmd.h delete mode 100644 code/esp32/components/eos/include/at_urc.h create mode 100644 code/esp32/components/eos/include/power.h create mode 100644 code/esp32/components/eos/power.c (limited to 'code/esp32') diff --git a/code/esp32/components/eos/at_cmd.c b/code/esp32/components/eos/at_cmd.c new file mode 100644 index 0000000..ea31485 --- /dev/null +++ b/code/esp32/components/eos/at_cmd.c @@ -0,0 +1,158 @@ +#include +#include + +#include +#include +#include + +#include "eos.h" + +#include "cell.h" +#include "at_cmd.h" + +static const char *TAG = "EOS ATCMD"; + +typedef struct ATURCItem { + regex_t re; + at_urc_cb_t cb; + char pattern[AT_SIZE_PATTERN]; +} ATURCItem; + +typedef struct ATURCList { + ATURCItem item[AT_SIZE_URC_LIST]; + int len; +} ATURCList; + +static ATURCList urc_list; +static ATURCItem *urc_curr; +static SemaphoreHandle_t mutex; + +static char at_buf[128]; + +void at_init(void) { + memset(&urc_list, 0, sizeof(ATURCList)); + + mutex = xSemaphoreCreateBinary(); + xSemaphoreGive(mutex); +} + +int at_urc_process(char *urc) { + regmatch_t match[AT_SIZE_NMATCH]; + at_urc_cb_t cb = NULL; + regmatch_t *m = NULL; + + xSemaphoreTake(mutex, portMAX_DELAY); + + if (urc_curr == NULL) { + int i; + + for (i=0; icb; + + xSemaphoreGive(mutex); + + if (cb) { + int r = cb(urc, m); + + if (r != AT_URC_MORE) { + xSemaphoreTake(mutex, portMAX_DELAY); + urc_curr = NULL; + xSemaphoreGive(mutex); + } + return 1; + } + return 0; +} + +int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags) { + int r; + int rv = EOS_OK; + + if (strlen(pattern) >= AT_SIZE_PATTERN) return EOS_ERR; + + xSemaphoreTake(mutex, portMAX_DELAY); + + r = regcomp(&urc_list.item[urc_list.len].re, pattern, flags); + if (r) rv = EOS_ERR; + + if (!rv && (urc_list.len == AT_SIZE_URC_LIST)) rv = EOS_ERR_FULL; + if (!rv) { + strcpy(urc_list.item[urc_list.len].pattern, pattern); + urc_list.item[urc_list.len].cb = cb; + urc_list.len++; + } + + xSemaphoreGive(mutex); + + return rv; +} + +int at_urc_delete(char *pattern) { + int i; + int rv = EOS_ERR_NOTFOUND; + + xSemaphoreTake(mutex, portMAX_DELAY); + + for (i=0; i &urc_list.item[i]) { + urc_curr--; + } + } + rv = EOS_OK; + break; + } + } + + xSemaphoreGive(mutex); + + return rv; +} + +int at_expect(char *str_ok, char *str_err, uint32_t timeout) { + int r; + int rv; + regex_t re_ok; + regex_t re_err; + uint32_t e = 0; + uint64_t t_start = esp_timer_get_time(); + + if (str_ok) { + rv = regcomp(&re_ok, str_ok, REG_EXTENDED | REG_NOSUB); + if (rv) return EOS_ERR; + } + + if (str_err) { + rv = regcomp(&re_err, str_err, REG_EXTENDED | REG_NOSUB); + if (rv) return EOS_ERR; + } + + do { + rv = eos_modem_readln(at_buf, sizeof(at_buf), timeout - e); + if (rv) return rv; + + if (at_buf[0] == '\0') continue; + + if (str_ok && (regexec(&re_ok, at_buf, 0, NULL, 0) == 0)) return 1; + if (str_err && (regexec(&re_err, at_buf, 0, NULL, 0) == 0)) return 0; + + r = at_urc_process(at_buf); + if (!r) ESP_LOGD(TAG, "expect unhandled URC: %s", at_buf); + + e = (uint32_t)(esp_timer_get_time() - t_start) / 1000; + if (e >= timeout) return EOS_ERR_TIMEOUT; + } while (1); +} diff --git a/code/esp32/components/eos/at_urc.c b/code/esp32/components/eos/at_urc.c deleted file mode 100644 index b362d6f..0000000 --- a/code/esp32/components/eos/at_urc.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include - -#include -#include - -#include "eos.h" -#include "at_urc.h" - -typedef struct ATURCItem { - regex_t re; - at_urc_cb_t cb; - char pattern[AT_SIZE_PATTERN]; -} ATURCItem; - -typedef struct ATURCList { - ATURCItem item[AT_SIZE_URC_LIST]; - int len; -} ATURCList; - -static ATURCList urc_list; -static ATURCItem *urc_curr; -static SemaphoreHandle_t mutex; - -int at_urc_process(char *urc) { - regmatch_t match[AT_SIZE_NMATCH]; - at_urc_cb_t cb = NULL; - regmatch_t *m = NULL; - - xSemaphoreTake(mutex, portMAX_DELAY); - - if (urc_curr == NULL) { - int i; - - for (i=0; icb; - - xSemaphoreGive(mutex); - - if (cb) { - int r = cb(urc, m); - - if (r != AT_URC_MORE) { - xSemaphoreTake(mutex, portMAX_DELAY); - urc_curr = NULL; - xSemaphoreGive(mutex); - } - return 1; - } - return 0; -} - -int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags) { - int r = EOS_OK; - - if (strlen(pattern) >= AT_SIZE_PATTERN) return EOS_ERR; - - r = regcomp(&urc_list.item[urc_list.len].re, pattern, flags); - if (r) return EOS_ERR; - - xSemaphoreTake(mutex, portMAX_DELAY); - - if (urc_list.len == AT_SIZE_URC_LIST) r = EOS_ERR_FULL; - - if (!r) { - strcpy(urc_list.item[urc_list.len].pattern, pattern); - urc_list.item[urc_list.len].cb = cb; - urc_list.len++; - } - - xSemaphoreGive(mutex); - - return r; -} - -int at_urc_delete(char *pattern) { - int i; - int r = EOS_ERR_NOTFOUND; - - xSemaphoreTake(mutex, portMAX_DELAY); - - for (i=0; i &urc_list.item[i]) { - urc_curr--; - } - } - - r = EOS_OK; - break; - } - } - - xSemaphoreGive(mutex); - - return r; -} diff --git a/code/esp32/components/eos/cell.c b/code/esp32/components/eos/cell.c index 138a4e4..2da1450 100644 --- a/code/esp32/components/eos/cell.c +++ b/code/esp32/components/eos/cell.c @@ -14,7 +14,7 @@ static void cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t s switch (mtype) { case EOS_CELL_MTYPE_DATA: - eos_modem_write(buffer+1, size-1); + if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer+1, size-1); break; case EOS_CELL_MTYPE_DATA_START: cell_mode = eos_modem_get_mode(); diff --git a/code/esp32/components/eos/cell_modem.c b/code/esp32/components/eos/cell_modem.c index 79e8e86..589f1d8 100644 --- a/code/esp32/components/eos/cell_modem.c +++ b/code/esp32/components/eos/cell_modem.c @@ -13,13 +13,12 @@ #include "eos.h" #include "net.h" -#include "at_urc.h" -#include "cell.h" +#include "power.h" -// XXX: Modem init, reconnect on failure +#include "at_cmd.h" +#include "cell.h" -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) +// XXX: PPP reconnect on failure #define UART_SIZE_BUF 1024 #define UART_SIZE_URC_BUF 128 @@ -29,16 +28,22 @@ #define UART_GPIO_DTR 32 #define UART_GPIO_RI 35 -static QueueHandle_t uart_queue; -static QueueHandle_t uart_ri_queue; +#define MODEM_ETYPE_INIT 1 +#define MODEM_ETYPE_RI 2 + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) static const char *TAG = "EOS MODEM"; static SemaphoreHandle_t mutex; -static char at_resp[128]; +static QueueHandle_t modem_queue; +static QueueHandle_t uart_queue; + static char uart_buf[UART_SIZE_URC_BUF]; static unsigned int uart_buf_len; + static uint8_t uart_mode = EOS_CELL_UART_MODE_NONE; static SemaphoreHandle_t uart_mutex; @@ -54,6 +59,10 @@ typedef enum { UART_EEVT_MODE = UART_EVENT_MAX } uart_eevt_type_t; +typedef struct { + uint8_t type; +} modem_event_t; + static void modem_atcmd_read(size_t bsize); static void uart_data_read(uint8_t mode) { @@ -105,7 +114,7 @@ static void uart_event_task(void *pvParameters) { while (1) { /* Waiting for UART event. */ - if (xQueueReceive(uart_queue, (void *)&event, (portTickType)portMAX_DELAY)) { + if (xQueueReceive(uart_queue, &event, portMAX_DELAY)) { switch (event.type) { case UART_DATA: /* Event of UART receiving data @@ -139,26 +148,66 @@ static void uart_event_task(void *pvParameters) { vTaskDelete(NULL); } -static void uart_ri_event_task(void *pvParameters) { - int level; +static void IRAM_ATTR uart_ri_isr_handler(void *arg) { + modem_event_t evt; - while (1) { - if (xQueueReceive(uart_ri_queue, (void *)&level, (portTickType)portMAX_DELAY) && (level == 0)) { - uint64_t t_start = esp_timer_get_time(); - if (xQueueReceive(uart_ri_queue, (void *)&level, 200 / portTICK_RATE_MS) && (level == 1)) { - uint64_t t_end = esp_timer_get_time(); - ESP_LOGI(TAG, "URC:%u", (uint32_t)(t_end - t_start)); - } else { - ESP_LOGI(TAG, "RING"); + evt.type = MODEM_ETYPE_RI; + xQueueSendFromISR(modem_queue, &evt, NULL); +} + +static int modem_atcmd_init(void) { + unsigned char *buf; + int echo_on = 0; + int tries = 3; + int r; + int rv = EOS_OK; + + rv = eos_modem_take(1000); + if (rv) return rv; + + do { + eos_modem_write("AT\r", 3); + r = at_expect("^AT", "^OK", 1000); + if (r >= 0) { + echo_on = r; + if (echo_on) { + r = at_expect("^OK", NULL, 1000); } + break; } + tries--; + } while (tries); + + if (tries == 0) { + eos_modem_give(); + return EOS_ERR_TIMEOUT; } - vTaskDelete(NULL); -} -static void IRAM_ATTR uart_ri_isr_handler(void *arg) { - int level = gpio_get_level(UART_GPIO_RI); - xQueueSendFromISR(uart_ri_queue, &level, NULL); + if (echo_on) { + eos_modem_write("AT&F\r", 5); + r = at_expect("^AT&F", NULL, 1000); + r = at_expect("^OK", NULL, 1000); + } else { + r = eos_modem_write("AT&F\r", 5); + r = at_expect("^OK", NULL, 1000); + + } + eos_modem_write("ATE0\r", 5); + r = at_expect("^ATE0", NULL, 1000); + r = at_expect("^OK", "^ERROR", 1000); + + eos_modem_write("AT+CSCLK=1\r", 11); + r = at_expect("^OK", "^ERROR", 1000); + eos_modem_write("AT+CFGRI=1\r", 11); + r = at_expect("^OK", "^ERROR", 1000); + + buf = eos_net_alloc(); + buf[0] = EOS_CELL_MTYPE_READY; + eos_net_send(EOS_NET_MTYPE_CELL, buf, 1, 0); + + eos_modem_give(); + + return EOS_OK; } static void modem_atcmd_read(size_t bsize) { @@ -175,8 +224,13 @@ static void modem_atcmd_read(size_t bsize) { while ((ln_end = strchr(ln_next, '\n'))) { ln_end--; if ((ln_end > ln_begin) && (*ln_end == '\r')) { + int r; + *ln_end = '\0'; - at_urc_process(ln_begin); + r = at_urc_process(ln_begin); + if (!r) { + ESP_LOGD(TAG, "unhandled URC: %s", ln_begin); + } } ln_next = ln_end + 2; ln_begin = ln_next; @@ -191,12 +245,54 @@ static void modem_atcmd_read(size_t bsize) { } while (rd != bsize); } +int modem_urc_init_handler(char *urc, regmatch_t *m) { + modem_event_t evt; + + evt.type = MODEM_ETYPE_INIT; + xQueueSend(modem_queue, &evt, portMAX_DELAY); + + return AT_URC_OK; +} + static void modem_set_mode(uint8_t mode) { uart_event_t evt; evt.type = UART_EEVT_MODE; evt.size = mode; - xQueueSend(uart_queue, (void *)&evt, portMAX_DELAY); + xQueueSend(uart_queue, &evt, portMAX_DELAY); +} + +static void modem_event_task(void *pvParameters) { + modem_event_t evt; + + while (1) { + if (xQueueReceive(modem_queue, &evt, portMAX_DELAY)) { + switch (evt.type) { + case MODEM_ETYPE_INIT: + modem_atcmd_init(); + break; + + case MODEM_ETYPE_RI: + ESP_LOGI(TAG, "URC from RI"); + break; + + default: + break; + } + + /* Obsolete!!! + uint64_t t_start = esp_timer_get_time(); + if (xQueueReceive(modem_queue, &level, 200 / portTICK_RATE_MS) && (level == 1)) { + uint64_t t_end = esp_timer_get_time(); + ESP_LOGI(TAG, "URC:%u", (uint32_t)(t_end - t_start)); + } else { + ESP_LOGI(TAG, "RING"); + } + */ + + } + } + vTaskDelete(NULL); } static char *memstr(char *mem, size_t size, char *str) { @@ -296,15 +392,14 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { } } -static int ppp_pause(void) { +static int ppp_pause(uint32_t timeout, uint8_t retries) { int done = 0; int len = 0; - int ret = EOS_OK; + int rv = EOS_OK; char *ok_str = NULL; uint64_t t_start; - uint32_t timeout = 500; - uint8_t retries = 1; + timeout += 1000; xSemaphoreTake(ppp_mutex, portMAX_DELAY); eos_modem_flush(); vTaskDelay(1000 / portTICK_PERIOD_MS); @@ -336,11 +431,11 @@ static int ppp_pause(void) { } if (timeout && !done && ((uint32_t)((esp_timer_get_time() - t_start) / 1000) > timeout)) { if (!retries) { - ret = EOS_ERR_TIMEOUT; - done = 1; modem_set_mode(EOS_CELL_UART_MODE_PPP); xSemaphoreGive(uart_mutex); xSemaphoreGive(ppp_mutex); + rv = EOS_ERR_TIMEOUT; + done = 1; } else { retries--; eos_modem_write("+++", 3); @@ -349,7 +444,7 @@ static int ppp_pause(void) { } } while (!done); - return ret; + return rv; } static int ppp_resume(void) { @@ -357,7 +452,7 @@ static int ppp_resume(void) { int rv = EOS_OK; eos_modem_write("ATO\r", 4); - r = eos_modem_resp("^CONNECT", "^(ERROR|NO CARRIER)", 1000); + r = at_expect("^CONNECT", "^(ERROR|NO CARRIER)", 1000); if (r <= 0) rv = EOS_ERR; modem_set_mode(EOS_CELL_UART_MODE_PPP); @@ -375,10 +470,14 @@ static int ppp_setup(void) { if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return EOS_ERR; modem_set_mode(EOS_CELL_UART_MODE_NONE); - xSemaphoreTake(uart_mutex, portMAX_DELAY); + r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS); + if (r == pdFALSE) { + modem_set_mode(uart_mode); + return EOS_ERR_TIMEOUT; + } eos_modem_write(cmd, cmd_len); - r = eos_modem_resp("^OK", "^ERROR", 1000); + r = at_expect("^OK", "^ERROR", 1000); if (r <= 0) { modem_set_mode(uart_mode); xSemaphoreGive(uart_mutex); @@ -386,7 +485,7 @@ static int ppp_setup(void) { } eos_modem_write("AT+CGDATA=\"PPP\",1\r", 18); - r = eos_modem_resp("^CONNECT", "^(ERROR|\\+CME ERROR|NO CARRIER)", 1000); + r = at_expect("^CONNECT", "^(ERROR|\\+CME ERROR|NO CARRIER)", 1000); if (r <= 0) { modem_set_mode(uart_mode); xSemaphoreGive(uart_mutex); @@ -410,11 +509,11 @@ static int ppp_disconnect(void) { pppapi_close(ppp_handle, 0); - rv = ppp_pause(); + rv = ppp_pause(1000, 2); if (rv) return rv; eos_modem_write("ATH\r", 4); - eos_modem_resp("^OK", NULL, 1000); + at_expect("^OK", NULL, 1000); xSemaphoreGive(uart_mutex); xSemaphoreGive(ppp_mutex); @@ -448,7 +547,7 @@ void eos_modem_init(void) { gpio_config(&io_conf); gpio_set_level(UART_GPIO_DTR, 0); - io_conf.intr_type = GPIO_PIN_INTR_ANYEDGE; + io_conf.intr_type = GPIO_INTR_NEGEDGE; io_conf.mode = GPIO_MODE_INPUT; io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_RI); io_conf.pull_up_en = 0; @@ -464,12 +563,16 @@ void eos_modem_init(void) { ppp_mutex = xSemaphoreCreateBinary(); xSemaphoreGive(ppp_mutex); - uart_ri_queue = xQueueCreate(4, sizeof(int)); - // Create a task to handle uart event from ISR + modem_queue = xQueueCreate(4, sizeof(modem_event_t)); xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL); - xTaskCreate(uart_ri_event_task, "uart_ri_event", EOS_TASK_SSIZE_UART_RI, NULL, EOS_TASK_PRIORITY_UART_RI, NULL); + xTaskCreate(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL); gpio_isr_handler_add(UART_GPIO_RI, uart_ri_isr_handler, NULL); + + at_init(); + at_urc_insert("^PB DONE", modem_urc_init_handler, REG_EXTENDED); + eos_modem_set_mode(EOS_CELL_UART_MODE_ATCMD); + ESP_LOGI(TAG, "INIT"); } @@ -488,10 +591,11 @@ size_t eos_modem_read(void *data, size_t size, uint32_t timeout) { int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout) { int done = 0; int len = 0; - int ret = EOS_OK; + int rv = EOS_OK; char *ln_end = NULL; uint64_t t_start = esp_timer_get_time(); + uart_buf[uart_buf_len] = '\0'; ln_end = strchr(uart_buf, '\n'); do { @@ -506,12 +610,13 @@ int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout) { if (ln_end) { ln_end--; if ((ln_end >= uart_buf) && (*ln_end == '\r')) { - if (buf_size > ln_end - uart_buf) { - memcpy(buf, uart_buf, ln_end - uart_buf); - buf[ln_end - uart_buf] = '\0'; - ret = EOS_OK; - } else { - ret = EOS_ERR; + if (buf) { + if (buf_size > ln_end - uart_buf) { + memcpy(buf, uart_buf, ln_end - uart_buf); + buf[ln_end - uart_buf] = '\0'; + } else { + rv = EOS_ERR; + } } done = 1; } @@ -524,40 +629,12 @@ int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout) { uart_buf_len = sizeof(uart_buf) / 2; } if (timeout && !done && ((uint32_t)((esp_timer_get_time() - t_start) / 1000) > timeout)) { - ret = EOS_ERR_TIMEOUT; + rv = EOS_ERR_TIMEOUT; done = 1; } } while (!done); - return ret; -} - -int eos_modem_resp(char *ok_str, char *err_str, uint32_t timeout) { - int rv; - regex_t re; - uint32_t e = 0; - uint64_t t_start = esp_timer_get_time(); - - do { - rv = eos_modem_readln(at_resp, sizeof(at_resp), timeout - e); - if (rv) return EOS_ERR; - - if (ok_str) { - rv = regcomp(&re, ok_str, REG_EXTENDED | REG_NOSUB); - if (rv) return EOS_ERR; - if (regexec(&re, at_resp, 0, NULL, 0) == 0) return 1; - } - - if (err_str) { - rv = regcomp(&re, err_str, REG_EXTENDED | REG_NOSUB); - if (rv) return EOS_ERR; - if (regexec(&re, at_resp, 0, NULL, 0) == 0) return 0; - } - - at_urc_process(at_resp); - e = (uint32_t)(esp_timer_get_time() - t_start) / 1000; - if (e >= timeout) return EOS_ERR; - } while (1); + return rv; } uint8_t eos_modem_get_mode(void) { @@ -590,22 +667,32 @@ int eos_modem_set_mode(uint8_t mode) { return rv; } -int eos_modem_take(void) { +int eos_modem_take(uint32_t timeout) { int rv = EOS_OK; xSemaphoreTake(mutex, portMAX_DELAY); if (uart_mode == EOS_CELL_UART_MODE_PPP) { - rv = ppp_pause(); + rv = ppp_pause(timeout, 0); } else { + int r; + modem_set_mode(EOS_CELL_UART_MODE_NONE); - xSemaphoreTake(uart_mutex, portMAX_DELAY); + r = xSemaphoreTake(uart_mutex, timeout ? timeout / portTICK_PERIOD_MS : portMAX_DELAY); + if (r == pdFALSE) { + modem_set_mode(uart_mode); + rv = EOS_ERR_TIMEOUT; + } } + + if (rv) xSemaphoreGive(mutex); + return rv; } void eos_modem_give(void) { if (uart_mode == EOS_CELL_UART_MODE_PPP) { - ppp_resume(); + int rv = ppp_resume(); + if (rv) ESP_LOGW(TAG, "PPP resume failed"); } else { modem_set_mode(uart_mode); xSemaphoreGive(uart_mutex); @@ -614,11 +701,31 @@ void eos_modem_give(void) { } void eos_modem_sleep(void) { + int r; + + xSemaphoreTake(mutex, portMAX_DELAY); + modem_set_mode(EOS_CELL_UART_MODE_NONE); + r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS); + if (r == pdFALSE) { + ESP_LOGE(TAG, "Obtaining mutex before sleep failed"); + } gpio_set_level(UART_GPIO_DTR, 1); } -void eos_modem_wake(void) { +void eos_modem_wake(uint8_t source) { + if (source == EOS_PWR_WAKE_UART) { + modem_event_t evt; + + evt.type = MODEM_ETYPE_RI; + xQueueSend(modem_queue, &evt, portMAX_DELAY); + } + gpio_set_intr_type(UART_GPIO_RI, GPIO_INTR_NEGEDGE); + gpio_isr_handler_add(UART_GPIO_RI, uart_ri_isr_handler, NULL); + gpio_set_level(UART_GPIO_DTR, 0); + modem_set_mode(uart_mode); + xSemaphoreGive(uart_mutex); + xSemaphoreGive(mutex); } void eos_ppp_set_apn(char *apn) { diff --git a/code/esp32/components/eos/cell_pcm.c b/code/esp32/components/eos/cell_pcm.c index 9ee6b63..c1419b8 100644 --- a/code/esp32/components/eos/cell_pcm.c +++ b/code/esp32/components/eos/cell_pcm.c @@ -54,7 +54,7 @@ static void i2s_event_task(void *pvParameters) { while (1) { // Waiting for I2S event. - if (xQueueReceive(i2s_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + if (xQueueReceive(i2s_queue, &event, portMAX_DELAY)) { switch (event.type) { case I2S_EVENT_RX_DONE: // Event of I2S receiving data @@ -248,7 +248,7 @@ void eos_pcm_start(void) { xSemaphoreGive(mutex); evt.type = I2S_EVENT_MAX; /* my type */ - xQueueSend(i2s_queue, (void *)&evt, portMAX_DELAY); + xQueueSend(i2s_queue, &evt, portMAX_DELAY); i2s_zero_dma_buffer(I2S_NUM_0); i2s_start(I2S_NUM_0); } diff --git a/code/esp32/components/eos/include/at_cmd.h b/code/esp32/components/eos/include/at_cmd.h new file mode 100644 index 0000000..ca46e23 --- /dev/null +++ b/code/esp32/components/eos/include/at_cmd.h @@ -0,0 +1,19 @@ +#include +#include +#include + +#define AT_SIZE_NMATCH 4 +#define AT_SIZE_PATTERN 64 + +#define AT_SIZE_URC_LIST 16 + +#define AT_URC_OK 0 +#define AT_URC_MORE 1 + +typedef int (*at_urc_cb_t) (char *, regmatch_t[]); + +void at_init(void); +int at_urc_process(char *urc); +int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags); +int at_urc_delete(char *pattern); +int at_expect(char *str_ok, char *str_err, uint32_t timeout); \ No newline at end of file diff --git a/code/esp32/components/eos/include/at_urc.h b/code/esp32/components/eos/include/at_urc.h deleted file mode 100644 index 9a4c641..0000000 --- a/code/esp32/components/eos/include/at_urc.h +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include - -#define AT_SIZE_NMATCH 4 -#define AT_SIZE_PATTERN 64 - -#define AT_SIZE_URC_LIST 16 - -#define AT_URC_OK 0 -#define AT_URC_MORE 1 - -typedef int (*at_urc_cb_t) (char *, regmatch_t[]); - -int at_urc_process(char *urc); -int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags); -int at_urc_delete(char *pattern); \ No newline at end of file diff --git a/code/esp32/components/eos/include/cell.h b/code/esp32/components/eos/include/cell.h index 3a9e955..17847ce 100644 --- a/code/esp32/components/eos/include/cell.h +++ b/code/esp32/components/eos/include/cell.h @@ -1,13 +1,14 @@ #include -#define EOS_CELL_MTYPE_DATA 0 -#define EOS_CELL_MTYPE_AUDIO 1 +#define EOS_CELL_MTYPE_READY 0 +#define EOS_CELL_MTYPE_DATA 1 +#define EOS_CELL_MTYPE_AUDIO 2 -#define EOS_CELL_MTYPE_DATA_START 2 -#define EOS_CELL_MTYPE_DATA_STOP 3 +#define EOS_CELL_MTYPE_DATA_START 4 +#define EOS_CELL_MTYPE_DATA_STOP 5 -#define EOS_CELL_MTYPE_AUDIO_START 4 -#define EOS_CELL_MTYPE_AUDIO_STOP 5 +#define EOS_CELL_MTYPE_AUDIO_START 6 +#define EOS_CELL_MTYPE_AUDIO_STOP 7 #define EOS_CELL_UART_MODE_NONE 0 #define EOS_CELL_UART_MODE_ATCMD 1 @@ -31,11 +32,11 @@ int eos_modem_resp(char *ok_str, char *err_str, uint32_t timeout); uint8_t eos_modem_get_mode(void); int eos_modem_set_mode(uint8_t mode); -int eos_modem_take(void); +int eos_modem_take(uint32_t timeout); void eos_modem_give(void); void eos_modem_sleep(void); -void eos_modem_wake(void); +void eos_modem_wake(uint8_t source); void eos_ppp_set_apn(char *apn); void eos_ppp_set_auth(char *user, char *pass); diff --git a/code/esp32/components/eos/include/eos.h b/code/esp32/components/eos/include/eos.h index 87ac9f3..0e660fb 100644 --- a/code/esp32/components/eos/include/eos.h +++ b/code/esp32/components/eos/include/eos.h @@ -1,22 +1,23 @@ #define EOS_OK 0 #define EOS_ERR -1 #define EOS_ERR_TIMEOUT -2 +#define EOS_ERR_BUSY -3 #define EOS_ERR_FULL -10 #define EOS_ERR_EMPTY -11 #define EOS_ERR_NOTFOUND -12 -#define EOS_ERR_BUSY -13 #define EOS_TASK_PRIORITY_UART 1 -#define EOS_TASK_PRIORITY_UART_RI 1 +#define EOS_TASK_PRIORITY_MODEM 1 #define EOS_TASK_PRIORITY_I2S 1 #define EOS_TASK_PRIORITY_NET_XCHG 1 #define EOS_TASK_PRIORITY_UDP_RCVR 1 +#define EOS_TASK_PRIORITY_PWR 1 #define EOS_TASK_SSIZE_UART 4096 -#define EOS_TASK_SSIZE_UART_RI 4096 +#define EOS_TASK_SSIZE_MODEM 4096 #define EOS_TASK_SSIZE_I2S 4096 #define EOS_TASK_SSIZE_NET_XCHG 8192 #define EOS_TASK_SSIZE_UDP_RCVR 4096 - +#define EOS_TASK_SSIZE_PWR 4096 diff --git a/code/esp32/components/eos/include/net.h b/code/esp32/components/eos/include/net.h index df1bd0d..818776e 100644 --- a/code/esp32/components/eos/include/net.h +++ b/code/esp32/components/eos/include/net.h @@ -1,7 +1,10 @@ #include +/* common */ +#define EOS_NET_SIZE_BUF 1500 + #define EOS_NET_MTYPE_SOCK 1 -#define EOS_NET_MTYPE_AUDIO 2 +#define EOS_NET_MTYPE_POWER 4 #define EOS_NET_MTYPE_WIFI 5 #define EOS_NET_MTYPE_CELL 6 @@ -10,9 +13,9 @@ #define EOS_NET_MAX_MTYPE 8 -#define EOS_NET_MTYPE_FLAG_ONEW 0x10 +#define EOS_NET_MTYPE_FLAG_ONEW 0x80 -#define EOS_NET_SIZE_BUF 1500 +/* esp32 specific */ #define EOS_NET_SIZE_BUFQ 4 #define EOS_NET_SIZE_SNDQ 4 @@ -25,4 +28,6 @@ void eos_net_init(void); unsigned char *eos_net_alloc(void); void eos_net_free(unsigned char *buf); int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len, uint8_t flags); -void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler); \ No newline at end of file +void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler); +void eos_net_sleep_done(void); +void eos_net_wake(uint8_t source); diff --git a/code/esp32/components/eos/include/power.h b/code/esp32/components/eos/include/power.h new file mode 100644 index 0000000..3f44507 --- /dev/null +++ b/code/esp32/components/eos/include/power.h @@ -0,0 +1,13 @@ +#include + +#define EOS_PWR_MTYPE_BUTTON 0 + +#define EOS_PWR_WAKE_BTN 1 +#define EOS_PWR_WAKE_NET 2 +#define EOS_PWR_WAKE_MSG 3 +#define EOS_PWR_WAKE_UART 4 + +void eos_power_init(void); +void eos_power_sleep(void); +void eos_power_wake(uint8_t source); +void eos_power_1v8rdy(void); \ No newline at end of file diff --git a/code/esp32/components/eos/net.c b/code/esp32/components/eos/net.c index 4eb4983..c5be1bf 100644 --- a/code/esp32/components/eos/net.c +++ b/code/esp32/components/eos/net.c @@ -15,6 +15,7 @@ #include "eos.h" #include "msgq.h" +#include "power.h" #include "net.h" #define SPI_GPIO_RTS 22 @@ -24,6 +25,10 @@ #define SPI_GPIO_SCLK 18 #define SPI_GPIO_CS 5 +#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 8) + +static volatile char net_sleep; + static EOSBufQ net_buf_q; static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; @@ -32,40 +37,74 @@ static EOSMsgItem net_sndq_array[EOS_NET_SIZE_SNDQ]; static SemaphoreHandle_t mutex; static SemaphoreHandle_t semaph; - +static TaskHandle_t net_xchg_task_handle; static const char *TAG = "EOS NET"; static eos_net_fptr_t mtype_handler[EOS_NET_MAX_MTYPE]; static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { - ESP_LOGE(TAG, "NET RECV: bad handler: %d", mtype); + ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len); +} + +// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. +static void _post_setup_cb(spi_slave_transaction_t *trans) { + gpio_set_level(SPI_GPIO_CTS, 1); +} + +// Called after transaction is sent/received. We use this to set the handshake line low. +static void _post_trans_cb(spi_slave_transaction_t *trans) { + gpio_set_level(SPI_GPIO_CTS, 0); } static void net_xchg_task(void *pvParameters) { int repeat = 0; + int wake = 0; unsigned char mtype = 0; unsigned char *buffer; uint16_t len; uint8_t flags; - unsigned char *buf_send = heap_caps_malloc(EOS_NET_SIZE_BUF, MALLOC_CAP_DMA); - unsigned char *buf_recv = heap_caps_malloc(EOS_NET_SIZE_BUF, MALLOC_CAP_DMA); + unsigned char *buf_send = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); + unsigned char *buf_recv = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); + esp_err_t ret; + spi_slave_transaction_t spi_tr; - spi_slave_transaction_t t; - memset(&t, 0, sizeof(t)); + //Configuration for the SPI bus + spi_bus_config_t spi_bus_cfg = { + .mosi_io_num = SPI_GPIO_MOSI, + .miso_io_num = SPI_GPIO_MISO, + .sclk_io_num = SPI_GPIO_SCLK + }; - t.length = EOS_NET_SIZE_BUF*8; - t.tx_buffer = buf_send; - t.rx_buffer = buf_recv; - for (;;) { + //Configuration for the SPI slave interface + spi_slave_interface_config_t spi_slave_cfg = { + .mode = 0, + .spics_io_num = SPI_GPIO_CS, + .queue_size = 2, + .flags = 0, + .post_setup_cb = _post_setup_cb, + .post_trans_cb = _post_trans_cb + }; + + //Initialize SPI slave interface + ret = spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); + assert(ret == ESP_OK); + + memset(&spi_tr, 0, sizeof(spi_tr)); + spi_tr.length = SPI_SIZE_BUF * 8; + spi_tr.tx_buffer = buf_send; + spi_tr.rx_buffer = buf_recv; + + while (1) { if (!repeat) { xSemaphoreTake(mutex, portMAX_DELAY); eos_msgq_pop(&net_send_q, &mtype, &buffer, &len, &flags); if (mtype) { - buf_send[0] = ((mtype << 3) | (len >> 8)) & 0xFF; - buf_send[1] = len & 0xFF; + buf_send[0] = mtype; + buf_send[1] = len >> 8; + buf_send[2] = len & 0xFF; if (buffer) { - memcpy(buf_send + 2, buffer, len); + memcpy(buf_send + 3, buffer, len); if (flags & EOS_NET_FLAG_BFREE) { free(buffer); } else { @@ -77,46 +116,69 @@ static void net_xchg_task(void *pvParameters) { gpio_set_level(SPI_GPIO_RTS, 0); buf_send[0] = 0; buf_send[1] = 0; + buf_send[2] = 0; } xSemaphoreGive(mutex); } - - memset(buf_recv, 0, EOS_NET_SIZE_BUF); - spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY); - // ESP_LOGI(TAG, "RECV:%d", (buf_recv[0] >> 3)); repeat = 0; - if (buf_recv[0] != 0) { - mtype = (buf_recv[0] >> 3); - len = ((buf_recv[0] & 0x07) << 8); - len |= buf_recv[1]; - buffer = buf_recv + 2; - if (mtype & EOS_NET_MTYPE_FLAG_ONEW) { - mtype &= ~EOS_NET_MTYPE_FLAG_ONEW; - if (buf_send[0]) repeat = 1; - } - if (mtype <= EOS_NET_MAX_MTYPE) { - mtype_handler[mtype-1](mtype, buffer, len); - } else { - bad_handler(mtype, buffer, len); - } + + buf_recv[0] = 0; + buf_recv[1] = 0; + buf_recv[2] = 0; + spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY); + // ESP_LOGD(TAG, "RECV:%d", buf_recv[0]); + + if (wake) { + eos_power_1v8rdy(); + wake = 0; } - } -} + if (buf_recv[0] == 0x00) continue; + if (buf_recv[0] == 0xFF) { // Sleep req + if (buf_send[0] == 0) { + int abort = 0; -// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. -static void _post_setup_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 1); -} + xSemaphoreTake(mutex, portMAX_DELAY); + net_sleep = 1; + if (eos_msgq_len(&net_send_q)) abort = 1; + xSemaphoreGive(mutex); -// Called after transaction is sent/received. We use this to set the handshake line low. -static void _post_trans_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 0); + spi_slave_free(VSPI_HOST); + + eos_power_sleep(); + if (abort) eos_power_wake(EOS_PWR_WAKE_MSG); + + vTaskSuspend(NULL); + + xSemaphoreTake(mutex, portMAX_DELAY); + net_sleep = 0; + xSemaphoreGive(mutex); + + wake = 1; + repeat = 1; + spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); + } + continue; + } + mtype = buf_recv[0]; + len = (uint16_t)buf_recv[1] << 8; + len |= (uint16_t)buf_recv[2] & 0xFF; + buffer = buf_recv + 3; + if (mtype & EOS_NET_MTYPE_FLAG_ONEW) { + mtype &= ~EOS_NET_MTYPE_FLAG_ONEW; + if (buf_send[0]) repeat = 1; + } + if (mtype <= EOS_NET_MAX_MTYPE) { + mtype_handler[mtype-1](mtype, buffer, len); + } else { + bad_handler(mtype, buffer, len); + } + } + vTaskDelete(NULL); } void eos_net_init(void) { int i; - esp_err_t ret; // Configuration for the handshake lines gpio_config_t io_conf; @@ -137,27 +199,6 @@ void eos_net_init(void) { gpio_config(&io_conf); gpio_set_level(SPI_GPIO_RTS, 0); - //Configuration for the SPI bus - spi_bus_config_t buscfg = { - .mosi_io_num = SPI_GPIO_MOSI, - .miso_io_num = SPI_GPIO_MISO, - .sclk_io_num = SPI_GPIO_SCLK - }; - - //Configuration for the SPI slave interface - spi_slave_interface_config_t slvcfg = { - .mode = 0, - .spics_io_num = SPI_GPIO_CS, - .queue_size = 2, - .flags = 0, - .post_setup_cb = _post_setup_cb, - .post_trans_cb = _post_trans_cb - }; - - //Initialize SPI slave interface - ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1); - assert(ret==ESP_OK); - eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_SNDQ); eos_bufq_init(&net_buf_q, net_bufq_array, EOS_NET_SIZE_BUFQ); for (i=0; i + +#include +#include +#include +#include +#include +#include +#include + +#include "eos.h" +#include "net.h" +#include "cell.h" +#include "power.h" + +#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_1V8RDY 4 + +typedef struct { + uint8_t type; + union { + uint8_t source; + uint8_t level; + }; +} power_event_t; + +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; + +static const char *TAG = "EOS POWER"; + +static QueueHandle_t power_queue; + +static void IRAM_ATTR btn_handler(void *arg) { + power_event_t evt; + + evt.type = POWER_ETYPE_BTN; + evt.level = gpio_get_level(POWER_GPIO_BTN); + xQueueSendFromISR(power_queue, &evt, NULL); +} + +static void IRAM_ATTR btn_wake_handler(void *arg) { + power_event_t evt; + + gpio_intr_disable(POWER_GPIO_BTN); + + evt.type = POWER_ETYPE_WAKE; + evt.source = EOS_PWR_WAKE_BTN; + xQueueSendFromISR(power_queue, &evt, NULL); + +} + +static void IRAM_ATTR net_wake_handler(void *arg) { + power_event_t evt; + + gpio_intr_disable(POWER_GPIO_NET); + + evt.type = POWER_ETYPE_WAKE; + evt.source = EOS_PWR_WAKE_NET; + xQueueSendFromISR(power_queue, &evt, NULL); +} + +static void IRAM_ATTR uart_wake_handler(void *arg) { + power_event_t evt; + + gpio_intr_disable(POWER_GPIO_UART); + + evt.type = POWER_ETYPE_WAKE; + evt.source = EOS_PWR_WAKE_UART; + xQueueSendFromISR(power_queue, &evt, NULL); +} + +void power_sleep(void) { + gpio_config_t io_conf; + + eos_modem_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_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_pm_lock_release(power_lock_apb_freq); + esp_pm_lock_release(power_lock_no_sleep); +} + +void power_wake_stage1(uint8_t source) { + gpio_config_t io_conf; + + 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)) { + gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_OUTPUT); + gpio_set_level(POWER_GPIO_BTN, 0); + vTaskDelay(200 / portTICK_PERIOD_MS); + gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_INPUT); + } + eos_net_wake(source); +} + +void power_wake_stage2(uint8_t source) { + eos_modem_wake(source); + + gpio_set_intr_type(POWER_GPIO_BTN, GPIO_INTR_ANYEDGE); + gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); + + ESP_LOGD(TAG, "WAKE"); +} + +static void power_event_task(void *pvParameters) { + unsigned char *buf; + power_event_t evt; + uint8_t source = 0; + int sleep = 0; + + while (1) { + if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) { + switch (evt.type) { + case POWER_ETYPE_SLEEP: + if (!sleep) { + power_sleep(); + sleep = 1; + } + break; + + case POWER_ETYPE_WAKE: + if (sleep) { + source = evt.source; + power_wake_stage1(source); + } + break; + + case POWER_ETYPE_1V8RDY: + if (sleep && source) { + power_wake_stage2(source); + sleep = 0; + source = 0; + } + break; + + 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, 0); + break; + + default: + break; + } + } + } + vTaskDelete(NULL); +} + +void eos_power_init(void) { + esp_err_t ret; + gpio_config_t io_conf; + esp_pm_config_esp32_t pwr_conf; + + io_conf.intr_type = GPIO_INTR_ANYEDGE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_BTN); + io_conf.pull_up_en = 1; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); + gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); + + ret = esp_sleep_enable_gpio_wakeup(); + assert(ret == ESP_OK); + + ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, NULL, &power_lock_cpu_freq); + assert(ret == ESP_OK); + ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, NULL, &power_lock_apb_freq); + assert(ret == ESP_OK); + ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, NULL, &power_lock_no_sleep); + assert(ret == ESP_OK); + + ret = esp_pm_lock_acquire(power_lock_cpu_freq); + assert(ret == ESP_OK); + ret = esp_pm_lock_acquire(power_lock_apb_freq); + assert(ret == ESP_OK); + ret = esp_pm_lock_acquire(power_lock_no_sleep); + assert(ret == ESP_OK); + + pwr_conf.max_freq_mhz = 160; + pwr_conf.min_freq_mhz = 80; + pwr_conf.light_sleep_enable = 1; + + ret = esp_pm_configure(&pwr_conf); + assert(ret == ESP_OK); + + power_queue = xQueueCreate(4, sizeof(power_event_t)); + xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL); + ESP_LOGI(TAG, "INIT"); +} + +void eos_power_sleep(void) { + power_event_t evt; + + evt.type = POWER_ETYPE_SLEEP; + evt.source = 0; + xQueueSend(power_queue, &evt, portMAX_DELAY); +} + +void eos_power_wake(uint8_t source) { + power_event_t evt; + + evt.type = POWER_ETYPE_WAKE; + evt.source = source; + + xQueueSend(power_queue, &evt, portMAX_DELAY); +} + +void eos_power_1v8rdy(void) { + power_event_t evt; + + evt.type = POWER_ETYPE_1V8RDY; + evt.source = 0; + + xQueueSend(power_queue, &evt, portMAX_DELAY); +} diff --git a/code/esp32/components/eos/wifi.c b/code/esp32/components/eos/wifi.c index 31aefea..3dd90ba 100755 --- a/code/esp32/components/eos/wifi.c +++ b/code/esp32/components/eos/wifi.c @@ -16,7 +16,7 @@ #include "net.h" #include "wifi.h" -// XXX: No DHCP server +// XXX: WiFi fail due to no DHCP server #define WIFI_MAX_SCAN_RECORDS 20 #define WIFI_MAX_CONNECT_ATTEMPTS 3 @@ -45,7 +45,7 @@ static uint8_t wifi_action; static uint8_t wifi_state; static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) { - esp_err_t ret; + esp_err_t ret = ESP_OK; char _disconnect; uint8_t _action, _state; unsigned char *rbuf; @@ -188,6 +188,9 @@ void eos_wifi_init(void) { ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config); assert(ret == ESP_OK); + ret = esp_wifi_stop(); + assert(ret == ESP_OK); + mutex = xSemaphoreCreateBinary(); xSemaphoreGive(mutex); @@ -260,7 +263,6 @@ int eos_wifi_connect(void) { if (rv) return rv; - esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config); if (_wifi_state == WIFI_STATE_STOPPED) { diff --git a/code/esp32/main/app_main.c b/code/esp32/main/app_main.c index 4a277cf..bd2e3e1 100644 --- a/code/esp32/main/app_main.c +++ b/code/esp32/main/app_main.c @@ -6,14 +6,17 @@ #include "_net.h" #include "wifi.h" #include "sock.h" +#include "power.h" #include "bq25895.h" +#define ESP_INTR_FLAG_DEFAULT 0 + // Main application void app_main() { tcpip_adapter_init(); eos_pcm_init(); - gpio_install_isr_service(0); + gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); eos_modem_init(); eos_net_init(); @@ -21,6 +24,8 @@ void app_main() { eos_wifi_init(); eos_sock_init(); + eos_power_init(); + eos_i2c_init(); eos_bq25895_set_ilim(); } -- cgit v1.2.3