diff options
| -rw-r--r-- | code/esp32/components/eos/cell_modem.c | 36 | ||||
| -rw-r--r-- | code/esp32/components/eos/include/cell.h | 4 | ||||
| -rw-r--r-- | code/esp32/components/eos/include/i2c.h | 1 | ||||
| -rw-r--r-- | code/esp32/components/eos/include/net.h | 5 | ||||
| -rw-r--r-- | code/esp32/components/eos/include/power.h | 7 | ||||
| -rw-r--r-- | code/esp32/components/eos/net.c | 17 | ||||
| -rw-r--r-- | code/esp32/components/eos/power.c | 166 | ||||
| -rw-r--r-- | code/esp32/main/app_main.c | 7 | 
8 files changed, 171 insertions, 72 deletions
| diff --git a/code/esp32/components/eos/cell_modem.c b/code/esp32/components/eos/cell_modem.c index 589f1d8..5315861 100644 --- a/code/esp32/components/eos/cell_modem.c +++ b/code/esp32/components/eos/cell_modem.c @@ -9,6 +9,7 @@  #include <netif/ppp/pppapi.h>  #include <driver/uart.h>  #include <driver/gpio.h> +#include <esp_sleep.h>  #include <esp_log.h>  #include "eos.h" @@ -44,7 +45,7 @@ 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 uint8_t uart_mode = EOS_CELL_UART_MODE_ATCMD;  static SemaphoreHandle_t uart_mutex;  static char ppp_apn[64]; @@ -107,10 +108,11 @@ static void uart_data_read(uint8_t mode) {  }  static void uart_event_task(void *pvParameters) { -    char mode = EOS_CELL_UART_MODE_NONE; -    char _mode = EOS_CELL_UART_MODE_NONE; +    char mode = EOS_CELL_UART_MODE_ATCMD; +    char _mode = EOS_CELL_UART_MODE_ATCMD;      uart_event_t event; +    xSemaphoreTake(uart_mutex, portMAX_DELAY);      while (1) {          /* Waiting for UART event.           */ @@ -196,10 +198,10 @@ static int modem_atcmd_init(void) {      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); +    eos_modem_write("AT+CSCLK=1\r", 11); +    r = at_expect("^OK", "^ERROR", 1000);      buf = eos_net_alloc();      buf[0] = EOS_CELL_MTYPE_READY; @@ -700,7 +702,7 @@ void eos_modem_give(void) {      xSemaphoreGive(mutex);  } -void eos_modem_sleep(void) { +void eos_modem_sleep(uint8_t mode) {      int r;      xSemaphoreTake(mutex, portMAX_DELAY); @@ -710,22 +712,30 @@ void eos_modem_sleep(void) {          ESP_LOGE(TAG, "Obtaining mutex before sleep failed");      }      gpio_set_level(UART_GPIO_DTR, 1); +    if (mode == EOS_PWR_SMODE_DEEP) { +        gpio_hold_en(UART_GPIO_DTR); +    }  } -void eos_modem_wake(uint8_t source) { +void eos_modem_wake(uint8_t source, uint8_t mode) {      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); +    if (mode != EOS_PWR_SMODE_DEEP) { +        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); +    } else { +        gpio_hold_dis(UART_GPIO_DTR); +    }  }  void eos_ppp_set_apn(char *apn) { diff --git a/code/esp32/components/eos/include/cell.h b/code/esp32/components/eos/include/cell.h index 17847ce..23adecf 100644 --- a/code/esp32/components/eos/include/cell.h +++ b/code/esp32/components/eos/include/cell.h @@ -35,8 +35,8 @@ int eos_modem_set_mode(uint8_t mode);  int eos_modem_take(uint32_t timeout);  void eos_modem_give(void); -void eos_modem_sleep(void); -void eos_modem_wake(uint8_t source); +void eos_modem_sleep(uint8_t mode); +void eos_modem_wake(uint8_t source, uint8_t mode);  void eos_ppp_set_apn(char *apn);  void eos_ppp_set_auth(char *user, char *pass); diff --git a/code/esp32/components/eos/include/i2c.h b/code/esp32/components/eos/include/i2c.h index 995a77e..144f5e1 100644 --- a/code/esp32/components/eos/include/i2c.h +++ b/code/esp32/components/eos/include/i2c.h @@ -2,6 +2,7 @@  #include <stdint.h>  void eos_i2c_init(void); +  int eos_i2c_read(uint8_t addr, uint8_t reg, uint8_t *data, size_t len);  uint8_t eos_i2c_read8(uint8_t addr, uint8_t reg);  int eos_i2c_write(uint8_t addr, uint8_t reg, uint8_t *data, size_t len); diff --git a/code/esp32/components/eos/include/net.h b/code/esp32/components/eos/include/net.h index 818776e..54bad6d 100644 --- a/code/esp32/components/eos/include/net.h +++ b/code/esp32/components/eos/include/net.h @@ -25,9 +25,10 @@  typedef void (*eos_net_fptr_t) (unsigned char, unsigned char *, uint16_t);  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); -void eos_net_sleep_done(void); -void eos_net_wake(uint8_t source); +void eos_net_sleep_done(uint8_t mode); +void eos_net_wake(uint8_t source, uint8_t mode); diff --git a/code/esp32/components/eos/include/power.h b/code/esp32/components/eos/include/power.h index 8a35a04..0a57b19 100644 --- a/code/esp32/components/eos/include/power.h +++ b/code/esp32/components/eos/include/power.h @@ -2,12 +2,19 @@  #define EOS_PWR_MTYPE_BUTTON    0 +#define EOS_PWR_WAKE_RST        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 +#define EOS_PWR_SMODE_LIGHT     1 +#define EOS_PWR_SMODE_DEEP      2 +  void eos_power_init(void); + +void eos_power_wait4init(void); +uint8_t eos_power_wakeup_cause(void);  void eos_power_sleep(void);  void eos_power_wake(uint8_t source);  void eos_power_net_ready(void);
\ No newline at end of file diff --git a/code/esp32/components/eos/net.c b/code/esp32/components/eos/net.c index 07434f7..9a4a024 100644 --- a/code/esp32/components/eos/net.c +++ b/code/esp32/components/eos/net.c @@ -27,7 +27,7 @@  #define SPI_SIZE_BUF        (EOS_NET_SIZE_BUF + 8) -static volatile char net_sleep; +static volatile char net_sleep = 0;  static EOSBufQ net_buf_q;  static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; @@ -94,6 +94,12 @@ static void net_xchg_task(void *pvParameters) {      spi_tr.tx_buffer = buf_send;      spi_tr.rx_buffer = buf_recv; +    if (eos_power_wakeup_cause()) { +        wake = 1; +        repeat = 1; +    } + +    eos_power_wait4init();      while (1) {          if (!repeat) {              xSemaphoreTake(mutex, portMAX_DELAY); @@ -127,7 +133,7 @@ static void net_xchg_task(void *pvParameters) {          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]); +        ESP_LOGD(TAG, "RECV:%d", buf_recv[0]);          if (wake) {              eos_power_net_ready(); @@ -154,9 +160,9 @@ static void net_xchg_task(void *pvParameters) {                  net_sleep = 0;                  xSemaphoreGive(mutex); +                spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1);                  wake = 1;                  repeat = 1; -                spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1);              }              continue;          } @@ -258,15 +264,16 @@ void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler) {      mtype_handler[mtype-1] = handler;  } -void eos_net_sleep_done(void) { +void eos_net_sleep_done(uint8_t mode) {      gpio_set_level(SPI_GPIO_CTS, 1);      vTaskDelay(200 / portTICK_PERIOD_MS);      gpio_set_level(SPI_GPIO_CTS, 0);  } -void eos_net_wake(uint8_t source) { +void eos_net_wake(uint8_t source, uint8_t mode) {      int sleep; +    if (mode == EOS_PWR_SMODE_DEEP) return;      do {          vTaskResume(net_xchg_task_handle);          vTaskDelay(10 / portTICK_PERIOD_MS); 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; diff --git a/code/esp32/main/app_main.c b/code/esp32/main/app_main.c index bd2e3e1..b700a8e 100644 --- a/code/esp32/main/app_main.c +++ b/code/esp32/main/app_main.c @@ -1,5 +1,9 @@ +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> +  #include <tcpip_adapter.h>  #include <driver/gpio.h> +#include <esp_sleep.h>  #include "i2c.h"  #include "cell.h" @@ -15,11 +19,12 @@  void app_main() {      tcpip_adapter_init(); +    eos_net_init(); +      eos_pcm_init();      gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);      eos_modem_init(); -    eos_net_init();      eos_cell_init();      eos_wifi_init();      eos_sock_init(); | 
