summaryrefslogtreecommitdiff
path: root/fw
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2025-07-28 23:37:45 +0200
committerUros Majstorovic <majstor@majstor.org>2025-07-28 23:37:45 +0200
commitfc70c6f78f43dbeda91d47b2d2071d4da4082121 (patch)
treec104744b62d3ea2c1a4a05eaab8283f368215300 /fw
parent58f41971b1e801ad2fbcea08e5152afa2b18ca73 (diff)
upgrade to ESP-IDF v5; fixed SPI net and app protocoles; reimplemented power management;
Diffstat (limited to 'fw')
-rw-r--r--fw/esp32/CMakeLists.txt4
-rw-r--r--fw/esp32/components/eos/CMakeLists.txt3
-rw-r--r--fw/esp32/components/eos/app.c243
-rw-r--r--fw/esp32/components/eos/app_main.c (renamed from fw/esp32/main/app_main.c)31
-rw-r--r--fw/esp32/components/eos/at_cmd.c1
-rw-r--r--fw/esp32/components/eos/cell.c84
-rw-r--r--fw/esp32/components/eos/cell_modem.c348
-rw-r--r--fw/esp32/components/eos/cell_pcm.c137
-rw-r--r--fw/esp32/components/eos/cell_sms.c13
-rw-r--r--fw/esp32/components/eos/cell_ussd.c13
-rw-r--r--fw/esp32/components/eos/cell_voice.c49
-rw-r--r--fw/esp32/components/eos/include/app.h15
-rw-r--r--fw/esp32/components/eos/include/cell.h16
-rw-r--r--fw/esp32/components/eos/include/eos.h16
-rw-r--r--fw/esp32/components/eos/include/msgq.h4
-rw-r--r--fw/esp32/components/eos/include/net.h32
-rw-r--r--fw/esp32/components/eos/include/net_priv.h33
-rw-r--r--fw/esp32/components/eos/include/power.h33
-rw-r--r--fw/esp32/components/eos/include/sock.h4
-rw-r--r--fw/esp32/components/eos/include/wifi.h3
-rw-r--r--fw/esp32/components/eos/msgq.c16
-rw-r--r--fw/esp32/components/eos/net.c497
-rw-r--r--fw/esp32/components/eos/power.c448
-rw-r--r--fw/esp32/components/eos/rng.c3
-rw-r--r--fw/esp32/components/eos/sock.c344
-rw-r--r--fw/esp32/components/eos/tun.c13
-rwxr-xr-xfw/esp32/components/eos/wifi.c66
-rw-r--r--fw/esp32/main/component.mk8
28 files changed, 1521 insertions, 956 deletions
diff --git a/fw/esp32/CMakeLists.txt b/fw/esp32/CMakeLists.txt
new file mode 100644
index 0000000..c81db52
--- /dev/null
+++ b/fw/esp32/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.16)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(eos_app)
diff --git a/fw/esp32/components/eos/CMakeLists.txt b/fw/esp32/components/eos/CMakeLists.txt
new file mode 100644
index 0000000..404b855
--- /dev/null
+++ b/fw/esp32/components/eos/CMakeLists.txt
@@ -0,0 +1,3 @@
+idf_component_register(SRCS "app_main.c" "msgq.c" "unicode.c" "gsm.c" "gsm_cp.c" "at_cmd.c" "cell.c" "cell_modem.c" "cell_pcm.c" "cell_voice.c" "cell_ussd.c" "cell_sms.c" "cell_pdp.c" "wifi.c" "net.c" "power.c" "rng.c" "sock.c" "app.c" "tun.c"
+ INCLUDE_DIRS "include"
+ REQUIRES esp_driver_gpio esp_driver_spi esp_driver_uart esp_driver_i2s esp_event esp_netif esp_wifi esp_timer vfs)
diff --git a/fw/esp32/components/eos/app.c b/fw/esp32/components/eos/app.c
index 8396376..662da17 100644
--- a/fw/esp32/components/eos/app.c
+++ b/fw/esp32/components/eos/app.c
@@ -15,209 +15,142 @@
#include "eos.h"
#include "msgq.h"
+#include "power.h"
#include "app.h"
+#include "net_priv.h"
-#define SPI_GPIO_CTS 26
-#define SPI_GPIO_RTS 27
-#define SPI_GPIO_MOSI 13
-#define SPI_GPIO_MISO 12
-#define SPI_GPIO_SCLK 14
-#define SPI_GPIO_CS 15
+#define SPI_GPIO_CTS 9
+#define SPI_GPIO_RTS 47
+#define SPI_GPIO_MOSI 11
+#define SPI_GPIO_MISO 13
+#define SPI_GPIO_SCLK 12
+#define SPI_GPIO_CS 10
-#define SPI_SIZE_BUF (EOS_APP_SIZE_BUF + 8)
+#define SPI_SIZE_BUF (EOS_APP_SIZE_BUF + 4)
#define SPI_SIZE_HDR 3
+#define SPI_HOST SPI2_HOST
+
static EOSBufQ app_buf_q;
static unsigned char *app_bufq_array[EOS_APP_SIZE_BUFQ];
static EOSMsgQ app_send_q;
static EOSMsgItem app_sndq_array[EOS_APP_SIZE_SNDQ];
-static SemaphoreHandle_t mutex;
-static SemaphoreHandle_t semaph;
-static TaskHandle_t app_xchg_task_handle;
-static const char *TAG = "EOS APP";
+static NETConfig app_config;
+static eos_net_handler_t app_handler[EOS_APP_MAX_MTYPE];
+
+static spi_bus_config_t app_spi_bus_cfg;
+static spi_slave_interface_config_t app_spi_iface_cfg;
+static spi_slave_transaction_t app_spi_tr_cfg;
-static eos_app_fptr_t app_handler[EOS_APP_MAX_MTYPE];
+static const char *TAG = "EOS APP";
static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) {
- ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len);
+ ESP_LOGE(TAG, "bad handler: 0x%.2X 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);
-}
+static void app_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ uint8_t idx;
-// 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 app_xchg_task(void *pvParameters) {
- unsigned char mtype = 0;
- unsigned char *buffer;
- uint16_t len;
- 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;
- size_t trans_len;
-
- static spi_slave_transaction_t spi_tr;
-
- //Configuration for the SPI bus
- static 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
- };
-
- //Configuration for the SPI slave interface
- static 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(HSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1);
- assert(ret == ESP_OK);
-
- memset(&spi_tr, 0, sizeof(spi_tr));
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
- spi_tr.length = SPI_SIZE_BUF * 8;
-
- while (1) {
- xSemaphoreTake(mutex, portMAX_DELAY);
-
- eos_msgq_pop(&app_send_q, &mtype, &buffer, &len);
- if (mtype) {
- buf_send[0] = mtype;
- buf_send[1] = len >> 8;
- buf_send[2] = len & 0xFF;
- if (buffer) {
- memcpy(buf_send + SPI_SIZE_HDR, buffer, len);
- eos_bufq_push(&app_buf_q, buffer);
- xSemaphoreGive(semaph);
- }
- } else {
- gpio_set_level(SPI_GPIO_RTS, 0);
- buf_send[0] = 0;
- buf_send[1] = 0;
- buf_send[2] = 0;
- len = 0;
- }
-
- xSemaphoreGive(mutex);
-
- buf_recv[0] = 0;
- buf_recv[1] = 0;
- buf_recv[2] = 0;
- spi_slave_transmit(HSPI_HOST, &spi_tr, portMAX_DELAY);
-
- trans_len = spi_tr.trans_len / 8;
- if (trans_len < SPI_SIZE_HDR) continue;
-
- if (len + SPI_SIZE_HDR > trans_len) {
- spi_tr.tx_buffer = buf_send + trans_len;
- spi_tr.rx_buffer = buf_recv + trans_len;
- spi_tr.length = (SPI_SIZE_BUF - trans_len) * 8;
- spi_slave_transmit(HSPI_HOST, &spi_tr, portMAX_DELAY);
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
- spi_tr.length = SPI_SIZE_BUF * 8;
- }
- mtype = buf_recv[0] & ~EOS_APP_MTYPE_FLAG_MASK;
- len = (uint16_t)buf_recv[1] << 8;
- len |= (uint16_t)buf_recv[2] & 0xFF;
- buffer = buf_recv + 3;
-
- if (mtype == 0x00) continue;
-
- if ((mtype <= EOS_APP_MAX_MTYPE) && (len <= EOS_APP_MTU)) {
- app_handler[mtype - 1](mtype, buffer, len);
- } else {
- bad_handler(mtype, buffer, len);
- }
+ idx = mtype & EOS_NET_MTYPE_MASK;
+ if (idx && (idx <= EOS_APP_MAX_MTYPE) && (buf_len <= EOS_APP_MTU)) {
+ app_handler[idx - 1](mtype, buffer, buf_len);
+ } else {
+ bad_handler(mtype, buffer, buf_len);
}
- vTaskDelete(NULL);
}
void eos_app_init(void) {
+ SemaphoreHandle_t mutex;
+ SemaphoreHandle_t bufq_mutex;
+ SemaphoreHandle_t bufq_semaph;
int i;
- // Configuration for the handshake lines
- gpio_config_t io_conf = {};
-
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_CTS);
- gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_CTS, 0);
-
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_RTS);
- gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_RTS, 0);
-
eos_msgq_init(&app_send_q, app_sndq_array, EOS_APP_SIZE_SNDQ);
eos_bufq_init(&app_buf_q, app_bufq_array, EOS_APP_SIZE_BUFQ);
for (i=0; i<EOS_APP_SIZE_BUFQ; i++) {
- eos_bufq_push(&app_buf_q, malloc(EOS_APP_SIZE_BUF));
+ unsigned char *buffer;
+
+ buffer = malloc(EOS_APP_SIZE_BUF);
+ assert(buffer != NULL);
+ eos_bufq_push(&app_buf_q, buffer);
}
for (i=0; i<EOS_APP_MAX_MTYPE; i++) {
app_handler[i] = bad_handler;
}
- semaph = xSemaphoreCreateCounting(EOS_APP_SIZE_BUFQ, EOS_APP_SIZE_BUFQ);
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
+ bufq_mutex = xSemaphoreCreateBinary();
+ assert(bufq_mutex != NULL);
+ bufq_semaph = xSemaphoreCreateCounting(EOS_APP_SIZE_BUFQ, EOS_APP_SIZE_BUFQ);
+ assert(bufq_semaph != NULL);
+
xSemaphoreGive(mutex);
- xTaskCreate(&app_xchg_task, "app_xchg", EOS_TASK_SSIZE_APP_XCHG, NULL, EOS_TASK_PRIORITY_APP_XCHG, &app_xchg_task_handle);
+ xSemaphoreGive(bufq_mutex);
+
+ app_config.sleep = 0;
+ app_config.sleep_req = 0;
+ app_config.present = 0;
+ app_config.dev = NET_DEV_APP;
+ app_config.gpio_mosi = SPI_GPIO_MOSI;
+ app_config.gpio_miso = SPI_GPIO_MISO;
+ app_config.gpio_sclk = SPI_GPIO_SCLK;
+ app_config.gpio_cs = SPI_GPIO_CS;
+ app_config.gpio_rts = SPI_GPIO_RTS;
+ app_config.gpio_cts = SPI_GPIO_CTS;
+ app_config.spi_host = SPI_HOST;
+ app_config.spi_bus_cfg = &app_spi_bus_cfg;
+ app_config.spi_iface_cfg = &app_spi_iface_cfg;
+ app_config.spi_tr_cfg = &app_spi_tr_cfg;
+ app_config.mutex = mutex;
+ app_config.bufq_mutex = bufq_mutex;
+ app_config.bufq_semaph = bufq_semaph;
+ app_config.buf_q = &app_buf_q;
+ app_config.send_q = &app_send_q;
+ app_config.msg_handler = app_msg_handler;
+
+ _eos_net_init_gpio(&app_config);
+
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ gpio_hold_dis(app_config.gpio_cts);
+ }
+
ESP_LOGI(TAG, "INIT");
}
-unsigned char *eos_app_alloc(void) {
- unsigned char *ret;
+void eos_app_run(void) {
+ BaseType_t rv;
- xSemaphoreTake(semaph, portMAX_DELAY);
- xSemaphoreTake(mutex, portMAX_DELAY);
- ret = eos_bufq_pop(&app_buf_q);
- xSemaphoreGive(mutex);
+ rv = xTaskCreate(&eos_net_xchg_task, "app_xchg", EOS_TASK_SSIZE_APP, &app_config, EOS_TASK_PRIORITY_APP, &app_config.xchg_task_handle);
+ assert(rv == pdPASS);
- return ret;
+ ESP_LOGI(TAG, "RUN");
}
-void eos_app_free(unsigned char *buf) {
- xSemaphoreTake(mutex, portMAX_DELAY);
- eos_bufq_push(&app_buf_q, buf);
- xSemaphoreGive(semaph);
- xSemaphoreGive(mutex);
+unsigned char *eos_app_alloc(void) {
+ return _eos_net_alloc(&app_config);
}
-int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t len) {
- int rv = EOS_OK;
+void eos_app_free(unsigned char *buf) {
+ _eos_net_free(&app_config, buf);
+}
- xSemaphoreTake(mutex, portMAX_DELAY);
- gpio_set_level(SPI_GPIO_RTS, 1);
- rv = eos_msgq_push(&app_send_q, mtype, buffer, len);
- xSemaphoreGive(mutex);
+int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ return _eos_net_send(&app_config, mtype, buffer, buf_len);
+}
- if (rv) eos_app_free(buffer);
+void eos_app_sleep_req(void) {
+ _eos_net_sleep_req(&app_config);
+}
- return rv;
+void eos_app_wake(void) {
+ _eos_net_wake(&app_config);
}
-void eos_app_set_handler(unsigned char mtype, eos_app_fptr_t handler) {
+void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler) {
if (handler == NULL) handler = bad_handler;
if (mtype && (mtype <= EOS_APP_MAX_MTYPE)) app_handler[mtype - 1] = handler;
}
diff --git a/fw/esp32/main/app_main.c b/fw/esp32/components/eos/app_main.c
index 79f76ab..e096a23 100644
--- a/fw/esp32/main/app_main.c
+++ b/fw/esp32/components/eos/app_main.c
@@ -2,6 +2,8 @@
#include <freertos/task.h>
#include <driver/gpio.h>
+#include <esp_system.h>
+
#include <esp_event.h>
#include <esp_netif.h>
#include <esp_err.h>
@@ -9,19 +11,17 @@
#include "i2c.h"
#include "cell.h"
-#include "_net.h"
+#include "net.h"
#include "wifi.h"
#include "sock.h"
#include "rng.h"
-#ifdef EOS_WITH_APP
#include "app.h"
#include "tun.h"
-#endif
#include "power.h"
#define ESP_INTR_FLAG_DEFAULT 0
-// Main application
+/* main application */
void app_main() {
esp_err_t ret;
@@ -31,21 +31,28 @@ void app_main() {
ret = esp_event_loop_create_default();
assert(ret == ESP_OK);
- eos_net_init();
+ ret = gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
+ assert(ret == ESP_OK);
- eos_cell_pcm_init();
- gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
+ eos_power_init();
+
+ eos_net_init();
+ eos_app_init();
+ eos_tun_init();
eos_modem_init();
eos_cell_init();
+ eos_cell_pcm_init();
eos_wifi_init();
eos_sock_init();
eos_rng_init();
-#ifdef EOS_WITH_APP
- eos_app_init();
- eos_tun_init();
-#endif
- eos_power_init();
+ eos_power_run();
+ eos_net_run();
+ eos_app_run();
+ eos_modem_run();
+ eos_cell_run();
+ eos_wifi_run();
+ eos_sock_run();
}
diff --git a/fw/esp32/components/eos/at_cmd.c b/fw/esp32/components/eos/at_cmd.c
index a1c329e..d9ec228 100644
--- a/fw/esp32/components/eos/at_cmd.c
+++ b/fw/esp32/components/eos/at_cmd.c
@@ -36,6 +36,7 @@ void at_init(void) {
memset(&urc_list, 0, sizeof(ATURCList));
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
}
diff --git a/fw/esp32/components/eos/cell.c b/fw/esp32/components/eos/cell.c
index d34172e..8665616 100644
--- a/fw/esp32/components/eos/cell.c
+++ b/fw/esp32/components/eos/cell.c
@@ -17,8 +17,6 @@
static const char *TAG = "EOS CELL";
-static uint8_t cell_mode;
-
static EOSBufQ cell_buf_q;
static unsigned char *cell_bufq_array[CELL_SIZE_QUEUE];
@@ -28,8 +26,6 @@ static QueueHandle_t cell_queue;
static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) {
uint8_t mtype;
- if (buf_len < 1) return;
-
mtype = buffer[0];
switch (mtype & EOS_CELL_MTYPE_MASK) {
case EOS_CELL_MTYPE_DEV: {
@@ -43,29 +39,47 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t
}
case EOS_CELL_MTYPE_RESET: {
+ int rv;
+
+ rv = eos_modem_take(1000);
+ if (rv) {
+ ESP_LOGE(TAG, "Reset modem failed: %d", rv);
+ break;
+ }
eos_modem_reset();
+ eos_modem_give();
break;
}
case EOS_CELL_MTYPE_UART_TAKE: {
- uint8_t mode;
-
- mode = eos_modem_get_mode();
- if (mode == EOS_CELL_UART_MODE_NONE) break;
+ int rv;
- eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY);
- cell_mode = mode;
+ if (eos_modem_get_mode() == EOS_CELL_UART_MODE_ATCMD) {
+ rv = eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY);
+ if (rv) ESP_LOGE(TAG, "Set RELAY mode failed: %d", rv);
+ }
break;
}
case EOS_CELL_MTYPE_UART_GIVE: {
- eos_modem_atinit();
- eos_modem_set_mode(cell_mode);
+ int rv;
+
+ if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) {
+ rv = eos_modem_take(1000);
+ if (!rv) {
+ eos_modem_atinit();
+ eos_modem_give();
+ }
+ rv = eos_modem_set_mode(EOS_CELL_UART_MODE_ATCMD);
+ if (rv) ESP_LOGE(TAG, "Set ATCMD mode failed: %d", rv);
+ }
break;
}
case EOS_CELL_MTYPE_UART_DATA: {
- if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer + 1, buf_len - 1);
+ if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) {
+ eos_modem_write(buffer + 1, buf_len - 1);
+ }
break;
}
}
@@ -108,23 +122,30 @@ static void cell_handler_task(void *pvParameters) {
vTaskDelete(NULL);
}
-static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
+static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) {
EOSMsgItem mi;
- unsigned char *buf;
+ unsigned char *_buffer;
+
+ if (buf_len < 1) return;
+
+ if (type & EOS_NET_MTYPE_FLAG_REPL) {
+ _cell_handler(type, buffer, buf_len);
+ return;
+ }
xSemaphoreTake(mutex, portMAX_DELAY);
- buf = eos_bufq_pop(&cell_buf_q);
+ _buffer = eos_bufq_pop(&cell_buf_q);
xSemaphoreGive(mutex);
- if (buf == NULL) {
- if (len) ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]);
+ if (_buffer == NULL) {
+ ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]);
return;
}
- memcpy(buf, buffer, len);
+ memcpy(_buffer, buffer, buf_len);
mi.type = type;
- mi.buffer = buf;
- mi.len = len;
+ mi.buffer = _buffer;
+ mi.len = buf_len;
xQueueSend(cell_queue, &mi, portMAX_DELAY);
}
@@ -133,13 +154,30 @@ void eos_cell_init(void) {
eos_bufq_init(&cell_buf_q, cell_bufq_array, CELL_SIZE_QUEUE);
for (i=0; i<CELL_SIZE_QUEUE; i++) {
- eos_bufq_push(&cell_buf_q, malloc(EOS_NET_SIZE_BUF));
+ unsigned char *buffer;
+
+ buffer = malloc(EOS_NET_SIZE_BUF);
+ assert(buffer != NULL);
+ eos_bufq_push(&cell_buf_q, buffer);
}
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
+
cell_queue = xQueueCreate(CELL_SIZE_QUEUE, sizeof(EOSMsgItem));
- xTaskCreate(cell_handler_task, "cell_handler", EOS_TASK_SSIZE_CELL, NULL, EOS_TASK_PRIORITY_CELL, NULL);
+ assert(cell_queue != NULL);
eos_net_set_handler(EOS_NET_MTYPE_CELL, cell_handler);
+
+ ESP_LOGI(TAG, "INIT");
+}
+
+void eos_cell_run(void) {
+ BaseType_t rv;
+
+ rv = xTaskCreate(cell_handler_task, "cell_handler", EOS_TASK_SSIZE_CELL, NULL, EOS_TASK_PRIORITY_CELL, NULL);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
}
diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c
index b279db1..4f8efd1 100644
--- a/fw/esp32/components/eos/cell_modem.c
+++ b/fw/esp32/components/eos/cell_modem.c
@@ -5,12 +5,15 @@
#include <freertos/semphr.h>
#include <freertos/task.h>
#include <freertos/queue.h>
+
#include <netif/ppp/pppos.h>
#include <netif/ppp/pppapi.h>
+
#include <driver/uart.h>
#include <driver/gpio.h>
+
+#include <esp_system.h>
#include <esp_timer.h>
-#include <esp_sleep.h>
#include <esp_log.h>
#include "eos.h"
@@ -24,30 +27,37 @@
#define UART_SIZE_IO_BUF 8192
-#define UART_GPIO_TXD 16
+// XXX: TXD and RXD switched for Quectel, fixed in new revision
+#define UART_GPIO_TXD 18
#define UART_GPIO_RXD 17
-#define UART_GPIO_DTR 32
-#define UART_GPIO_RI 35
+#define UART_GPIO_DTR 15
+#define UART_GPIO_RI 16
+#define MODEM_GPIO_RST 6
+#define MODEM_GPIO_USB_EN 7
+#define MODEM_GPIO_USB_S 14
+
+#define UART_PORT UART_NUM_1
#define MODEM_ETYPE_ATINIT 1
#define MODEM_ETYPE_STATUS 2
#define MODEM_ETYPE_RING 3
-#define AT_CMD_INIT_SIZE 5
-
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
-static const char *TAG = "EOS MODEM";
-
-static char *at_cmd_init[AT_CMD_INIT_SIZE] = {
- "AT+CFGRI=1\r",
- "AT+CSCLK=1\r",
+static char *at_cmd_init[] = {
+ // "AT+CFGRI=1\r",
+ // "AT+CSCLK=1\r",
+ "AT+QSCLK=1\r",
+ "AT+QCFG=\"risignaltype\",\"physical\"\r",
+ "AT+QURCCFG=\"urcport\",\"uart1\"\r",
"AT+CLIP=1\r",
"AT+CMGF=0\r",
"AT+CPMS=\"ME\",\"ME\",\"ME\"\r"
};
+static const char *TAG = "EOS CELL MODEM";
+
static SemaphoreHandle_t mutex;
static QueueHandle_t modem_queue;
@@ -84,8 +94,6 @@ typedef struct {
size_t param_len;
} modem_event_t;
-static void modem_send_status(void);
-
static void atcmd_read(size_t bsize) {
char *ln_end;
int rd = 0;
@@ -94,6 +102,9 @@ static void atcmd_read(size_t bsize) {
char *uart_curr = uart_buf + uart_buf_len;
int _rd = eos_modem_read(uart_curr, MIN(bsize - rd, sizeof(uart_buf) - uart_buf_len - 1), 100);
+ /* after sleep one 0xff character is emitted */
+ if ((_rd == 1) && (*uart_curr == 0xff)) return;
+
rd += _rd;
uart_buf_len += _rd;
uart_buf[uart_buf_len] = '\0';
@@ -123,7 +134,7 @@ static void uart_data_read(uint8_t mode) {
int rd;
size_t bsize;
- uart_get_buffered_data_len(UART_NUM_2, &bsize);
+ uart_get_buffered_data_len(UART_PORT, &bsize);
switch (mode) {
case EOS_CELL_UART_MODE_ATCMD: {
atcmd_read(bsize);
@@ -132,7 +143,6 @@ static void uart_data_read(uint8_t mode) {
case EOS_CELL_UART_MODE_PPP: {
rd = 0;
-
do {
int _rd = eos_modem_read(uart_buf, MIN(bsize - rd, sizeof(uart_buf)), 100);
if (ppp_handle) pppos_input_tcpip(ppp_handle, (uint8_t *)uart_buf, _rd);
@@ -143,15 +153,17 @@ static void uart_data_read(uint8_t mode) {
case EOS_CELL_UART_MODE_RELAY: {
unsigned char *buf;
- rd = 0;
+ int rv;
+ rd = 0;
do {
int _rd;
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA;
_rd = eos_modem_read(buf + 1, MIN(bsize - rd, EOS_NET_SIZE_BUF - 1), 100);
- eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
rd += _rd;
} while (rd != bsize);
break;
@@ -160,36 +172,20 @@ static void uart_data_read(uint8_t mode) {
}
static void uart_event_task(void *pvParameters) {
- char mode;
- char _mode;
+ uint8_t mode, _mode;
uart_event_t event;
- eos_power_wait4wake();
-
xSemaphoreTake(mutex, portMAX_DELAY);
- _mode = uart_mode;
- xSemaphoreTake(uart_mutex, portMAX_DELAY);
-
if (!modem_initialized) {
- int r;
-
- at_cmd("\r\rAT\r");
- r = at_expect("^OK", NULL, 500);
- if (!r) {
- r = eos_modem_atinit();
- if (!r) {
- modem_present = 1;
- } else {
- _mode = EOS_CELL_UART_MODE_NONE;
- ESP_LOGE(TAG, "Modem init failed");
- }
- }
+ eos_modem_reset();
}
-
- if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex);
- mode = _mode;
+ mode = _mode = uart_mode;
xSemaphoreGive(mutex);
+ if (mode != EOS_CELL_UART_MODE_NONE) {
+ xSemaphoreTake(uart_mutex, portMAX_DELAY);
+ }
+
while (1) {
/* Waiting for UART event.
*/
@@ -198,6 +194,8 @@ static void uart_event_task(void *pvParameters) {
case UART_DATA: {
/* Event of UART receiving data
*/
+
+ ESP_LOGI(TAG, "UART DATA READ");
if (mode != EOS_CELL_UART_MODE_NONE) uart_data_read(mode);
if ((mode != _mode) && (uart_buf_len == 0)) {
if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex);
@@ -244,27 +242,6 @@ static void IRAM_ATTR uart_ring_handler(void *arg) {
xQueueSendFromISR(modem_queue, &evt, NULL);
}
-static void modem_init_gpio(void) {
- // Configuration for the DTR/RI lines
- gpio_config_t io_conf = {};
-
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_DTR);
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- gpio_config(&io_conf);
- gpio_set_level(UART_GPIO_DTR, 0);
-
- 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;
- io_conf.pull_down_en = 0;
- gpio_config(&io_conf);
- gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
-}
-
static size_t modem_get_status(unsigned char *buffer) {
size_t len;
@@ -310,12 +287,14 @@ static void modem_atinit_handler(char *urc, regmatch_t m[]) {
xQueueSend(modem_queue, &evt, portMAX_DELAY);
}
-static int modem_atinit(void) {
+static int modem_atinit_evt(void) {
int r;
+ vTaskDelay(500 / portTICK_PERIOD_MS);
+
xSemaphoreTake(mutex, portMAX_DELAY);
uart_change_mode(EOS_CELL_UART_MODE_NONE);
- r = xSemaphoreTake(uart_mutex, 1000);
+ r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
if (r == pdFALSE) {
uart_change_mode(uart_mode);
xSemaphoreGive(mutex);
@@ -323,6 +302,8 @@ static int modem_atinit(void) {
}
r = eos_modem_atinit();
+ modem_send_status();
+
uart_change_mode(uart_mode);
xSemaphoreGive(uart_mutex);
xSemaphoreGive(mutex);
@@ -337,10 +318,10 @@ static void modem_event_task(void *pvParameters) {
if (xQueueReceive(modem_queue, &evt, portMAX_DELAY)) {
switch (evt.type) {
case MODEM_ETYPE_ATINIT: {
- int r;
+ int rv;
- r = modem_atinit();
- if (!r) {
+ rv = modem_atinit_evt();
+ if (!rv) {
modem_present = 1;
} else {
ESP_LOGE(TAG, "Modem init failed");
@@ -350,11 +331,13 @@ static void modem_event_task(void *pvParameters) {
case MODEM_ETYPE_STATUS: {
unsigned char *buf;
+ int rv;
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS;
memcpy(buf + 1, evt.param, evt.param_len);
- eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
break;
}
@@ -365,7 +348,7 @@ static void modem_event_task(void *pvParameters) {
}
/* Obsolete
uint64_t t_start = esp_timer_get_time();
- if (xQueueReceive(modem_queue, &level, 200 / portTICK_RATE_MS) && (level == 1)) {
+ if (xQueueReceive(modem_queue, &level, 200 / portTICK_PERIOD_MS) && (level == 1)) {
uint64_t t_end = esp_timer_get_time();
ESP_LOGI(TAG, "URC:%u", (uint32_t)(t_end - t_start));
} else {
@@ -399,11 +382,11 @@ static char *memstr(char *mem, size_t size, char *str) {
return NULL;
}
-static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *ctx) {
+static uint32_t ppp_output_cb(ppp_pcb *pcb, const void *data, uint32_t len, void *ctx) {
size_t rv;
xSemaphoreTake(ppp_mutex, portMAX_DELAY);
- rv = eos_modem_write(data, len);
+ rv = eos_modem_write((uint8_t *)data, len);
xSemaphoreGive(ppp_mutex);
return rv;
@@ -412,15 +395,16 @@ static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *c
/* PPP status callback */
static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
struct netif *pppif = ppp_netif(pcb);
+ int r;
LWIP_UNUSED_ARG(ctx);
switch (err_code) {
case PPPERR_NONE: {
ESP_LOGI(TAG, "status_cb: Connect");
- ESP_LOGI(TAG," our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
- ESP_LOGI(TAG," his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
- ESP_LOGI(TAG," netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
+ ESP_LOGI(TAG," local ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
+ ESP_LOGI(TAG," remote ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
+ ESP_LOGI(TAG," netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
xSemaphoreTake(mutex, portMAX_DELAY);
ppp_connected = 1;
@@ -485,18 +469,26 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
}
xSemaphoreTake(mutex, portMAX_DELAY);
+ ppp_connected = 0;
+ ip_addr_set_zero(&ppp_ipaddr);
+ modem_send_status();
+ uart_change_mode(EOS_CELL_UART_MODE_NONE);
+ r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
+ if (r == pdFALSE) {
+ uart_mode = EOS_CELL_UART_MODE_NONE;
+ uart_mode_next = EOS_CELL_UART_MODE_NONE;
+ xSemaphoreGive(mutex);
+ ESP_LOGE(TAG, "status_cb: Obtaining UART mutex failed");
+
+ return;
+ }
+
if (uart_mode_next != EOS_CELL_UART_MODE_NONE) {
uart_mode = uart_mode_next;
uart_mode_next = EOS_CELL_UART_MODE_NONE;
} else {
uart_mode = EOS_CELL_UART_MODE_ATCMD;
}
- ppp_connected = 0;
- ip_addr_set_zero(&ppp_ipaddr);
- modem_send_status();
- uart_change_mode(EOS_CELL_UART_MODE_NONE);
- xSemaphoreTake(uart_mutex, portMAX_DELAY);
-
ppp_handle = NULL;
uart_change_mode(uart_mode);
@@ -607,6 +599,12 @@ static int ppp_setup(void) {
return EOS_ERR_TIMEOUT;
}
+ if (ppp_handle) {
+ uart_change_mode(uart_mode);
+ xSemaphoreGive(uart_mutex);
+ return EOS_ERR;
+ }
+
at_cmd(cmd);
r = at_expect("^OK", "^(ERROR|NO CARRIER)", 1000);
if (r) {
@@ -636,6 +634,7 @@ static int ppp_setup(void) {
}
void eos_modem_init(void) {
+ gpio_config_t io_conf = {};
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
@@ -643,37 +642,91 @@ void eos_modem_init(void) {
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
- uart_param_config(UART_NUM_2, &uart_config);
- uart_set_pin(UART_NUM_2, UART_GPIO_TXD, UART_GPIO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
- uart_driver_install(UART_NUM_2, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0);
+ esp_err_t ret;
+ int rv;
- if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) {
- uart_mode = EOS_CELL_UART_MODE_ATCMD;
+ ret = uart_param_config(UART_PORT, &uart_config);
+ assert(ret == ESP_OK);
+ ret = uart_set_pin(UART_PORT, UART_GPIO_TXD, UART_GPIO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
+ assert(ret == ESP_OK);
+ ret = uart_driver_install(UART_PORT, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0);
+ assert(ret == ESP_OK);
+
+ // Configuration for the RST/DTR/USB/RI lines
+ gpio_set_level(MODEM_GPIO_RST, 1);
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT_OD;
+ io_conf.pin_bit_mask = BIT64(MODEM_GPIO_RST);
+ io_conf.pull_up_en = 0;
+ io_conf.pull_down_en = 0;
+ gpio_config(&io_conf);
+
+ gpio_set_level(UART_GPIO_DTR, 0);
+ /* enable USB MUX and grab signals */
+ gpio_set_level(MODEM_GPIO_USB_EN, 0);
+ gpio_set_level(MODEM_GPIO_USB_S, 1);
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT;
+ io_conf.pin_bit_mask = BIT64(UART_GPIO_DTR) | BIT64(MODEM_GPIO_USB_EN) | BIT64(MODEM_GPIO_USB_S);
+ io_conf.pull_up_en = 0;
+ io_conf.pull_down_en = 0;
+ gpio_config(&io_conf);
+
+ io_conf.intr_type = GPIO_INTR_NEGEDGE;
+ io_conf.mode = GPIO_MODE_INPUT;
+ io_conf.pin_bit_mask = BIT64(UART_GPIO_RI);
+ io_conf.pull_up_en = 1;
+ io_conf.pull_down_en = 0;
+ gpio_config(&io_conf);
+
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ gpio_hold_dis(UART_GPIO_DTR);
+ gpio_hold_dis(MODEM_GPIO_USB_EN);
+ gpio_hold_dis(MODEM_GPIO_USB_S);
+ } else {
modem_present = 0;
modem_initialized = 0;
- modem_init_gpio();
}
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
uart_mutex = xSemaphoreCreateBinary();
+ assert(uart_mutex != NULL);
xSemaphoreGive(uart_mutex);
ppp_mutex = xSemaphoreCreateBinary();
+ assert(ppp_mutex != NULL);
xSemaphoreGive(ppp_mutex);
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(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL);
+ assert(modem_queue != NULL);
at_init();
- at_urc_insert("^PB DONE", modem_atinit_handler, REG_EXTENDED);
- at_urc_insert("^\\+CME ERROR: SIM not inserted", modem_atinit_handler, REG_EXTENDED);
+ rv = at_urc_insert("^RDY", modem_atinit_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ eos_cell_sms_init();
+ eos_cell_ussd_init();
+ eos_cell_voice_init();
ESP_LOGI(TAG, "INIT");
}
+void eos_modem_run(void) {
+ BaseType_t rv;
+
+ gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
+
+ rv = xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL);
+ assert(rv == pdPASS);
+ rv = xTaskCreate(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
int eos_modem_atinit(void) {
int echo_on = 0;
int tries = 3;
@@ -706,32 +759,36 @@ int eos_modem_atinit(void) {
r = at_expect("^ATE0", NULL, 1000);
r = at_expect("^OK", "^ERROR", 1000);
- for (i=0; i<AT_CMD_INIT_SIZE; i++) {
+ for (i=0; i<sizeof(at_cmd_init)/sizeof(char *); i++) {
at_cmd(at_cmd_init[i]);
- r = at_expect("^OK", "^ERROR", 1000);
+ r = at_expect("^OK", "ERROR", 1000);
}
+ modem_present = 1;
modem_initialized = 1;
- eos_cell_voice_init();
- eos_cell_sms_init();
- eos_cell_ussd_init();
+ return EOS_OK;
+}
- modem_send_status();
+void eos_modem_reset(void) {
+ gpio_set_level(MODEM_GPIO_RST, 0);
+ vTaskDelay(500 / portTICK_PERIOD_MS);
+ gpio_set_level(MODEM_GPIO_RST, 1);
- return EOS_OK;
+ modem_initialized = 0;
+ uart_mode = EOS_CELL_UART_MODE_ATCMD;
}
void eos_modem_flush(void){
- uart_wait_tx_done(UART_NUM_2, portMAX_DELAY);
+ uart_wait_tx_done(UART_PORT, portMAX_DELAY);
}
size_t eos_modem_write(void *data, size_t size) {
- return uart_write_bytes(UART_NUM_2, (const char *)data, size);
+ return uart_write_bytes(UART_PORT, (const char *)data, size);
}
size_t eos_modem_read(void *data, size_t size, uint32_t timeout) {
- return uart_read_bytes(UART_NUM_2, (uint8_t *)data, size, timeout / portTICK_RATE_MS);
+ return uart_read_bytes(UART_PORT, (uint8_t *)data, size, timeout / portTICK_PERIOD_MS);
}
int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout) {
@@ -791,6 +848,16 @@ int eos_modem_present(void) {
return rv;
}
+int eos_modem_initialized(void) {
+ int rv;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ rv = modem_initialized;
+ xSemaphoreGive(mutex);
+
+ return rv;
+}
+
uint8_t eos_modem_get_mode(void) {
uint8_t ret;
@@ -832,7 +899,6 @@ int eos_modem_set_mode(uint8_t mode) {
}
if (!rv) {
uart_mode = mode;
- modem_send_status();
}
}
}
@@ -876,71 +942,53 @@ void eos_modem_give(void) {
xSemaphoreGive(mutex);
}
-void eos_modem_sleep(void) {
- int r;
+void eos_modem_sleep_req(void) {
+ int rv;
+ gpio_set_level(UART_GPIO_DTR, 1);
xSemaphoreTake(mutex, portMAX_DELAY);
uart_change_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_deep_sleep(void) {
+ rv = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
+ if (rv == pdFALSE) ESP_LOGE(TAG, "Obtaining UART mutex before sleep failed");
+ gpio_isr_handler_remove(UART_GPIO_RI);
+ gpio_reset_pin(UART_GPIO_RI);
+ /* for deep sleep */
gpio_hold_en(UART_GPIO_DTR);
+ gpio_hold_en(MODEM_GPIO_USB_EN);
+ gpio_hold_en(MODEM_GPIO_USB_S);
+ eos_power_sleep_rdy(EOS_PWR_DEV_MODEM);
}
-void eos_modem_wake(uint8_t source, uint8_t mode) {
- if (source == EOS_PWR_WAKE_UART) {
- modem_event_t evt;
+void eos_modem_wake(void) {
+ gpio_config_t io_conf = {
+ .pin_bit_mask = BIT64(UART_GPIO_RI),
+ .mode = GPIO_MODE_INPUT,
+ .intr_type = GPIO_INTR_NEGEDGE,
+ };
+ uint32_t dev;
- evt.type = MODEM_ETYPE_RING;
- xQueueSend(modem_queue, &evt, portMAX_DELAY);
- }
+ gpio_hold_dis(UART_GPIO_DTR);
+ gpio_hold_dis(MODEM_GPIO_USB_EN);
+ gpio_hold_dis(MODEM_GPIO_USB_S);
- switch (mode) {
- case EOS_PWR_SMODE_LIGHT: {
- gpio_set_intr_type(UART_GPIO_RI, GPIO_INTR_NEGEDGE);
- gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
- gpio_set_level(UART_GPIO_DTR, 0);
+ gpio_config(&io_conf);
+ gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
- uart_change_mode(uart_mode);
- xSemaphoreGive(uart_mutex);
- xSemaphoreGive(mutex);
+ uart_change_mode(uart_mode);
+ xSemaphoreGive(uart_mutex);
+ xSemaphoreGive(mutex);
- break;
- }
+ gpio_set_level(UART_GPIO_DTR, 0);
- case EOS_PWR_SMODE_DEEP: {
- gpio_hold_dis(UART_GPIO_DTR);
- modem_init_gpio();
+ dev = eos_power_wakeup_source();
+ if (dev == EOS_PWR_DEV_MODEM) {
+ modem_event_t evt;
- break;
- }
+ evt.type = MODEM_ETYPE_RING;
+ xQueueSend(modem_queue, &evt, portMAX_DELAY);
}
}
-int eos_modem_reset(void) {
- int rv;
-
- rv = eos_modem_take(1000);
- if (rv) return rv;
-
- at_cmd("AT+CRESET\r");
- at_expect("^OK", NULL, 1000);
-
- uart_change_mode(EOS_CELL_UART_MODE_ATCMD);
- xSemaphoreGive(uart_mutex);
-
- uart_mode = EOS_CELL_UART_MODE_ATCMD;
- modem_initialized = 0;
- modem_send_status();
- xSemaphoreGive(mutex);
-
- return EOS_OK;
-}
void eos_ppp_get_apn(char *apn) {
xSemaphoreTake(mutex, portMAX_DELAY);
diff --git a/fw/esp32/components/eos/cell_pcm.c b/fw/esp32/components/eos/cell_pcm.c
new file mode 100644
index 0000000..3f5089d
--- /dev/null
+++ b/fw/esp32/components/eos/cell_pcm.c
@@ -0,0 +1,137 @@
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <driver/i2s_tdm.h>
+#include <esp_log.h>
+
+#include "eos.h"
+#include "net.h"
+#include "cell.h"
+
+#define PCM_GPIO_BCK 1
+#define PCM_GPIO_WS 41
+#define PCM_GPIO_DIN 2
+#define PCM_GPIO_DOUT 42
+
+#define PCM_RX_WM 256 /* receive watermark, must be less than NET_SIZE_MTU */
+
+static i2s_chan_handle_t tx_chan;
+static i2s_chan_handle_t rx_chan;
+
+static const char *TAG = "EOS CELL PCM";
+
+static void pcm_rcvr_task(void *pvParameters) {
+ unsigned char *buffer;
+ size_t size_r;
+ esp_err_t ret;
+ int done = 0;
+ int rv;
+
+ while (!done) {
+ buffer = eos_net_alloc();
+ buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM;
+ ret = i2s_channel_read(rx_chan, buffer + 1, PCM_RX_WM, &size_r, 1000);
+ switch (ret) {
+ case ESP_OK: {
+ assert(size_r == PCM_RX_WM);
+ break;
+ }
+
+ case ESP_ERR_INVALID_STATE: {
+ done = 1;
+ break;
+ }
+
+ default: {
+ done = 1;
+ ESP_LOGE(TAG, "CHAN READ ERR:%d", ret);
+ break;
+ }
+ }
+ if (ret == ESP_OK) {
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buffer, size_r + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
+ } else {
+ eos_net_free(buffer);
+ }
+ }
+ vTaskDelete(NULL);
+}
+
+void eos_cell_pcm_start(void) {
+ BaseType_t rv;
+ esp_err_t ret;
+
+ ret = i2s_channel_enable(tx_chan);
+ if (ret) {
+ ESP_LOGE(TAG, "TX CHAN ENABLE ERR:%d", ret);
+ return;
+ }
+
+ ret = i2s_channel_enable(rx_chan);
+ if (ret) {
+ ESP_LOGE(TAG, "RX CHAN ENABLE ERR:%d", ret);
+ return;
+ }
+
+ rv = xTaskCreate(&pcm_rcvr_task, "pcm_rcvr", EOS_TASK_SSIZE_PCM, NULL, EOS_TASK_PRIORITY_PCM, NULL);
+ assert(rv == pdPASS);
+}
+
+void eos_cell_pcm_stop(void) {
+ esp_err_t ret;
+
+ ret = i2s_channel_disable(tx_chan);
+ if (ret) ESP_LOGE(TAG, "TX CHAN DISABLE ERR:%d", ret);
+
+ ret = i2s_channel_disable(rx_chan);
+ if (ret) ESP_LOGE(TAG, "RX CHAN DISABLE ERR:%d", ret);
+}
+
+void eos_cell_pcm_push(unsigned char *data, size_t size) {
+ esp_err_t ret;
+ size_t size_w;
+
+ ret = i2s_channel_write(tx_chan, data, size, &size_w, 1000);
+ if (ret == ESP_OK) {
+ assert(size_w == size);
+ } else {
+ ESP_LOGE(TAG, "CHAN WRITE ERR:%d", ret);
+ }
+}
+
+void eos_cell_pcm_init(void) {
+ i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_SLAVE);
+ i2s_tdm_config_t tdm_cfg = {
+ .clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(8000),
+ .slot_cfg = I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO,
+ I2S_TDM_SLOT0),
+ .gpio_cfg = {
+ .mclk = I2S_GPIO_UNUSED,
+ .bclk = PCM_GPIO_BCK,
+ .ws = PCM_GPIO_WS,
+ .din = PCM_GPIO_DIN,
+ .dout = PCM_GPIO_DOUT,
+ .invert_flags = {
+ .mclk_inv = false,
+ .bclk_inv = false,
+ .ws_inv = false,
+ },
+ },
+ };
+ esp_err_t ret;
+
+ tdm_cfg.slot_cfg.total_slot = 16;
+ ret = i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan);
+ assert(ret == ESP_OK);
+
+ ret = i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg);
+ assert(ret == ESP_OK);
+
+ ret = i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg);
+ assert(ret == ESP_OK);
+
+ ESP_LOGI(TAG, "INIT");
+}
diff --git a/fw/esp32/components/eos/cell_sms.c b/fw/esp32/components/eos/cell_sms.c
index 5145cd7..1cd4cda 100644
--- a/fw/esp32/components/eos/cell_sms.c
+++ b/fw/esp32/components/eos/cell_sms.c
@@ -13,7 +13,7 @@
#define CTRL_Z 0x1a
-static const char *TAG = "EOS SMS";
+static const char *TAG = "EOS CELL SMS";
static char _pdu_in[2048];
static char _pdu_out[2048];
@@ -266,7 +266,8 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b
}
buf_len = _rv;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
} while (1);
eos_modem_give();
@@ -345,9 +346,13 @@ static void sms_received_handler(char *urc, regmatch_t m[]) {
}
buf_len = _rv;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_cell_sms_init(void) {
- at_urc_insert("^\\+CMTI: .*,([0-9]+)$", sms_received_handler, REG_EXTENDED);
+ int rv;
+
+ rv = at_urc_insert("^\\+CMTI: .*,([0-9]+)$", sms_received_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
}
diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c
index 375025f..fb77b67 100644
--- a/fw/esp32/components/eos/cell_ussd.c
+++ b/fw/esp32/components/eos/cell_ussd.c
@@ -9,7 +9,7 @@
#include "at_cmd.h"
#include "cell.h"
-static const char *TAG = "EOS USSD";
+static const char *TAG = "EOS CELL USSD";
extern char *at_cmd_buf;
@@ -64,7 +64,8 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) {
len = 2;
if (m[2].rm_so == -1) {
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
return;
}
@@ -101,9 +102,13 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) {
return;
}
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_cell_ussd_init(void) {
- at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED);
+ int rv;
+
+ rv = at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
}
diff --git a/fw/esp32/components/eos/cell_voice.c b/fw/esp32/components/eos/cell_voice.c
index 2a7bb18..273b402 100644
--- a/fw/esp32/components/eos/cell_voice.c
+++ b/fw/esp32/components/eos/cell_voice.c
@@ -13,6 +13,8 @@
#include "at_cmd.h"
#include "cell.h"
+static const char *TAG = "EOS CELL VOICE";
+
extern char *at_cmd_buf;
void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
@@ -93,35 +95,41 @@ static void ring_handler(char *urc, regmatch_t m[]) {
memcpy(buf + 1, ring_buf + match[1].rm_so, num_len);
len += num_len;
}
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void busy_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
uint16_t len;
+ int rv;
eos_cell_pcm_stop();
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BUSY;
len = 1;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void miss_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
uint16_t len;
+ int rv;
eos_cell_pcm_stop();
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_MISS;
len = 1;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void call_begin_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
+ int rv;
vTaskDelay(100 / portTICK_PERIOD_MS);
at_cmd("AT+CECH=0x0000\r");
@@ -142,12 +150,14 @@ static void call_begin_handler(char *urc, regmatch_t m[]) {
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void call_end_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
int duration = 0;
+ int rv;
eos_cell_pcm_stop();
@@ -158,14 +168,29 @@ static void call_end_handler(char *urc, regmatch_t m[]) {
buf[2] = duration >> 16;
buf[3] = duration >> 8;
buf[4] = duration;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, 5);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 5);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_cell_voice_init(void) {
- at_urc_insert("^RING", ring_handler, REG_EXTENDED);
- at_urc_insert("^BUSY", busy_handler, REG_EXTENDED);
- at_urc_insert("^NO CARRIER", miss_handler, REG_EXTENDED);
- at_urc_insert("^MISSED.CALL: [^ ]+ (\\+?[0-9]+)$", miss_handler, REG_EXTENDED);
- at_urc_insert("^VOICE CALL: BEGIN", call_begin_handler, REG_EXTENDED);
- at_urc_insert("^VOICE CALL: END: ([0-9]{6}$)$", call_end_handler, REG_EXTENDED);
-} \ No newline at end of file
+ int rv;
+
+ rv = at_urc_insert("^RING", ring_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^BUSY", busy_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^NO CARRIER", miss_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^MISSED.CALL: [^ ]+ (\\+?[0-9]+)$", miss_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^VOICE CALL: BEGIN", call_begin_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^VOICE CALL: END: ([0-9]{6}$)$", call_end_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+}
diff --git a/fw/esp32/components/eos/include/app.h b/fw/esp32/components/eos/include/app.h
index 2033b2b..b6dba99 100644
--- a/fw/esp32/components/eos/include/app.h
+++ b/fw/esp32/components/eos/include/app.h
@@ -1,5 +1,7 @@
#include <stdint.h>
+#include "net.h"
+
/* common */
#define EOS_APP_MTU 1500
#define EOS_APP_SIZE_BUF EOS_APP_MTU
@@ -7,17 +9,18 @@
#define EOS_APP_MTYPE_TUN 1
#define EOS_APP_MAX_MTYPE 8
-#define EOS_APP_MTYPE_FLAG_MASK 0xc0
-
/* esp32 specific */
#define EOS_APP_SIZE_BUFQ 4
#define EOS_APP_SIZE_SNDQ 4
-typedef void (*eos_app_fptr_t) (unsigned char, unsigned char *, uint16_t);
-
void eos_app_init(void);
+void eos_app_run(void);
unsigned char *eos_app_alloc(void);
void eos_app_free(unsigned char *buf);
-int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t len);
-void eos_app_set_handler(unsigned char mtype, eos_app_fptr_t handler);
+
+int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+
+void eos_app_sleep_req(void);
+void eos_app_wake(void);
+void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler);
diff --git a/fw/esp32/components/eos/include/cell.h b/fw/esp32/components/eos/include/cell.h
index cb9f49c..c1e7545 100644
--- a/fw/esp32/components/eos/include/cell.h
+++ b/fw/esp32/components/eos/include/cell.h
@@ -27,7 +27,6 @@
#define EOS_CELL_MTYPE_VOICE_END 7
#define EOS_CELL_MTYPE_VOICE_MISS 8
#define EOS_CELL_MTYPE_VOICE_BUSY 9
-#define EOS_CELL_MTYPE_VOICE_ERR 10
#define EOS_CELL_MTYPE_SMS_MSG 1
#define EOS_CELL_MTYPE_SMS_LIST 2
@@ -76,24 +75,26 @@
#define EOS_CELL_UART_SIZE_BUF 1024
void eos_cell_init(void);
+void eos_cell_run(void);
void eos_modem_init(void);
+void eos_modem_run(void);
int eos_modem_atinit(void);
+void eos_modem_reset(void);
void eos_modem_flush(void);
size_t eos_modem_write(void *data, size_t size);
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 eos_modem_resp(char *ok_str, char *err_str, uint32_t timeout);
int eos_modem_present(void);
+int eos_modem_initialized(void);
uint8_t eos_modem_get_mode(void);
size_t eos_modem_get_status(unsigned char *buffer);
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_deep_sleep(void);
-void eos_modem_wake(uint8_t source, uint8_t mode);
-int eos_modem_reset(void);
+
+void eos_modem_sleep_req(void);
+void eos_modem_wake(void);
void eos_ppp_get_apn(char *apn);
void eos_ppp_set_apn(char *apn);
@@ -105,8 +106,7 @@ int eos_ppp_connect(void);
void eos_ppp_disconnect(void);
void eos_cell_pcm_init(void);
-ssize_t eos_cell_pcm_read(unsigned char *data, size_t size);
-int eos_cell_pcm_push(unsigned char *data, size_t size);
+void eos_cell_pcm_push(unsigned char *data, size_t size);
void eos_cell_pcm_start(void);
void eos_cell_pcm_stop(void);
diff --git a/fw/esp32/components/eos/include/eos.h b/fw/esp32/components/eos/include/eos.h
index bc9dc51..e772637 100644
--- a/fw/esp32/components/eos/include/eos.h
+++ b/fw/esp32/components/eos/include/eos.h
@@ -11,21 +11,21 @@
#define EOS_ERR_NOMEM -100
-#define EOS_TASK_PRIORITY_NET_XCHG 1
-#define EOS_TASK_PRIORITY_APP_XCHG 1
-#define EOS_TASK_PRIORITY_UDP_RCVR 1
+#define EOS_TASK_PRIORITY_NET 1
+#define EOS_TASK_PRIORITY_APP 1
+#define EOS_TASK_PRIORITY_SOCK 1
#define EOS_TASK_PRIORITY_UART 1
#define EOS_TASK_PRIORITY_MODEM 1
-#define EOS_TASK_PRIORITY_I2S 1
+#define EOS_TASK_PRIORITY_PCM 1
#define EOS_TASK_PRIORITY_CELL 1
#define EOS_TASK_PRIORITY_PWR 1
-#define EOS_TASK_SSIZE_NET_XCHG 8192
-#define EOS_TASK_SSIZE_APP_XCHG 8192
-#define EOS_TASK_SSIZE_UDP_RCVR 4096
+#define EOS_TASK_SSIZE_NET 8192
+#define EOS_TASK_SSIZE_APP 8192
+#define EOS_TASK_SSIZE_SOCK 4096
#define EOS_TASK_SSIZE_UART 4096
#define EOS_TASK_SSIZE_MODEM 4096
-#define EOS_TASK_SSIZE_I2S 4096
+#define EOS_TASK_SSIZE_PCM 4096
#define EOS_TASK_SSIZE_CELL 4096
#define EOS_TASK_SSIZE_PWR 4096
diff --git a/fw/esp32/components/eos/include/msgq.h b/fw/esp32/components/eos/include/msgq.h
index bbfe041..b5ae9ac 100644
--- a/fw/esp32/components/eos/include/msgq.h
+++ b/fw/esp32/components/eos/include/msgq.h
@@ -14,9 +14,9 @@ typedef struct EOSMsgQ {
} EOSMsgQ;
void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size);
+uint8_t eos_msgq_len(EOSMsgQ *msgq);
int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len);
void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len);
-uint8_t eos_msgq_len(EOSMsgQ *msgq);
typedef struct EOSBufQ {
uint8_t idx_r;
@@ -26,6 +26,6 @@ typedef struct EOSBufQ {
} EOSBufQ;
void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size);
+uint8_t eos_bufq_len(EOSBufQ *bufq);
int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer);
unsigned char *eos_bufq_pop(EOSBufQ *bufq);
-uint8_t eos_bufq_len(EOSBufQ *bufq);
diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h
index 3e9e625..b500e82 100644
--- a/fw/esp32/components/eos/include/net.h
+++ b/fw/esp32/components/eos/include/net.h
@@ -5,32 +5,36 @@
#define EOS_NET_SIZE_BUF EOS_NET_MTU
#define EOS_NET_MTYPE_SOCK 1
-#define EOS_NET_MTYPE_RNG 3
-#define EOS_NET_MTYPE_POWER 4
+#define EOS_NET_MTYPE_WIFI 2
+#define EOS_NET_MTYPE_CELL 3
+#define EOS_NET_MTYPE_APP 4
+#define EOS_NET_MTYPE_RNG 5
-#define EOS_NET_MTYPE_WIFI 5
-#define EOS_NET_MTYPE_CELL 6
-#define EOS_NET_MTYPE_SIP 7
-#define EOS_NET_MTYPE_APP 8
+#define EOS_NET_MAX_MTYPE 5
-#define EOS_NET_MAX_MTYPE 8
+#define EOS_NET_MTYPE_SLEEP 0x10 /* does not have net handler */
#define EOS_NET_MTYPE_FLAG_ONEW 0x40
#define EOS_NET_MTYPE_FLAG_REPL 0x80
-#define EOS_NET_MTYPE_FLAG_MASK 0xc0
+#define EOS_NET_MTYPE_MASK 0x3F /* 0x0F if mtype is handled by evtq */
/* esp32 specific */
#define EOS_NET_SIZE_BUFQ 4
#define EOS_NET_SIZE_SNDQ 4
-typedef void (*eos_net_fptr_t) (unsigned char, unsigned char *, uint16_t);
+typedef void (*eos_net_handler_t) (unsigned char, unsigned char *, uint16_t);
+void eos_net_xchg_task(void *param);
void eos_net_init(void);
+void eos_net_run(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);
-void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len);
-void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler);
-void eos_net_sleep(void);
-void eos_net_wake(uint8_t source, uint8_t mode);
+
+int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+
+void eos_net_sleep_req(void);
+void eos_net_wake(void);
+
+void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler);
diff --git a/fw/esp32/components/eos/include/net_priv.h b/fw/esp32/components/eos/include/net_priv.h
new file mode 100644
index 0000000..fa1de61
--- /dev/null
+++ b/fw/esp32/components/eos/include/net_priv.h
@@ -0,0 +1,33 @@
+#define NET_DEV_NET EOS_PWR_DEV_NET
+#define NET_DEV_APP EOS_PWR_DEV_APP
+
+typedef struct NETConfig {
+ int sleep;
+ int sleep_req;
+ int present;
+ int gpio_mosi;
+ int gpio_miso;
+ int gpio_sclk;
+ int gpio_cs;
+ int gpio_rts;
+ int gpio_cts;
+ uint32_t dev;
+ spi_host_device_t spi_host;
+ spi_bus_config_t *spi_bus_cfg;
+ spi_slave_interface_config_t *spi_iface_cfg;
+ spi_slave_transaction_t *spi_tr_cfg;
+ TaskHandle_t xchg_task_handle;
+ SemaphoreHandle_t mutex;
+ SemaphoreHandle_t bufq_mutex;
+ SemaphoreHandle_t bufq_semaph;
+ EOSBufQ *buf_q;
+ EOSMsgQ *send_q;
+ eos_net_handler_t msg_handler;
+} NETConfig;
+
+void _eos_net_init_gpio(NETConfig *config);
+unsigned char *_eos_net_alloc(NETConfig *config);
+void _eos_net_free(NETConfig *config, unsigned char *buf);
+int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+void _eos_net_sleep_req(NETConfig *config);
+void _eos_net_wake(NETConfig *config);
diff --git a/fw/esp32/components/eos/include/power.h b/fw/esp32/components/eos/include/power.h
index 2215907..2590b80 100644
--- a/fw/esp32/components/eos/include/power.h
+++ b/fw/esp32/components/eos/include/power.h
@@ -1,22 +1,25 @@
#include <stdint.h>
-#define EOS_PWR_MTYPE_BUTTON 1
+#define EOS_PWR_GPIO_NET 8
+#define EOS_PWR_GPIO_APP 10
+#define EOS_PWR_GPIO_MODEM 16
-#define EOS_PWR_WAKE_RST 0
-#define EOS_PWR_WAKE_BTN 1
-#define EOS_PWR_WAKE_UART 2
-#define EOS_PWR_WAKE_NET 3
-#define EOS_PWR_WAKE_NETQ 4
-#define EOS_PWR_WAKE_UNDEF 5
+#define EOS_PWR_DEV_NONE 0
+#define EOS_PWR_DEV_NET ((uint32_t)1 << EOS_PWR_GPIO_NET)
+#define EOS_PWR_DEV_APP ((uint32_t)1 << EOS_PWR_GPIO_APP)
+#define EOS_PWR_DEV_MODEM ((uint32_t)1 << EOS_PWR_GPIO_MODEM)
+#define EOS_PWR_DEV_ALL (EOS_PWR_DEV_NET | EOS_PWR_DEV_APP | EOS_PWR_DEV_MODEM)
-#define EOS_PWR_SMODE_LIGHT 1
-#define EOS_PWR_SMODE_DEEP 2
+#define EOS_PWR_SMODE_TICKLESS 1
+#define EOS_PWR_SMODE_LIGHT 2
+#define EOS_PWR_SMODE_DEEP 3
void eos_power_init(void);
+void eos_power_run(void);
+void eos_power_sys_sleep(uint8_t mode);
+void eos_power_sys_wake(uint8_t mode) ;
+uint32_t eos_power_wakeup_source(void);
-void eos_power_wait4init(void);
-void eos_power_wait4wake(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
+void eos_power_sleep_req(uint8_t mode, uint32_t dev);
+void eos_power_sleep_rdy(uint32_t dev);
+void eos_power_wake(uint32_t dev);
diff --git a/fw/esp32/components/eos/include/sock.h b/fw/esp32/components/eos/include/sock.h
index 7e937cb..f2cf0c4 100644
--- a/fw/esp32/components/eos/include/sock.h
+++ b/fw/esp32/components/eos/include/sock.h
@@ -15,4 +15,6 @@ typedef struct EOSNetAddr {
uint16_t port;
} EOSNetAddr;
-void eos_sock_init(void); \ No newline at end of file
+void eos_sock_init(void);
+void eos_sock_run(void);
+void eos_sock_reopen(void); \ No newline at end of file
diff --git a/fw/esp32/components/eos/include/wifi.h b/fw/esp32/components/eos/include/wifi.h
index c1819e7..d080e25 100644
--- a/fw/esp32/components/eos/include/wifi.h
+++ b/fw/esp32/components/eos/include/wifi.h
@@ -13,6 +13,7 @@
#define EOS_WIFI_MAX_SCAN_RECORDS 20
void eos_wifi_init(void);
+void eos_wifi_run(void);
int eos_wifi_scan(void);
int eos_wifi_auth(char *ssid, char *pass);
@@ -21,4 +22,4 @@ int eos_wifi_disconnect(void);
ssize_t eos_wifi_get_status(unsigned char *buffer);
void eos_wifi_send_status(void);
-void eos_wifi_send_scan(void); \ No newline at end of file
+void eos_wifi_send_scan(void);
diff --git a/fw/esp32/components/eos/msgq.c b/fw/esp32/components/eos/msgq.c
index c200f7c..57fb669 100644
--- a/fw/esp32/components/eos/msgq.c
+++ b/fw/esp32/components/eos/msgq.c
@@ -12,6 +12,10 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) {
msgq->array = array;
}
+uint8_t eos_msgq_len(EOSMsgQ *msgq) {
+ return (uint8_t)(msgq->idx_w - msgq->idx_r);
+}
+
int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) {
if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL;
@@ -37,10 +41,6 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui
}
}
-uint8_t eos_msgq_len(EOSMsgQ *msgq) {
- return (uint8_t)(msgq->idx_w - msgq->idx_r);
-}
-
void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) {
bufq->idx_r = 0;
bufq->idx_w = 0;
@@ -48,6 +48,10 @@ void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) {
bufq->array = array;
}
+uint8_t eos_bufq_len(EOSBufQ *bufq) {
+ return (uint8_t)(bufq->idx_w - bufq->idx_r);
+}
+
int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer) {
if ((uint8_t)(bufq->idx_w - bufq->idx_r) == bufq->size) return EOS_ERR_FULL;
@@ -60,7 +64,3 @@ unsigned char *eos_bufq_pop(EOSBufQ *bufq) {
return bufq->array[IDX_MASK(bufq->idx_r++, bufq->size)];
}
-
-uint8_t eos_bufq_len(EOSBufQ *bufq) {
- return (uint8_t)(bufq->idx_w - bufq->idx_r);
-}
diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c
index 56ec940..0ba2a2d 100644
--- a/fw/esp32/components/eos/net.c
+++ b/fw/esp32/components/eos/net.c
@@ -16,20 +16,21 @@
#include "eos.h"
#include "msgq.h"
#include "power.h"
+#include "app.h"
#include "net.h"
+#include "net_priv.h"
-#define SPI_GPIO_RTS 22
-#define SPI_GPIO_CTS 21
-#define SPI_GPIO_MOSI 23
-#define SPI_GPIO_MISO 19
-#define SPI_GPIO_SCLK 18
-#define SPI_GPIO_CS 5
+#define SPI_GPIO_RTS 35
+#define SPI_GPIO_CTS 3
+#define SPI_GPIO_MOSI 40
+#define SPI_GPIO_MISO 39
+#define SPI_GPIO_SCLK 38
+#define SPI_GPIO_CS 8
#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 4)
#define SPI_SIZE_HDR 3
-static volatile int net_sleep = 0;
-static volatile int net_wake = 0;
+#define SPI_HOST SPI3_HOST
static EOSBufQ net_buf_q;
static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ];
@@ -37,262 +38,440 @@ static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ];
static EOSMsgQ net_send_q;
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 NETConfig net_config;
+static eos_net_handler_t net_handler[EOS_NET_MAX_MTYPE];
+
+static spi_bus_config_t net_spi_bus_cfg;
+static spi_slave_interface_config_t net_spi_iface_cfg;
+static spi_slave_transaction_t net_spi_tr_cfg;
+
static const char *TAG = "EOS NET";
-static eos_net_fptr_t net_handler[EOS_NET_MAX_MTYPE];
+static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, buf_len);
+}
+
+static void net_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ uint8_t idx;
-static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) {
- ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len);
+ idx = mtype & EOS_NET_MTYPE_MASK;
+ if (idx && (idx <= EOS_NET_MAX_MTYPE) && (buf_len <= EOS_NET_MTU)) {
+ net_handler[idx - 1](mtype, buffer, buf_len);
+ } else {
+ bad_handler(mtype, buffer, buf_len);
+ }
}
-// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high.
+/* Called after a transaction is queued and ready for pickup by master */
static void _post_setup_cb(spi_slave_transaction_t *trans) {
- gpio_set_level(SPI_GPIO_CTS, 1);
+ NETConfig *config = trans->user;
+
+ gpio_set_level(config->gpio_cts, 0);
}
-// Called after transaction is sent/received. We use this to set the handshake line low.
+/* Called after transaction is sent/received */
static void _post_trans_cb(spi_slave_transaction_t *trans) {
- gpio_set_level(SPI_GPIO_CTS, 0);
+ NETConfig *config = trans->user;
+
+ gpio_set_level(config->gpio_cts, 1);
+}
+
+static void net_goto_sleep(NETConfig *config) {
+ esp_err_t ret;
+ uint8_t msgq_len;
+
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ msgq_len = eos_msgq_len(config->send_q);
+ if (msgq_len) {
+ gpio_set_level(config->gpio_rts, 0);
+ } else {
+ gpio_set_level(config->gpio_rts, 1);
+ }
+ xSemaphoreGive(config->mutex);
+
+ ret = spi_slave_free(config->spi_host);
+ assert(ret == ESP_OK);
+
+ /* for deep sleep */
+ gpio_hold_en(config->gpio_cts);
+
+ eos_power_sleep_rdy(config->dev);
+ vTaskSuspend(NULL);
+
+ gpio_hold_dis(config->gpio_cts);
+
+ ret = spi_slave_initialize(config->spi_host, config->spi_bus_cfg, config->spi_iface_cfg, SPI_DMA_CH_AUTO);
+ assert(ret == ESP_OK);
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ config->sleep = 0;
+ msgq_len = eos_msgq_len(config->send_q);
+ if (msgq_len) {
+ gpio_set_level(config->gpio_rts, 0);
+ } else {
+ gpio_set_level(config->gpio_rts, 1);
+ }
+ xSemaphoreGive(config->mutex);
}
-static void net_xchg_task(void *pvParameters) {
- int wake = 0;
- int skip_msg = 0;
+void eos_net_xchg_task(void *param) {
+ NETConfig *config = param;
+ int present, skip_msg = 0, sleep_msg = 0;
unsigned char mtype = 0;
unsigned char mtype_flags = 0;
unsigned char *buffer;
- uint16_t len;
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);
+ uint16_t buf_len;
+ size_t trans_len;
+ spi_bus_config_t *spi_bus_cfg = config->spi_bus_cfg;
+ spi_slave_interface_config_t *spi_iface_cfg = config->spi_iface_cfg;
+ spi_slave_transaction_t *spi_tr_cfg = config->spi_tr_cfg;
esp_err_t ret;
- static spi_slave_transaction_t spi_tr;
-
- //Configuration for the SPI bus
- static 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
- };
-
- //Configuration for the SPI slave interface
- static 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, 2);
- assert(ret == ESP_OK);
-
- memset(&spi_tr, 0, sizeof(spi_tr));
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
- spi_tr.length = SPI_SIZE_BUF * 8;
-
- if (eos_power_wakeup_cause() != EOS_PWR_WAKE_RST) {
- wake = 1;
- skip_msg = 1;
+ assert(buf_send != NULL);
+ assert(buf_recv != NULL);
+
+ /* Configuration for the SPI bus */
+ spi_bus_cfg->mosi_io_num = config->gpio_mosi;
+ spi_bus_cfg->miso_io_num = config->gpio_miso;
+ spi_bus_cfg->sclk_io_num = config->gpio_sclk;
+
+ /* Configuration for the SPI slave interface */
+ spi_iface_cfg->mode = 0;
+ spi_iface_cfg->spics_io_num = config->gpio_cs;
+ spi_iface_cfg->queue_size = 2;
+ spi_iface_cfg->flags = 0;
+ spi_iface_cfg->post_setup_cb = _post_setup_cb;
+ spi_iface_cfg->post_trans_cb = _post_trans_cb;
+
+ spi_tr_cfg->tx_buffer = buf_send;
+ spi_tr_cfg->rx_buffer = buf_recv;
+ spi_tr_cfg->length = SPI_SIZE_BUF * 8;
+ spi_tr_cfg->user = config;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ present = config->present;
+ xSemaphoreGive(config->mutex);
+ if (!present) {
+ vTaskSuspend(NULL);
}
- eos_power_wait4init();
+ /* Initialize SPI slave interface */
+ ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO);
+ assert(ret == ESP_OK);
+
while (1) {
if (!skip_msg) {
- xSemaphoreTake(mutex, portMAX_DELAY);
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
- eos_msgq_pop(&net_send_q, &mtype, &buffer, &len);
+ eos_msgq_pop(config->send_q, &mtype, &buffer, &buf_len);
if (mtype) {
buf_send[0] = mtype;
- buf_send[1] = len >> 8;
- buf_send[2] = len & 0xFF;
+ buf_send[1] = buf_len >> 8;
+ buf_send[2] = buf_len & 0xFF;
if (buffer) {
- memcpy(buf_send + SPI_SIZE_HDR, buffer, len);
- eos_bufq_push(&net_buf_q, buffer);
- xSemaphoreGive(semaph);
+ memcpy(buf_send + SPI_SIZE_HDR, buffer, buf_len);
+ xSemaphoreTake(config->bufq_mutex, portMAX_DELAY);
+ eos_bufq_push(config->buf_q, buffer);
+ xSemaphoreGive(config->bufq_mutex);
+ xSemaphoreGive(config->bufq_semaph);
}
+ } else if (!sleep_msg && config->sleep_req) {
+ buf_send[0] = EOS_NET_MTYPE_SLEEP;
+ buf_send[1] = 0;
+ buf_send[2] = 0;
+ sleep_msg = 1;
+ config->sleep_req = 0;
+ if (config->dev == NET_DEV_NET) config->sleep = 1;
} else {
- gpio_set_level(SPI_GPIO_RTS, 0);
+ gpio_set_level(config->gpio_rts, 1);
buf_send[0] = 0;
buf_send[1] = 0;
buf_send[2] = 0;
}
- xSemaphoreGive(mutex);
+ xSemaphoreGive(config->mutex);
}
skip_msg = 0;
buf_recv[0] = 0;
buf_recv[1] = 0;
buf_recv[2] = 0;
- spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY);
- // ESP_LOGI(TAG, "RECV:%d", buf_recv[0]);
+ ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY);
+ assert(ret == ESP_OK);
+
+ trans_len = spi_tr_cfg->trans_len / 8;
+
+ ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", buf_recv[0], config->dev, trans_len);
+
+ if (sleep_msg && (config->dev == NET_DEV_NET)) {
+ net_goto_sleep(config);
+ sleep_msg = 0;
+ continue;
+ }
+
+ if (trans_len < 1) {
+ ESP_LOGE(TAG, "RECV LEN:%d", trans_len);
+ continue;
+ }
- if (wake) {
- eos_power_net_ready();
- wake = 0;
+ /* SPI reset */
+ if ((trans_len == 1) && (buf_recv[0] == 0)) {
+ if (buf_send[0]) skip_msg = 1;
+ continue;
}
- if ((spi_tr.trans_len / 8) < SPI_SIZE_HDR) continue;
- if (buf_recv[0] == 0x00) continue;
+ mtype = buf_recv[0] & EOS_NET_MTYPE_MASK;
+ mtype_flags = buf_recv[0] & ~EOS_NET_MTYPE_MASK;
+ if (buf_send[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) {
+ skip_msg = 1;
+ }
- if (buf_recv[0] == 0xFF) { // Sleep req
- if (buf_send[0] == 0) {
- spi_slave_free(VSPI_HOST);
- eos_power_sleep();
+ if (buf_send[0] && (trans_len < buf_len + SPI_SIZE_HDR) && !skip_msg) {
+ spi_tr_cfg->tx_buffer = buf_send + trans_len;
+ spi_tr_cfg->rx_buffer = buf_recv + trans_len;
+ spi_tr_cfg->length = (SPI_SIZE_BUF - trans_len) * 8;
+ ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY);
+ assert(ret == ESP_OK);
+ trans_len += spi_tr_cfg->trans_len / 8;
+ spi_tr_cfg->tx_buffer = buf_send;
+ spi_tr_cfg->rx_buffer = buf_recv;
+ spi_tr_cfg->length = SPI_SIZE_BUF * 8;
+ }
- xSemaphoreTake(mutex, portMAX_DELAY);
- net_sleep = 1;
- if (eos_msgq_len(&net_send_q)) net_wake = 1;
- xSemaphoreGive(mutex);
+ if (mtype == 0) continue;
- if (net_wake) eos_power_wake(EOS_PWR_WAKE_NETQ);
- vTaskSuspend(NULL);
+ if (mtype == EOS_NET_MTYPE_SLEEP) {
+ uint8_t mode;
- xSemaphoreTake(mutex, portMAX_DELAY);
- net_sleep = 0;
- net_wake = 0;
- xSemaphoreGive(mutex);
+ mode = EOS_PWR_SMODE_LIGHT;
- spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1);
- wake = 1;
- skip_msg = 1;
+ switch (config->dev) {
+ case NET_DEV_NET: {
+ eos_power_sleep_req(mode, EOS_PWR_DEV_ALL);
+ break;
+ }
+ case NET_DEV_APP: {
+ uint8_t msgq_len;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ msgq_len = eos_msgq_len(config->send_q);
+ if (msgq_len == 0) {
+ config->sleep = 1;
+ config->sleep_req = 0;
+ }
+ xSemaphoreGive(config->mutex);
+ if (msgq_len == 0) {
+ net_goto_sleep(config);
+ sleep_msg = 0;
+ }
+ break;
+ }
}
continue;
}
- mtype = buf_recv[0] & ~EOS_NET_MTYPE_FLAG_MASK;
- mtype_flags = buf_recv[0] & EOS_NET_MTYPE_FLAG_MASK;
- len = (uint16_t)buf_recv[1] << 8;
- len |= (uint16_t)buf_recv[2] & 0xFF;
- buffer = buf_recv + SPI_SIZE_HDR;
- if ((mtype <= EOS_NET_MAX_MTYPE) && (len <= EOS_NET_MTU)) {
- net_handler[mtype - 1](buf_recv[0], buffer, len);
- } else {
- bad_handler(buf_recv[0], buffer, len);
- }
- if ((mtype_flags & EOS_NET_MTYPE_FLAG_ONEW) && buf_send[0]) {
- skip_msg = 1;
+ if (trans_len < SPI_SIZE_HDR) {
+ ESP_LOGE(TAG, "RECV LEN:%d", trans_len);
+ continue;
}
+ buf_len = (uint16_t)buf_recv[1] << 8;
+ buf_len |= (uint16_t)buf_recv[2] & 0xFF;
+ buffer = buf_recv + SPI_SIZE_HDR;
+ config->msg_handler(buf_recv[0], buffer, buf_len);
+
if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) {
- spi_tr.tx_buffer = buf_recv;
- spi_tr.rx_buffer = NULL;
- spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY);
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
+ spi_tr_cfg->tx_buffer = buf_recv;
+ spi_tr_cfg->rx_buffer = NULL;
+ ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY);
+ assert(ret == ESP_OK);
+ spi_tr_cfg->tx_buffer = buf_send;
+ spi_tr_cfg->rx_buffer = buf_recv;
}
}
+
vTaskDelete(NULL);
}
-void eos_net_init(void) {
- int i;
-
- // Configuration for the handshake lines
+void _eos_net_init_gpio(NETConfig *config) {
+ /* Configuration for the handshake lines */
gpio_config_t io_conf = {};
+ gpio_set_level(config->gpio_rts, 1);
+ gpio_set_level(config->gpio_cts, 1);
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_CTS);
+ io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
+ io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
+ io_conf.pin_bit_mask = BIT64(config->gpio_rts) | BIT64(config->gpio_cts);
gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_CTS, 0);
+}
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_RTS);
- gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_RTS, 0);
+void eos_net_init(void) {
+ SemaphoreHandle_t mutex;
+ SemaphoreHandle_t bufq_mutex;
+ SemaphoreHandle_t bufq_semaph;
+ int i;
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<EOS_NET_SIZE_BUFQ; i++) {
- eos_bufq_push(&net_buf_q, malloc(EOS_NET_SIZE_BUF));
+ unsigned char *buffer;
+
+ buffer = malloc(EOS_NET_SIZE_BUF);
+ assert(buffer != NULL);
+ eos_bufq_push(&net_buf_q, buffer);
}
for (i=0; i<EOS_NET_MAX_MTYPE; i++) {
net_handler[i] = bad_handler;
}
- semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ);
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
+ bufq_mutex = xSemaphoreCreateBinary();
+ assert(bufq_mutex != NULL);
+ bufq_semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ);
+ assert(bufq_semaph != NULL);
+
xSemaphoreGive(mutex);
- xTaskCreate(&net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET_XCHG, NULL, EOS_TASK_PRIORITY_NET_XCHG, &net_xchg_task_handle);
+ xSemaphoreGive(bufq_mutex);
+
+ net_config.sleep = 0;
+ net_config.sleep_req = 0;
+ net_config.present = 1;
+ net_config.dev = NET_DEV_NET;
+ net_config.gpio_mosi = SPI_GPIO_MOSI;
+ net_config.gpio_miso = SPI_GPIO_MISO;
+ net_config.gpio_sclk = SPI_GPIO_SCLK;
+ net_config.gpio_cs = SPI_GPIO_CS;
+ net_config.gpio_rts = SPI_GPIO_RTS;
+ net_config.gpio_cts = SPI_GPIO_CTS;
+ net_config.spi_host = SPI_HOST;
+ net_config.spi_bus_cfg = &net_spi_bus_cfg;
+ net_config.spi_iface_cfg = &net_spi_iface_cfg;
+ net_config.spi_tr_cfg = &net_spi_tr_cfg;
+ net_config.mutex = mutex;
+ net_config.bufq_mutex = bufq_mutex;
+ net_config.bufq_semaph = bufq_semaph;
+ net_config.buf_q = &net_buf_q;
+ net_config.send_q = &net_send_q;
+ net_config.msg_handler = net_msg_handler;
+
+ _eos_net_init_gpio(&net_config);
+
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ gpio_hold_dis(net_config.gpio_cts);
+ }
+
ESP_LOGI(TAG, "INIT");
}
-unsigned char *eos_net_alloc(void) {
+void eos_net_run(void) {
+ BaseType_t rv;
+
+ rv = xTaskCreate(&eos_net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET, &net_config, EOS_TASK_PRIORITY_NET, &net_config.xchg_task_handle);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
+unsigned char *_eos_net_alloc(NETConfig *config) {
unsigned char *ret;
- xSemaphoreTake(semaph, portMAX_DELAY);
- xSemaphoreTake(mutex, portMAX_DELAY);
- ret = eos_bufq_pop(&net_buf_q);
- xSemaphoreGive(mutex);
+ xSemaphoreTake(config->bufq_semaph, portMAX_DELAY);
+ xSemaphoreTake(config->bufq_mutex, portMAX_DELAY);
+ ret = eos_bufq_pop(config->buf_q);
+ xSemaphoreGive(config->bufq_mutex);
return ret;
}
+void _eos_net_free(NETConfig *config, unsigned char *buf) {
+ xSemaphoreTake(config->bufq_mutex, portMAX_DELAY);
+ eos_bufq_push(config->buf_q, buf);
+ xSemaphoreGive(config->bufq_semaph);
+ xSemaphoreGive(config->bufq_mutex);
+}
+
+unsigned char *eos_net_alloc(void) {
+ return _eos_net_alloc(&net_config);
+}
+
void eos_net_free(unsigned char *buf) {
- xSemaphoreTake(mutex, portMAX_DELAY);
- eos_bufq_push(&net_buf_q, buf);
- xSemaphoreGive(semaph);
- xSemaphoreGive(mutex);
+ _eos_net_free(&net_config, buf);
}
-int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len) {
+int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
int rv = EOS_OK;
int sleep;
- xSemaphoreTake(mutex, portMAX_DELAY);
- sleep = net_sleep && !net_wake;
- gpio_set_level(SPI_GPIO_RTS, 1);
- rv = eos_msgq_push(&net_send_q, mtype, buffer, len);
- xSemaphoreGive(mutex);
-
- if (rv) eos_net_free(buffer);
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ sleep = config->sleep;
+ rv = eos_msgq_push(config->send_q, mtype, buffer, buf_len);
+ if (!rv && !sleep) gpio_set_level(config->gpio_rts, 0);
+ xSemaphoreGive(config->mutex);
- if (sleep) eos_power_wake(EOS_PWR_WAKE_NETQ);
+ if (!rv && sleep) eos_power_wake(config->dev);
+ if (rv) _eos_net_free(config, buffer);
return rv;
}
-void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len) {
+int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ return _eos_net_send(&net_config, mtype, buffer, buf_len);
+}
+
+void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
buffer -= SPI_SIZE_HDR;
buffer[0] = mtype;
- buffer[1] = len >> 8;
- buffer[2] = len & 0xFF;
+ buffer[1] = buf_len >> 8;
+ buffer[2] = buf_len & 0xFF;
}
-void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler) {
- if (handler == NULL) handler = bad_handler;
- if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler;
-}
+void _eos_net_sleep_req(NETConfig *config) {
+ int sleep, present;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ sleep = config->sleep;
+ present = config->present;
+ if (!sleep && present) {
+ config->sleep_req = 1;
+ gpio_set_level(config->gpio_rts, 0);
+ }
+ xSemaphoreGive(config->mutex);
-void eos_net_sleep(void) {
- gpio_set_level(SPI_GPIO_CTS, 1);
- vTaskDelay(200 / portTICK_PERIOD_MS);
- gpio_set_level(SPI_GPIO_CTS, 0);
+ if (!present) eos_power_sleep_rdy(config->dev);
}
-void eos_net_wake(uint8_t source, uint8_t mode) {
- int sleep;
+void _eos_net_wake(NETConfig *config) {
+ int sleep, present;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ present = config->present;
+ xSemaphoreGive(config->mutex);
- if (mode == EOS_PWR_SMODE_DEEP) return;
+ if (!present) return;
do {
- vTaskResume(net_xchg_task_handle);
+ vTaskResume(config->xchg_task_handle);
vTaskDelay(10 / portTICK_PERIOD_MS);
-
- xSemaphoreTake(mutex, portMAX_DELAY);
- sleep = net_sleep;
- xSemaphoreGive(mutex);
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ sleep = config->sleep;
+ xSemaphoreGive(config->mutex);
} while (sleep);
}
+
+void eos_net_sleep_req(void) {
+ _eos_net_sleep_req(&net_config);
+}
+
+void eos_net_wake(void) {
+ _eos_net_wake(&net_config);
+}
+
+void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler) {
+ if (handler == NULL) handler = bad_handler;
+ if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler;
+}
diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c
index b98c0ec..27c44a5 100644
--- a/fw/esp32/components/eos/power.c
+++ b/fw/esp32/components/eos/power.c
@@ -4,37 +4,30 @@
#include <freertos/task.h>
#include <freertos/queue.h>
#include <driver/gpio.h>
+#include <driver/rtc_io.h>
+#include <driver/uart.h>
+
+#include <esp_system.h>
#include <esp_sleep.h>
-#include <esp_timer.h>
#include <esp_pm.h>
#include <esp_log.h>
-#include <esp32/rom/rtc.h>
#include "eos.h"
#include "net.h"
+#include "app.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_SLEEP1 2
-#define POWER_ETYPE_SLEEP2 3
-#define POWER_ETYPE_WAKE 4
-#define POWER_ETYPE_NETRDY 5
+#define PWR_ETYPE_SLEEP_REQ 1
+#define PWR_ETYPE_SLEEP_RDY 2
+#define PWR_ETYPE_WAKE 3
typedef struct {
uint8_t type;
- union {
- uint8_t source;
- uint8_t level;
- };
+ uint8_t mode;
+ uint32_t dev;
} 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;
@@ -43,232 +36,119 @@ 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;
-
- 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;
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = EOS_PWR_DEV_NET;
xQueueSendFromISR(power_queue, &evt, NULL);
}
-static void IRAM_ATTR uart_wake_handler(void *arg) {
+static void IRAM_ATTR app_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;
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = EOS_PWR_DEV_APP;
xQueueSendFromISR(power_queue, &evt, NULL);
}
-static void timer_handler(void *arg) {
+static void IRAM_ATTR modem_wake_handler(void *arg) {
power_event_t evt;
- evt.type = POWER_ETYPE_SLEEP2;
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = EOS_PWR_DEV_MODEM;
xQueueSendFromISR(power_queue, &evt, NULL);
}
-static void power_sleep_stage1(int modem_wake_en) {
- 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);
- if (modem_wake_en) {
- 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);
- if (modem_wake_en) {
- gpio_wakeup_enable(POWER_GPIO_UART, GPIO_INTR_LOW_LEVEL);
- }
-
- esp_timer_start_once(timer, 10 * 1000000);
-
- esp_pm_lock_release(power_lock_cpu_freq);
- esp_pm_lock_release(power_lock_apb_freq);
- esp_pm_lock_release(power_lock_no_sleep);
-}
-
-static void power_sleep_stage2(int modem_wake_en, 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);
-
- gpio_deep_sleep_hold_en();
- esp_sleep_enable_ext0_wakeup(POWER_GPIO_BTN, 0);
- if (modem_wake_en) {
- esp_sleep_enable_ext1_wakeup((uint64_t)1 << POWER_GPIO_UART, ESP_EXT1_WAKEUP_ALL_LOW);
- }
-
- ESP_LOGI(TAG, "DEEP SLEEP");
-
- eos_modem_deep_sleep();
- esp_deep_sleep_start();
- break;
- }
- }
-}
-
-static void power_wake_stage1(uint8_t source, uint8_t mode) {
- 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;
- 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_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);
- }
-
- eos_net_wake(source, mode);
-}
-
-static 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);
-
- ESP_LOGI(TAG, "WAKE");
- wake_done = 1;
-}
-
static void power_event_task(void *pvParameters) {
power_event_t evt;
- uint8_t source;
- uint8_t wakeup_cause;
uint8_t mode;
- int sleep1, sleep2;
- int modem_wake_en;
+ uint32_t sleep_req, sleep_rdy;
+ int sys_sleep;
mode = 0;
- source = 0;
- wakeup_cause = eos_power_wakeup_cause();
- if (wakeup_cause != EOS_PWR_WAKE_RST) {
- mode = EOS_PWR_SMODE_DEEP;
- sleep1 = 1;
- } else {
- sleep1 = 0;
- }
- sleep2 = 0;
- modem_wake_en = 0;
-
+ sys_sleep = 0;
+ sleep_req = 0;
+ sleep_rdy = 0;
while (1) {
if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) {
switch (evt.type) {
- case POWER_ETYPE_SLEEP1: {
- if (!sleep1) {
- modem_wake_en = eos_modem_present();
- mode = EOS_PWR_SMODE_LIGHT;
- power_sleep_stage1(modem_wake_en);
- sleep1 = 1;
- sleep2 = 1;
+ 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();
}
- break;
- }
-
- case POWER_ETYPE_SLEEP2: {
- if (sleep2) {
- mode = EOS_PWR_SMODE_DEEP;
- power_sleep_stage2(modem_wake_en, mode);
- sleep2 = 0;
+ if ((evt.dev & EOS_PWR_DEV_APP) && !(sleep_req & EOS_PWR_DEV_APP)) {
+ eos_app_sleep_req();
}
- break;
- }
-
- case POWER_ETYPE_WAKE: {
- if (sleep1) {
- source = evt.source;
- power_wake_stage1(source, mode);
- if (sleep2) {
- esp_timer_stop(timer);
- sleep2 = 0;
- }
+ if ((evt.dev & EOS_PWR_DEV_MODEM) && !(sleep_req & EOS_PWR_DEV_MODEM)) {
+ eos_modem_sleep_req();
+ }
+ sleep_req |= evt.dev;
+ if (sleep_rdy == EOS_PWR_DEV_ALL) {
+ eos_power_sleep_rdy(0);
}
break;
}
- case POWER_ETYPE_NETRDY: {
- power_wake_stage2(source, mode);
- sleep1 = 0;
- source = 0;
+ 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;
+ if (!sys_sleep && mode && (sleep_rdy == EOS_PWR_DEV_ALL)) {
+ sys_sleep = 1;
+ eos_power_sys_sleep(mode);
+ }
break;
}
- case POWER_ETYPE_BTN: {
- unsigned char *buf;
-
- buf = eos_net_alloc();
- buf[0] = EOS_PWR_MTYPE_BUTTON;
- buf[1] = evt.level;
- eos_net_send(EOS_NET_MTYPE_POWER, buf, 2);
+ case PWR_ETYPE_WAKE: {
+ ESP_LOGI(TAG, "WAKE:0x%.8lX", evt.dev);
+ 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);
break;
}
-
- default:
- break;
}
}
}
@@ -276,35 +156,9 @@ static void power_event_task(void *pvParameters) {
}
void eos_power_init(void) {
- esp_err_t ret;
- gpio_config_t io_conf = {};
- esp_timer_create_args_t timer_args = {};
- esp_pm_config_esp32_t pwr_conf;
- uint8_t wakeup_cause;
-
- 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);
-
- 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);
- 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);
- */
+ esp_err_t ret;
+ esp_pm_config_t pwr_conf;
ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, NULL, &power_lock_cpu_freq);
assert(ret == ESP_OK);
@@ -326,70 +180,118 @@ void eos_power_init(void) {
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);
-
- wakeup_cause = eos_power_wakeup_cause();
- if (wakeup_cause != EOS_PWR_WAKE_RST) {
- eos_power_wake(wakeup_cause);
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ 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);
}
- init_done = 1;
+ power_queue = xQueueCreate(4, sizeof(power_event_t));
+ assert(power_queue != NULL);
+
ESP_LOGI(TAG, "INIT");
}
-void eos_power_wait4init(void) {
- while (!init_done);
-}
+void eos_power_run(void) {
+ BaseType_t rv;
-void eos_power_wait4wake(void) {
- if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) return;
- while (!wake_done);
-}
+ rv = xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL);
+ assert(rv == pdPASS);
-uint8_t eos_power_wakeup_cause(void) {
- esp_reset_reason_t reset_cause = esp_reset_reason();
- esp_sleep_wakeup_cause_t wakeup_cause = esp_sleep_get_wakeup_cause();
+ ESP_LOGI(TAG, "RUN");
+}
- if (reset_cause == ESP_RST_DEEPSLEEP) {
- switch (wakeup_cause) {
- case ESP_SLEEP_WAKEUP_EXT0:
- return EOS_PWR_WAKE_BTN;
+void eos_power_sys_sleep(uint8_t mode) {
+ switch (mode) {
+ case EOS_PWR_SMODE_TICKLESS: {
+ esp_pm_lock_release(power_lock_cpu_freq);
+ esp_pm_lock_release(power_lock_apb_freq);
+ esp_pm_lock_release(power_lock_no_sleep);
+ break;
+ }
- case ESP_SLEEP_WAKEUP_EXT1:
- return EOS_PWR_WAKE_UART;
+ case EOS_PWR_SMODE_LIGHT:
+ case EOS_PWR_SMODE_DEEP: {
+ esp_err_t ret;
+
+ /* in case of missing modem */
+ 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) {
+ gpio_deep_sleep_hold_en();
+ esp_deep_sleep_start();
+ } else {
+ ESP_LOGI(TAG, "LIGHT SLEEP");
+ uart_wait_tx_idle_polling(UART_NUM_0);
+ ret = esp_light_sleep_start();
+ ESP_LOGI(TAG, "LIGHT WAKE: %d", ret);
+ eos_power_wake(eos_power_wakeup_source());
+ }
+ break;
+ }
+ }
+}
- default:
- return EOS_PWR_WAKE_UNDEF;
+void eos_power_sys_wake(uint8_t mode) {
+ switch (mode) {
+ case EOS_PWR_SMODE_TICKLESS: {
+ esp_pm_lock_acquire(power_lock_cpu_freq);
+ esp_pm_lock_acquire(power_lock_apb_freq);
+ esp_pm_lock_acquire(power_lock_no_sleep);
+ break;
+ }
+ case EOS_PWR_SMODE_LIGHT:
+ case EOS_PWR_SMODE_DEEP: {
+ rtc_gpio_pullup_dis(EOS_PWR_GPIO_MODEM);
+ esp_sleep_disable_ext1_wakeup_io(0);
+ if (mode == EOS_PWR_SMODE_DEEP) {
+ gpio_deep_sleep_hold_dis();
+ }
+ break;
}
+ }
+}
+
+uint32_t eos_power_wakeup_source(void) {
+ esp_sleep_wakeup_cause_t wakeup_cause;
+ uint32_t dev;
+
+ dev = EOS_PWR_DEV_NONE;
+ wakeup_cause = esp_sleep_get_wakeup_cause();
+ if (wakeup_cause == ESP_SLEEP_WAKEUP_EXT1) {
+ dev = esp_sleep_get_ext1_wakeup_status();
+ return dev;
} else {
- return EOS_PWR_WAKE_RST;
+ ESP_LOGE(TAG, "BAD WAKEUP CAUSE");
}
+ return dev;
}
-void eos_power_sleep(void) {
+void eos_power_sleep_req(uint8_t mode, uint32_t dev) {
power_event_t evt;
- evt.type = POWER_ETYPE_SLEEP1;
- evt.source = 0;
+ evt.type = PWR_ETYPE_SLEEP_REQ;
+ evt.mode = mode;
+ evt.dev = dev;
xQueueSend(power_queue, &evt, portMAX_DELAY);
}
-void eos_power_wake(uint8_t source) {
+void eos_power_sleep_rdy(uint32_t dev) {
power_event_t evt;
- evt.type = POWER_ETYPE_WAKE;
- evt.source = source;
-
+ evt.type = PWR_ETYPE_SLEEP_RDY;
+ evt.dev = dev;
xQueueSend(power_queue, &evt, portMAX_DELAY);
}
-void eos_power_net_ready(void) {
+void eos_power_wake(uint32_t dev) {
power_event_t evt;
- evt.type = POWER_ETYPE_NETRDY;
- evt.source = 0;
-
+ ESP_LOGI(TAG, "WAKE SENT");
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = dev;
xQueueSend(power_queue, &evt, portMAX_DELAY);
}
diff --git a/fw/esp32/components/eos/rng.c b/fw/esp32/components/eos/rng.c
index 3927df1..675a79c 100644
--- a/fw/esp32/components/eos/rng.c
+++ b/fw/esp32/components/eos/rng.c
@@ -1,4 +1,4 @@
-#include <esp_system.h>
+#include <esp_random.h>
#include <esp_log.h>
#include <esp_err.h>
@@ -26,6 +26,7 @@ rng_handler_fin:
void eos_rng_init(void) {
eos_net_set_handler(EOS_NET_MTYPE_RNG, rng_handler);
+
ESP_LOGI(TAG, "INIT");
}
diff --git a/fw/esp32/components/eos/sock.c b/fw/esp32/components/eos/sock.c
index 08d95d5..b6ed3e9 100644
--- a/fw/esp32/components/eos/sock.c
+++ b/fw/esp32/components/eos/sock.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
+#include <sys/select.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
@@ -9,6 +10,9 @@
#include <esp_system.h>
#include <esp_log.h>
#include <esp_err.h>
+#include <esp_vfs.h>
+#include <esp_vfs_dev.h>
+#include <esp_vfs_eventfd.h>
#include <lwip/sockets.h>
#include <lwip/err.h>
@@ -23,8 +27,14 @@
static const char *TAG = "EOS SOCK";
static SemaphoreHandle_t mutex;
+static int cmd_fd, rep_fd;
static int _socks[EOS_SOCK_MAX_SOCK];
+#define CMD_OPEN 1
+#define CMD_CLOSE 2
+#define CMD_SEND 3
+#define CMD_REOPEN 4
+
static int t_open_dgram(void) {
struct sockaddr_in _myaddr;
int sock;
@@ -74,83 +84,246 @@ static ssize_t t_recvfrom(int sock, void *msg, size_t msg_size, EOSNetAddr *addr
return recvlen;
}
+static void populate_fds(fd_set *fds, int *max_fd) {
+ int i;
+
+ *max_fd = cmd_fd;
+
+ FD_ZERO(fds);
+ FD_SET(cmd_fd, fds);
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ if (_socks[i]) {
+ FD_SET(_socks[i], fds);
+ if (_socks[i] > *max_fd) {
+ *max_fd = _socks[i];
+ }
+ }
+ }
+}
+
static void udp_rcvr_task(void *pvParameters) {
- uint8_t sock_i = (uint8_t)pvParameters;
- int sock = _socks[sock_i-1];
-
- do {
- EOSNetAddr addr;
- unsigned char *buf, *_buf;
- ssize_t rv;
-
- buf = eos_net_alloc();
- rv = t_recvfrom(sock, buf + EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF - EOS_SOCK_SIZE_UDP_HDR, &addr);
- if (rv < 0) {
- eos_net_free(buf);
- ESP_LOGE(TAG, "UDP RECV ERR:%d", rv);
- break;
+ EOSNetAddr addr;
+ unsigned char *buffer;
+ uint16_t buf_len;
+ fd_set all_fds, read_fds;
+ uint8_t sock_i;
+ uint8_t cmd[8];
+ ssize_t _rv;
+ int sock, max_fd, i;
+ int rv;
+
+ assert(sizeof(buffer) == 4);
+
+ populate_fds(&all_fds, &max_fd);
+ while (1) {
+ memcpy(&read_fds, &all_fds, sizeof(fd_set));
+ rv = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
+ if (rv <= 0) {
+ ESP_LOGE(TAG, "SELECT ERR:%d", rv);
+ continue;
}
- _buf = buf;
- _buf[0] = EOS_SOCK_MTYPE_PKT;
- _buf[1] = sock_i;
- _buf += 2;
- memcpy(_buf, addr.host, sizeof(addr.host));
- _buf += sizeof(addr.host);
- _buf[0] = addr.port >> 8;
- _buf[1] = addr.port;
- _buf += sizeof(addr.port);
- eos_net_send(EOS_NET_MTYPE_SOCK, buf, rv + EOS_SOCK_SIZE_UDP_HDR);
- } while (1);
- xSemaphoreTake(mutex, portMAX_DELAY);
- _socks[sock_i-1] = 0;
- xSemaphoreGive(mutex);
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ sock = _socks[i];
+ if (sock && FD_ISSET(sock, &read_fds)) {
+ unsigned char *_buf;
+
+ buffer = eos_net_alloc();
+ _rv = t_recvfrom(sock, buffer + EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF - EOS_SOCK_SIZE_UDP_HDR, &addr);
+ if (_rv < 0) {
+ eos_net_free(buffer);
+ ESP_LOGE(TAG, "RECV ERR:%d", _rv);
+ }
+ _buf = buffer;
+ _buf[0] = EOS_SOCK_MTYPE_PKT;
+ _buf[1] = i + 1;
+ _buf += 2;
+ memcpy(_buf, addr.host, sizeof(addr.host));
+ _buf += sizeof(addr.host);
+ _buf[0] = addr.port >> 8;
+ _buf[1] = addr.port;
+ _buf += sizeof(addr.port);
+ rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, _rv + EOS_SOCK_SIZE_UDP_HDR);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
+ }
+ }
+ if (FD_ISSET(cmd_fd, &read_fds)) {
+ rv = read(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ switch (cmd[0]) {
+ case CMD_OPEN: {
+ sock = t_open_dgram();
+ sock_i = 0;
+ if (sock > 0) {
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ if (_socks[i] == 0) {
+ sock_i = i + 1;
+ _socks[i] = sock;
+ break;
+ }
+ }
+ if (sock_i) {
+ populate_fds(&all_fds, &max_fd);
+ }
+ }
+ memset(cmd, 0, sizeof(cmd));
+ cmd[1] = sock_i;
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ case CMD_CLOSE: {
+ sock_i = cmd[1] - 1;
+ sock = _socks[sock_i];
+ if (sock) {
+ t_close(sock);
+ _socks[sock_i] = 0;
+ populate_fds(&all_fds, &max_fd);
+ }
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ case CMD_SEND: {
+ sock_i = cmd[1] - 1;
+ buf_len = (uint16_t)cmd[2] << 8;
+ buf_len |= (uint16_t)cmd[3];
+ memcpy(&buffer, cmd + 4, sizeof(buffer));
+
+ sock = _socks[sock_i];
+ memcpy(addr.host, buffer, sizeof(addr.host));
+ buffer += sizeof(addr.host);
+ buf_len -= sizeof(addr.host);
+ addr.port = (uint16_t)buffer[0] << 8;
+ addr.port |= (uint16_t)buffer[1];
+ buffer += sizeof(addr.port);
+ buf_len -= sizeof(addr.port);
+ _rv = t_sendto(sock, buffer, buf_len, &addr);
+
+ memset(cmd, 0, sizeof(cmd));
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ case CMD_REOPEN: {
+ buffer = NULL;
+ buf_len = 0;
+
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ sock = _socks[i];
+ if (sock) {
+ t_close(sock);
+ _socks[i] = -1;
+ }
+ }
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ sock = _socks[i];
+ if (sock) {
+ sock = t_open_dgram();
+ if (sock > 0) {
+ _socks[i] = sock;
+ } else {
+ _socks[i] = 0;
+ if (buffer) {
+ buffer[buf_len] = i + 1;
+ buf_len++;
+ } else {
+ buffer = eos_net_alloc();
+ buffer[0] = EOS_SOCK_MTYPE_CLOSE;
+ buffer[1] = i + 1;
+ buf_len = 2;
+ }
+ }
+ }
+ }
+ if (buffer) {
+ rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
+ }
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ default:
+ ESP_LOGE(TAG, "BAD CMD:%d", cmd[0]);
+ break;
+ }
+
+ }
+ }
+
vTaskDelete(NULL);
}
static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) {
unsigned char mtype;
uint8_t sock_i;
- int sock, i;
+ uint8_t cmd[8];
+ int rv;
if (buf_len < 1) return;
+ memset(cmd, 0, sizeof(cmd));
+
mtype = buffer[0];
switch (mtype) {
case EOS_SOCK_MTYPE_PKT: {
- EOSNetAddr addr;
+ unsigned char *_buf = buffer;
if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return;
- sock_i = buffer[1]-1;
- if (sock_i >= EOS_SOCK_MAX_SOCK) return;
-
- sock = _socks[sock_i];
- buffer += 2;
- memcpy(addr.host, buffer, sizeof(addr.host));
- buffer += sizeof(addr.host);
- addr.port = (uint16_t)buffer[0] << 8;
- addr.port |= (uint16_t)buffer[1];
- buffer += sizeof(addr.port);
- t_sendto(sock, buffer, buf_len - EOS_SOCK_SIZE_UDP_HDR, &addr);
+ sock_i = buffer[1];
+ if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return;
+
+ _buf += 2;
+ cmd[0] = CMD_SEND;
+ cmd[1] = sock_i;
+ cmd[2] = buf_len >> 8;
+ cmd[3] = buf_len;
+ memcpy(cmd + 4, &_buf, sizeof(_buf));
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+
+ assert(cmd[0] == CMD_SEND);
break;
}
case EOS_SOCK_MTYPE_OPEN_DGRAM: {
- sock = t_open_dgram();
- sock_i = 0;
- if (sock > 0) {
- xSemaphoreTake(mutex, portMAX_DELAY);
- for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
- if (_socks[i] == 0) {
- sock_i = i+1;
- _socks[i] = sock;
- break;
- }
- }
- xSemaphoreGive(mutex);
- }
- if (sock_i) xTaskCreate(&udp_rcvr_task, "udp_rcvr", EOS_TASK_SSIZE_UDP_RCVR, (void *)sock_i, EOS_TASK_PRIORITY_UDP_RCVR, NULL);
+ cmd[0] = CMD_OPEN;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+
+ assert(cmd[0] == CMD_OPEN);
+ sock_i = cmd[1];
buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM;
buffer[1] = sock_i;
eos_net_reply(EOS_NET_MTYPE_SOCK, buffer, 2);
@@ -160,19 +333,72 @@ static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b
case EOS_SOCK_MTYPE_CLOSE: {
if (buf_len < 2) return;
- sock_i = buffer[1]-1;
- if (sock_i >= EOS_SOCK_MAX_SOCK) return;
+ sock_i = buffer[1];
+ if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return;
+
+ cmd[0] = CMD_CLOSE;
+ cmd[1] = sock_i;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
- sock = _socks[sock_i];
- t_close(sock);
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+
+ assert(cmd[0] == CMD_CLOSE);
break;
}
}
}
void eos_sock_init(void) {
+ esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
+ esp_err_t ret;
+
+ ret = esp_vfs_eventfd_register(&config);
+ assert(ret == ESP_OK);
+
+ cmd_fd = eventfd(0, 0);
+ assert(cmd_fd > 0);
+
+ rep_fd = eventfd(0, 0);
+ assert(rep_fd > 0);
+
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
+
eos_net_set_handler(EOS_NET_MTYPE_SOCK, sock_handler);
+
ESP_LOGI(TAG, "INIT");
}
+
+void eos_sock_run(void) {
+ BaseType_t rv;
+
+ rv = xTaskCreate(&udp_rcvr_task, "udp_rcvr", EOS_TASK_SSIZE_SOCK, NULL, EOS_TASK_PRIORITY_SOCK, NULL);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
+void eos_sock_reopen(void) {
+ uint8_t cmd[8];
+ int rv;
+
+ cmd[0] = CMD_REOPEN;
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+ assert(cmd[0] == CMD_REOPEN);
+}
diff --git a/fw/esp32/components/eos/tun.c b/fw/esp32/components/eos/tun.c
index a7181ee..f27fcfe 100644
--- a/fw/esp32/components/eos/tun.c
+++ b/fw/esp32/components/eos/tun.c
@@ -6,13 +6,14 @@
#include <lwip/tcpip.h>
#include <lwip/etharp.h>
+#include "net.h"
#include "app.h"
#include "tun.h"
static ip4_addr_t ipaddr, netmask, gw;
static struct netif netif_tun;
-static err_t ESP_IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) {
+static err_t IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) {
unsigned char *buf;
struct pbuf *q;
@@ -27,7 +28,7 @@ static err_t ESP_IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const
return ERR_OK;
}
-static void ESP_IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) {
+static void IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) {
struct netif *netif = &netif_tun;
struct pbuf *p;
int rv;
@@ -55,11 +56,15 @@ static err_t tun_init(struct netif *netif) {
}
void eos_tun_init(void) {
+ struct netif *rv;
+
IP4_ADDR(&gw, 0,0,0,0);
IP4_ADDR(&ipaddr, 192,168,10,2);
IP4_ADDR(&netmask, 255,255,255,0);
- netif_add(&netif_tun, &ipaddr, &netmask, &gw, NULL, tun_init, tcpip_input);
+ rv = netif_add(&netif_tun, &ipaddr, &netmask, &gw, NULL, tun_init, tcpip_input);
+ assert(rv != NULL);
+
netif_set_up(&netif_tun);
eos_app_set_handler(EOS_APP_MTYPE_TUN, tun_input);
-} \ No newline at end of file
+}
diff --git a/fw/esp32/components/eos/wifi.c b/fw/esp32/components/eos/wifi.c
index 2be169f..77f9143 100755
--- a/fw/esp32/components/eos/wifi.c
+++ b/fw/esp32/components/eos/wifi.c
@@ -10,7 +10,6 @@
#include <esp_log.h>
#include <esp_err.h>
#include <esp_wifi.h>
-#include <nvs_flash.h>
#include "eos.h"
#include "net.h"
@@ -53,8 +52,6 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e
ESP_LOGI(TAG, "Event disconnected - reason: %d", sta_disconnected->reason);
if (sta_disconnected->reason == WIFI_REASON_ASSOC_LEAVE) {
- stop = 0;
- reconnect_cnt = 0;
eos_wifi_send_status();
break;
}
@@ -113,25 +110,25 @@ static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b
mtype = buffer[0];
switch (mtype) {
case EOS_WIFI_MTYPE_STATUS: {
- int reply;
- ssize_t rv;
+ unsigned char *_buffer;
+ ssize_t _rv;
+ int reply, rv;
reply = _mtype & EOS_NET_MTYPE_FLAG_REPL;
if (reply) {
- rv = eos_wifi_get_status(buffer + 1);
- if (rv < 0) break;
+ _rv = eos_wifi_get_status(buffer + 1);
+ if (_rv < 0) break;
- eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, rv + 1);
+ eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, _rv + 1);
} else {
- unsigned char *buf;
-
- buf = eos_net_alloc();
- buf[0] = EOS_WIFI_MTYPE_STATUS;
- rv = eos_wifi_get_status(buf + 1);
- if (rv < 0) break;
+ _buffer = eos_net_alloc();
+ _buffer[0] = EOS_WIFI_MTYPE_STATUS;
+ _rv = eos_wifi_get_status(_buffer + 1);
+ if (_rv < 0) break;
- eos_net_send(EOS_NET_MTYPE_WIFI, buf, rv + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_WIFI, _buffer, _rv + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
break;
}
@@ -202,20 +199,14 @@ static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b
}
void eos_wifi_init(void) {
- esp_err_t ret;
wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();
+ esp_err_t ret;
wifi_netif = esp_netif_create_default_wifi_sta();
ret = esp_wifi_init(&wifi_config);
assert(ret == ESP_OK);
- ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL);
- assert(ret == ESP_OK);
-
- ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL);
- assert(ret == ESP_OK);
-
ret = esp_wifi_set_storage(WIFI_STORAGE_RAM);
assert(ret == ESP_OK);
@@ -226,9 +217,22 @@ void eos_wifi_init(void) {
assert(ret == ESP_OK);
eos_net_set_handler(EOS_NET_MTYPE_WIFI, wifi_handler);
+
ESP_LOGI(TAG, "INIT");
}
+void eos_wifi_run(void) {
+ esp_err_t ret;
+
+ ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL);
+ assert(ret == ESP_OK);
+
+ ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL);
+ assert(ret == ESP_OK);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
ssize_t eos_wifi_get_status(unsigned char *buffer) {
unsigned char *p;
wifi_ap_record_t ap_info;
@@ -293,26 +297,28 @@ ssize_t eos_wifi_get_status(unsigned char *buffer) {
void eos_wifi_send_status(void) {
unsigned char *rbuf;
- ssize_t rv;
+ ssize_t _rv;
+ int rv;
rbuf = eos_net_alloc();
rbuf[0] = EOS_WIFI_MTYPE_STATUS;
- rv = eos_wifi_get_status(rbuf + 1);
- if (rv < 0) {
+ _rv = eos_wifi_get_status(rbuf + 1);
+ if (_rv < 0) {
eos_net_free(rbuf);
return;
}
- eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, rv + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, _rv + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_wifi_send_scan(void) {
static wifi_ap_record_t scan_r[EOS_WIFI_MAX_SCAN_RECORDS];
static uint16_t scan_n;
- unsigned char *rbuf, *p;
- int i;
size_t len;
esp_err_t ret;
+ unsigned char *rbuf, *p;
+ int i, rv;
scan_n = EOS_WIFI_MAX_SCAN_RECORDS;
memset(scan_r, 0, sizeof(scan_r));
@@ -336,5 +342,7 @@ void eos_wifi_send_scan(void) {
strcpy((char *)p, (char *)scan_r[i].ssid);
p += len + 1;
}
- eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf);
+
+ rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
diff --git a/fw/esp32/main/component.mk b/fw/esp32/main/component.mk
deleted file mode 100644
index 61f8990..0000000
--- a/fw/esp32/main/component.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Main component makefile.
-#
-# This Makefile can be left empty. By default, it will take the sources in the
-# src/ directory, compile them and link them into lib(subdirectory_name).a
-# in the build directory. This behaviour is entirely configurable,
-# please read the ESP-IDF documents if you need to do this.
-#