summaryrefslogtreecommitdiff
path: root/fw/esp32/components/eos/cell_modem.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/esp32/components/eos/cell_modem.c')
-rw-r--r--fw/esp32/components/eos/cell_modem.c546
1 files changed, 347 insertions, 199 deletions
diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c
index 09d65d9..029abe1 100644
--- a/fw/esp32/components/eos/cell_modem.c
+++ b/fw/esp32/components/eos/cell_modem.c
@@ -29,8 +29,9 @@
#define UART_GPIO_DTR 32
#define UART_GPIO_RI 35
-#define MODEM_ETYPE_INIT 1
-#define MODEM_ETYPE_RI 2
+#define MODEM_ETYPE_ATINIT 1
+#define MODEM_ETYPE_STATUS 2
+#define MODEM_ETYPE_RING 3
#define AT_CMD_INIT_SIZE 5
@@ -47,7 +48,6 @@ static char *at_cmd_init[AT_CMD_INIT_SIZE] = {
"AT+CPMS=\"ME\",\"ME\",\"ME\"\r"
};
-static char modem_initialized = 0;
static SemaphoreHandle_t mutex;
static QueueHandle_t modem_queue;
@@ -58,16 +58,19 @@ static char uart_buf[EOS_CELL_UART_SIZE_BUF];
static size_t uart_buf_len;
static char uart_buf_dirty = 0;
-static uint8_t uart_mode = EOS_CELL_UART_MODE_ATCMD;
-static uint8_t _uart_mode = EOS_CELL_UART_MODE_UNDEF;
+static uint8_t RTC_NOINIT_ATTR modem_initialized;
+static uint8_t RTC_NOINIT_ATTR uart_mode;
+static uint8_t uart_mode_next = EOS_CELL_UART_MODE_NONE;
static SemaphoreHandle_t uart_mutex;
-static char ppp_apn[64];
-static char ppp_user[64];
-static char ppp_pass[64];
+static char ppp_apn[EOS_CELL_PDP_SIZE_APN];
+static char ppp_usr[EOS_CELL_PDP_SIZE_USR];
+static char ppp_pwd[EOS_CELL_PDP_SIZE_PWD];
static SemaphoreHandle_t ppp_mutex;
static ppp_pcb *ppp_handle;
+static int ppp_connected;
+static ip_addr_t ppp_ipaddr;
static struct netif ppp_netif;
typedef enum {
@@ -76,22 +79,57 @@ typedef enum {
typedef struct {
uint8_t type;
+ unsigned char param[2];
+ size_t param_len;
} modem_event_t;
-static void modem_atcmd_read(size_t bsize);
+static void modem_send_status(void);
+
+static void atcmd_read(size_t bsize) {
+ char *ln_end;
+ int rd = 0;
+
+ do {
+ 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);
+
+ rd += _rd;
+ uart_buf_len += _rd;
+ uart_buf[uart_buf_len] = '\0';
+ while ((ln_end = strchr(uart_curr, '\n'))) {
+ char *_ln_end = ln_end;
+
+ while ((_ln_end > uart_buf) && (*(_ln_end - 1) == '\r')) _ln_end--;
+ memcpy(urc_buf, uart_buf, _ln_end - uart_buf);
+ urc_buf[_ln_end - uart_buf] = '\0';
+
+ uart_buf_len -= ln_end - uart_buf + 1;
+ if (uart_buf_len) memmove(uart_buf, ln_end + 1, uart_buf_len);
+ if (!uart_buf_dirty) at_urc_process(urc_buf);
+
+ uart_curr = uart_buf;
+ uart_buf[uart_buf_len] = '\0';
+ uart_buf_dirty = 0;
+ }
+ if (uart_buf_len == sizeof(uart_buf) - 1) {
+ uart_buf_len = 0;
+ uart_buf_dirty = 1;
+ }
+ } while (rd != bsize);
+}
static void uart_data_read(uint8_t mode) {
- unsigned char *buf;
int rd;
size_t bsize;
uart_get_buffered_data_len(UART_NUM_2, &bsize);
switch (mode) {
- case EOS_CELL_UART_MODE_ATCMD:
- modem_atcmd_read(bsize);
+ case EOS_CELL_UART_MODE_ATCMD: {
+ atcmd_read(bsize);
break;
+ }
- case EOS_CELL_UART_MODE_PPP:
+ case EOS_CELL_UART_MODE_PPP: {
rd = 0;
do {
@@ -100,8 +138,10 @@ static void uart_data_read(uint8_t mode) {
rd += _rd;
} while (rd != bsize);
break;
+ }
- case EOS_CELL_UART_MODE_RELAY:
+ case EOS_CELL_UART_MODE_RELAY: {
+ unsigned char *buf;
rd = 0;
do {
@@ -114,25 +154,45 @@ static void uart_data_read(uint8_t mode) {
rd += _rd;
} while (rd != bsize);
break;
-
- default:
- break;
-
+ }
}
}
static void uart_event_task(void *pvParameters) {
- char mode = EOS_CELL_UART_MODE_ATCMD;
- char _mode = EOS_CELL_UART_MODE_ATCMD;
+ char mode;
+ char _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) {
+ _mode = EOS_CELL_UART_MODE_NONE;
+ ESP_LOGE(TAG, "Modem init failed");
+ }
+ }
+ }
+
+ if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex);
+ mode = _mode;
+ xSemaphoreGive(mutex);
+
while (1) {
/* Waiting for UART event.
*/
if (xQueueReceive(uart_queue, &event, portMAX_DELAY)) {
switch (event.type) {
- case UART_DATA:
+ case UART_DATA: {
/* Event of UART receiving data
*/
if (mode != EOS_CELL_UART_MODE_NONE) uart_data_read(mode);
@@ -141,8 +201,9 @@ static void uart_event_task(void *pvParameters) {
mode = _mode;
}
break;
+ }
- case UART_EEVT_MODE:
+ case UART_EEVT_MODE: {
/* Mode change
*/
_mode = (char)event.size;
@@ -155,6 +216,7 @@ static void uart_event_task(void *pvParameters) {
mode = _mode;
}
break;
+ }
default:
break;
@@ -164,14 +226,7 @@ static void uart_event_task(void *pvParameters) {
vTaskDelete(NULL);
}
-static void IRAM_ATTR uart_ri_isr_handler(void *arg) {
- modem_event_t evt;
-
- evt.type = MODEM_ETYPE_RI;
- xQueueSendFromISR(modem_queue, &evt, NULL);
-}
-
-static void modem_set_mode(uint8_t mode) {
+static void uart_change_mode(uint8_t mode) {
uart_event_t evt;
evt.type = UART_EEVT_MODE;
@@ -179,110 +234,97 @@ static void modem_set_mode(uint8_t mode) {
xQueueSend(uart_queue, &evt, portMAX_DELAY);
}
-static int modem_atcmd_init(void) {
- unsigned char *buf;
- int echo_on = 0;
- int tries = 3;
- int i, r;
+static void IRAM_ATTR uart_ring_handler(void *arg) {
+ modem_event_t evt;
- xSemaphoreTake(mutex, portMAX_DELAY);
- modem_set_mode(EOS_CELL_UART_MODE_NONE);
- r = xSemaphoreTake(uart_mutex, 1000);
- if (r == pdFALSE) {
- modem_set_mode(uart_mode);
- xSemaphoreGive(mutex);
- return EOS_ERR_TIMEOUT;
- }
+ evt.type = MODEM_ETYPE_RING;
+ xQueueSendFromISR(modem_queue, &evt, NULL);
+}
- do {
- at_cmd("AT\r");
- r = at_expect("^AT", "^OK", 1000);
- if (r >= 0) {
- echo_on = r;
- if (echo_on) {
- r = at_expect("^OK", NULL, 1000);
- }
- break;
- }
- tries--;
- } while (tries);
+static void modem_init_gpio(void) {
+ // Configuration for the DTR/RI lines
+ gpio_config_t io_conf = {};
- if (tries == 0) {
- modem_set_mode(uart_mode);
- xSemaphoreGive(uart_mutex);
- xSemaphoreGive(mutex);
+ 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);
- return EOS_ERR_TIMEOUT;
- }
+ 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);
+}
- if (echo_on) {
- at_cmd("AT&F\r");
- r = at_expect("^AT&F", NULL, 1000);
- r = at_expect("^OK", NULL, 1000);
- } else {
- at_cmd("AT&F\r");
- r = at_expect("^OK", NULL, 1000);
- }
- at_cmd("ATE0\r");
- r = at_expect("^ATE0", NULL, 1000);
- r = at_expect("^OK", "^ERROR", 1000);
+static size_t modem_get_status(unsigned char *buffer) {
+ size_t len;
- for (i=0; i<AT_CMD_INIT_SIZE; i++) {
- at_cmd(at_cmd_init[i]);
- r = at_expect("^OK", "^ERROR", 1000);
- }
+ len = 1;
+ if (modem_initialized) {
+ switch (uart_mode) {
+ case EOS_CELL_UART_MODE_ATCMD: {
+ buffer[0] = EOS_CELL_STATUS_IDLE;
+ break;
+ }
- buf = eos_net_alloc();
- buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_READY;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, 1);
+ case EOS_CELL_UART_MODE_RELAY: {
+ buffer[0] = EOS_CELL_STATUS_RELAY;
+ break;
+ }
- modem_initialized = 1;
- modem_set_mode(uart_mode);
- xSemaphoreGive(uart_mutex);
- xSemaphoreGive(mutex);
+ case EOS_CELL_UART_MODE_PPP: {
+ buffer[0] = EOS_CELL_STATUS_PPP;
+ buffer[1] = ppp_connected;
+ len = 2;
+ break;
+ }
+ }
+ } else {
+ buffer[0] = EOS_CELL_STATUS_RESET;
+ }
- return EOS_OK;
+ return len;
}
+static void modem_send_status(void) {
+ modem_event_t evt;
-static void modem_atcmd_read(size_t bsize) {
- char *ln_end;
- int rd = 0;
-
- do {
- 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);
+ evt.type = MODEM_ETYPE_STATUS;
+ evt.param_len = modem_get_status(evt.param);
+ xQueueSend(modem_queue, &evt, portMAX_DELAY);
+}
- rd += _rd;
- uart_buf_len += _rd;
- uart_buf[uart_buf_len] = '\0';
- while ((ln_end = strchr(uart_curr, '\n'))) {
- char *_ln_end = ln_end;
+static void modem_atinit_handler(char *urc, regmatch_t m[]) {
+ modem_event_t evt;
- while ((_ln_end > uart_buf) && (*(_ln_end - 1) == '\r')) _ln_end--;
- memcpy(urc_buf, uart_buf, _ln_end - uart_buf);
- urc_buf[_ln_end - uart_buf] = '\0';
+ evt.type = MODEM_ETYPE_ATINIT;
+ xQueueSend(modem_queue, &evt, portMAX_DELAY);
+}
- uart_buf_len -= ln_end - uart_buf + 1;
- if (uart_buf_len) memmove(uart_buf, ln_end + 1, uart_buf_len);
- if (!uart_buf_dirty) at_urc_process(urc_buf);
+static int modem_atinit(void) {
+ int r;
- uart_curr = uart_buf;
- uart_buf[uart_buf_len] = '\0';
- uart_buf_dirty = 0;
- }
- if (uart_buf_len == sizeof(uart_buf) - 1) {
- uart_buf_len = 0;
- uart_buf_dirty = 1;
- }
- } while (rd != bsize);
-}
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ uart_change_mode(EOS_CELL_UART_MODE_NONE);
+ r = xSemaphoreTake(uart_mutex, 1000);
+ if (r == pdFALSE) {
+ uart_change_mode(uart_mode);
+ xSemaphoreGive(mutex);
+ return EOS_ERR_TIMEOUT;
+ }
-static void modem_urc_init_handler(char *urc, regmatch_t m[]) {
- modem_event_t evt;
+ r = eos_modem_atinit();
+ uart_change_mode(uart_mode);
+ xSemaphoreGive(uart_mutex);
+ xSemaphoreGive(mutex);
- evt.type = MODEM_ETYPE_INIT;
- xQueueSend(modem_queue, &evt, portMAX_DELAY);
+ return r;
}
static void modem_event_task(void *pvParameters) {
@@ -291,16 +333,28 @@ static void modem_event_task(void *pvParameters) {
while (1) {
if (xQueueReceive(modem_queue, &evt, portMAX_DELAY)) {
switch (evt.type) {
- case MODEM_ETYPE_INIT:
- modem_atcmd_init();
+ case MODEM_ETYPE_ATINIT: {
+ int r;
+
+ r = modem_atinit();
+ if (r) ESP_LOGE(TAG, "Modem init failed");
break;
+ }
- case MODEM_ETYPE_RI:
- ESP_LOGI(TAG, "URC from RI");
+ case MODEM_ETYPE_STATUS: {
+ unsigned char *buf;
+
+ 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);
break;
+ }
- default:
+ case MODEM_ETYPE_RING: {
+ ESP_LOGI(TAG, "URC from RI");
break;
+ }
}
/* Obsolete
uint64_t t_start = esp_timer_get_time();
@@ -350,21 +404,23 @@ 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) {
- unsigned char *rbuf;
struct netif *pppif = ppp_netif(pcb);
LWIP_UNUSED_ARG(ctx);
- switch(err_code) {
+ 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));
- rbuf = eos_net_alloc();
- rbuf[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_CONNECT;
- rbuf[1] = EOS_OK;
- eos_net_send(EOS_NET_MTYPE_CELL, rbuf, 2);
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ ppp_connected = 1;
+ ip_addr_copy(ppp_ipaddr, pppif->ip_addr);
+ modem_send_status();
+ xSemaphoreGive(mutex);
+
return;
}
case PPPERR_PARAM: {
@@ -422,16 +478,20 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
}
xSemaphoreTake(mutex, portMAX_DELAY);
-
- if (_uart_mode == EOS_CELL_UART_MODE_UNDEF) _uart_mode = EOS_CELL_UART_MODE_ATCMD;
- uart_mode = _uart_mode;
- _uart_mode = EOS_CELL_UART_MODE_UNDEF;
-
- modem_set_mode(EOS_CELL_UART_MODE_NONE);
+ 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;
- modem_set_mode(uart_mode);
+ uart_change_mode(uart_mode);
xSemaphoreGive(uart_mutex);
xSemaphoreGive(mutex);
@@ -450,7 +510,7 @@ static int ppp_pause(uint32_t timeout) {
uint64_t t_start;
uint32_t dt, _dt;
- modem_set_mode(EOS_CELL_UART_MODE_NONE);
+ uart_change_mode(EOS_CELL_UART_MODE_NONE);
t_start = esp_timer_get_time();
r = xSemaphoreTake(uart_mutex, timeout ? timeout / portTICK_PERIOD_MS : portMAX_DELAY);
@@ -458,14 +518,14 @@ static int ppp_pause(uint32_t timeout) {
if (timeout) {
dt = ((esp_timer_get_time() - t_start) / 1000);
if (dt >= timeout) {
- modem_set_mode(EOS_CELL_UART_MODE_PPP);
+ uart_change_mode(EOS_CELL_UART_MODE_PPP);
xSemaphoreGive(uart_mutex);
return EOS_ERR_TIMEOUT;
}
}
r = xSemaphoreTake(ppp_mutex, timeout ? (timeout - dt) / portTICK_PERIOD_MS : portMAX_DELAY);
if (r == pdFALSE) {
- modem_set_mode(EOS_CELL_UART_MODE_PPP);
+ uart_change_mode(EOS_CELL_UART_MODE_PPP);
xSemaphoreGive(uart_mutex);
return EOS_ERR_TIMEOUT;
}
@@ -500,7 +560,7 @@ static int ppp_pause(uint32_t timeout) {
uart_buf_len = sizeof(uart_buf) / 2;
}
if (!done && timeout && (dt >= timeout)) {
- modem_set_mode(EOS_CELL_UART_MODE_PPP);
+ uart_change_mode(EOS_CELL_UART_MODE_PPP);
xSemaphoreGive(uart_mutex);
xSemaphoreGive(ppp_mutex);
return EOS_ERR_TIMEOUT;
@@ -516,9 +576,9 @@ static int ppp_resume(void) {
at_cmd("ATO\r");
r = at_expect("^CONNECT", "^(ERROR|NO CARRIER)", 1000);
- if (r <= 0) rv = EOS_ERR;
+ if (r) rv = EOS_ERR;
- modem_set_mode(EOS_CELL_UART_MODE_PPP);
+ uart_change_mode(EOS_CELL_UART_MODE_PPP);
xSemaphoreGive(uart_mutex);
xSemaphoreGive(ppp_mutex);
@@ -533,25 +593,25 @@ static int ppp_setup(void) {
cmd_len = snprintf(cmd, sizeof(cmd), "AT+CGDCONT=1,\"IP\",\"%s\"\r", ppp_apn);
if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return EOS_ERR;
- modem_set_mode(EOS_CELL_UART_MODE_NONE);
+ uart_change_mode(EOS_CELL_UART_MODE_NONE);
r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
if (r == pdFALSE) {
- modem_set_mode(uart_mode);
+ uart_change_mode(uart_mode);
return EOS_ERR_TIMEOUT;
}
at_cmd(cmd);
r = at_expect("^OK", "^ERROR", 1000);
- if (r <= 0) {
- modem_set_mode(uart_mode);
+ if (r) {
+ uart_change_mode(uart_mode);
xSemaphoreGive(uart_mutex);
return EOS_ERR;
}
at_cmd("AT+CGDATA=\"PPP\",1\r");
r = at_expect("^CONNECT", "^NO CARRIER", 1000);
- if (r <= 0) {
- modem_set_mode(uart_mode);
+ if (r) {
+ uart_change_mode(uart_mode);
xSemaphoreGive(uart_mutex);
return EOS_ERR;
}
@@ -559,18 +619,16 @@ static int ppp_setup(void) {
ppp_handle = pppapi_pppos_create(&ppp_netif, ppp_output_cb, ppp_status_cb, NULL);
ppp_set_usepeerdns(ppp_handle, 1);
ppp_set_default(ppp_handle);
- ppp_set_auth(ppp_handle, PPPAUTHTYPE_ANY, ppp_user, ppp_pass);
+ ppp_set_auth(ppp_handle, PPPAUTHTYPE_ANY, ppp_usr, ppp_pwd);
ppp_connect(ppp_handle, 0);
- modem_set_mode(EOS_CELL_UART_MODE_PPP);
+ uart_change_mode(EOS_CELL_UART_MODE_PPP);
xSemaphoreGive(uart_mutex);
return EOS_OK;
}
void eos_modem_init(void) {
- /* Configure parameters of an UART driver,
- * communication pins and install the driver */
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
@@ -582,23 +640,11 @@ void eos_modem_init(void) {
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);
- // 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);
+ if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) {
+ uart_mode = EOS_CELL_UART_MODE_ATCMD;
+ modem_initialized = 0;
+ modem_init_gpio();
+ }
mutex = xSemaphoreCreateBinary();
xSemaphoreGive(mutex);
@@ -613,16 +659,59 @@ void eos_modem_init(void) {
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);
- gpio_isr_handler_add(UART_GPIO_RI, uart_ri_isr_handler, NULL);
-
at_init();
- at_urc_insert("^PB DONE", modem_urc_init_handler, REG_EXTENDED);
- eos_modem_set_mode(EOS_CELL_UART_MODE_ATCMD);
+ at_urc_insert("^PB DONE", modem_atinit_handler, REG_EXTENDED);
+ at_urc_insert("^\\+CME ERROR: SIM not inserted", modem_atinit_handler, REG_EXTENDED);
+
+ ESP_LOGI(TAG, "INIT");
+}
+
+int eos_modem_atinit(void) {
+ int echo_on = 0;
+ int tries = 3;
+ int i, r;
+
+ do {
+ at_cmd("AT\r");
+ r = at_expect("^AT", "^OK", 1000);
+ if (r >= 0) {
+ echo_on = !r;
+ if (echo_on) {
+ r = at_expect("^OK", NULL, 1000);
+ }
+ break;
+ }
+ tries--;
+ } while (tries);
+
+ if (tries == 0) return EOS_ERR_TIMEOUT;
+
+ if (echo_on) {
+ at_cmd("AT&F\r");
+ r = at_expect("^AT&F", NULL, 1000);
+ r = at_expect("^OK", NULL, 1000);
+ } else {
+ at_cmd("AT&F\r");
+ r = at_expect("^OK", NULL, 1000);
+ }
+ at_cmd("ATE0\r");
+ r = at_expect("^ATE0", NULL, 1000);
+ r = at_expect("^OK", "^ERROR", 1000);
+
+ for (i=0; i<AT_CMD_INIT_SIZE; i++) {
+ at_cmd(at_cmd_init[i]);
+ r = at_expect("^OK", "^ERROR", 1000);
+ }
+
+ modem_initialized = 1;
eos_cell_voice_init();
eos_cell_sms_init();
eos_cell_ussd_init();
- ESP_LOGI(TAG, "INIT");
+
+ modem_send_status();
+
+ return EOS_OK;
}
void eos_modem_flush(void){
@@ -688,27 +777,45 @@ uint8_t eos_modem_get_mode(void) {
uint8_t ret;
xSemaphoreTake(mutex, portMAX_DELAY);
- ret = uart_mode;
+ if (modem_initialized) {
+ ret = uart_mode;
+ } else {
+ ret = EOS_CELL_UART_MODE_NONE;
+ }
xSemaphoreGive(mutex);
return ret;
}
+size_t eos_modem_get_status(unsigned char *buffer) {
+ size_t len;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ len = modem_get_status(buffer);
+ xSemaphoreGive(mutex);
+
+ return len;
+}
+
int eos_modem_set_mode(uint8_t mode) {
int rv = EOS_OK;
xSemaphoreTake(mutex, portMAX_DELAY);
- if (mode != uart_mode) {
+ if (!modem_initialized) rv = EOS_ERR_BUSY;
+ if (!rv && (mode != uart_mode)) {
if ((uart_mode == EOS_CELL_UART_MODE_PPP) && ppp_handle) {
- _uart_mode = mode;
+ uart_mode_next = mode;
pppapi_close(ppp_handle, 0);
} else {
if (mode == EOS_CELL_UART_MODE_PPP) {
rv = ppp_setup();
} else {
- modem_set_mode(mode);
+ uart_change_mode(mode);
+ }
+ if (!rv) {
+ uart_mode = mode;
+ modem_send_status();
}
- if (!rv) uart_mode = mode;
}
}
xSemaphoreGive(mutex);
@@ -727,10 +834,10 @@ int eos_modem_take(uint32_t timeout) {
} else {
int r;
- modem_set_mode(EOS_CELL_UART_MODE_NONE);
+ uart_change_mode(EOS_CELL_UART_MODE_NONE);
r = xSemaphoreTake(uart_mutex, timeout ? timeout / portTICK_PERIOD_MS : portMAX_DELAY);
if (r == pdFALSE) {
- modem_set_mode(uart_mode);
+ uart_change_mode(uart_mode);
rv = EOS_ERR_TIMEOUT;
}
}
@@ -745,45 +852,55 @@ void eos_modem_give(void) {
int rv = ppp_resume();
if (rv) ESP_LOGW(TAG, "PPP resume failed");
} else {
- modem_set_mode(uart_mode);
+ uart_change_mode(uart_mode);
xSemaphoreGive(uart_mutex);
}
xSemaphoreGive(mutex);
}
-void eos_modem_sleep(uint8_t mode) {
+void eos_modem_sleep(void) {
int r;
xSemaphoreTake(mutex, portMAX_DELAY);
- modem_set_mode(EOS_CELL_UART_MODE_NONE);
+ 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);
- if (mode == EOS_PWR_SMODE_DEEP) {
- gpio_hold_en(UART_GPIO_DTR);
- }
+}
+
+void eos_modem_deep_sleep(void) {
+ gpio_hold_en(UART_GPIO_DTR);
}
void eos_modem_wake(uint8_t source, uint8_t mode) {
if (source == EOS_PWR_WAKE_UART) {
modem_event_t evt;
- evt.type = MODEM_ETYPE_RI;
+ evt.type = MODEM_ETYPE_RING;
xQueueSend(modem_queue, &evt, portMAX_DELAY);
}
- if (mode != EOS_PWR_SMODE_DEEP) {
- gpio_set_intr_type(UART_GPIO_RI, GPIO_INTR_NEGEDGE);
- gpio_isr_handler_add(UART_GPIO_RI, uart_ri_isr_handler, NULL);
- gpio_set_level(UART_GPIO_DTR, 0);
+ 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);
- modem_set_mode(uart_mode);
- xSemaphoreGive(uart_mutex);
- xSemaphoreGive(mutex);
- } else {
- gpio_hold_dis(UART_GPIO_DTR);
+ uart_change_mode(uart_mode);
+ xSemaphoreGive(uart_mutex);
+ xSemaphoreGive(mutex);
+
+ break;
+ }
+
+ case EOS_PWR_SMODE_DEEP: {
+ gpio_hold_dis(UART_GPIO_DTR);
+ modem_init_gpio();
+
+ break;
+ }
}
}
@@ -795,23 +912,54 @@ int eos_modem_reset(void) {
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;
- eos_modem_give();
+ modem_send_status();
+ xSemaphoreGive(mutex);
return EOS_OK;
}
+void eos_ppp_get_apn(char *apn) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ strcpy(apn, ppp_apn);
+ xSemaphoreGive(mutex);
+}
+
void eos_ppp_set_apn(char *apn) {
xSemaphoreTake(mutex, portMAX_DELAY);
strncpy(ppp_apn, apn, sizeof(ppp_apn) - 1);
+ ppp_apn[sizeof(ppp_apn) - 1] = '\0';
+ xSemaphoreGive(mutex);
+}
+
+void eos_ppp_get_usr(char *usr) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ strcpy(usr, ppp_usr);
+ xSemaphoreGive(mutex);
+}
+
+void eos_ppp_set_usr(char *usr) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ strncpy(ppp_usr, usr, sizeof(ppp_usr) - 1);
+ ppp_usr[sizeof(ppp_usr) - 1] = '\0';
+ xSemaphoreGive(mutex);
+}
+
+void eos_ppp_get_pwd(char *pwd) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ strcpy(pwd, ppp_pwd);
xSemaphoreGive(mutex);
}
-void eos_ppp_set_auth(char *user, char *pass) {
+void eos_ppp_set_pwd(char *pwd) {
xSemaphoreTake(mutex, portMAX_DELAY);
- strncpy(ppp_user, user, sizeof(ppp_user) - 1);
- strncpy(ppp_pass, pass, sizeof(ppp_pass) - 1);
+ strncpy(ppp_pwd, pwd, sizeof(ppp_pwd) - 1);
+ ppp_pwd[sizeof(ppp_pwd) - 1] = '\0';
xSemaphoreGive(mutex);
}