diff options
Diffstat (limited to 'fw')
166 files changed, 5732 insertions, 4384 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..8750f85 --- /dev/null +++ b/fw/esp32/components/eos/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "app_main.c" "msgq.c" "unicode.c" "power.c" "net.c" "app.c" "rng.c" "wifi.c" "sock.c" "tun.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" + 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..ab04c2c 100644 --- a/fw/esp32/components/eos/app.c +++ b/fw/esp32/components/eos/app.c @@ -15,209 +15,168 @@ #include "eos.h" #include "msgq.h" +#include "power.h" +#include "net.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_RTS 47 +#define SPI_GPIO_CTS 9 +#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_HDR 3 +#define SPI_HOST SPI2_HOST + +#define APP_SIZE_BUFQ 16 +#define APP_SIZE_SNDQ 16 static EOSBufQ app_buf_q; -static unsigned char *app_bufq_array[EOS_APP_SIZE_BUFQ]; +static unsigned char *app_bufq_array[APP_SIZE_BUFQ]; static EOSMsgQ app_send_q; -static EOSMsgItem app_sndq_array[EOS_APP_SIZE_SNDQ]; +static EOSMsgItem app_sndq_array[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 eos_app_fptr_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 void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { - ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len); -} +static const char *TAG = "EOS APP"; -// 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 bad_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { + ESP_LOGE(TAG, "BAD HANDLER: 0x%.2X LEN: %d", mtype, len); } -// 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 IRAM_ATTR app_bridge(unsigned char mtype, EOSMessage *msg, uint16_t len) { + EOSMessage _msg; + int rv; + + eos_net_alloc(&_msg); + if (len > _msg.size) { + eos_net_free(&_msg); + return; + } + memcpy(_msg.buffer, msg->buffer, len); + rv = eos_net_send(mtype & EOS_NET_MTYPE_MASK, &_msg, len); + if (rv) ESP_LOGE(TAG, "BRIDGE ERR: %d", rv); } -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); - } +static void IRAM_ATTR app_msg_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { + uint8_t idx; + + idx = mtype & EOS_NET_MTYPE_FLAG_BRIDGE ? EOS_NET_MTYPE_BRIDGE : mtype & EOS_NET_MTYPE_MASK; + if ((idx < EOS_APP_MAX_MTYPE) && (len <= msg->size)) { + app_handler[idx](mtype, msg, len); + } else { + bad_handler(mtype, msg, 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)); + eos_msgq_init(&app_send_q, app_sndq_array, APP_SIZE_SNDQ); + eos_bufq_init(&app_buf_q, app_bufq_array, APP_SIZE_BUFQ); + for (i=0; i<APP_SIZE_BUFQ; i++) { + unsigned char *buffer; + + buffer = malloc(EOS_NET_MTU); + 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(APP_SIZE_BUFQ, 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 = esp_reset_reason() == ESP_RST_DEEPSLEEP ? 1 : 0; + app_config.sleep_req = 0; + app_config.present = 1; + app_config.dev = NET_DEV_APP; + 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.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.handler = app_msg_handler; + + /* Configuration for the SPI bus */ + app_spi_bus_cfg.mosi_io_num = SPI_GPIO_MOSI; + app_spi_bus_cfg.miso_io_num = SPI_GPIO_MISO; + app_spi_bus_cfg.sclk_io_num = SPI_GPIO_SCLK; + app_spi_bus_cfg.intr_flags = ESP_INTR_FLAG_IRAM; + + /* Configuration for the SPI slave interface */ + app_spi_iface_cfg.mode = 0; + app_spi_iface_cfg.spics_io_num = SPI_GPIO_CS; + app_spi_iface_cfg.queue_size = 2; + app_spi_iface_cfg.flags = 0; + + _eos_net_init_gpio(&app_config); + eos_app_set_handler(EOS_NET_MTYPE_BRIDGE, app_bridge); + 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); +void eos_app_alloc(EOSMessage *msg) { + _eos_net_alloc(&app_config, msg); } -int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t len) { - int rv = EOS_OK; +void eos_app_free(EOSMessage *msg) { + _eos_net_free(&app_config, msg); +} - 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, EOSMessage *msg, uint16_t len) { + return _eos_net_send(&app_config, mtype, msg, len); +} - if (rv) eos_app_free(buffer); +void eos_app_sleep_req(void) { + _eos_net_sleep_req(&app_config); +} + +void eos_app_wake(void) { + _eos_net_wake(&app_config); +} + +void eos_app_deep_sleep(void) { + _eos_net_deep_sleep(&app_config); +} - return rv; +void eos_app_deep_wake(void) { + _eos_net_deep_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; + if (mtype < EOS_APP_MAX_MTYPE) app_handler[mtype] = handler; } diff --git a/fw/esp32/main/app_main.c b/fw/esp32/components/eos/app_main.c index 79f76ab..885f9c8 100644 --- a/fw/esp32/main/app_main.c +++ b/fw/esp32/components/eos/app_main.c @@ -2,26 +2,25 @@ #include <freertos/task.h> #include <driver/gpio.h> +#include <esp_system.h> + #include <esp_event.h> #include <esp_netif.h> #include <esp_err.h> #include <esp_log.h> -#include "i2c.h" -#include "cell.h" -#include "_net.h" +#include "power.h" +#include "net.h" +#include "app.h" +#include "rng.h" #include "wifi.h" #include "sock.h" -#include "rng.h" -#ifdef EOS_WITH_APP -#include "app.h" #include "tun.h" -#endif -#include "power.h" +#include "cell.h" #define ESP_INTR_FLAG_DEFAULT 0 -// Main application +/* main application */ void app_main() { esp_err_t ret; @@ -31,21 +30,31 @@ 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); + /* first one */ + 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_net_run(); + eos_app_run(); + eos_modem_run(); + eos_cell_run(); + eos_wifi_run(); + eos_sock_run(); + + /* last one */ + eos_power_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..7dc4a32 100644 --- a/fw/esp32/components/eos/cell.c +++ b/fw/esp32/components/eos/cell.c @@ -17,55 +17,70 @@ 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]; static SemaphoreHandle_t mutex; static QueueHandle_t cell_queue; -static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { - uint8_t mtype; +static void _cell_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; + int rv; - if (buf_len < 1) return; + if (len < 1) return; mtype = buffer[0]; switch (mtype & EOS_CELL_MTYPE_MASK) { case EOS_CELL_MTYPE_DEV: { switch (mtype & ~EOS_CELL_MTYPE_MASK) { case EOS_CELL_MTYPE_STATUS: { - size_t rv; + size_t _rv; + + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; + if (msg->size < 3) break; - rv = eos_modem_get_status(buffer + 1); - eos_net_reply(EOS_NET_MTYPE_CELL, buffer, rv + 1); + _rv = eos_modem_get_status(buffer + 1); + eos_net_reply(EOS_NET_MTYPE_CELL, msg, _rv + 1); break; } case EOS_CELL_MTYPE_RESET: { + 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; - - 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); + 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, len - 1); + } break; } } @@ -73,33 +88,35 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t } case EOS_CELL_MTYPE_VOICE: { - eos_cell_voice_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_voice_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_SMS: { - eos_cell_sms_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_sms_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_USSD: { - eos_cell_ussd_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_ussd_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_PDP: { - eos_cell_pdp_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_pdp_handler(_mtype, msg, len); break; } } } static void cell_handler_task(void *pvParameters) { + EOSMessage msg; EOSMsgItem mi; while (1) { if (xQueueReceive(cell_queue, &mi, portMAX_DELAY)) { - _cell_handler(mi.type, mi.buffer, mi.len); + eos_msg_init(&msg, mi.buffer, mi.size); + _cell_handler(mi.type, &msg, mi.len); xSemaphoreTake(mutex, portMAX_DELAY); eos_bufq_push(&cell_buf_q, mi.buffer); xSemaphoreGive(mutex); @@ -108,22 +125,31 @@ 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, EOSMessage *msg, uint16_t len) { EOSMsgItem mi; - unsigned char *buf; + unsigned char *buffer; + + if (len < 1) return; + if (len > EOS_CELL_MTU) return; + + if (eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ) { + _cell_handler(type, msg, 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", msg->buffer[0]); return; } - memcpy(buf, buffer, len); mi.type = type; - mi.buffer = buf; + mi.buffer = buffer; + mi.size = EOS_CELL_MTU; + memcpy(mi.buffer, msg->buffer, len); mi.len = len; xQueueSend(cell_queue, &mi, portMAX_DELAY); } @@ -133,13 +159,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_CELL_MTU); + 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..9a024ae 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); @@ -142,16 +152,22 @@ static void uart_data_read(uint8_t mode) { } case EOS_CELL_UART_MODE_RELAY: { - unsigned char *buf; - rd = 0; + EOSMessage msg; + 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); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + break; + } + msg.buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; + _rd = eos_modem_read(msg.buffer + 1, MIN(bsize - rd, msg.size - 1), 100); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, _rd + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); rd += _rd; } while (rd != bsize); break; @@ -160,36 +176,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 +198,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 +246,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 +291,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 +306,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 +322,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"); @@ -349,12 +334,19 @@ static void modem_event_task(void *pvParameters) { } case MODEM_ETYPE_STATUS: { - unsigned char *buf; + EOSMessage msg; + 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); + eos_net_alloc(&msg); + if (msg.size < 3) { + eos_net_free(&msg); + break; + } + + msg.buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; + memcpy(msg.buffer + 1, evt.param, evt.param_len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, evt.param_len + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); break; } @@ -365,7 +357,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 +391,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 +404,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 +478,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 +608,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) { @@ -635,7 +642,21 @@ static int ppp_setup(void) { return EOS_OK; } +static void modem_init_ri(void) { + gpio_config_t io_conf = { + .pin_bit_mask = BIT64(UART_GPIO_RI), + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_NEGEDGE, + .pull_up_en = 1, + .pull_down_en = 0, + }; + + gpio_config(&io_conf); + gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); +} + 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 +664,89 @@ 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; - modem_present = 0; - modem_initialized = 0; - modem_init_gpio(); - } + 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); mutex = xSemaphoreCreateBinary(); - xSemaphoreGive(mutex); + assert(mutex != NULL); + if (esp_reset_reason() != ESP_RST_DEEPSLEEP) { + xSemaphoreGive(mutex); + } uart_mutex = xSemaphoreCreateBinary(); - xSemaphoreGive(uart_mutex); + assert(uart_mutex != NULL); + if (esp_reset_reason() != ESP_RST_DEEPSLEEP) { + 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); + + // 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, esp_reset_reason() == ESP_RST_DEEPSLEEP ? 1 : 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); + + if (esp_reset_reason() != ESP_RST_DEEPSLEEP) { + modem_init_ri(); + } 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; + + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + eos_modem_deep_wake(); + } else { + uart_mode = EOS_CELL_UART_MODE_NONE; + modem_present = 0; + modem_initialized = 0; + } + + 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 +779,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 +868,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 +919,6 @@ int eos_modem_set_mode(uint8_t mode) { } if (!rv) { uart_mode = mode; - modem_send_status(); } } } @@ -876,70 +962,39 @@ 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); -} + 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); -void eos_modem_deep_sleep(void) { - gpio_hold_en(UART_GPIO_DTR); + 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; - - evt.type = MODEM_ETYPE_RING; - xQueueSend(modem_queue, &evt, portMAX_DELAY); - } - - 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); - - 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(); +void eos_modem_wake(void) { + modem_init_ri(); + uart_change_mode(uart_mode); + xSemaphoreGive(uart_mutex); + xSemaphoreGive(mutex); - break; - } - } + gpio_set_level(UART_GPIO_DTR, 0); } -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); +void eos_modem_deep_sleep(void) { + gpio_hold_en(UART_GPIO_DTR); + gpio_hold_en(MODEM_GPIO_USB_EN); + gpio_hold_en(MODEM_GPIO_USB_S); +} - return EOS_OK; +void eos_modem_deep_wake(void) { + gpio_hold_dis(UART_GPIO_DTR); + gpio_hold_dis(MODEM_GPIO_USB_EN); + gpio_hold_dis(MODEM_GPIO_USB_S); } void eos_ppp_get_apn(char *apn) { diff --git a/fw/esp32/components/eos/cell_pcm.c b/fw/esp32/components/eos/cell_pcm.c index b993021..67a3a08 100644 --- a/fw/esp32/components/eos/cell_pcm.c +++ b/fw/esp32/components/eos/cell_pcm.c @@ -1,309 +1,141 @@ +#include <stdint.h> #include <stdlib.h> -#include <string.h> #include <freertos/FreeRTOS.h> -#include <freertos/semphr.h> #include <freertos/task.h> -#include <freertos/queue.h> -#include <driver/i2s.h> -#include <driver/gpio.h> +#include <driver/i2s_tdm.h> #include <esp_log.h> #include "eos.h" #include "net.h" -#include "msgq.h" #include "cell.h" -#define PCM_MIC_WM 128 -#define PCM_HOLD_CNT_TX 3 -#define PCM_HOLD_CNT_RX 3 -#define PCM_SIZE_BUFQ 4 -#define PCM_SIZE_BUF (PCM_MIC_WM * 4) +#define PCM_GPIO_BCK 1 +#define PCM_GPIO_WS 41 +#define PCM_GPIO_DIN 2 +#define PCM_GPIO_DOUT 42 -#define PCM_GPIO_BCK 33 -#define PCM_GPIO_WS 4 -#define PCM_GPIO_DIN 34 -#define PCM_GPIO_DOUT 2 +#define PCM_RX_WM 256 /* receive watermark, must be less than NET_SIZE_MTU */ -#define PCM_ETYPE_WRITE 1 +static i2s_chan_handle_t tx_chan; +static i2s_chan_handle_t rx_chan; -static EOSBufQ pcm_buf_q; -static unsigned char *pcm_bufq_array[PCM_SIZE_BUFQ]; +static const char *TAG = "EOS CELL PCM"; -static EOSMsgQ pcm_evt_q; -static EOSMsgItem pcm_evtq_array[PCM_SIZE_BUFQ]; -static char pcm_hold_tx; -static char pcm_active = 0; - -static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1}; - -static QueueHandle_t i2s_queue; -static SemaphoreHandle_t mutex; - -static const char *TAG = "EOS PCM"; - -static void i2s_event_task(void *pvParameters) { - i2s_event_t event; - ssize_t hold_bytes_r = 0; - unsigned char *hold_buf = NULL; - char hold_cnt = 0; - - while (1) { - // Waiting for I2S event. - if (xQueueReceive(i2s_queue, &event, portMAX_DELAY)) { - switch (event.type) { - case I2S_EVENT_RX_DONE: { - ssize_t bytes_r; - size_t bytes_w; - uint16_t bytes_e; - unsigned char _type; - unsigned char *buf; - - if (!pcm_active) { - if (hold_buf) { - eos_net_free(hold_buf); - hold_buf = NULL; - } - break; - } - - // Event of I2S receiving data - if (!hold_cnt) { - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; - bytes_r = eos_cell_pcm_read(buf + 1, PCM_MIC_WM); - if (bytes_r < 0) { - ESP_LOGE(TAG, "*** I2S READ ERROR ***"); - eos_net_free(buf); - break; - } - eos_net_send(EOS_NET_MTYPE_CELL, buf, bytes_r + 1); - } else { - if (hold_buf == NULL) { - hold_buf = eos_net_alloc(); - hold_buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; - hold_bytes_r = 0; - } - if (1 + hold_bytes_r + PCM_MIC_WM <= EOS_NET_SIZE_BUF) { - bytes_r = eos_cell_pcm_read(hold_buf + 1 + hold_bytes_r, PCM_MIC_WM); - if (bytes_r < 0) { - ESP_LOGE(TAG, "*** I2S READ ERROR ***"); - break; - } - hold_bytes_r += bytes_r; - } - hold_cnt--; - if (hold_cnt == 0) { - eos_net_send(EOS_NET_MTYPE_CELL, hold_buf, hold_bytes_r + 1); - hold_buf = NULL; - } - } - - buf = NULL; - xSemaphoreTake(mutex, portMAX_DELAY); - if (pcm_hold_tx && (eos_msgq_len(&pcm_evt_q) == PCM_HOLD_CNT_TX)) pcm_hold_tx = 0; - if (!pcm_hold_tx) eos_msgq_pop(&pcm_evt_q, &_type, &buf, &bytes_e); - xSemaphoreGive(mutex); - - if (buf) { - esp_err_t ret; - - ret = i2s_write(I2S_NUM_0, (const void *)buf, bytes_e, &bytes_w, 1000 / portTICK_RATE_MS); - xSemaphoreTake(mutex, portMAX_DELAY); - eos_bufq_push(&pcm_buf_q, buf); - xSemaphoreGive(mutex); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "*** I2S WRITE ERROR ***"); - break; - } - } - break; - } +static void pcm_rcvr_task(void *pvParameters) { + EOSMessage msg; + size_t size_r; + esp_err_t ret; + int done = 0; + int rv; - case I2S_EVENT_DMA_ERROR: { - ESP_LOGE(TAG, "*** I2S DMA ERROR ***"); - break; - } + while (!done) { + eos_net_alloc(&msg); + if (msg.size < PCM_RX_WM + 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; + ret = i2s_channel_read(rx_chan, msg.buffer + 1, PCM_RX_WM, &size_r, 1000); + switch (ret) { + case ESP_OK: { + assert(size_r == PCM_RX_WM); + break; + } - case I2S_EVENT_MAX: { - hold_cnt = PCM_HOLD_CNT_RX; - break; - } + case ESP_ERR_INVALID_STATE: { + done = 1; + break; + } - default: - 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, &msg, size_r + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); + } else { + eos_net_free(&msg); + } } vTaskDelete(NULL); } -void eos_cell_pcm_init(void) { - int i; - - i2s_config_t i2s_config = { - .mode = I2S_MODE_SLAVE | I2S_MODE_TX | I2S_MODE_RX, - .sample_rate = 32000, - .bits_per_sample = 32, - .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .dma_buf_count = 4, - .dma_buf_len = PCM_MIC_WM, - .use_apll = true, - .fixed_mclk = 2048000 * 8, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 - }; - - i2s_pin_config_t pin_config = { - .bck_io_num = PCM_GPIO_BCK, - .ws_io_num = PCM_GPIO_WS, - .data_in_num = PCM_GPIO_DIN, - .data_out_num = PCM_GPIO_DOUT - }; - i2s_driver_install(I2S_NUM_0, &i2s_config, 10, &i2s_queue); //install and start i2s driver - i2s_stop(I2S_NUM_0); - i2s_set_pin(I2S_NUM_0, &pin_config); - gpio_matrix_in(pin_config.ws_io_num, I2S0I_WS_IN_IDX, 1); - gpio_matrix_in(pin_config.bck_io_num, I2S0I_BCK_IN_IDX, 1); - ESP_LOGI(TAG, "TX FIFO:%d TX CHAN:%d RX FIFO:%d RX CHAN:%d", I2S[I2S_NUM_0]->fifo_conf.tx_fifo_mod, I2S[I2S_NUM_0]->conf_chan.tx_chan_mod, I2S[I2S_NUM_0]->fifo_conf.rx_fifo_mod, I2S[I2S_NUM_0]->conf_chan.rx_chan_mod); - - I2S[I2S_NUM_0]->fifo_conf.tx_fifo_mod = 2; - I2S[I2S_NUM_0]->conf_chan.tx_chan_mod = 0; - - I2S[I2S_NUM_0]->fifo_conf.rx_fifo_mod = 3; - I2S[I2S_NUM_0]->conf_chan.rx_chan_mod = 1; - // I2S[I2S_NUM_0]->conf.tx_mono = 1; - I2S[I2S_NUM_0]->conf.rx_mono = 1; - // I2S[I2S_NUM_0]->timing.tx_dsync_sw = 1 - // I2S[I2S_NUM_0]->timing.rx_dsync_sw = 1 - // I2S[I2S_NUM_0]->conf.sig_loopback = 0; - - // I2S[I2S_NUM_0]->timing.tx_bck_in_inv = 1; - - eos_msgq_init(&pcm_evt_q, pcm_evtq_array, PCM_SIZE_BUFQ); - eos_bufq_init(&pcm_buf_q, pcm_bufq_array, PCM_SIZE_BUFQ); - for (i=0; i<PCM_SIZE_BUFQ; i++) { - eos_bufq_push(&pcm_buf_q, malloc(PCM_SIZE_BUF)); - } - - mutex = xSemaphoreCreateBinary(); - xSemaphoreGive(mutex); - - // Create a task to handle i2s event from ISR - xTaskCreate(i2s_event_task, "i2s_event", EOS_TASK_SSIZE_I2S, NULL, EOS_TASK_PRIORITY_I2S, NULL); - ESP_LOGI(TAG, "INIT"); -} - -ssize_t eos_cell_pcm_read(unsigned char *data, size_t size) { - static unsigned char buf[PCM_SIZE_BUF]; - size_t bytes_r; +void eos_cell_pcm_start(void) { + BaseType_t rv; esp_err_t ret; - int i; - if (size > PCM_MIC_WM) return EOS_ERR; - - ret = i2s_read(I2S_NUM_0, (void *)buf, size * 4, &bytes_r, 1000 / portTICK_RATE_MS); - if (ret != ESP_OK) return EOS_ERR; + ret = i2s_channel_enable(tx_chan); + if (ret) { + ESP_LOGE(TAG, "TX CHAN ENABLE ERR:%d", ret); + return; + } - for (i=0; i<size/2; i++) { - data[i * 2] = buf[i * 8 + 3]; - data[i * 2 + 1] = buf[i * 8 + 2]; + ret = i2s_channel_enable(rx_chan); + if (ret) { + ESP_LOGE(TAG, "RX CHAN ENABLE ERR:%d", ret); + return; } - return bytes_r / 4; + rv = xTaskCreate(&pcm_rcvr_task, "pcm_rcvr", EOS_TASK_SSIZE_PCM, NULL, EOS_TASK_PRIORITY_PCM, NULL); + assert(rv == pdPASS); } -static ssize_t pcm_expand(unsigned char *buf, unsigned char *data, size_t size) { - int i; - - if (size > PCM_MIC_WM) return EOS_ERR; +void eos_cell_pcm_stop(void) { + esp_err_t ret; - memset(buf, 0, PCM_SIZE_BUF); - for (i=0; i<size/2; i++) { - buf[i * 8 + 3] = data[i * 2]; - buf[i * 8 + 2] = data[i * 2 + 1]; - } + ret = i2s_channel_disable(tx_chan); + if (ret) ESP_LOGE(TAG, "TX CHAN DISABLE ERR:%d", ret); - return size * 4; + ret = i2s_channel_disable(rx_chan); + if (ret) ESP_LOGE(TAG, "RX CHAN DISABLE ERR:%d", ret); } -int eos_cell_pcm_push(unsigned char *data, size_t size) { - unsigned char *buf = NULL; - ssize_t esize; - int rv; - - if (size > PCM_MIC_WM) return EOS_ERR; - - xSemaphoreTake(mutex, portMAX_DELAY); - if (!pcm_active) { - xSemaphoreGive(mutex); - return EOS_ERR; - } - if (pcm_hold_tx && (eos_msgq_len(&pcm_evt_q) == PCM_HOLD_CNT_TX)) { - unsigned char _type; - uint16_t _len; +void eos_cell_pcm_push(unsigned char *data, size_t size) { + esp_err_t ret; + size_t size_w; - eos_msgq_pop(&pcm_evt_q, &_type, &buf, &_len); + ret = i2s_channel_write(tx_chan, data, size, &size_w, 1000); + if (ret == ESP_OK) { + assert(size_w == size); } else { - buf = eos_bufq_pop(&pcm_buf_q); - } - xSemaphoreGive(mutex); - - if (buf == NULL) return EOS_ERR_EMPTY; - - esize = pcm_expand(buf, data, size); - if (esize < 0) { - xSemaphoreTake(mutex, portMAX_DELAY); - eos_bufq_push(&pcm_buf_q, buf); - xSemaphoreGive(mutex); - return esize; + ESP_LOGE(TAG, "CHAN WRITE ERR:%d", ret); } - - xSemaphoreTake(mutex, portMAX_DELAY); - rv = eos_msgq_push(&pcm_evt_q, PCM_ETYPE_WRITE, buf, esize); - if (rv) eos_bufq_push(&pcm_buf_q, buf); - xSemaphoreGive(mutex); - - return rv; } -void eos_cell_pcm_start(void) { - i2s_event_t evt; - - xSemaphoreTake(mutex, portMAX_DELAY); - if (pcm_active) { - xSemaphoreGive(mutex); - return; - } - while (1) { - unsigned char _type; - unsigned char *buf; - uint16_t len; - - eos_msgq_pop(&pcm_evt_q, &_type, &buf, &len); - if (buf) { - eos_bufq_push(&pcm_buf_q, buf); - } else { - break; - } - } - pcm_active = 1; - pcm_hold_tx = 1; - xSemaphoreGive(mutex); +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; - evt.type = I2S_EVENT_MAX; /* my type */ - xQueueSend(i2s_queue, &evt, portMAX_DELAY); - i2s_zero_dma_buffer(I2S_NUM_0); - i2s_start(I2S_NUM_0); -} + tdm_cfg.slot_cfg.total_slot = 16; + ret = i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan); + assert(ret == ESP_OK); -void eos_cell_pcm_stop(void) { - char active; + ret = i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg); + assert(ret == ESP_OK); - xSemaphoreTake(mutex, portMAX_DELAY); - active = pcm_active; - pcm_active = 0; - xSemaphoreGive(mutex); + ret = i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg); + assert(ret == ESP_OK); - if (active) i2s_stop(I2S_NUM_0); + ESP_LOGI(TAG, "INIT"); } diff --git a/fw/esp32/components/eos/cell_pdp.c b/fw/esp32/components/eos/cell_pdp.c index d04b66b..9ff3ed7 100644 --- a/fw/esp32/components/eos/cell_pdp.c +++ b/fw/esp32/components/eos/cell_pdp.c @@ -7,20 +7,28 @@ #include "net.h" #include "cell.h" -void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +void eos_cell_pdp_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; + + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; + switch (mtype) { case EOS_CELL_MTYPE_PDP_SET_APN: case EOS_CELL_MTYPE_PDP_SET_USR: case EOS_CELL_MTYPE_PDP_SET_PWD: { - char *arg; + char arg[EOS_CELL_PDP_SIZE_ARG + 1]; buffer++; - buf_len--; + len--; - arg = (char *)buffer; - if (buf_len > EOS_CELL_PDP_SIZE_ARG) break; + if (len > EOS_CELL_PDP_SIZE_ARG) break; + + memcpy(arg, buffer, len); + arg[len] = '\0'; - buffer[buf_len] = '\0'; switch (mtype) { case EOS_CELL_MTYPE_PDP_SET_APN: { eos_ppp_set_apn(arg); @@ -43,10 +51,12 @@ void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t b case EOS_CELL_MTYPE_PDP_GET_APN: case EOS_CELL_MTYPE_PDP_GET_USR: case EOS_CELL_MTYPE_PDP_GET_PWD: { - char *arg; + char arg[EOS_CELL_PDP_SIZE_ARG + 1]; + + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; + if (msg->size < EOS_CELL_PDP_SIZE_ARG + 1) break; buffer[0] = EOS_CELL_MTYPE_PDP | mtype; - arg = (char *)(buffer + 1); switch (mtype) { case EOS_CELL_MTYPE_PDP_GET_APN: { eos_ppp_get_apn(arg); @@ -63,8 +73,9 @@ void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t b break; } } + memcpy(buffer + 1, arg, strlen(arg)); - eos_net_reply(EOS_NET_MTYPE_CELL, buffer, strlen(arg) + 1); + eos_net_reply(EOS_NET_MTYPE_CELL, msg, strlen(arg) + 1); break; } diff --git a/fw/esp32/components/eos/cell_sms.c b/fw/esp32/components/eos/cell_sms.c index 5145cd7..c162d4d 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]; @@ -224,26 +224,30 @@ static ssize_t sms_decode(char *pdu, size_t pdu_len, unsigned char *buf, uint16_ return buf_len; } -void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +void eos_cell_sms_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; int rv; + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; buffer++; - buf_len--; + len--; + switch (mtype) { case EOS_CELL_MTYPE_SMS_LIST: { - if (buf_len < 1) return; + if (len < 1) break; rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CMGL=%d\r", buffer[0]); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); do { - unsigned char *buf; - uint16_t buf_len; - + EOSMessage _msg; char *pdu = _pdu_in; size_t pdu_size = sizeof(_pdu_in); size_t pdu_len; @@ -257,16 +261,20 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b pdu_len = strlen(pdu); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_LIST_ITEM; - _rv = sms_decode(pdu, pdu_len, buf + 1, EOS_NET_SIZE_BUF - 1); + eos_net_alloc(&_msg); + if (_msg.size < 1) { + eos_net_free(&_msg); + continue; + } + _msg.buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_LIST_ITEM; + _rv = sms_decode(pdu, pdu_len, _msg.buffer + 1, _msg.size - 1); if (_rv < 0) { - eos_net_free(buf); + eos_net_free(&_msg); continue; } - buf_len = _rv; - eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &_msg, _rv + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } while (1); eos_modem_give(); @@ -281,19 +289,19 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b size_t pdu_len; ssize_t _rv; - _rv = sms_encode(buffer, buf_len, pdu, pdu_size); - if (_rv < 0) return; + _rv = sms_encode(buffer, len, pdu, pdu_size); + if (_rv < 0) break; pdu_len = _rv; - if (pdu_size < pdu_len + 2) return; + if (pdu_size < pdu_len + 2) break; pdu[pdu_len] = CTRL_Z; pdu[pdu_len + 1] = '\0'; rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CMGS=%d\r", pdu_len / 2); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); // wait for: '> ' (0d 0a 3e 20) @@ -309,15 +317,13 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b } static void sms_received_handler(char *urc, regmatch_t m[]) { + EOSMessage msg; char cmd[32]; - unsigned char *buf; - uint16_t buf_len; - int ref, rv; - char *pdu = _pdu_out; size_t pdu_size = sizeof(_pdu_out); size_t pdu_len; ssize_t _rv; + int ref, rv; sscanf(urc + m[1].rm_so, "%d", &ref); @@ -336,18 +342,25 @@ static void sms_received_handler(char *urc, regmatch_t m[]) { rv = at_expect("^OK", NULL, 1000); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; - _rv = sms_decode(pdu, pdu_len, buf + 1, EOS_NET_SIZE_BUF - 1); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; + _rv = sms_decode(pdu, pdu_len, msg.buffer + 1, msg.size - 1); if (_rv < 0) { - eos_net_free(buf); + eos_net_free(&msg); return; } - buf_len = _rv; - eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, _rv + 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..002391e 100644 --- a/fw/esp32/components/eos/cell_ussd.c +++ b/fw/esp32/components/eos/cell_ussd.c @@ -9,25 +9,30 @@ #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; -void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +void eos_cell_ussd_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; int rv; + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; buffer++; - buf_len--; + len--; + switch (mtype) { case EOS_CELL_MTYPE_USSD_REQUEST: { - if (buf_len > EOS_CELL_USSD_SIZE_REQ) return; + if (len > EOS_CELL_USSD_SIZE_REQ) break; - buffer[buf_len] = '\0'; - rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CUSD=1,\"%s\",15\r", buffer); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CUSD=1,\"%.*s\",15\r", len, buffer); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); rv = at_expect("^OK", "^ERROR", 1000); @@ -38,7 +43,7 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t case EOS_CELL_MTYPE_USSD_CANCEL: { rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd("AT+CUSD=2\r"); rv = at_expect("^OK", "^ERROR", 1000); @@ -50,60 +55,69 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t } static void ussd_reply_handler(char *urc, regmatch_t m[]) { - int rep, rv; - unsigned char *buf; + EOSMessage msg; uint16_t len; - char *_buf; - size_t _len; + char *rbuf; + size_t rlen; + int rep, rv; sscanf(urc + m[1].rm_so, "%1d", &rep); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_USSD | EOS_CELL_MTYPE_USSD_REPLY; - buf[1] = rep; + eos_net_alloc(&msg); + if (msg.size < 2) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_USSD | EOS_CELL_MTYPE_USSD_REPLY; + msg.buffer[1] = rep; 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, &msg, len); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); return; } - _buf = (char *)buf + len; - _len = m[2].rm_eo - m[2].rm_so - 2; - if (_len > EOS_NET_SIZE_BUF - len) { - eos_net_free(buf); + rbuf = (char *)msg.buffer + len; + rlen = m[2].rm_eo - m[2].rm_so - 2; + if (msg.size < rlen + len + 1) { + eos_net_free(&msg); return; } - memcpy(_buf, urc + m[2].rm_so + 2, _len); - len += _len; + memcpy(rbuf, urc + m[2].rm_so + 2, rlen); + rbuf[rlen] = '\0'; rv = EOS_OK; do { char *end; - end = strchr(_buf, '"'); + end = strchr(rbuf, '"'); if (end) { - len += end - _buf; + len += end - rbuf; break; } else { - _len = strlen(_buf); - _buf[_len] = '\n'; - _buf += _len + 1; - len += _len + 1; + rlen = strlen(rbuf); + rbuf[rlen] = '\n'; + rbuf += rlen + 1; + len += rlen + 1; } - rv = eos_modem_readln(_buf, EOS_NET_SIZE_BUF - len, 1000); + rv = eos_modem_readln(rbuf, msg.size - len, 1000); if (rv) break; } while (1); if (rv) { - ESP_LOGE(TAG, "error"); - eos_net_free(buf); + ESP_LOGE(TAG, "ERROR"); + eos_net_free(&msg); return; } - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 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..0ec543b 100644 --- a/fw/esp32/components/eos/cell_voice.c +++ b/fw/esp32/components/eos/cell_voice.c @@ -13,23 +13,30 @@ #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) { +void eos_cell_voice_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; int rv; + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; buffer++; - buf_len--; + len--; + switch (mtype) { case EOS_CELL_MTYPE_VOICE_DIAL: { - if (buf_len > EOS_CELL_SIZE_PHNUM) return; + if (len > EOS_CELL_SIZE_PHNUM) break; - buffer[buf_len] = '\0'; - rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "ATD%s;\r", buffer); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "ATD%.*s;\r", len, buffer); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); rv = at_expect("^OK", "^(ERROR|\\+CME ERROR: [0-9]+)", 1000); @@ -41,7 +48,7 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t case EOS_CELL_MTYPE_VOICE_ANSWER: { rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd("ATA\r"); // Response will be picked up by urc handler @@ -55,7 +62,7 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t eos_cell_pcm_stop(); rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd("AT+CHUP\r"); // Response will be picked up by urc handler @@ -65,63 +72,83 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t } case EOS_CELL_MTYPE_VOICE_PCM: { - eos_cell_pcm_push(buffer, buf_len); + eos_cell_pcm_push(buffer, len); break; } } } static void ring_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; - char *ring_buf; + EOSMessage msg; uint16_t len; + char *buffer; regmatch_t match[2]; int rv = EOS_OK; - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_RING; + eos_net_alloc(&msg); + if (msg.size < EOS_CELL_SIZE_PHNUM + 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_RING; len = 1; - rv = at_expect_match("^\\+CLIP: \"(\\+?[0-9]+)\"", NULL, &ring_buf, match, 2, REG_EXTENDED, 1000); + rv = at_expect_match("^\\+CLIP: \"(\\+?[0-9]+)\"", NULL, &buffer, match, 2, REG_EXTENDED, 1000); if (!rv) { regoff_t num_len; num_len = match[1].rm_eo - match[1].rm_so; if (num_len > EOS_CELL_SIZE_PHNUM) { - eos_net_free(buf); + eos_net_free(&msg); return; } - memcpy(buf + 1, ring_buf + match[1].rm_so, num_len); + memcpy(msg.buffer + 1, buffer + 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, &msg, 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; + EOSMessage msg; + 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); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BUSY; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 1); + 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; + EOSMessage msg; + 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); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_MISS; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void call_begin_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; + EOSMessage msg; + int rv; + + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } vTaskDelay(100 / portTICK_PERIOD_MS); at_cmd("AT+CECH=0x0000\r"); @@ -140,32 +167,53 @@ static void call_begin_handler(char *urc, regmatch_t m[]) { at_expect("^OK", "^ERROR", 1000); */ - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; - eos_net_send(EOS_NET_MTYPE_CELL, buf, 1); + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void call_end_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; + EOSMessage msg; int duration = 0; + int rv; eos_cell_pcm_stop(); + eos_net_alloc(&msg); + if (msg.size < 5) { + eos_net_free(&msg); + return; + } + sscanf(urc + m[1].rm_so, "%6d", &duration); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_END; - buf[1] = duration >> 24; - buf[2] = duration >> 16; - buf[3] = duration >> 8; - buf[4] = duration; - eos_net_send(EOS_NET_MTYPE_CELL, buf, 5); + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_END; + msg.buffer[1] = duration >> 24; + msg.buffer[2] = duration >> 16; + msg.buffer[3] = duration >> 8; + msg.buffer[4] = duration; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 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/i2c.c b/fw/esp32/components/eos/i2c.c deleted file mode 100644 index 828e4cd..0000000 --- a/fw/esp32/components/eos/i2c.c +++ /dev/null @@ -1,82 +0,0 @@ -#include <stdlib.h> - -#include <esp_log.h> -#include <driver/i2c.h> - -#include "eos.h" - -static const char *TAG = "EOS I2C"; - -#define I2C_MASTER_NUM I2C_NUM_0 -#define I2C_MASTER_FREQ_HZ 100000 -#define I2C_MASTER_GPIO_SCL 25 -#define I2C_MASTER_GPIO_SDA 26 - -#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ -#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ -#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ -#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ -#define ACK_VAL 0x0 /*!< I2C ack value */ -#define NCK_VAL 0x1 /*!< I2C nack value */ - -void eos_i2c_init(void) { - i2c_config_t conf; - conf.mode = I2C_MODE_MASTER; - conf.sda_io_num = I2C_MASTER_GPIO_SDA; - conf.sda_pullup_en = GPIO_PULLUP_ENABLE; - conf.scl_io_num = I2C_MASTER_GPIO_SCL; - conf.scl_pullup_en = GPIO_PULLUP_ENABLE; - conf.master.clk_speed = I2C_MASTER_FREQ_HZ; - i2c_param_config(I2C_MASTER_NUM, &conf); - i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); - ESP_LOGI(TAG, "INIT"); -} - -int eos_i2c_read(uint8_t addr, uint8_t reg, uint8_t *data, size_t len) { - int i, ret; - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, addr << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN); - i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, addr << 1 | I2C_MASTER_READ, ACK_CHECK_EN); - for (i=0; i < len - 1; i++) { - i2c_master_read_byte(cmd, data+i, ACK_VAL); - } - i2c_master_read_byte(cmd, data+i, NCK_VAL); - i2c_master_stop(cmd); - - ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); - i2c_cmd_link_delete(cmd); - if (ret != ESP_OK) { - return EOS_ERR; - } - return EOS_OK; -} - -int eos_i2c_write(uint8_t addr, uint8_t reg, uint8_t *data, size_t len) { - int i, ret; - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, addr << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN); - i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); - for (i=0; i < len; i++) { - i2c_master_write_byte(cmd, *(data+i), ACK_CHECK_EN); - } - i2c_master_stop(cmd); - - ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); - i2c_cmd_link_delete(cmd); - if (ret != ESP_OK) { - return EOS_ERR; - } - return EOS_OK; -} - -int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *data) { - return eos_i2c_read(addr, reg, data, 1); -} - -int eos_i2c_write8(uint8_t addr, uint8_t reg, uint8_t data) { - return eos_i2c_write(addr, reg, &data, 1); -} diff --git a/fw/esp32/components/eos/include/_net.h b/fw/esp32/components/eos/include/_net.h deleted file mode 100644 index 35b5308..0000000 --- a/fw/esp32/components/eos/include/_net.h +++ /dev/null @@ -1 +0,0 @@ -#include "net.h"
\ No newline at end of file diff --git a/fw/esp32/components/eos/include/app.h b/fw/esp32/components/eos/include/app.h index 2033b2b..38fba1a 100644 --- a/fw/esp32/components/eos/include/app.h +++ b/fw/esp32/components/eos/include/app.h @@ -1,23 +1,21 @@ #include <stdint.h> -/* common */ -#define EOS_APP_MTU 1500 -#define EOS_APP_SIZE_BUF EOS_APP_MTU +#include "net.h" #define EOS_APP_MTYPE_TUN 1 #define EOS_APP_MAX_MTYPE 8 -#define EOS_APP_MTYPE_FLAG_MASK 0xc0 +void eos_app_init(void); +void eos_app_run(void); -/* esp32 specific */ -#define EOS_APP_SIZE_BUFQ 4 -#define EOS_APP_SIZE_SNDQ 4 +void eos_app_alloc(EOSMessage *msg); +void eos_app_free(EOSMessage *msg); -typedef void (*eos_app_fptr_t) (unsigned char, unsigned char *, uint16_t); +int eos_app_send(unsigned char mtype, EOSMessage *msg, uint16_t len); -void eos_app_init(void); +void eos_app_sleep_req(void); +void eos_app_wake(void); +void eos_app_deep_sleep(void); +void eos_app_deep_wake(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); +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..30347c1 100644 --- a/fw/esp32/components/eos/include/cell.h +++ b/fw/esp32/components/eos/include/cell.h @@ -1,6 +1,10 @@ #include <sys/types.h> #include <stdint.h> +#include "net.h" + +#define EOS_CELL_MTU EOS_NET_MTU + #define EOS_CELL_MTYPE_DEV 0x10 #define EOS_CELL_MTYPE_VOICE 0x20 #define EOS_CELL_MTYPE_SMS 0x30 @@ -27,7 +31,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 +79,28 @@ #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_sleep_req(void); +void eos_modem_wake(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_deep_wake(void); void eos_ppp_get_apn(char *apn); void eos_ppp_set_apn(char *apn); @@ -105,15 +112,14 @@ 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); -void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); -void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); -void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); -void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); +void eos_cell_voice_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_cell_sms_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_cell_ussd_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_cell_pdp_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); void eos_cell_voice_init(void); void eos_cell_sms_init(void); diff --git a/fw/esp32/components/eos/include/eos.h b/fw/esp32/components/eos/include/eos.h index bc9dc51..3f9755d 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_UART 1 -#define EOS_TASK_PRIORITY_MODEM 1 -#define EOS_TASK_PRIORITY_I2S 1 -#define EOS_TASK_PRIORITY_CELL 1 -#define EOS_TASK_PRIORITY_PWR 1 +#define EOS_TASK_PRIORITY_NET 16 +#define EOS_TASK_PRIORITY_APP 17 +#define EOS_TASK_PRIORITY_SOCK 10 +#define EOS_TASK_PRIORITY_UART 10 +#define EOS_TASK_PRIORITY_MODEM 10 +#define EOS_TASK_PRIORITY_PCM 10 +#define EOS_TASK_PRIORITY_CELL 10 +#define EOS_TASK_PRIORITY_PWR 10 -#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/i2c.h b/fw/esp32/components/eos/include/i2c.h deleted file mode 100644 index f014141..0000000 --- a/fw/esp32/components/eos/include/i2c.h +++ /dev/null @@ -1,9 +0,0 @@ -#include <sys/types.h> -#include <stdint.h> - -void eos_i2c_init(void); - -int eos_i2c_read(uint8_t addr, uint8_t reg, uint8_t *data, size_t len); -int eos_i2c_write(uint8_t addr, uint8_t reg, uint8_t *data, size_t len); -int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *data); -int eos_i2c_write8(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/fw/esp32/components/eos/include/msgq.h b/fw/esp32/components/eos/include/msgq.h index bbfe041..2b216d1 100644 --- a/fw/esp32/components/eos/include/msgq.h +++ b/fw/esp32/components/eos/include/msgq.h @@ -1,8 +1,27 @@ #include <stdint.h> +#ifndef _EOS_MSGQ_H_ +#define _EOS_MSGQ_H_ + +#define EOS_MSG_FLAG_WAKE 0x01 +#define EOS_MSG_FLAG_RPLY_REQ 0x02 +#define EOS_MSG_FLAG_RPLY_REP 0x04 + +typedef struct EOSMessage { + unsigned char *buffer; + uint16_t size; + uint8_t flags; +} EOSMessage; + +void eos_msg_init(EOSMessage *msg, unsigned char *buffer, uint16_t size); +void eos_msg_set_flags(EOSMessage *msg, uint8_t flags); +void eos_msg_clear_flags(EOSMessage *msg, uint8_t flags); +uint8_t eos_msg_flags(EOSMessage *msg); + typedef struct EOSMsgItem { unsigned char type; unsigned char *buffer; + uint16_t size; uint16_t len; } EOSMsgItem; @@ -14,9 +33,9 @@ typedef struct EOSMsgQ { } EOSMsgQ; void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); -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); +int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, EOSMessage *msg, uint16_t len); +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len); typedef struct EOSBufQ { uint8_t idx_r; @@ -26,6 +45,8 @@ 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); + +#endif /* _EOS_MSGQ_H_ */ diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h index 3e9e625..edf1a58 100644 --- a/fw/esp32/components/eos/include/net.h +++ b/fw/esp32/components/eos/include/net.h @@ -1,36 +1,40 @@ #include <stdint.h> -/* common */ +#include "msgq.h" + #define EOS_NET_MTU 1500 -#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_BRIDGE 0 /* handler only */ +#define EOS_NET_MTYPE_WIFI 1 +#define EOS_NET_MTYPE_CELL 2 +#define EOS_NET_MTYPE_SOCK 3 +#define EOS_NET_MTYPE_RNG 4 -#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 0x20 /* 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_FLAG_ONEW 0x80 +#define EOS_NET_MTYPE_FLAG_REPL 0x40 +#define EOS_NET_MTYPE_FLAG_BRIDGE 0x08 -/* esp32 specific */ -#define EOS_NET_SIZE_BUFQ 4 -#define EOS_NET_SIZE_SNDQ 4 +#define EOS_NET_MTYPE_MASK 0x0F -typedef void (*eos_net_fptr_t) (unsigned char, unsigned char *, uint16_t); +typedef void (*eos_net_handler_t) (unsigned char, EOSMessage *msg, uint16_t); +void eos_net_xchg_task(void *param); void eos_net_init(void); +void eos_net_run(void); + +void eos_net_alloc(EOSMessage *msg); +void eos_net_free(EOSMessage *msg); + +int eos_net_send(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_net_reply(unsigned char mtype, EOSMessage *msg, uint16_t len); + +void eos_net_sleep_req(void); +void eos_net_wake(void); +void eos_net_deep_sleep(void); +void eos_net_deep_wake(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); +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..5627e12 --- /dev/null +++ b/fw/esp32/components/eos/include/net_priv.h @@ -0,0 +1,30 @@ +#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_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; + 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 handler; +} NETConfig; + +void _eos_net_init_gpio(NETConfig *config); +void _eos_net_alloc(NETConfig *config, EOSMessage *msg); +void _eos_net_free(NETConfig *config, EOSMessage *msg); +int _eos_net_send(NETConfig *config, unsigned char mtype, EOSMessage *msg, uint16_t len); +void _eos_net_sleep_req(NETConfig *config); +void _eos_net_wake(NETConfig *config); +void _eos_net_deep_sleep(NETConfig *config); +void _eos_net_deep_wake(NETConfig *config); diff --git a/fw/esp32/components/eos/include/power.h b/fw/esp32/components/eos/include/power.h index 2215907..c7d184c 100644 --- a/fw/esp32/components/eos/include/power.h +++ b/fw/esp32/components/eos/include/power.h @@ -1,22 +1,26 @@ #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_set_mode(uint8_t mode); +void eos_power_sleep_req(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/tun.h b/fw/esp32/components/eos/include/tun.h index 3acb2a6..ab1e0f4 100644 --- a/fw/esp32/components/eos/include/tun.h +++ b/fw/esp32/components/eos/include/tun.h @@ -1 +1,5 @@ +#include <stdint.h> + +void eos_tun_portmap_add(uint32_t ext_addr); +void eos_tun_portmap_remove(void); void eos_tun_init(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..0aae73a 100644 --- a/fw/esp32/components/eos/include/wifi.h +++ b/fw/esp32/components/eos/include/wifi.h @@ -1,3 +1,5 @@ +#include <sys/types.h> + #define EOS_WIFI_MTYPE_STATUS 0 #define EOS_WIFI_MTYPE_SCAN 1 #define EOS_WIFI_MTYPE_START 2 @@ -13,12 +15,13 @@ #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); int eos_wifi_connect(void); int eos_wifi_disconnect(void); -ssize_t eos_wifi_get_status(unsigned char *buffer); +ssize_t eos_wifi_get_status(unsigned char *buffer, size_t size); 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..50dbd3e 100644 --- a/fw/esp32/components/eos/msgq.c +++ b/fw/esp32/components/eos/msgq.c @@ -5,6 +5,24 @@ #define IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) +void eos_msg_init(EOSMessage *msg, unsigned char *buffer, uint16_t size) { + msg->buffer = buffer; + msg->size = size; + msg->flags = 0; +} + +void eos_msg_set_flags(EOSMessage *msg, uint8_t flags) { + msg->flags |= flags; +} + +void eos_msg_clear_flags(EOSMessage *msg, uint8_t flags) { + msg->flags &= ~flags; +} + +uint8_t eos_msg_flags(EOSMessage *msg) { + return msg->flags; +} + void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->idx_r = 0; msgq->idx_w = 0; @@ -12,35 +30,46 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->array = array; } -int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) { +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, EOSMessage *msg, uint16_t len) { + uint8_t idx; + if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL; - uint8_t idx = IDX_MASK(msgq->idx_w, msgq->size); + idx = IDX_MASK(msgq->idx_w, msgq->size); msgq->array[idx].type = type; - msgq->array[idx].buffer = buffer; - msgq->array[idx].len = len; + if (msg) { + msgq->array[idx].buffer = msg->buffer; + msgq->array[idx].size = msg->size; + msgq->array[idx].len = len; + } else { + msgq->array[idx].buffer = NULL; + msgq->array[idx].size = 0; + msgq->array[idx].len = 0; + } msgq->idx_w++; + return EOS_OK; } -void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len) { +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len) { if (msgq->idx_r == msgq->idx_w) { *type = 0; - *buffer = NULL; + eos_msg_init(msg, NULL, 0); *len = 0; } else { uint8_t idx = IDX_MASK(msgq->idx_r, msgq->size); + *type = msgq->array[idx].type; - *buffer = msgq->array[idx].buffer; + eos_msg_init(msg, msgq->array[idx].buffer, msgq->array[idx].size); *len = msgq->array[idx].len; msgq->idx_r++; } } -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 +77,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 +93,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..dd3180a 100644 --- a/fw/esp32/components/eos/net.c +++ b/fw/esp32/components/eos/net.c @@ -16,283 +16,495 @@ #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 +#define SPI_HOST SPI3_HOST -static volatile int net_sleep = 0; -static volatile int net_wake = 0; +#define NET_SIZE_BUFQ 8 +#define NET_SIZE_SNDQ 8 + +#define NET_SIZE_HDR 3 +#define NET_SIZE_BUF (EOS_NET_MTU + 4) + +// #define EOS_DEBUG 1 static EOSBufQ net_buf_q; -static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; +static unsigned char *net_bufq_array[NET_SIZE_BUFQ]; static EOSMsgQ net_send_q; -static EOSMsgItem net_sndq_array[EOS_NET_SIZE_SNDQ]; +static EOSMsgItem net_sndq_array[NET_SIZE_SNDQ]; + +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 SemaphoreHandle_t mutex; -static SemaphoreHandle_t semaph; -static TaskHandle_t net_xchg_task_handle; static const char *TAG = "EOS NET"; -static eos_net_fptr_t net_handler[EOS_NET_MAX_MTYPE]; +static void bad_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { + ESP_LOGE(TAG, "BAD HANDLER: 0x%.2X LEN: %d", mtype, len); +} + +static void IRAM_ATTR net_bridge(unsigned char mtype, EOSMessage *msg, uint16_t len) { + EOSMessage _msg; + int rv; + + eos_app_alloc(&_msg); + if (len > _msg.size) { + eos_app_free(&_msg); + return; + } + memcpy(_msg.buffer, msg->buffer, len); + rv = eos_app_send(mtype & EOS_NET_MTYPE_MASK, &_msg, len); + if (rv) ESP_LOGE(TAG, "BRIDGE ERR: %d", rv); +} + +static void IRAM_ATTR net_msg_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { + uint8_t idx; + + idx = mtype & EOS_NET_MTYPE_FLAG_BRIDGE ? EOS_NET_MTYPE_BRIDGE : mtype & EOS_NET_MTYPE_MASK; + if ((idx < EOS_NET_MAX_MTYPE) && (len <= msg->size)) { + net_handler[idx](mtype, msg, len); + } else { + bad_handler(mtype, msg, len); + } +} + +/* Called after a transaction is queued and ready for pickup by master */ +static void IRAM_ATTR _post_setup_cb(spi_slave_transaction_t *trans) { + NETConfig *config = trans->user; -static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { - ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len); + gpio_set_level(config->gpio_cts, 0); } -// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. -static void _post_setup_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 1); +/* Called after transaction is sent/received */ +static void IRAM_ATTR _post_trans_cb(spi_slave_transaction_t *trans) { + NETConfig *config = trans->user; + + gpio_set_level(config->gpio_cts, 1); } -// Called after transaction is sent/received. We use this to set the handshake line low. -static void _post_trans_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 0); +static void net_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); + + eos_power_sleep_rdy(config->dev); +} + +static void net_wake(NETConfig *config) { + esp_err_t ret; + uint8_t msgq_len; + + 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 IRAM_ATTR eos_net_xchg_task(void *param) { + NETConfig *config = param; + int 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); + unsigned char *snd_buf; + unsigned char *rcv_buf; + EOSMessage msg; + uint16_t snd_buf_len, rcv_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, *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); + if (!config->present) { + vTaskDelete(NULL); + return; + } + + snd_buf = spi_bus_dma_memory_alloc(config->spi_host, NET_SIZE_BUF, MALLOC_CAP_DMA); + assert(snd_buf != NULL); + + rcv_buf = spi_bus_dma_memory_alloc(config->spi_host, NET_SIZE_BUF, MALLOC_CAP_DMA); + assert(rcv_buf != NULL); + + memset(&_spi_tr_cfg, 0, sizeof(_spi_tr_cfg)); + spi_tr_cfg = &_spi_tr_cfg; + + spi_iface_cfg->post_setup_cb = _post_setup_cb; + spi_iface_cfg->post_trans_cb = _post_trans_cb; - 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; + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; + spi_tr_cfg->length = NET_SIZE_BUF * 8; + spi_tr_cfg->user = config; - if (eos_power_wakeup_cause() != EOS_PWR_WAKE_RST) { - wake = 1; - skip_msg = 1; + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + _eos_net_deep_wake(config); + vTaskSuspend(NULL); + net_wake(config); + } else { + ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO); + assert(ret == ESP_OK); } - eos_power_wait4init(); while (1) { if (!skip_msg) { - xSemaphoreTake(mutex, portMAX_DELAY); + int msg_free; - eos_msgq_pop(&net_send_q, &mtype, &buffer, &len); + xSemaphoreTake(config->mutex, portMAX_DELAY); + + msg_free = 0; + snd_buf_len = 0; + eos_msgq_pop(config->send_q, &mtype, &msg, &snd_buf_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(&net_buf_q, buffer); - xSemaphoreGive(semaph); +#ifdef EOS_DEBUG + ESP_LOGI(TAG, "SEND:0x%.2X DEV:0x%.8lX LEN:%d", mtype, config->dev, snd_buf_len); +#endif + snd_buf[0] = mtype; + snd_buf[1] = snd_buf_len >> 8; + snd_buf[2] = snd_buf_len & 0xFF; + if (msg.buffer) { + memcpy(snd_buf + NET_SIZE_HDR, msg.buffer, snd_buf_len); + msg_free = 1; } + } else if (!sleep_msg && config->sleep_req) { + snd_buf[0] = EOS_NET_MTYPE_SLEEP; + snd_buf[1] = 0; + snd_buf[2] = 0; + sleep_msg = 1; + config->sleep_req = 0; + config->sleep = 1; } else { - gpio_set_level(SPI_GPIO_RTS, 0); - buf_send[0] = 0; - buf_send[1] = 0; - buf_send[2] = 0; + gpio_set_level(config->gpio_rts, 1); + snd_buf[0] = 0; + snd_buf[1] = 0; + snd_buf[2] = 0; } - xSemaphoreGive(mutex); + xSemaphoreGive(config->mutex); + + if (msg_free) _eos_net_free(config, &msg); } 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]); + rcv_buf[0] = 0; + rcv_buf[1] = 0; + rcv_buf[2] = 0; + + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); + assert(ret == ESP_OK); - if (wake) { - eos_power_net_ready(); - wake = 0; + trans_len = spi_tr_cfg->trans_len / 8; + +#ifdef EOS_DEBUG + ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", rcv_buf[0], config->dev, trans_len); +#endif + + if (sleep_msg) { + net_sleep(config); + vTaskSuspend(NULL); + net_wake(config); + sleep_msg = 0; + continue; } - if ((spi_tr.trans_len / 8) < SPI_SIZE_HDR) continue; - if (buf_recv[0] == 0x00) continue; + /* SPI reset */ + if (trans_len < NET_SIZE_HDR) { + if (snd_buf[0]) skip_msg = 1; + continue; + } - if (buf_recv[0] == 0xFF) { // Sleep req - if (buf_send[0] == 0) { - spi_slave_free(VSPI_HOST); - eos_power_sleep(); + mtype = rcv_buf[0] & EOS_NET_MTYPE_MASK; + mtype_flags = rcv_buf[0] & ~EOS_NET_MTYPE_MASK; + if (snd_buf[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) { + skip_msg = 1; + } + rcv_buf_len = (uint16_t)rcv_buf[1] << 8; + rcv_buf_len |= (uint16_t)rcv_buf[2] & 0xFF; - xSemaphoreTake(mutex, portMAX_DELAY); - net_sleep = 1; - if (eos_msgq_len(&net_send_q)) net_wake = 1; - xSemaphoreGive(mutex); + if (snd_buf[0] && (trans_len < snd_buf_len + NET_SIZE_HDR) && !skip_msg) { + spi_tr_cfg->tx_buffer = snd_buf + trans_len; + spi_tr_cfg->rx_buffer = rcv_buf + trans_len; + spi_tr_cfg->length = (NET_SIZE_BUF - trans_len) * 8; - if (net_wake) eos_power_wake(EOS_PWR_WAKE_NETQ); - vTaskSuspend(NULL); + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); + assert(ret == ESP_OK); - xSemaphoreTake(mutex, portMAX_DELAY); - net_sleep = 0; - net_wake = 0; - xSemaphoreGive(mutex); + trans_len += spi_tr_cfg->trans_len / 8; + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; + spi_tr_cfg->length = NET_SIZE_BUF * 8; + } - spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); - wake = 1; - skip_msg = 1; - } + if (rcv_buf[0] == EOS_NET_MTYPE_SLEEP) { + eos_power_sleep_req(config->dev); 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 (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; + if (mtype == 0) continue; + + eos_msg_init(&msg, rcv_buf + NET_SIZE_HDR, EOS_NET_MTU); + if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) eos_msg_set_flags(&msg, EOS_MSG_FLAG_RPLY_REQ); + config->handler(rcv_buf[0], &msg, rcv_buf_len); + + if (eos_msg_flags(&msg) & EOS_MSG_FLAG_RPLY_REQ) { + if (!(eos_msg_flags(&msg) & EOS_MSG_FLAG_RPLY_REP)) { + // eos_net_reply(EOS_MTYPE_ERR, msg, 0); + } + spi_tr_cfg->tx_buffer = rcv_buf; + 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 = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; } } + 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, NET_SIZE_SNDQ); + eos_bufq_init(&net_buf_q, net_bufq_array, NET_SIZE_BUFQ); + for (i=0; i<NET_SIZE_BUFQ; i++) { + unsigned char *buffer; - 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)); + buffer = malloc(EOS_NET_MTU); + 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(NET_SIZE_BUFQ, 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 = esp_reset_reason() == ESP_RST_DEEPSLEEP ? 1 : 0; + net_config.sleep_req = 0; + net_config.present = 1; + net_config.dev = NET_DEV_NET; + 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.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.handler = net_msg_handler; + + /* Configuration for the SPI bus */ + net_spi_bus_cfg.mosi_io_num = SPI_GPIO_MOSI; + net_spi_bus_cfg.miso_io_num = SPI_GPIO_MISO; + net_spi_bus_cfg.sclk_io_num = SPI_GPIO_SCLK; + net_spi_bus_cfg.intr_flags = ESP_INTR_FLAG_IRAM; + + /* Configuration for the SPI slave interface */ + net_spi_iface_cfg.mode = 0; + net_spi_iface_cfg.spics_io_num = SPI_GPIO_CS; + net_spi_iface_cfg.queue_size = 2; + net_spi_iface_cfg.flags = 0; + + _eos_net_init_gpio(&net_config); + eos_net_set_handler(EOS_NET_MTYPE_BRIDGE, net_bridge); + ESP_LOGI(TAG, "INIT"); } -unsigned char *eos_net_alloc(void) { - unsigned char *ret; +void eos_net_run(void) { + BaseType_t rv; - xSemaphoreTake(semaph, portMAX_DELAY); - xSemaphoreTake(mutex, portMAX_DELAY); - ret = eos_bufq_pop(&net_buf_q); - xSemaphoreGive(mutex); + 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); - return ret; + ESP_LOGI(TAG, "RUN"); } -void eos_net_free(unsigned char *buf) { - xSemaphoreTake(mutex, portMAX_DELAY); - eos_bufq_push(&net_buf_q, buf); - xSemaphoreGive(semaph); - xSemaphoreGive(mutex); +void _eos_net_alloc(NETConfig *config, EOSMessage *msg) { + xSemaphoreTake(config->bufq_semaph, portMAX_DELAY); + xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); + msg->buffer = eos_bufq_pop(config->buf_q); + msg->size = EOS_NET_MTU; + xSemaphoreGive(config->bufq_mutex); } -int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len) { - int rv = EOS_OK; - int sleep; +void _eos_net_free(NETConfig *config, EOSMessage *msg) { + xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); + eos_bufq_push(config->buf_q, msg->buffer); + xSemaphoreGive(config->bufq_semaph); + xSemaphoreGive(config->bufq_mutex); +} - 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); +void eos_net_alloc(EOSMessage *msg) { + _eos_net_alloc(&net_config, msg); +} + +void eos_net_free(EOSMessage *msg) { + _eos_net_free(&net_config, msg); +} + +int _eos_net_send(NETConfig *config, unsigned char mtype, EOSMessage *msg, uint16_t len) { + int wake, rv; + + wake = eos_msg_flags(msg) & EOS_MSG_FLAG_WAKE; + rv = EOS_OK; + + xSemaphoreTake(config->mutex, portMAX_DELAY); + + if (!config->present) rv = EOS_ERR_NOTFOUND; + if (rv) goto net_send_fin; + + if (!wake && (config->sleep || config->sleep_req)) rv = EOS_ERR_BUSY; + if (rv) goto net_send_fin; - if (rv) eos_net_free(buffer); + rv = eos_msgq_push(config->send_q, mtype, msg, len); + if (rv) goto net_send_fin; - if (sleep) eos_power_wake(EOS_PWR_WAKE_NETQ); + /* we can't wake app module by pulling rts low */ + gpio_set_level(config->gpio_rts, 0); + +net_send_fin: + xSemaphoreGive(config->mutex); + + if (rv) _eos_net_free(config, msg); return rv; } -void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len) { - buffer -= SPI_SIZE_HDR; +int eos_net_send(unsigned char mtype, EOSMessage *msg, uint16_t len) { + return _eos_net_send(&net_config, mtype, msg, len); +} + +void eos_net_reply(unsigned char mtype, EOSMessage *msg, uint16_t len) { + unsigned char *buffer = msg->buffer - NET_SIZE_HDR; + + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) return; + if (eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REP) return; buffer[0] = mtype; buffer[1] = len >> 8; buffer[2] = len & 0xFF; + eos_msg_set_flags(msg, EOS_MSG_FLAG_RPLY_REP); } -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; -void eos_net_sleep(void) { - gpio_set_level(SPI_GPIO_CTS, 1); - vTaskDelay(200 / portTICK_PERIOD_MS); - gpio_set_level(SPI_GPIO_CTS, 0); + 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); + + 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_deep_sleep(NETConfig *config) { + gpio_hold_en(config->gpio_cts); +} + +void _eos_net_deep_wake(NETConfig *config) { + gpio_hold_dis(config->gpio_cts); +} + +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_deep_sleep(void) { + _eos_net_deep_sleep(&net_config); +} + +void eos_net_deep_wake(void) { + _eos_net_deep_wake(&net_config); +} + +void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler) { + if (handler == NULL) handler = bad_handler; + if (mtype < EOS_NET_MAX_MTYPE) net_handler[mtype] = handler; +} diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c index b98c0ec..1f58f77 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_SET_MODE 1 +#define PWR_ETYPE_SLEEP_REQ 2 +#define PWR_ETYPE_SLEEP_RDY 3 +#define PWR_ETYPE_WAKE 4 typedef struct { uint8_t type; - union { - uint8_t source; - uint8_t level; - }; + uint32_t param; } 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,154 @@ 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.param = 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.param = 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.param = 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); +static void power_sleep_req(uint32_t dev) { + if (dev & EOS_PWR_DEV_NET) { + eos_net_sleep_req(); } - - 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); + if (dev & EOS_PWR_DEV_APP) { + eos_app_sleep_req(); + } + if (dev & EOS_PWR_DEV_MODEM) { + eos_modem_sleep_req(); } - - 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"); +static void power_sleep_rdy(uint32_t dev) { + gpio_config_t io_conf = { + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_NEGEDGE, + .pull_up_en = 1, + .pull_down_en = 0, + }; - eos_modem_deep_sleep(); - esp_deep_sleep_start(); - break; - } + if (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); } -} - -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; + if (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); } - - 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); + if (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); } - - 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_wake(uint32_t dev) { + if (dev & EOS_PWR_DEV_NET) { + gpio_isr_handler_remove(EOS_PWR_GPIO_NET); + gpio_reset_pin(EOS_PWR_GPIO_NET); + eos_net_wake(); + } + if (dev & EOS_PWR_DEV_APP) { + gpio_isr_handler_remove(EOS_PWR_GPIO_APP); + gpio_reset_pin(EOS_PWR_GPIO_APP); + eos_app_wake(); + } + if (dev & EOS_PWR_DEV_MODEM) { + gpio_isr_handler_remove(EOS_PWR_GPIO_MODEM); + gpio_reset_pin(EOS_PWR_GPIO_MODEM); + eos_modem_wake(); + } } 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) { + sys_sleep = 0; + sleep_req = 0; + sleep_rdy = 0; + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { mode = EOS_PWR_SMODE_DEEP; - sleep1 = 1; - } else { - sleep1 = 0; + sys_sleep = 1; + sleep_rdy = EOS_PWR_DEV_ALL; + power_sleep_rdy(sleep_rdy); } - sleep2 = 0; - modem_wake_en = 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_SET_MODE: { + mode = evt.param; + if (sleep_rdy == EOS_PWR_DEV_ALL) { + eos_power_sleep_rdy(0); } break; } - case POWER_ETYPE_SLEEP2: { - if (sleep2) { - mode = EOS_PWR_SMODE_DEEP; - power_sleep_stage2(modem_wake_en, mode); - sleep2 = 0; - } + case PWR_ETYPE_SLEEP_REQ: { + evt.param &= ~sleep_req; + evt.param &= ~sleep_rdy; + + power_sleep_req(evt.param); + + sleep_req |= evt.param; break; } - case POWER_ETYPE_WAKE: { - if (sleep1) { - source = evt.source; - power_wake_stage1(source, mode); - if (sleep2) { - esp_timer_stop(timer); - sleep2 = 0; - } + case PWR_ETYPE_SLEEP_RDY: { + evt.param &= sleep_req; + evt.param &= ~sleep_rdy; + + power_sleep_rdy(evt.param); + + sleep_req &= ~evt.param; + sleep_rdy |= evt.param; + if (!sys_sleep && mode && (sleep_rdy == EOS_PWR_DEV_ALL)) { + sys_sleep = 1; + eos_power_sys_sleep(mode); } break; } - case POWER_ETYPE_NETRDY: { - power_wake_stage2(source, mode); - sleep1 = 0; - source = 0; - break; - } + case PWR_ETYPE_WAKE: { + evt.param &= ~sleep_req; + evt.param &= sleep_rdy; - case POWER_ETYPE_BTN: { - unsigned char *buf; + if (sys_sleep) { + eos_power_sys_wake(mode); + sys_sleep = 0; + mode = 0; + } - buf = eos_net_alloc(); - buf[0] = EOS_PWR_MTYPE_BUTTON; - buf[1] = evt.level; - eos_net_send(EOS_NET_MTYPE_POWER, buf, 2); - break; - } + power_wake(evt.param); - default: + sleep_rdy &= ~evt.param; break; + } } } } @@ -276,35 +191,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 +215,132 @@ 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); } - 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); + + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + eos_power_wake(eos_power_wakeup_source()); + } -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) { + eos_net_deep_sleep(); + eos_app_deep_sleep(); + eos_modem_deep_sleep(); + + 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_set_mode(uint8_t mode) { power_event_t evt; - evt.type = POWER_ETYPE_SLEEP1; - evt.source = 0; + evt.type = PWR_ETYPE_SET_MODE; + evt.param = mode; xQueueSend(power_queue, &evt, portMAX_DELAY); } -void eos_power_wake(uint8_t source) { +void eos_power_sleep_req(uint32_t dev) { power_event_t evt; - evt.type = POWER_ETYPE_WAKE; - evt.source = source; - + evt.type = PWR_ETYPE_SLEEP_REQ; + evt.param = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } -void eos_power_net_ready(void) { +void eos_power_sleep_rdy(uint32_t dev) { power_event_t evt; - evt.type = POWER_ETYPE_NETRDY; - evt.source = 0; + evt.type = PWR_ETYPE_SLEEP_RDY; + evt.param = dev; + xQueueSend(power_queue, &evt, portMAX_DELAY); +} + +void eos_power_wake(uint32_t dev) { + power_event_t evt; + ESP_LOGI(TAG, "WAKE SENT"); + evt.type = PWR_ETYPE_WAKE; + evt.param = 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..6f53a0b 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> @@ -7,25 +7,24 @@ static const char *TAG = "EOS RNG"; -static void rng_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { +static void rng_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char *buffer = msg->buffer; uint16_t rng_len = 0; - if (buf_len < sizeof(uint16_t)) goto rng_handler_fin; + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) return; + if (len < sizeof(uint16_t)) return; rng_len = (uint16_t)buffer[0] << 8; rng_len |= (uint16_t)buffer[1]; - if (rng_len > EOS_NET_SIZE_BUF) { - rng_len = 0; - goto rng_handler_fin; - } - esp_fill_random(buffer, rng_len); + if (rng_len > msg->size) return; -rng_handler_fin: - eos_net_reply(EOS_NET_MTYPE_RNG, buffer, rng_len); + esp_fill_random(buffer, rng_len); + eos_net_reply(EOS_NET_MTYPE_RNG, msg, rng_len); } 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..dcad8b2 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,105 +84,316 @@ static ssize_t t_recvfrom(int sock, void *msg, size_t msg_size, EOSNetAddr *addr return recvlen; } -static void udp_rcvr_task(void *pvParameters) { - uint8_t sock_i = (uint8_t)pvParameters; - int sock = _socks[sock_i-1]; +static void populate_fds(fd_set *fds, int *max_fd) { + int i; - 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; + *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]; + } } - _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); + } +} + +static void cmd_xchg(uint8_t *cmd) { + int rv; xSemaphoreTake(mutex, portMAX_DELAY); - _socks[sock_i-1] = 0; + + rv = write(cmd_fd, cmd, sizeof(uint64_t)); + assert(rv == sizeof(uint64_t)); + + do { + rv = read(rep_fd, cmd, sizeof(uint64_t)); + assert(rv == sizeof(uint64_t)); + } while (cmd[0] == 0); + xSemaphoreGive(mutex); +} + +static void udp_rcvr_task(void *pvParameters) { + EOSNetAddr addr; + EOSMessage msg; + unsigned char *buffer; + uint16_t 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; + + 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; + } + + for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { + sock = _socks[i]; + if (sock && FD_ISSET(sock, &read_fds)) { + eos_net_alloc(&msg); + if (msg.size < EOS_SOCK_SIZE_UDP_HDR) { + eos_net_free(&msg); + continue; + } + _rv = t_recvfrom(sock, msg.buffer + EOS_SOCK_SIZE_UDP_HDR, msg.size - EOS_SOCK_SIZE_UDP_HDR, &addr); + if (_rv < 0) { + eos_net_free(&msg); + ESP_LOGE(TAG, "RECV ERR:%d", _rv); + continue; + } + buffer = msg.buffer; + buffer[0] = EOS_SOCK_MTYPE_PKT; + buffer[1] = i + 1; + buffer += 2; + memcpy(buffer, addr.host, sizeof(addr.host)); + buffer += sizeof(addr.host); + buffer[0] = addr.port >> 8; + buffer[1] = addr.port; + buffer += sizeof(addr.port); + rv = eos_net_send(EOS_NET_MTYPE_SOCK, &msg, _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); + } + } + 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; + sock = _socks[sock_i]; + if (sock) { + len = (uint16_t)cmd[2] << 8; + len |= (uint16_t)cmd[3]; + memcpy(&buffer, cmd + 4, sizeof(buffer)); + + memcpy(addr.host, buffer, sizeof(addr.host)); + buffer += sizeof(addr.host); + len -= sizeof(addr.host); + addr.port = (uint16_t)buffer[0] << 8; + addr.port |= (uint16_t)buffer[1]; + buffer += sizeof(addr.port); + len -= sizeof(addr.port); + _rv = t_sendto(sock, buffer, len, &addr); + } + + rv = write(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + break; + } + + case CMD_REOPEN: { + for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { + sock = _socks[i]; + if (sock) { + t_close(sock); + _socks[i] = -1; + } + } + + len = 0; + eos_msg_init(&msg, NULL, 0); + 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 (msg.buffer) { + if (msg.size == len) break; + msg.buffer[len] = i + 1; + len++; + } else { + eos_net_alloc(&msg); + if (msg.size < 2) break; + msg.buffer[0] = EOS_SOCK_MTYPE_CLOSE; + msg.buffer[1] = i + 1; + len = 2; + } + } + } + } + if (msg.buffer) { + rv = eos_net_send(EOS_NET_MTYPE_SOCK, &msg, 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) { +static void sock_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { unsigned char mtype; + unsigned char *buffer = msg->buffer; uint8_t sock_i; - int sock, i; + uint8_t cmd[8]; + + if (len < 1) return; - 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; + uint16_t _len = len; + + if (len < EOS_SOCK_SIZE_UDP_HDR) break; + + sock_i = buffer[1]; + if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) break; - if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return; + _buf += 2; + _len -= 2; + cmd[0] = CMD_SEND; + cmd[1] = sock_i; + cmd[2] = _len >> 8; + cmd[3] = _len; + memcpy(cmd + 4, &_buf, sizeof(_buf)); - sock_i = buffer[1]-1; - if (sock_i >= EOS_SOCK_MAX_SOCK) return; + cmd_xchg(cmd); - 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); + 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); + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; + if (msg->size < 2) break; + + cmd[0] = CMD_OPEN; + + cmd_xchg(cmd); + + 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); + + eos_net_reply(EOS_NET_MTYPE_SOCK, msg, 2); break; } case EOS_SOCK_MTYPE_CLOSE: { - if (buf_len < 2) return; + if (len < 2) break; + + sock_i = buffer[1]; + if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) break; + + cmd[0] = CMD_CLOSE; + cmd[1] = sock_i; - sock_i = buffer[1]-1; - if (sock_i >= EOS_SOCK_MAX_SOCK) return; + cmd_xchg(cmd); - sock = _socks[sock_i]; - t_close(sock); + 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]; + + cmd[0] = CMD_REOPEN; + + cmd_xchg(cmd); + + assert(cmd[0] == CMD_REOPEN); +} diff --git a/fw/esp32/components/eos/tun.c b/fw/esp32/components/eos/tun.c index a7181ee..cb1dde6 100644 --- a/fw/esp32/components/eos/tun.c +++ b/fw/esp32/components/eos/tun.c @@ -4,39 +4,49 @@ #include <lwip/pbuf.h> #include <lwip/netif.h> #include <lwip/tcpip.h> -#include <lwip/etharp.h> +#include <lwip/ip.h> +#include <lwip/lwip_napt.h> +#include <esp_log.h> + +#include "net.h" #include "app.h" #include "tun.h" +static const char *TAG = "EOS TUN"; + 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) { - unsigned char *buf; +static err_t IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) { + EOSMessage msg; struct pbuf *q; for (q = p; q != NULL; q = q->next) { - if (q->len > EOS_APP_MTU) continue; + eos_app_alloc(&msg); + if (q->len > msg.size) { + eos_app_free(&msg); + continue; + } - buf = eos_app_alloc(); - memcpy(buf, q->payload, q->len); - eos_app_send(EOS_APP_MTYPE_TUN, buf, q->len); + memcpy(msg.buffer, q->payload, q->len); + eos_app_send(EOS_APP_MTYPE_TUN, &msg, q->len); } 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, EOSMessage *msg, uint16_t len) { struct netif *netif = &netif_tun; struct pbuf *p; int rv; if (!netif_is_up(netif)) return; - p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); + p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM); if (p == NULL) return; - memcpy(p->payload, buffer, len); + + memcpy(p->payload, msg->buffer, len); rv = netif->input(p, netif); if (rv != ERR_OK) { pbuf_free(p); @@ -54,12 +64,31 @@ static err_t tun_init(struct netif *netif) { return ERR_OK; } +void eos_tun_portmap_add(uint32_t ext_addr) { + ip4_addr_t app_addr; + + IP4_ADDR(&app_addr, 192,168,152,1); + ip_portmap_add(IP_PROTO_TCP, ext_addr, 22, app_addr.addr, 22); +} + +void eos_tun_portmap_remove(void) { + ip_portmap_remove(IP_PROTO_TCP, 22); +} + void eos_tun_init(void) { + struct netif *rv; + IP4_ADDR(&gw, 0,0,0,0); - IP4_ADDR(&ipaddr, 192,168,10,2); + IP4_ADDR(&ipaddr, 192,168,152,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); + ip_napt_enable_netif(&netif_tun, 1); eos_app_set_handler(EOS_APP_MTYPE_TUN, tun_input); -}
\ No newline at end of file + + ESP_LOGI(TAG, "INIT"); + ESP_LOGI(TAG, "addres: %x", (unsigned int)ipaddr.addr); +} diff --git a/fw/esp32/components/eos/wifi.c b/fw/esp32/components/eos/wifi.c index 2be169f..fe1b382 100755 --- a/fw/esp32/components/eos/wifi.c +++ b/fw/esp32/components/eos/wifi.c @@ -10,10 +10,10 @@ #include <esp_log.h> #include <esp_err.h> #include <esp_wifi.h> -#include <nvs_flash.h> #include "eos.h" #include "net.h" +#include "tun.h" #include "wifi.h" // XXX: WiFi fail due to no DHCP server @@ -53,9 +53,8 @@ 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(); + eos_tun_portmap_remove(); break; } if ((reconnect_cnt == 0) && (sta_disconnected->reason == WIFI_REASON_BEACON_TIMEOUT)) { @@ -67,6 +66,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e reconnect_cnt++; } else { eos_wifi_send_status(); + eos_tun_portmap_remove(); reconnect_cnt = 0; if (stop) { @@ -87,13 +87,17 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e got_ip = (ip_event_got_ip_t *)event_data; ESP_LOGI(TAG, "Event got IP - addres: " IPSTR, IP2STR(&got_ip->ip_info.ip)); + ESP_LOGI(TAG, "Event got IP - addres: %x", (unsigned int)got_ip->ip_info.ip.addr); eos_wifi_send_status(); + eos_tun_portmap_remove(); + eos_tun_portmap_add(got_ip->ip_info.ip.addr); /* if (got_ip->ip_changed) { recreate all sockets } */ + break; } @@ -104,35 +108,25 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e } -static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { +static void wifi_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char *buffer = msg->buffer; + uint16_t buf_size = msg->size; esp_err_t ret = ESP_OK; - uint8_t mtype; + unsigned char mtype; - if (buf_len < 1) return; + if (len < 1) return; mtype = buffer[0]; switch (mtype) { case EOS_WIFI_MTYPE_STATUS: { - int reply; ssize_t rv; - reply = _mtype & EOS_NET_MTYPE_FLAG_REPL; - - if (reply) { - rv = eos_wifi_get_status(buffer + 1); - if (rv < 0) break; - - eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, rv + 1); - } else { - unsigned char *buf; + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; - buf = eos_net_alloc(); - buf[0] = EOS_WIFI_MTYPE_STATUS; - rv = eos_wifi_get_status(buf + 1); - if (rv < 0) break; + rv = eos_wifi_get_status(buffer + 1, buf_size - 1); + if (rv < 0) break; - eos_net_send(EOS_NET_MTYPE_WIFI, buf, rv + 1); - } + eos_net_reply(EOS_NET_MTYPE_WIFI, msg, rv + 1); break; } @@ -202,20 +196,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,14 +214,30 @@ void eos_wifi_init(void) { assert(ret == ESP_OK); eos_net_set_handler(EOS_NET_MTYPE_WIFI, wifi_handler); + ESP_LOGI(TAG, "INIT"); } -ssize_t eos_wifi_get_status(unsigned char *buffer) { +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, size_t size) { unsigned char *p; wifi_ap_record_t ap_info; esp_err_t ret; + /* 1 + sizeof(uint32_t) + sizeof(ap_info.ssid) - 1 */ + if (size < sizeof(uint32_t) + sizeof(ap_info.ssid)) return EOS_ERR_SIZE; + p = buffer; ret = esp_wifi_sta_get_ap_info(&ap_info); switch (ret) { @@ -292,27 +296,34 @@ ssize_t eos_wifi_get_status(unsigned char *buffer) { } void eos_wifi_send_status(void) { - unsigned char *rbuf; - ssize_t rv; - - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_STATUS; - rv = eos_wifi_get_status(rbuf + 1); - if (rv < 0) { - eos_net_free(rbuf); + EOSMessage msg; + ssize_t _rv; + int rv; + + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_WIFI_MTYPE_STATUS; + _rv = eos_wifi_get_status(msg.buffer + 1, msg.size - 1); + if (_rv < 0) { + eos_net_free(&msg); return; } - eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, rv + 1); + rv = eos_net_send(EOS_NET_MTYPE_WIFI, &msg, _rv + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } void eos_wifi_send_scan(void) { + EOSMessage msg; 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 *p; + int i, rv; scan_n = EOS_WIFI_MAX_SCAN_RECORDS; memset(scan_r, 0, sizeof(scan_r)); @@ -324,17 +335,23 @@ void eos_wifi_send_scan(void) { ESP_LOGI(TAG, "Scan done: %d", scan_n); - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_SCAN; - p = rbuf + 1; + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_WIFI_MTYPE_SCAN; + p = msg.buffer + 1; for (i=0; i<scan_n; i++) { len = strnlen((char *)scan_r[i].ssid, sizeof(scan_r[i].ssid)); if (len == sizeof(scan_r[i].ssid)) continue; - if (p - rbuf + len + 1 > EOS_NET_SIZE_BUF) break; + if (p - msg.buffer + len + 1 > msg.size) break; 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, &msg, p - msg.buffer); + 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. -# diff --git a/fw/fe310/eos/board.h b/fw/fe310/eos/board.h index 21732dc..7836bd7 100644 --- a/fw/fe310/eos/board.h +++ b/fw/fe310/eos/board.h @@ -1,24 +1,30 @@ -#define SPI_DIV_NET 16 -#define SPI_DIV_EVE 4 -#define SPI_DIV_SDC 1024 +#define SPI_DIV_NET 16 /* 60 MHz max */ +#define SPI_DIV_EVE 5 /* 30 MHz max */ +#define SPI_DIV_SDC 5 #define SPI_DIV_CAM 24 +#define SPI_DIV_LCD 0 /* spi 9bit */ +#define SPI_DIV_HPAMP 1024 #define SPI_CSID_NET 0 #define SPI_CSID_EVE 2 -#define SPI_CSID_SDC -1 +#define SPI_CSID_SDC SPI_CSID_NONE #define SPI_CSID_CAM 3 +#define SPI_CSID_LCD SPI_CSID_NONE +#define SPI_CSID_HPAMP SPI_CSID_NONE -#define SPI_IOF_MASK ((1 << IOF_SPI1_SCK) | (1 << IOF_SPI1_MOSI) | (1 << IOF_SPI1_MISO) | (1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS2) | (1 << IOF_SPI1_SS3)) - -#define SPI_CSPIN_NET -1 -#define SPI_CSPIN_EVE -1 +#define SPI_CSPIN_NET 2 +#define SPI_CSPIN_EVE 9 #define SPI_CSPIN_SDC 0 -#define SPI_CSPIN_CAM -1 -/* only when i2s is off */ -#define SPI_CSPIN_LCD 21 +#define SPI_CSPIN_CAM 10 +#define SPI_CSPIN_LCD 21 /* only when i2s is off */ +#define SPI_CSPIN_HPAMP (SPI_CSFLAG_EGPIO | EGPIO_PIN_HPAMP_CS) -#define NET_PIN_RTS 20 -#define NET_PIN_CTS 22 +#define SPI_IOF_MASK ((1 << IOF_SPI1_SCK) | (1 << IOF_SPI1_MOSI) | (1 << IOF_SPI1_MISO) | (1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS2) | (1 << IOF_SPI1_SS3)) +// #define SPI_IOF_CSXOR ((1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS3)) +#define SPI_IOF_CSXOR 0 + +#define NET_PIN_RTS 22 +#define NET_PIN_CTS 20 #define EGPIO_PIN_INT 23 @@ -32,6 +38,8 @@ #define I2S_PIN_INT 16 /* only when i2s is off */ -#define EVE_PIN_INTR 1 /* only when EGPIO_PIN_CTP_SEL is off */ -#define CTP_PIN_INT 1 /* only when EGPIO_PIN_CTP_SEL is on */ -#define CTP_PIN_RST 19 +#define CTP_PIN_INT 1 /* EGPIO_PIN_CTP_SEL is on: CTP int; EGPIO_PIN_CTP_SEL is off: EVE int */ +#define CTP_PIN_RST 19 /* only when EGPIO_PIN_CTP_SEL is on */ + +/* EVE gpio in dev/eve_priv.h */ +/* FXL6408 gpio in dev/egpio.h */
\ No newline at end of file diff --git a/fw/fe310/eos/dev/Makefile b/fw/fe310/eos/dev/Makefile index 75f36ab..874e625 100644 --- a/fw/fe310/eos/dev/Makefile +++ b/fw/fe310/eos/dev/Makefile @@ -1,7 +1,8 @@ include ../../common.mk CFLAGS += -I$(bsp_dir)/include -I$(ext_dir)/crypto -obj = flash.o spi.o net.o bq25895.o sdcard.o sdc_crypto.o lcd.o gt911.o ili9806e.o eve.o ov2640.o cam.o egpio.o fxl6408.o apds9151.o tps61052.o +obj = flash.o aon.o pwr.o batt.o hpamp.o egpio.o eve.o lcd.o ctp.o spi.o net.o sdcard.o sdc_crypto.o app.o +subdirs = drv lib = ../../libeos-dev.a @@ -14,7 +15,13 @@ lib = ../../libeos-dev.a all: $(lib) $(lib): $(obj) - $(AR) rcs $@ $(obj) + for i in $(subdirs); do \ + (cd $$i && $(MAKE)) || exit; \ + done + $(AR) rcs $@ $(obj) drv/*.o clean: + for i in $(subdirs); do \ + (cd $$i && $(MAKE) clean) || exit; \ + done rm -f *.o $(lib) diff --git a/fw/fe310/eos/dev/aon.c b/fw/fe310/eos/dev/aon.c new file mode 100644 index 0000000..abf75d3 --- /dev/null +++ b/fw/fe310/eos/dev/aon.c @@ -0,0 +1,95 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "eos.h" +#include "soc/aon.h" + +#include "aon.h" + +#define AON_EVE_REG 0 +#define AON_NET_REG 0 +#define AON_APP_REG 0 + +#define AON_EVE_PWM_MASK 0x000000FF +#define AON_EVE_PWR_MASK 0x00000300 +#define AON_EVE_LCD_MASK 0x00000400 +#define AON_NET_MASK 0x00000800 +#define AON_APP_MASK 0x00001000 + +void eos_aon_save4eve_pwm(uint8_t brightness) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_EVE_REG); + reg &= ~AON_EVE_PWM_MASK; + reg |= brightness; + + eos_aon_set_reg(AON_EVE_REG, reg); +} + +uint8_t eos_aon_load4eve_pwm(void) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_EVE_REG) & AON_EVE_PWM_MASK; + return reg; +} + +void eos_aon_save4eve_pwr(uint8_t power_state) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_EVE_REG); + reg &= ~AON_EVE_PWR_MASK; + reg |= ((uint32_t)power_state << 8) & AON_EVE_PWR_MASK; + + eos_aon_set_reg(AON_EVE_REG, reg); +} + +uint8_t eos_aon_load4eve_pwr(void) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_EVE_REG) & AON_EVE_PWR_MASK; + reg = reg >> 8; + return reg; +} + +void eos_aon_save4eve_lcd(int absent) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_EVE_REG); + reg &= ~AON_EVE_LCD_MASK; + if (absent) reg |= AON_EVE_LCD_MASK; + + eos_aon_set_reg(AON_EVE_REG, reg); +} + +int eos_aon_load4eve_lcd(void) { + return !!(eos_aon_get_reg(AON_EVE_REG) & AON_EVE_LCD_MASK); +} + +void eos_aon_save4net(int absent) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_NET_REG); + reg &= ~AON_NET_MASK; + if (absent) reg |= AON_NET_MASK; + + eos_aon_set_reg(AON_NET_REG, reg); +} + +int eos_aon_load4net(void) { + return !!(eos_aon_get_reg(AON_NET_REG) & AON_NET_MASK); +} + +void eos_aon_save4app(int ctp_sel) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_APP_REG); + reg &= ~AON_APP_MASK; + if (ctp_sel) reg |= AON_APP_MASK; + + eos_aon_set_reg(AON_APP_REG, reg); + +} + +int eos_aon_load4app(void) { + return !!(eos_aon_get_reg(AON_APP_REG) & AON_APP_MASK); +}
\ No newline at end of file diff --git a/fw/fe310/eos/dev/aon.h b/fw/fe310/eos/dev/aon.h new file mode 100644 index 0000000..eb3953c --- /dev/null +++ b/fw/fe310/eos/dev/aon.h @@ -0,0 +1,16 @@ +#include <stdint.h> + +void eos_aon_save4eve_pwm(uint8_t brightness); +uint8_t eos_aon_load4eve_pwm(void); + +void eos_aon_save4eve_pwr(uint8_t power_state); +uint8_t eos_aon_load4eve_pwr(void); + +void eos_aon_save4eve_lcd(int absent); +int eos_aon_load4eve_lcd(void); + +void eos_aon_save4net(int absent); +int eos_aon_load4net(void); + +void eos_aon_save4app(int ctp_sel); +int eos_aon_load4app(void);
\ No newline at end of file diff --git a/fw/fe310/eos/dev/app.c b/fw/fe310/eos/dev/app.c index 3c215f4..4c6b7cd 100644 --- a/fw/fe310/eos/dev/app.c +++ b/fw/fe310/eos/dev/app.c @@ -2,13 +2,21 @@ #include <stdint.h> #include "eos.h" +#include "log.h" +#include "eve/eve.h" +#include "eve/eve_touch_engine.h" + +#include "egpio.h" +#include "egpio_priv.h" +#include "eve.h" + +#include "aon.h" +#include "ctp.h" +#include "lcd.h" #include "hpamp.h" -#include "app.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif +#include "app.h" void eos_app_hp_change(int hp_det) { if (hp_det) { @@ -16,10 +24,91 @@ void eos_app_hp_change(int hp_det) { rv = eos_hpamp_init(); if (rv) { -#ifdef EOS_DEBUG - printf("I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv); -#endif + EOS_LOG(EOS_LOG_ERR, "I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv); return; } } } + +int eos_app_give(void) { + int rv, _rv; + + if (!eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR; + + eos_aon_save4app(eos_egpio_get_val(EGPIO_PIN_CTP_SEL)); + + rv = eos_egpio_intr_disable(); + if (rv) return rv; + + rv = eve_select(); + if (rv) goto app_give_err_select; + + _eos_eve_sleep(); + + rv = eos_lcd_give(); + if (rv) goto app_give_err; + + rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0); + if (rv) goto app_give_err; + + rv = eos_egpio_set_val(EGPIO_PIN_DISP_SEL, 0); + if (rv) goto app_give_err; + + eve_pwr_sleep(); + +app_give_err: + if (rv) _eos_eve_wake(); + eve_deselect(); + +app_give_err_select: + _rv = eos_egpio_intr_set(); + if (!rv && _rv) return _rv; + + return rv; +} + +int eos_app_take(void) { + int rv, _rv, ctp_sel; + + if (eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR; + + ctp_sel = eos_aon_load4app(); + + rv = eos_egpio_intr_disable(); + if (rv) return rv; + + rv = eve_select(); + if (rv) goto app_take_err_select; + + eve_pwr_wake(); + + rv = eos_egpio_set_val(EGPIO_PIN_DISP_SEL, 1); + if (rv) goto app_take_err; + + rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, ctp_sel); + if (rv) goto app_take_err; + + if (!ctp_sel) { + eve_touch_reset_engine(); + } + + rv = eos_lcd_take(); + if (rv) goto app_take_err; + + _eos_eve_wake(); + +app_take_err: + if (rv) eve_pwr_sleep(); + eve_deselect(); + + if (!rv && ctp_sel) { + _rv = _eos_ctp_reset(); + if (_rv) rv = _rv; + } + +app_take_err_select: + _rv = eos_egpio_intr_set(); + if (!rv && _rv) return _rv; + + return rv; +} diff --git a/fw/fe310/eos/dev/app.h b/fw/fe310/eos/dev/app.h index 4ee2e8d..e88ba20 100644 --- a/fw/fe310/eos/dev/app.h +++ b/fw/fe310/eos/dev/app.h @@ -1,3 +1,5 @@ #include <stdint.h> -void eos_app_hp_change(int hp_det);
\ No newline at end of file +void eos_app_hp_change(int hp_det); +int eos_app_give(void); +int eos_app_take(void);
\ No newline at end of file diff --git a/fw/fe310/eos/dev/batt.c b/fw/fe310/eos/dev/batt.c new file mode 100644 index 0000000..45e6af0 --- /dev/null +++ b/fw/fe310/eos/dev/batt.c @@ -0,0 +1,52 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "eos.h" +#include "log.h" + +#include "soc/pwr.h" + +#include "drv/bq25895.h" + +int eos_batt_init(void) { + uint8_t wakeup_cause; + int rst, rv; +#ifdef EOS_DEBUG + uint8_t data; + int i; +#endif + + rv = EOS_OK; + + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); + if (rst) { + // if (!rv) rv = bq25895_reg_write(0x14, 0x80); // reset + // if (!rv) rv = bq25895_reg_write(0x14, 0x00); + if (!rv) rv = bq25895_reg_write(0x07, 0x8d); // disable watchdog + if (!rv) rv = bq25895_reg_write(0x03, 0x2e); // disable charging, 3.7V minimum output + } + if (rv) return rv; + +#ifdef EOS_DEBUG + EOS_LOG(EOS_LOG_INFO, "BQ25895:\n"); + for (i=0; i<0x15; i++) { + rv = bq25895_reg_read(i, &data); + if (!rv) EOS_LOG(EOS_LOG_INFO, " REG%.2X: %.2X\n", i, data); + } +#endif + + return EOS_OK; +} + +int eos_batt_read_fault(uint8_t *fault0, uint8_t *fault1) { + int rv; + + rv = bq25895_read_fault(fault0); + if (rv) return rv; + + rv = bq25895_read_fault(fault1); + if (rv) return rv; + + return EOS_OK; +}
\ No newline at end of file diff --git a/fw/fe310/eos/dev/batt.h b/fw/fe310/eos/dev/batt.h new file mode 100644 index 0000000..e761a37 --- /dev/null +++ b/fw/fe310/eos/dev/batt.h @@ -0,0 +1,4 @@ +#include <stdint.h> + +int eos_batt_init(void); +int eos_batt_read_fault(uint8_t *fault0, uint8_t *fault1); diff --git a/fw/fe310/eos/dev/cam.h b/fw/fe310/eos/dev/cam.h new file mode 100644 index 0000000..b0e1368 --- /dev/null +++ b/fw/fe310/eos/dev/cam.h @@ -0,0 +1,20 @@ +#include "cam_def.h" +#include "drv/ov2640.h" +#include "drv/arducam.h" + +#include "egpio.h" +#include "egpio_priv.h" + +#define eos_cam_init ov2640_init +#define eos_cam_set_pixfmt ov2640_set_pixfmt +#define eos_cam_set_framesize ov2640_set_pixfmt + +#define eos_cam_capture arducam_capture +#define eos_cam_capture_done arducam_capture_done +#define eos_cam_capture_wait arducam_capture_wait +#define eos_cam_fbuf_size arducam_fbuf_size +#define eos_cam_fbuf_read arducam_fbuf_read +#define eos_cam_fbuf_done arducam_fbuf_done + +#define eos_cam_en() eos_egpio_set_val(EGPIO_PIN_CAM_EN, 1) +#define eos_cam_dis() eos_egpio_set_val(EGPIO_PIN_CAM_EN, 0) diff --git a/fw/fe310/eos/dev/cam_def.h b/fw/fe310/eos/dev/cam_def.h new file mode 100644 index 0000000..4a44f98 --- /dev/null +++ b/fw/fe310/eos/dev/cam_def.h @@ -0,0 +1,65 @@ +typedef enum { + CAM_PIXFORMAT_INVALID = 0, + CAM_PIXFORMAT_BINARY, // 1BPP/BINARY + CAM_PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE + CAM_PIXFORMAT_RGB565, // 2BPP/RGB565 + CAM_PIXFORMAT_YUV422, // 2BPP/YUV422 + CAM_PIXFORMAT_BAYER, // 1BPP/RAW + CAM_PIXFORMAT_JPEG, // JPEG/COMPRESSED +} cam_pixformat_t; + +typedef enum { + CAM_FRAMESIZE_INVALID = 0, + // C/SIF Resolutions + CAM_FRAMESIZE_QQCIF, // 88x72 + CAM_FRAMESIZE_QCIF, // 176x144 + CAM_FRAMESIZE_CIF, // 352x288 + CAM_FRAMESIZE_QQSIF, // 88x60 + CAM_FRAMESIZE_QSIF, // 176x120 + CAM_FRAMESIZE_SIF, // 352x240 + // VGA Resolutions + CAM_FRAMESIZE_QQQQVGA, // 40x30 + CAM_FRAMESIZE_QQQVGA, // 80x60 + CAM_FRAMESIZE_QQVGA, // 160x120 + CAM_FRAMESIZE_QVGA, // 320x240 + CAM_FRAMESIZE_VGA, // 640x480 + CAM_FRAMESIZE_HQQQVGA, // 60x40 + CAM_FRAMESIZE_HQQVGA, // 120x80 + CAM_FRAMESIZE_HQVGA, // 240x160 + // FFT Resolutions + CAM_FRAMESIZE_64X32, // 64x32 + CAM_FRAMESIZE_64X64, // 64x64 + CAM_FRAMESIZE_128X64, // 128x64 + CAM_FRAMESIZE_128X128, // 128x128 + CAM_FRAMESIZE_320X320, // 320x320 + // Other + CAM_FRAMESIZE_LCD, // 128x160 + CAM_FRAMESIZE_QQVGA2, // 128x160 + CAM_FRAMESIZE_WVGA, // 720x480 + CAM_FRAMESIZE_WVGA2, // 752x480 + CAM_FRAMESIZE_SVGA, // 800x600 + CAM_FRAMESIZE_XGA, // 1024x768 + CAM_FRAMESIZE_SXGA, // 1280x1024 + CAM_FRAMESIZE_UXGA, // 1600x1200 + CAM_FRAMESIZE_HD, // 1280x720 + CAM_FRAMESIZE_FHD, // 1920x1080 + CAM_FRAMESIZE_QHD, // 2560x1440 + CAM_FRAMESIZE_QXGA, // 2048x1536 + CAM_FRAMESIZE_WQXGA, // 2560x1600 + CAM_FRAMESIZE_WQXGA2, // 2592x1944 +} cam_framesize_t; + +typedef enum { + CAM_GAINCEILING_2X, + CAM_GAINCEILING_4X, + CAM_GAINCEILING_8X, + CAM_GAINCEILING_16X, + CAM_GAINCEILING_32X, + CAM_GAINCEILING_64X, + CAM_GAINCEILING_128X, +} cam_gainceiling_t; + +typedef enum { + CAM_SDE_NORMAL, + CAM_SDE_NEGATIVE, +} cam_sde_t; diff --git a/fw/fe310/eos/dev/ctp.c b/fw/fe310/eos/dev/ctp.c index fcc3c68..e58f929 100644 --- a/fw/fe310/eos/dev/ctp.c +++ b/fw/fe310/eos/dev/ctp.c @@ -10,17 +10,13 @@ #include "eve/eve_touch_engine.h" #include "egpio.h" +#include "egpio_priv.h" #include "eve.h" -#include "pwr.h" #include "drv/fxl6408.h" #include "drv/gt911.h" #include "ctp.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - int eos_ctp_init(void) { uint8_t wakeup_cause; int rv, rst; @@ -36,7 +32,15 @@ int eos_ctp_init(void) { return rv; } +int _eos_ctp_reset(void) { + if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; + + gt911_reset(); + return EOS_OK; +} + int eos_ctp_reset(void) { + uint8_t status = 0; int rv; if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; @@ -52,10 +56,17 @@ int eos_ctp_reset(void) { return EOS_OK; } +int _eos_ctp_sleep(void) { + if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; + + return gt911_sleep(); +} + int eos_ctp_sleep(void) { int rv; if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; + if (!gt911_running()) return EOS_ERR; rv = eos_egpio_intr_disable(); if (rv) return rv; @@ -69,10 +80,18 @@ int eos_ctp_sleep(void) { return EOS_OK; } +int _eos_ctp_wake(void) { + if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; + + gt911_wake(); + return EOS_OK; +} + int eos_ctp_wake(void) { int rv; if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; + if (gt911_running()) return EOS_ERR; rv = eos_egpio_fxl_set_pin(EGPIO_PIN_CTP_INT, FXL6408_REG_PULL_DIR, 1); if (rv) return rv; @@ -86,7 +105,7 @@ int eos_ctp_wake(void) { } int eos_ctp_give(void) { - int rv; + int rv, _rv; if (!eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; if (!eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR; @@ -94,23 +113,24 @@ int eos_ctp_give(void) { rv = eos_egpio_intr_disable(); if (rv) return rv; - rv = eve_select(); - if (rv) return rv; - rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0); - if (rv) return rv; + if (rv) goto ctp_give_err; + + rv = eve_select(); + if (rv) goto ctp_give_err; eve_touch_set_engine(EVE_TOUCH_ENGINE_GOODIX); eve_deselect(); - rv = eos_egpio_intr_set(); - if (rv) return rv; +ctp_give_err: + _rv = eos_egpio_intr_set(); + if (!rv && _rv) return _rv; - return EOS_OK; + return rv; } int eos_ctp_take(void) { - int rv; + int rv, _rv; if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR; @@ -119,26 +139,26 @@ int eos_ctp_take(void) { if (rv) return rv; rv = eve_select(); - if (rv) return rv; + if (rv) goto ctp_take_err; eve_touch_set_engine(EVE_TOUCH_ENGINE_HOST); eve_deselect(); rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 1); - if (rv) return rv; + if (rv) goto ctp_take_err; gt911_reset(); - rv = eos_egpio_intr_set(); - if (rv) return rv; +ctp_take_err: + _rv = eos_egpio_intr_set(); + if (!rv && _rv) return _rv; - return EOS_OK; + return rv; } int eos_ctp_handle_intr(void) { uint8_t status; uint8_t points[GT911_SIZE_PBUF * GT911_MAX_POINTS]; - static int clear_tag0 = 0; int i, num_points; int rv; uint32_t start; @@ -150,11 +170,11 @@ int eos_ctp_handle_intr(void) { num_points = status & 0xf; if (num_points > 5) { rv = EOS_ERR; - goto handle_intr_fin; + goto handle_intr_fin1; } rv = eve_select(); - if (rv) goto handle_intr_fin; + if (rv) goto handle_intr_fin1; start = eos_get_tick(); while (!eve_touch_ehost_ready()) { @@ -163,20 +183,14 @@ int eos_ctp_handle_intr(void) { if (eos_tdelta_ms(start) > EVE_CMD_EXEC_TO) { rv = EOS_ERR_TIMEOUT; - eve_deselect(); - goto handle_intr_fin; + goto handle_intr_fin0; } if (num_points) { - if (clear_tag0) { - eve_touch_clear_tag0(); - clear_tag0 = 0; - } rv = gt911_get_points(num_points, points); if (rv) { rv = EOS_ERR; - eve_deselect(); - goto handle_intr_fin; + goto handle_intr_fin0; } for (i=0; i<num_points; i++) { @@ -193,20 +207,14 @@ int eos_ctp_handle_intr(void) { } } else { eve_touch_ehost_enter(0, 0x8000, 0x8000); - clear_tag0 = 1; } eve_touch_ehost_end(); +handle_intr_fin0: eve_deselect(); - -handle_intr_fin: +handle_intr_fin1: gt911_set_status(0); - if (rv) { -#ifdef EOS_DEBUG - printf("CTP HANDLE INTR ERR:%d\n", rv); -#endif - return rv; - } + if (rv) return rv; - return 1; + return status; } diff --git a/fw/fe310/eos/dev/ctp.h b/fw/fe310/eos/dev/ctp.h index 72a0a75..c17f1e4 100644 --- a/fw/fe310/eos/dev/ctp.h +++ b/fw/fe310/eos/dev/ctp.h @@ -1,7 +1,14 @@ #include <stdint.h> int eos_ctp_init(void); + +int _eos_ctp_reset(void); int eos_ctp_reset(void); + +int _eos_ctp_sleep(void); int eos_ctp_sleep(void); + +int _eos_ctp_wake(void); int eos_ctp_wake(void); + int eos_ctp_handle_intr(void);
\ No newline at end of file diff --git a/fw/fe310/eos/dev/drv/arducam.c b/fw/fe310/eos/dev/drv/arducam.c index a50830a..8ac3823 100644 --- a/fw/fe310/eos/dev/drv/arducam.c +++ b/fw/fe310/eos/dev/drv/arducam.c @@ -36,21 +36,21 @@ #define ARDUCAM_VAL_GPIO_PWREN 0x04 static uint8_t reg_read(uint8_t addr) { - uint8_t ret; + uint8_t rv; - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(addr, 0); - ret = drv_spi_xchg8(0, 0); - drv_spi_cs_clear(); + rv = drv_spi_xchg8(0, 0); + drv_spi_clear_cs(); - return ret; + return rv; } static void reg_write(uint8_t addr, uint8_t val) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(addr | 0x80, 0); drv_spi_xchg8(val, 0); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } void arducam_capture(void) { @@ -70,25 +70,25 @@ void arducam_capture_wait(void) { } uint32_t arducam_fbuf_size(void) { - uint32_t ret; + uint32_t rv; - ret = reg_read(ARDUCAM_REG_FIFO_SIZE1); - ret |= reg_read(ARDUCAM_REG_FIFO_SIZE2) << 8; - ret |= (reg_read(ARDUCAM_REG_FIFO_SIZE3) & 0x7f) << 16; - return ret; + rv = reg_read(ARDUCAM_REG_FIFO_SIZE1); + rv |= reg_read(ARDUCAM_REG_FIFO_SIZE2) << 8; + rv |= (reg_read(ARDUCAM_REG_FIFO_SIZE3) & 0x7f) << 16; + return rv; } void arducam_fbuf_read(uint8_t *buffer, uint16_t sz, int first) { int i; - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(ARDUCAM_REG_READ_BURST, 0); if (first) drv_spi_xchg8(0, 0); for (i=0; i<sz; i++) { buffer[i] = drv_spi_xchg8(0, 0); } - drv_spi_cs_clear(); + drv_spi_clear_cs(); } void arducam_fbuf_done(void) { diff --git a/fw/fe310/eos/dev/drv/gt911.c b/fw/fe310/eos/dev/drv/gt911.c index cd71d9a..8eb4358 100644 --- a/fw/fe310/eos/dev/drv/gt911.c +++ b/fw/fe310/eos/dev/drv/gt911.c @@ -124,6 +124,10 @@ void gt911_wake(void) { drv_gpio_set(GPIO_INPUT_EN, GT911_PIN_INT); } +int gt911_running(void) { + return drv_gpio_get(GPIO_INPUT_EN, GT911_PIN_INT); +} + int gt911_cfg_read(uint8_t *cfg_buf) { int rv; @@ -148,20 +152,20 @@ int gt911_cfg_print(void) { rv = gt911_cfg_read(cfg_buf); if (rv) return rv; - printf("GT911 CFG:\n"); + DRV_LOG(DRV_LOG_INFO, "GT911 CFG:\n"); for (i=0; i<GT911_SIZE_CFG-2; i++) { - printf("%.2X", cfg_buf[i]); + DRV_LOG(DRV_LOG_INFO, "%.2X", cfg_buf[i]); if (i % 8 == 7) { - printf("\n"); + DRV_LOG(DRV_LOG_INFO, "\n"); } else { - printf(" "); + DRV_LOG(DRV_LOG_INFO, " "); } } rv = gt911_fw_ver(cfg_buf); if (rv) return rv; - printf("GT911 FW VER:%.2X%.2X\n", cfg_buf[1], cfg_buf[0]); + DRV_LOG(DRV_LOG_INFO, "GT911 FW VER:%.2X%.2X\n", cfg_buf[1], cfg_buf[0]); return DRV_OK; } diff --git a/fw/fe310/eos/dev/drv/gt911.h b/fw/fe310/eos/dev/drv/gt911.h index 9db6981..61a6593 100644 --- a/fw/fe310/eos/dev/drv/gt911.h +++ b/fw/fe310/eos/dev/drv/gt911.h @@ -10,6 +10,7 @@ void gt911_reset(void); int gt911_sleep(void); void gt911_wake(void); +int gt911_running(void); int gt911_cfg_read(uint8_t *cfg_buf); int gt911_cfg_write(uint8_t *cfg_buf); diff --git a/fw/fe310/eos/dev/drv/ili9806e.c b/fw/fe310/eos/dev/drv/ili9806e.c index 45aabb7..b57a14c 100644 --- a/fw/fe310/eos/dev/drv/ili9806e.c +++ b/fw/fe310/eos/dev/drv/ili9806e.c @@ -5,15 +5,11 @@ #include "platform.h" #include "ili9806e.h" -#ifdef DRV_DEBUG -#include <stdio.h> -#endif - int ili9806e_init(void) { int rv; uint8_t chip_id[3]; - drv_spi_cs_set(); + drv_spi_set_cs(); /* LCD Setting */ drv_spi9bit_write(0, 0xFF); // change to Page 1 CMD @@ -38,15 +34,13 @@ int ili9806e_init(void) { drv_spi9bit_write(0, 0x02); drv_spi9bit_read(&chip_id[2]); -#ifdef DRV_DEBUG - printf("LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]); -#endif + DRV_LOG(DRV_LOG_INFO, "LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]); drv_spi9bit_write(0, 0xFE); // disable read drv_spi9bit_write(1, 0x00); if (memcmp(chip_id, "\x98\x06\x04", sizeof(chip_id))) { - drv_spi_cs_clear(); + drv_spi_clear_cs(); return DRV_ERR_NOTFOUND; } @@ -404,28 +398,28 @@ int ili9806e_init(void) { drv_spi9bit_write(0, 0x29); drv_sleep(25); - drv_spi_cs_clear(); + drv_spi_clear_cs(); return DRV_OK; } void ili9806e_sleep(void) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi9bit_write(0, 0x28); drv_sleep(10); drv_spi9bit_write(0, 0x10); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } void ili9806e_wake(void) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi9bit_write(0, 0x11); drv_sleep(120); drv_spi9bit_write(0, 0x29); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } diff --git a/fw/fe310/eos/dev/drv/pcm1770.c b/fw/fe310/eos/dev/drv/pcm1770.c index c617ae9..eec7bd0 100644 --- a/fw/fe310/eos/dev/drv/pcm1770.c +++ b/fw/fe310/eos/dev/drv/pcm1770.c @@ -5,8 +5,8 @@ #include "pcm1770.h" void pcm1770_reg_write(uint8_t addr, uint8_t val) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(addr, 0); drv_spi_xchg8(val, 0); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } diff --git a/fw/fe310/eos/dev/drv/platform.h b/fw/fe310/eos/dev/drv/platform.h index d1f7248..a2405d5 100644 --- a/fw/fe310/eos/dev/drv/platform.h +++ b/fw/fe310/eos/dev/drv/platform.h @@ -1,6 +1,7 @@ #include "board.h" #include "eos.h" +#include "log.h" #include "soc/timer.h" #include "soc/i2c.h" #include "soc/spi.h" @@ -16,17 +17,18 @@ #define DRV_ERR EOS_ERR #define DRV_ERR_NOTFOUND EOS_ERR_NOTFOUND -/* should define theese for non-EOS platforms: -#define GPIO_INPUT_EN -#define GPIO_OUTPUT_EN -#define GPIO_OUTPUT_VAL -*/ +#define DRV_LOG_DEBUG EOS_LOG_DEBUG +#define DRV_LOG_INFO EOS_LOG_INFO +#define DRV_LOG_ERR EOS_LOG_ERR +#define DRV_LOG_NONE EOS_LOG_NONE +#define DRV_LOG_LEVEL EOS_LOG_LEVEL +#define DRV_LOG(l, ...) EOS_LOG(l, __VA_ARGS__) #define GT911_PIN_INT CTP_PIN_INT #define GT911_PIN_RST CTP_PIN_RST -#define drv_spi_cs_set eos_spi_cs_set -#define drv_spi_cs_clear eos_spi_cs_clear +#define drv_spi_set_cs eos_spi_set_cs +#define drv_spi_clear_cs eos_spi_clear_cs #define drv_spi_xchg8 eos_spi_xchg8 #define drv_spi9bit_read eos_spi9bit_read #define drv_spi9bit_write eos_spi9bit_write @@ -38,5 +40,12 @@ #define drv_sleep eos_sleep +/* should define theese for non-EOS platforms: +#define GPIO_INPUT_EN +#define GPIO_OUTPUT_EN +#define GPIO_OUTPUT_VAL +*/ + +#define drv_gpio_get eos_gpio_get #define drv_gpio_set eos_gpio_set #define drv_gpio_clear eos_gpio_clear diff --git a/fw/fe310/eos/dev/drv/sdc_platform.h b/fw/fe310/eos/dev/drv/sdc_platform.h index 5d562c2..daf2670 100644 --- a/fw/fe310/eos/dev/drv/sdc_platform.h +++ b/fw/fe310/eos/dev/drv/sdc_platform.h @@ -1,19 +1,31 @@ /* included from sdcard.h - needs relative includes */ #include "../../eos.h" +#include "../../log.h" #include "../../soc/timer.h" #include "../../soc/spi.h" #include "../sdc_crypto.h" +#ifdef EOS_DEBUG +#define SDC_DEBUG +#endif + #define SDC_OK EOS_OK #define SDC_ERR EOS_ERR #define SDC_ERR_BUSY EOS_ERR_BUSY +#define SDC_LOG_DEBUG EOS_LOG_DEBUG +#define SDC_LOG_INFO EOS_LOG_INFO +#define SDC_LOG_ERR EOS_LOG_ERR +#define SDC_LOG_NONE EOS_LOG_NONE +#define SDC_LOG_LEVEL EOS_LOG_LEVEL +#define SDC_LOG(l, ...) EOS_LOG(l, __VA_ARGS__) + #define sdc_spi_xchg8 eos_spi_xchg8 #define sdc_spi_xchg16 eos_spi_xchg16 #define sdc_spi_xchg32 eos_spi_xchg32 -#define sdc_spi_cs_set eos_spi_cs_set -#define sdc_spi_cs_clear eos_spi_cs_clear +#define sdc_spi_set_cs eos_spi_set_cs +#define sdc_spi_clear_cs eos_spi_clear_cs #define sdc_sleep eos_sleep #define sdc_get_tick eos_get_tick #define sdc_tdelta_ms eos_tdelta_ms diff --git a/fw/fe310/eos/dev/drv/sdcard.c b/fw/fe310/eos/dev/drv/sdcard.c index 96b01ae..7d21b3d 100644 --- a/fw/fe310/eos/dev/drv/sdcard.c +++ b/fw/fe310/eos/dev/drv/sdcard.c @@ -126,18 +126,18 @@ static void sdc_buf_recv(unsigned char *buffer, uint16_t len) { } static void sdc_select(void) { - sdc_spi_cs_set(); + sdc_spi_set_cs(); sdc_spi_xchg8(0xff, 0); } static void sdc_deselect(void) { - sdc_spi_cs_clear(); + sdc_spi_clear_cs(); sdc_spi_xchg8(0xff, 0); } static int sdc_xchg_cmd(uint8_t cmd, uint32_t arg, uint8_t flags) { int i; - uint8_t ret; + uint8_t rv; uint8_t crc = 0x7f; cmd |= 0x40; @@ -156,11 +156,11 @@ static int sdc_xchg_cmd(uint8_t cmd, uint32_t arg, uint8_t flags) { i = SDC_NCR; do { - ret = sdc_xchg8(0xff); - } while ((ret & 0x80) && --i); - if (ret & 0x80) return SDC_ERR_BUSY; + rv = sdc_xchg8(0xff); + } while ((rv & 0x80) && --i); + if (rv & 0x80) return SDC_ERR_BUSY; - return ret; + return rv; } static int sdc_ready(uint32_t timeout) { @@ -256,11 +256,12 @@ int sdc_init(uint32_t timeout) { uint32_t start; start = sdc_get_tick(); - sdc_sleep(5); - for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */ + do { + if (sdc_tdelta_ms(start) > timeout) return SDC_ERR_BUSY; + for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */ - rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD); - if (rv != SDC_R1_IDLE_STATE) return SDC_RV2ERR(rv); + rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD); + } while (rv != SDC_R1_IDLE_STATE); sdc_select(); rv = sdc_cmd(SEND_IF_COND, 0x1aa, SDC_CMD_FLAG_CRC | SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); @@ -341,11 +342,11 @@ int sdc_init(uint32_t timeout) { if (rv) return rv; #ifdef SDC_DEBUG - printf("SDCARD CSD: "); + SDC_LOG(SDC_LOG_INFO, "SDCARD CSD: "); for (i=0; i<16; i++) { - printf("%.2x ", csd[i]); + SDC_LOG(SDC_LOG_INFO, "%.2x ", csd[i]); } - printf("\n"); + SDC_LOG(SDC_LOG_INFO, "\n"); #endif if (csd[10] & 0x40) _type |= SDC_CAP_ERASE_EN; } @@ -366,7 +367,7 @@ void sdc_clear(void) { sdc_type = SDC_TYPE_NONE; } -int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) { +int sdc_get_sect_count(uint32_t *sectors, uint32_t timeout) { int rv; uint8_t csd[16]; uint32_t start; @@ -393,7 +394,7 @@ int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) { return SDC_OK; } -int sdc_get_blk_size(uint32_t timeout, uint32_t *size) { +int sdc_get_blk_size(uint32_t *size, uint32_t timeout) { int rv; uint8_t rbl[64]; /* SD Status or CSD register */ uint32_t start; diff --git a/fw/fe310/eos/dev/drv/sdcard.h b/fw/fe310/eos/dev/drv/sdcard.h index 39891bb..b4da896 100644 --- a/fw/fe310/eos/dev/drv/sdcard.h +++ b/fw/fe310/eos/dev/drv/sdcard.h @@ -20,8 +20,8 @@ uint8_t sdc_get_type(void); uint8_t sdc_get_cap(void); void sdc_clear(void); -int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors); -int sdc_get_blk_size(uint32_t timeout, uint32_t *size); +int sdc_get_sect_count(uint32_t *sectors, uint32_t timeout); +int sdc_get_blk_size(uint32_t *size, uint32_t timeout); int sdc_sync(uint32_t timeout); int sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout); int sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer); diff --git a/fw/fe310/eos/dev/egpio.c b/fw/fe310/eos/dev/egpio.c index 7358082..076986a 100644 --- a/fw/fe310/eos/dev/egpio.c +++ b/fw/fe310/eos/dev/egpio.c @@ -6,6 +6,8 @@ #include "board.h" #include "eos.h" +#include "log.h" + #include "event.h" #include "soc/interrupt.h" @@ -18,24 +20,31 @@ #include "sdcard.h" #include "ctp.h" #include "eve.h" + #include "app.h" #include "drv/fxl6408.h" #include "egpio.h" +#include "egpio_priv.h" /* FXL chip only */ -static const uint8_t egpio_switch[2] = { - EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE, +static const uint8_t egpio_switch[EGPIO_MAX_FXL_CHIP] = { + EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE, EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET, }; static uint8_t egpio_pinval[EGPIO_MAX_CHIP]; +static uint8_t egpio_intmask[EGPIO_MAX_FXL_CHIP]; static uint8_t egpio_alt_pin; static uint32_t wake_start; static eos_egpio_intr_handler_t egpio_intr_handler; static eos_egpio_ext_handler_t egpio_ext_handler; +static int egpio_fxl_set_mask(uint8_t chip_id, uint8_t mask); +static int egpio_set_val(uint8_t pin, int val); +static int egpio_get_val(uint8_t pin); + #define EGPIO_ALT_EVEAUDIO_DIS 0x01 #define EGPIO_ALT_LSGAIN_SEL 0x02 #define EGPIO_ALT_AUDIO_SEL 0x04 @@ -43,8 +52,8 @@ static eos_egpio_ext_handler_t egpio_ext_handler; #define BITSET(var, bit, val) { var = (val) ? (var | (bit)) : (var & ~(bit)); } #define PINSWITCH(STPIN, SETPIN) { \ int rv; \ - BITSET(egpio_alt_pin, pin2alt_bit(STPIN), _eos_egpio_get_val(STPIN)); \ - rv = _eos_egpio_set_val(SETPIN, !!(egpio_alt_pin & pin2alt_bit(SETPIN))); \ + BITSET(egpio_alt_pin, pin2alt_bit(STPIN), egpio_get_val(STPIN)); \ + rv = egpio_set_val(SETPIN, !!(egpio_alt_pin & pin2alt_bit(SETPIN))); \ if (rv) return rv; \ } @@ -65,20 +74,22 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { int rv; switch (chip_id) { - case 0: { + case EGPIO_CHIP_FXL0: { if (intr & EGPIO_BIT_BAT_INT) { uint8_t fault0, fault1; rv = eos_batt_read_fault(&fault0, &fault1); if (rv) return rv; - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_BAT, fault1, fault0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_BAT, fault1, fault0); } if (intr & EGPIO_BIT_CTP_INT) { - eos_ctp_handle_intr(); + rv = eos_ctp_handle_intr(); + if (rv < 0) return rv; } if (intr & EGPIO_BIT_EVE_INT) { - eos_eve_handle_intr(); + rv = eos_eve_handle_intr(); + if (rv < 0) return rv; } if (intr & EGPIO_BIT_BTN_WAKE) { int btn_wake, tdelta; @@ -89,27 +100,29 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { } else { tdelta = eos_tdelta_ms(wake_start); } - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_WAKE, btn_wake, btn_wake ? tdelta : 0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_WAKE, btn_wake, btn_wake ? tdelta : 0); } - if (intr & EGPIO_BIT_SDCARD_DET) { - int sdc_det = eos_egpio_get_val(EGPIO_PIN_SDCARD_DET); + if (intr & EGPIO_BIT_SDCARD_NDET) { + int sdc_det; - eos_sdc_insert(sdc_det); - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_SDCARD, sdc_det, 0); + sdc_det = !eos_egpio_get_val(EGPIO_PIN_SDCARD_NDET); + rv = eos_sdc_insert(sdc_det, 0); + if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INSERT ERR:%d\n", rv); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_SDCARD, sdc_det, rv); } break; } - case 1: { + case EGPIO_CHIP_FXL1: { if (intr & EGPIO_BIT_MIC_MUTE) { - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_MUTE, eos_egpio_get_val(EGPIO_PIN_MIC_MUTE), 0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_MUTE, eos_egpio_get_val(EGPIO_PIN_MIC_MUTE), 0); } if (intr & EGPIO_BIT_HP_NDET) { int hp_det, i2s_running, app_audio; hp_det = !eos_egpio_get_val(EGPIO_PIN_HP_NDET); i2s_running = eos_i2s_running(); - app_audio = !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL); + app_audio = !egpio_get_val(EGPIO_PIN_AUDIO_SEL); if (i2s_running || app_audio) { if (i2s_running) { eos_i2s_hp_change(hp_det); @@ -125,7 +138,7 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { PINSWITCH(EGPIO_PIN_EVEAUDIO_DIS, EGPIO_PIN_LSGAIN_SEL); } } - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_HP, hp_det, 0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_HP, hp_det, 0); } break; } @@ -135,14 +148,18 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { } static int handle_egpio_evt(uint8_t chip_id) { - uint8_t intr_reg, def_reg; + uint8_t intr_reg, mask_reg; int rv; rv = fxl6408_reg_read(chip_id, FXL6408_REG_INT_STATE, &intr_reg); - if (rv) return rv;; - if (!intr_reg) return 0; + if (rv) return rv; + + intr_reg &= ~egpio_intmask[chip_id]; + if (!intr_reg) return EOS_OK; if (intr_reg & egpio_switch[chip_id]) { + uint8_t def_reg; + rv = fxl6408_reg_read(chip_id, FXL6408_REG_I_DEFAULT, &def_reg); if (rv) return rv; @@ -157,64 +174,63 @@ static int handle_egpio_evt(uint8_t chip_id) { rv = handle_egpio_intr(chip_id, intr_reg); if (rv) return rv; - return 1; + return EOS_OK; } -static void handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - type &= ~EOS_EVT_MASK; - - switch (type) { - case EGPIO_ETYPE_INT: { - int rv; +static void handle_evt(unsigned char type, EOSMessage *msg, uint16_t len) { + int rv; - rv = handle_egpio_evt(0); - if (rv < 0) goto handle_evt_fin; + switch (type & ~EOS_EVT_MASK) { + case EOS_EGPIO_ETYPE_INT: { + rv = handle_egpio_evt(EGPIO_CHIP_FXL0); + if (rv) goto handle_evt_fin; if (GPIO_REG(GPIO_INPUT_VAL) & (1 << EGPIO_PIN_INT)) goto handle_evt_fin; - rv = handle_egpio_evt(1); - if (rv < 0) goto handle_evt_fin; + rv = handle_egpio_evt(EGPIO_CHIP_FXL1); + if (rv) goto handle_evt_fin; if (GPIO_REG(GPIO_INPUT_VAL) & (1 << EGPIO_PIN_INT)) goto handle_evt_fin; if (egpio_ext_handler) rv = egpio_ext_handler(); handle_evt_fin: - clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_LOW_IP) = (1 << EGPIO_PIN_INT); + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT); set_csr(mstatus, MSTATUS_MIE); + if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO HANDLE INTR ERR:%d\n", rv); break; } - case EGPIO_ETYPE_INT_CTP: - case EGPIO_ETYPE_INT_EVE: { + case EOS_EGPIO_ETYPE_INT_CTP: { if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) { - eos_ctp_handle_intr(); + rv = eos_ctp_handle_intr(); } else { - eos_eve_handle_intr(); + rv = eos_eve_handle_intr(); } -handle_evt_eve_fin: + GPIO_REG(GPIO_LOW_IP) = (1 << CTP_PIN_INT); clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INT); - GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) |= (1 << CTP_PIN_INT); set_csr(mstatus, MSTATUS_MIE); + if (rv < 0) EOS_LOG(EOS_LOG_ERR, "CTP/EVE HANDLE INTR ERR:%d\n", rv); break; } + + default: + eos_evtq_bad_handler(type, msg, len); + break; + } } static void handle_intr(void) { GPIO_REG(GPIO_LOW_IE) &= ~(1 << EGPIO_PIN_INT); - eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT, NULL, 0); + eos_evtq_push_isr(EOS_EVT_EGPIO | EOS_EGPIO_ETYPE_INT, NULL, 0); } -static void handle_intr_eve(void) { - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); - if (egpio_pinval[EGPIO_CHIP_FXL0] & EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL)) { - eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT_CTP, NULL, 0); - } else { - eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT_EVE, NULL, 0); - } +static void handle_intr_ctp(void) { + GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT); + eos_evtq_push_isr(EOS_EVT_EGPIO | EOS_EGPIO_ETYPE_INT_CTP, NULL, 0); } int eos_egpio_init(void) { @@ -224,83 +240,98 @@ int eos_egpio_init(void) { wakeup_cause = eos_pwr_wakeup_cause(); rst = (wakeup_cause == EOS_PWR_WAKE_RST); if (rst) { - rv = fxl6408_reg_read(0, FXL6408_REG_ID_CTRL, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_ID_CTRL, &data); + if (rv) return rv; + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_ID_CTRL, &data); + if (rv) return rv; + + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, 0xff); if (rv) return rv; - rv = fxl6408_reg_read(1, FXL6408_REG_ID_CTRL, &data); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL1, 0xff); if (rv) return rv; - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, 0xff); + /* clear interrupts */ + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_INT_STATE, &data); if (rv) return rv; - rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, 0xff); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_INT_STATE, &data); if (rv) return rv; /* 1st chip */ data = EGPIO_BIT_CTP_SEL | EGPIO_BIT_EXP_IO0 | EGPIO_BIT_EXP_IO1; - rv = fxl6408_reg_write(0, FXL6408_REG_IO_DIR, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_IO_DIR, data); if (rv) return rv; data = EGPIO_BIT_CTP_SEL; - rv = fxl6408_reg_write(0, FXL6408_REG_O_STATE, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_O_STATE, data); if (rv) return rv; data = EGPIO_BIT_EXP_IO0 | EGPIO_BIT_EXP_IO1; - rv = fxl6408_reg_write(0, FXL6408_REG_O_HIZ, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_O_HIZ, data); if (rv) return rv; - data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; - rv = fxl6408_reg_write(0, FXL6408_REG_PULL_ENA, data); + data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_PULL_ENA, data); if (rv) return rv; - data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; - rv = fxl6408_reg_write(0, FXL6408_REG_PULL_DIR, data); + data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_PULL_DIR, data); if (rv) return rv; /* 2nd chip */ data = EGPIO_BIT_HPAMP_CS | EGPIO_BIT_AUDIO_SEL | EGPIO_BIT_USR0 | EGPIO_BIT_USR1 | EGPIO_BIT_USR2 | EGPIO_BIT_USR3; - rv = fxl6408_reg_write(1, FXL6408_REG_IO_DIR, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_IO_DIR, data); if (rv) return rv; data = EGPIO_BIT_HPAMP_CS | EGPIO_BIT_AUDIO_SEL; - rv = fxl6408_reg_write(1, FXL6408_REG_O_STATE, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_O_STATE, data); if (rv) return rv; data = EGPIO_BIT_USR0 | EGPIO_BIT_USR1 | EGPIO_BIT_USR2 | EGPIO_BIT_USR3; - rv = fxl6408_reg_write(1, FXL6408_REG_O_HIZ, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_O_HIZ, data); if (rv) return rv; data = 0; - rv = fxl6408_reg_write(1, FXL6408_REG_PULL_ENA, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_PULL_ENA, data); if (rv) return rv; data = 0; - rv = fxl6408_reg_write(1, FXL6408_REG_PULL_DIR, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_PULL_DIR, data); if (rv) return rv; + } else { + /* read interrupt mask */ + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_INT_MASK, &data); + if (rv) return rv; + egpio_intmask[EGPIO_CHIP_FXL0] = data; + + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_INT_MASK, &data); + if (rv) return rv; + egpio_intmask[EGPIO_CHIP_FXL1] = data; } - rv = fxl6408_reg_read(0, FXL6408_REG_I_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_I_STATE, &data); if (rv) return rv; - data &= egpio_switch[0]; + data &= egpio_switch[EGPIO_CHIP_FXL0]; egpio_pinval[EGPIO_CHIP_FXL0] = data; data |= EGPIO_BIT_EVE_INT | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; - rv = fxl6408_reg_write(0, FXL6408_REG_I_DEFAULT, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_I_DEFAULT, data); if (rv) return rv; - rv = fxl6408_reg_read(0, FXL6408_REG_IO_DIR, &data_dir); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_IO_DIR, &data_dir); if (rv) return rv; - rv = fxl6408_reg_read(0, FXL6408_REG_O_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_O_STATE, &data); if (rv) return rv; egpio_pinval[EGPIO_CHIP_FXL0] |= (data & data_dir); - rv = fxl6408_reg_read(1, FXL6408_REG_I_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_I_STATE, &data); if (rv) return rv; - data &= egpio_switch[1]; + data &= egpio_switch[EGPIO_CHIP_FXL1]; egpio_pinval[EGPIO_CHIP_FXL1] = data; - rv = fxl6408_reg_write(1, FXL6408_REG_I_DEFAULT, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_I_DEFAULT, data); if (rv) return rv; - rv = fxl6408_reg_read(1, FXL6408_REG_IO_DIR, &data_dir); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_IO_DIR, &data_dir); if (rv) return rv; - rv = fxl6408_reg_read(1, FXL6408_REG_O_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_O_STATE, &data); if (rv) return rv; egpio_pinval[EGPIO_CHIP_FXL1] |= (data & data_dir); @@ -313,31 +344,31 @@ int eos_egpio_run(void) { eos_evtq_set_handler(EOS_EVT_EGPIO, handle_evt); - GPIO_REG(GPIO_INPUT_EN) |= (1 << EGPIO_PIN_INT); - clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT); - set_csr(mstatus, MSTATUS_MIE); - eos_intr_set(INT_GPIO_BASE + EGPIO_PIN_INT, IRQ_PRIORITY_EGPIO, handle_intr); - - /* EVE_PIN_INT will be set in intr_set() below */ - eos_intr_set(INT_GPIO_BASE + EVE_PIN_INT, IRQ_PRIORITY_EVE, handle_intr_eve); - wakeup_cause = eos_pwr_wakeup_cause(); rst = (wakeup_cause == EOS_PWR_WAKE_RST); if (rst) { - /* turn on interrupts when all is configured */ - data = ~(EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT); - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + /* enable interrupts when all is configured */ + data = ~(EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, data); if (rv) return rv; data = ~(EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET); - rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, data); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL1, data); if (rv) return rv; } rv = eos_egpio_intr_set(); if (rv) return rv; + /* CTP_PIN_INT is configured in intr_set() above */ + eos_intr_set(INT_GPIO_BASE + CTP_PIN_INT, IRQ_PRIORITY_CTP, handle_intr_ctp); + + GPIO_REG(GPIO_INPUT_EN) |= (1 << EGPIO_PIN_INT); + clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT); + set_csr(mstatus, MSTATUS_MIE); + eos_intr_set(INT_GPIO_BASE + EGPIO_PIN_INT, IRQ_PRIORITY_EGPIO, handle_intr); + return EOS_OK; } @@ -346,33 +377,32 @@ void eos_egpio_eve_set(uint16_t gpio_reg) { if (gpio_reg & (1 << EVE_GPIO_DISP)) egpio_pinval[EGPIO_CHIP_EVE] |= EGPIO_PIN2BIT(EGPIO_PIN_DISP_SEL); } -int _eos_egpio_intr_set(int i2s_running, int app_disp) { - uint8_t data; +static int egpio_intr_set(int i2s_running, int app_disp) { + uint8_t mask; int rv; - rv = fxl6408_reg_read(0, FXL6408_REG_INT_MASK, &data); - if (rv) return rv; + mask = egpio_intmask[EGPIO_CHIP_FXL0]; + mask |= EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT; - data &= ~(EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); - if (app_disp) { - data |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); - } else if (!i2s_running) { - if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) { - data |= EGPIO_BIT_CTP_INT; + if (!app_disp) { + if (i2s_running) { + mask &= ~(EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); + } else if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) { + mask &= ~EGPIO_BIT_EVE_INT; } else { - data |= EGPIO_BIT_EVE_INT; + mask &= ~EGPIO_BIT_CTP_INT; } } - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, mask); if (rv) return rv; - GPIO_REG(GPIO_INPUT_EN) |= (1 << EVE_PIN_INT); + GPIO_REG(GPIO_INPUT_EN) |= (1 << CTP_PIN_INT); clear_csr(mstatus, MSTATUS_MIE); if (app_disp || i2s_running) { - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT); } else { - GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) |= (1 << CTP_PIN_INT); } set_csr(mstatus, MSTATUS_MIE); @@ -380,25 +410,23 @@ int _eos_egpio_intr_set(int i2s_running, int app_disp) { } int eos_egpio_intr_set(void) { - return _eos_egpio_intr_set(eos_i2s_running(), !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); + return egpio_intr_set(eos_i2s_running(), !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); } int eos_egpio_intr_disable(void) { - uint8_t data; + uint8_t mask; int rv; - rv = fxl6408_reg_read(0, FXL6408_REG_INT_MASK, &data); - if (rv) return rv; - - data |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); + mask = egpio_intmask[EGPIO_CHIP_FXL0]; + mask |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, mask); if (rv) return rv; clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT); set_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << EVE_PIN_INT); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << CTP_PIN_INT); return EOS_OK; } @@ -435,7 +463,17 @@ int eos_egpio_fxl_set_pin(uint8_t reg, uint8_t pin, uint8_t val) { return EOS_OK; } -int _eos_egpio_get_val(uint8_t pin) { +static int egpio_fxl_set_mask(uint8_t chip_id, uint8_t mask) { + int rv; + + rv = fxl6408_reg_write(chip_id, FXL6408_REG_INT_MASK, mask); + if (rv) return rv; + + egpio_intmask[chip_id] = mask; + return EOS_OK; +} + +static int egpio_get_val(uint8_t pin) { uint8_t chip_id; chip_id = EGPIO_PIN2CHIP(pin); @@ -443,7 +481,7 @@ int _eos_egpio_get_val(uint8_t pin) { return !!(egpio_pinval[chip_id] & EGPIO_PIN2BIT(pin)); } -int _eos_egpio_set_val(uint8_t pin, int val) { +static int egpio_set_val(uint8_t pin, int val) { uint8_t chip_id; int rv; @@ -485,7 +523,7 @@ int eos_egpio_get_val(uint8_t pin) { case EGPIO_PIN_EVEAUDIO_DIS: case EGPIO_PIN_LSGAIN_SEL: { - int lspk_on = (eos_i2s_running() || !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); + int lspk_on = (eos_i2s_running() || !egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) { return !!(egpio_alt_pin & pin2alt_bit(pin)); @@ -498,7 +536,7 @@ int eos_egpio_get_val(uint8_t pin) { } } - return _eos_egpio_get_val(pin); + return egpio_get_val(pin); } int eos_egpio_set_val(uint8_t pin, int val) { @@ -520,7 +558,7 @@ int eos_egpio_set_val(uint8_t pin, int val) { return EOS_OK; } - if ((val != _eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { + if ((val != egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { if (val) { /* store LSGAIN_SEL pin and set EVEAUDIO_DIS pin */ PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS); @@ -534,7 +572,7 @@ int eos_egpio_set_val(uint8_t pin, int val) { case EGPIO_PIN_EVEAUDIO_DIS: case EGPIO_PIN_LSGAIN_SEL: { - int lspk_on = (eos_i2s_running() || !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); + int lspk_on = (eos_i2s_running() || !egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) { BITSET(egpio_alt_pin, pin2alt_bit(pin), val); @@ -549,7 +587,7 @@ int eos_egpio_set_val(uint8_t pin, int val) { } } - rv = _eos_egpio_set_val(pin, val); + rv = egpio_set_val(pin, val); if (rv) return rv; return EOS_OK; @@ -559,13 +597,13 @@ int eos_egpio_i2s_start(void) { uint8_t data; int rv, audio_sel; - rv = _eos_egpio_intr_set(1, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); + rv = egpio_intr_set(1, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); if (rv) return rv; - audio_sel = _eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL); + audio_sel = egpio_get_val(EGPIO_PIN_AUDIO_SEL); BITSET(egpio_alt_pin, pin2alt_bit(EGPIO_PIN_AUDIO_SEL), audio_sel); - rv = _eos_egpio_set_val(EGPIO_PIN_AUDIO_SEL, 1); + rv = egpio_set_val(EGPIO_PIN_AUDIO_SEL, 1); if (rv) return rv; if (!audio_sel && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { @@ -579,7 +617,7 @@ int eos_egpio_i2s_start(void) { int eos_egpio_i2s_stop(void) { int rv, audio_sel; - rv = _eos_egpio_intr_set(0, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); + rv = egpio_intr_set(0, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); if (rv) return rv; audio_sel = (egpio_alt_pin & pin2alt_bit(EGPIO_PIN_AUDIO_SEL)); @@ -588,7 +626,7 @@ int eos_egpio_i2s_stop(void) { PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS); } - rv = _eos_egpio_set_val(EGPIO_PIN_AUDIO_SEL, audio_sel); + rv = egpio_set_val(EGPIO_PIN_AUDIO_SEL, audio_sel); if (rv) return rv; return EOS_OK; diff --git a/fw/fe310/eos/dev/egpio.h b/fw/fe310/eos/dev/egpio.h index 7d20443..a916ed5 100644 --- a/fw/fe310/eos/dev/egpio.h +++ b/fw/fe310/eos/dev/egpio.h @@ -1,93 +1,13 @@ #include <stdint.h> -#define EGPIO_ETYPE_INT 1 -#define EGPIO_ETYPE_INT_CTP 2 -#define EGPIO_ETYPE_INT_EVE 3 +#define EOS_EGPIO_ETYPE_INT 1 +#define EOS_EGPIO_ETYPE_INT_CTP 2 /* EGPIO_PIN_CTP_SEL is on: CTP int; EGPIO_PIN_CTP_SEL is off: EVE int */ -#define EGPIO_INT_TYPE_BAT 1 -#define EGPIO_INT_TYPE_WAKE 2 -#define EGPIO_INT_TYPE_SDCARD 3 -#define EGPIO_INT_TYPE_MUTE 4 -#define EGPIO_INT_TYPE_HP 5 - -#define EGPIO_CHIP_FXL0 0x00 -#define EGPIO_CHIP_FXL1 0x01 -#define EGPIO_CHIP_EVE 0x02 - -#define EGPIO_MAX_CHIP 3 - -#define EGPIO_PIN_MASK 0x07 -#define EGPIO_PIN_MASK_CHIP 0x30 - -#define EGPIO_PIN2BIT(X) (1 << ((X) & EGPIO_PIN_MASK)) -#define EGPIO_PIN2CHIP(X) (((X) & EGPIO_PIN_MASK_CHIP) >> 4) -#define EGPIO_PIN(C,P) (((C) << 4) | (P)) - -#define EGPIO0_PIN_EVE_INT 0x00 /* EVE interrrupt */ -#define EGPIO0_PIN_SDCARD_DET 0x01 /* SD Card detect */ -#define EGPIO0_PIN_EXP_IO0 0x02 /* expansion io 0 */ -#define EGPIO0_PIN_EXP_IO1 0x03 /* expansion io 1 */ -#define EGPIO0_PIN_BTN_WAKE 0x04 /* wake button */ -#define EGPIO0_PIN_BAT_INT 0x05 /* battery charger IC inetrrupt */ -#define EGPIO0_PIN_CTP_SEL 0x06 /* switch CTP connection: EVE_DISP:1 and CTP_SEL:0 - connected to EVE chip, EVE_DISP:X and CTP_SEL:1 - connected to fe310 chip, EVE_DISP:0 and CTP_SEL:0 - connected to app module */ -#define EGPIO0_PIN_CTP_INT 0x07 /* CTP interrupt */ - -#define EGPIO1_PIN_MIC_MUTE 0x00 /* microphone disable */ -#define EGPIO1_PIN_HPAMP_CS 0x01 /* SPI chip select for headphone amplifier (pcm1770) */ -#define EGPIO1_PIN_AUDIO_SEL 0x02 /* switch audio connection: 0 - connected to app module, 1 - connected to fe310 chip (only when i2s is off) */ -#define EGPIO1_PIN_HP_NDET 0x03 /* headphone detect: 0 - inserted, 1 - not inserted */ -#define EGPIO1_PIN_USR0 0x04 /* user IO */ -#define EGPIO1_PIN_USR1 0x05 -#define EGPIO1_PIN_USR2 0x06 -#define EGPIO1_PIN_USR3 0x07 - -#define EGPIOE_PIN_DISP 0x07 /* EVE DISP GPIO */ - -#define EGPIO_PIN_ALT 0x08 - -#define EGPIO_PIN_EVE_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EVE_INT) -#define EGPIO_PIN_SDCARD_DET EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_SDCARD_DET) -#define EGPIO_PIN_EXP_IO0 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO0) -#define EGPIO_PIN_EXP_IO1 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO1) -#define EGPIO_PIN_BTN_WAKE EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BTN_WAKE) -#define EGPIO_PIN_BAT_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BAT_INT) -#define EGPIO_PIN_CTP_SEL EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_SEL) -#define EGPIO_PIN_CTP_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_INT) - -#define EGPIO_PIN_MIC_MUTE EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_MIC_MUTE) -#define EGPIO_PIN_HPAMP_CS EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HPAMP_CS) -#define EGPIO_PIN_AUDIO_SEL EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_AUDIO_SEL) -#define EGPIO_PIN_HP_NDET EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HP_NDET) -#define EGPIO_PIN_USR0 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR0) -#define EGPIO_PIN_USR1 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR1) -#define EGPIO_PIN_USR2 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR2) -#define EGPIO_PIN_USR3 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR3) - -/* EVE pins defined in eve.h */ -#define EGPIO_PIN_USR4 EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_USR) -#define EGPIO_PIN_EVEAUDIO_DIS EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_EVEAUDIO_DIS) -#define EGPIO_PIN_LSGAIN_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LSGAIN_SEL | EGPIO_PIN_ALT) -#define EGPIO_PIN_LCD_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LCD_EN) -#define EGPIO_PIN_CAM_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_CAM_EN) -#define EGPIO_PIN_DISP_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EGPIOE_PIN_DISP) - -#define EGPIO_BIT_EVE_INT EGPIO_PIN2BIT(EGPIO0_PIN_EVE_INT) -#define EGPIO_BIT_SDCARD_DET EGPIO_PIN2BIT(EGPIO0_PIN_SDCARD_DET) -#define EGPIO_BIT_EXP_IO0 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO0) -#define EGPIO_BIT_EXP_IO1 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO1) -#define EGPIO_BIT_BTN_WAKE EGPIO_PIN2BIT(EGPIO0_PIN_BTN_WAKE) -#define EGPIO_BIT_BAT_INT EGPIO_PIN2BIT(EGPIO0_PIN_BAT_INT) -#define EGPIO_BIT_CTP_SEL EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL) -#define EGPIO_BIT_CTP_INT EGPIO_PIN2BIT(EGPIO0_PIN_CTP_INT) - -#define EGPIO_BIT_MIC_MUTE EGPIO_PIN2BIT(EGPIO1_PIN_MIC_MUTE) -#define EGPIO_BIT_HPAMP_CS EGPIO_PIN2BIT(EGPIO1_PIN_HPAMP_CS) -#define EGPIO_BIT_AUDIO_SEL EGPIO_PIN2BIT(EGPIO1_PIN_AUDIO_SEL) -#define EGPIO_BIT_HP_NDET EGPIO_PIN2BIT(EGPIO1_PIN_HP_NDET) -#define EGPIO_BIT_USR0 EGPIO_PIN2BIT(EGPIO1_PIN_USR0) -#define EGPIO_BIT_USR1 EGPIO_PIN2BIT(EGPIO1_PIN_USR1) -#define EGPIO_BIT_USR2 EGPIO_PIN2BIT(EGPIO1_PIN_USR2) -#define EGPIO_BIT_USR3 EGPIO_PIN2BIT(EGPIO1_PIN_USR3) +#define EOS_EGPIO_INT_TYPE_BAT 1 +#define EOS_EGPIO_INT_TYPE_WAKE 2 +#define EOS_EGPIO_INT_TYPE_SDCARD 3 +#define EOS_EGPIO_INT_TYPE_MUTE 4 +#define EOS_EGPIO_INT_TYPE_HP 5 typedef void (*eos_egpio_intr_handler_t) (uint8_t type, int data0, int data1); typedef int (*eos_egpio_ext_handler_t) (void); @@ -95,7 +15,6 @@ typedef int (*eos_egpio_ext_handler_t) (void); int eos_egpio_init(void); int eos_egpio_run(void); void eos_egpio_eve_set(uint16_t gpio_reg); -int _eos_egpio_intr_set(int i2s_running, int app_running); int eos_egpio_intr_set(void); int eos_egpio_intr_enable(void); int eos_egpio_intr_disable(void); @@ -106,8 +25,6 @@ void eos_egpio_set_ext_handler(eos_egpio_ext_handler_t handler); int eos_egpio_fxl_get_pin(uint8_t reg, uint8_t pin, uint8_t *val); int eos_egpio_fxl_set_pin(uint8_t reg, uint8_t pin, uint8_t val); -int _eos_egpio_get_val(uint8_t pin); -int _eos_egpio_set_val(uint8_t pin, int val); int eos_egpio_get_val(uint8_t pin); int eos_egpio_set_val(uint8_t pin, int val); diff --git a/fw/fe310/eos/dev/egpio_priv.h b/fw/fe310/eos/dev/egpio_priv.h new file mode 100644 index 0000000..04fe271 --- /dev/null +++ b/fw/fe310/eos/dev/egpio_priv.h @@ -0,0 +1,81 @@ +#include "eve_priv.h" + +#define EGPIO_CHIP_FXL0 0 +#define EGPIO_CHIP_FXL1 1 +#define EGPIO_CHIP_EVE 2 + +#define EGPIO_MAX_CHIP 3 +#define EGPIO_MAX_FXL_CHIP 2 + +#define EGPIO_PIN_MASK 0x07 +#define EGPIO_PIN_MASK_CHIP 0x30 + +#define EGPIO_PIN2BIT(X) (1 << ((X) & EGPIO_PIN_MASK)) +#define EGPIO_PIN2CHIP(X) (((X) & EGPIO_PIN_MASK_CHIP) >> 4) +#define EGPIO_PIN(C,P) (((C) << 4) | (P)) + +#define EGPIO0_PIN_EVE_INT 0x00 /* EVE interrrupt */ +#define EGPIO0_PIN_SDCARD_NDET 0x01 /* SD Card detect: 0 - inserted, 1 - not inserted */ +#define EGPIO0_PIN_EXP_IO0 0x02 /* expansion io 0 */ +#define EGPIO0_PIN_EXP_IO1 0x03 /* expansion io 1 */ +#define EGPIO0_PIN_BTN_WAKE 0x04 /* wake button */ +#define EGPIO0_PIN_BAT_INT 0x05 /* battery charger IC inetrrupt */ +#define EGPIO0_PIN_CTP_SEL 0x06 /* switch CTP connection: EVE_DISP:1 and CTP_SEL:0 - connected to EVE chip, EVE_DISP:X and CTP_SEL:1 - connected to fe310 chip, EVE_DISP:0 and CTP_SEL:0 - connected to app module */ +#define EGPIO0_PIN_CTP_INT 0x07 /* CTP interrupt */ + +#define EGPIO1_PIN_MIC_MUTE 0x00 /* microphone disable */ +#define EGPIO1_PIN_HPAMP_CS 0x01 /* SPI chip select for headphone amplifier (pcm1770) */ +#define EGPIO1_PIN_AUDIO_SEL 0x02 /* switch audio connection: 0 - connected to app module, 1 - connected to fe310 chip (only when i2s is off) */ +#define EGPIO1_PIN_HP_NDET 0x03 /* headphone detect: 0 - inserted, 1 - not inserted */ +#define EGPIO1_PIN_USR0 0x04 /* user IO */ +#define EGPIO1_PIN_USR1 0x05 +#define EGPIO1_PIN_USR2 0x06 +#define EGPIO1_PIN_USR3 0x07 + +#define EGPIOE_PIN_DISP 0x07 /* EVE DISP GPIO */ + +#define EGPIO_PIN_ALT 0x08 + +#define EGPIO_BIT_EVE_INT EGPIO_PIN2BIT(EGPIO0_PIN_EVE_INT) +#define EGPIO_BIT_SDCARD_NDET EGPIO_PIN2BIT(EGPIO0_PIN_SDCARD_NDET) +#define EGPIO_BIT_EXP_IO0 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO0) +#define EGPIO_BIT_EXP_IO1 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO1) +#define EGPIO_BIT_BTN_WAKE EGPIO_PIN2BIT(EGPIO0_PIN_BTN_WAKE) +#define EGPIO_BIT_BAT_INT EGPIO_PIN2BIT(EGPIO0_PIN_BAT_INT) +#define EGPIO_BIT_CTP_SEL EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL) +#define EGPIO_BIT_CTP_INT EGPIO_PIN2BIT(EGPIO0_PIN_CTP_INT) + +#define EGPIO_BIT_MIC_MUTE EGPIO_PIN2BIT(EGPIO1_PIN_MIC_MUTE) +#define EGPIO_BIT_HPAMP_CS EGPIO_PIN2BIT(EGPIO1_PIN_HPAMP_CS) +#define EGPIO_BIT_AUDIO_SEL EGPIO_PIN2BIT(EGPIO1_PIN_AUDIO_SEL) +#define EGPIO_BIT_HP_NDET EGPIO_PIN2BIT(EGPIO1_PIN_HP_NDET) +#define EGPIO_BIT_USR0 EGPIO_PIN2BIT(EGPIO1_PIN_USR0) +#define EGPIO_BIT_USR1 EGPIO_PIN2BIT(EGPIO1_PIN_USR1) +#define EGPIO_BIT_USR2 EGPIO_PIN2BIT(EGPIO1_PIN_USR2) +#define EGPIO_BIT_USR3 EGPIO_PIN2BIT(EGPIO1_PIN_USR3) + +#define EGPIO_PIN_EVE_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EVE_INT) +#define EGPIO_PIN_SDCARD_NDET EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_SDCARD_NDET) +#define EGPIO_PIN_EXP_IO0 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO0) +#define EGPIO_PIN_EXP_IO1 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO1) +#define EGPIO_PIN_BTN_WAKE EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BTN_WAKE) +#define EGPIO_PIN_BAT_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BAT_INT) +#define EGPIO_PIN_CTP_SEL EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_SEL) +#define EGPIO_PIN_CTP_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_INT) + +#define EGPIO_PIN_MIC_MUTE EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_MIC_MUTE) +#define EGPIO_PIN_HPAMP_CS EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HPAMP_CS) +#define EGPIO_PIN_AUDIO_SEL EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_AUDIO_SEL) +#define EGPIO_PIN_HP_NDET EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HP_NDET) +#define EGPIO_PIN_USR0 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR0) +#define EGPIO_PIN_USR1 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR1) +#define EGPIO_PIN_USR2 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR2) +#define EGPIO_PIN_USR3 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR3) + +/* EVE pins defined in eve.h */ +#define EGPIO_PIN_USR4 EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_USR) +#define EGPIO_PIN_EVEAUDIO_DIS EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_EVEAUDIO_DIS) +#define EGPIO_PIN_LSGAIN_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LSGAIN_SEL | EGPIO_PIN_ALT) +#define EGPIO_PIN_LCD_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LCD_EN) +#define EGPIO_PIN_CAM_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_CAM_EN) +#define EGPIO_PIN_DISP_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EGPIOE_PIN_DISP) diff --git a/fw/fe310/eos/dev/eve.c b/fw/fe310/eos/dev/eve.c index dad7dfe..873cd7a 100644 --- a/fw/fe310/eos/dev/eve.c +++ b/fw/fe310/eos/dev/eve.c @@ -2,6 +2,7 @@ #include <stdint.h> #include "eos.h" +#include "log.h" #include "event.h" #include "soc/pwr.h" @@ -11,15 +12,12 @@ #include "eve/eve_touch_engine.h" #include "egpio.h" +#include "egpio_priv.h" #include "spi.h" #include "aon.h" -#include "pwr.h" #include "eve.h" - -#ifdef EOS_DEBUG -#include <stdio.h> -#endif +#include "eve_priv.h" static void handle_time(unsigned char type) { int rv; @@ -36,13 +34,12 @@ int eos_eve_handle_intr(void) { int rv; rv = eve_select(); - if (rv) return 0; + if (rv) return rv; intr_flags = eve_handle_intr(); eve_deselect(); - if (intr_flags == 0) return 0; - return 1; + return intr_flags; } int eos_eve_init(void) { @@ -64,17 +61,9 @@ int eos_eve_init(void) { eve_touch_init_engine(eos_egpio_get_val(EGPIO_PIN_CTP_SEL) ? EVE_TOUCH_ENGINE_HOST : EVE_TOUCH_ENGINE_GOODIX); gpio_reg = EVE_GPIO_DEFAULT; } else { - uint8_t pwr_state; - - pwr_state = eos_aon_load4eve(); - eve_pwr_set_state(pwr_state); - eve_activate(); gpio_reg = eve_gpio_read(); eve_cmd_set_offset(); - if (gpio_reg & EVE_GPIO_DISP) { - eve_pwr_set_state(EVE_PSTATE_ACTIVE); - } eve_deactivate(); } @@ -92,49 +81,86 @@ eve_init_fin: } int eos_eve_run(void) { - int rv; + uint8_t wakeup_cause; + int rst, rv; + + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); - if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR_BUSY; + if (!rst) { + /* was active before sleep */ + if (eve_pwr_state() == EVE_PSTATE_ACTIVE) return EOS_OK; + + /* Display is attached to app module */ + if (!eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; + } rv = eve_select(); if (rv) return rv; - eve_touch_intr_enable(); - eve_touch_start(); - eve_intr_enable(); - eve_clk_start(); + if (!rst) eve_pwr_wake(); + _eos_eve_wake(); + if (rst) eve_set_brightness(0x40); eve_deselect(); return EOS_OK; } +void _eos_eve_sleep(void) { + eos_aon_save4eve_pwm(eve_get_brightness()); + eve_set_brightness(0); + eve_clk_stop(); + eve_intr_disable(); + eve_touch_stop(); + eve_touch_intr_disable(); +} + int eos_eve_sleep(void) { int rv; + if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR; + rv = eve_select(); if (rv) return rv; - eos_aon_save4eve(eve_pwr_state()); - eve_clk_stop(); - eve_intr_disable(); - eve_touch_stop(); - eve_touch_intr_disable(); + _eos_eve_sleep(); eve_pwr_sleep(); eve_deselect(); return EOS_OK; } +void _eos_eve_wake(void) { + eve_touch_intr_enable(); + eve_touch_start(); + eve_intr_enable(); + eve_clk_start(); + eve_set_brightness(eos_aon_load4eve_pwm()); +} + +int eos_eve_wake(void) { + int disp, rv; + + if (eve_pwr_state() == EVE_PSTATE_ACTIVE) return EOS_ERR; + if (!eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; + + rv = eve_select(); + if (rv) return rv; + + eve_pwr_wake(); + _eos_eve_wake(); + + eve_deselect(); + + return rv; +} + void eve_calibrate(void) { int rv, d; -#ifdef EOS_DEBUG uint32_t matrix[6]; -#endif if (!eve_selected()) { -#ifdef EOS_DEBUG - printf("EVE CALIBRATE: NOT SELECTED\n"); -#endif + EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE: NOT SELECTED\n"); return; } @@ -155,25 +181,21 @@ void eve_calibrate(void) { eos_evtq_exec(); rv = eve_select(); if (rv) { -#ifdef EOS_DEBUG - printf("EVE CALIBRATE ERR:%d\n", rv); -#endif + EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE ERR:%d\n", rv); return; } } while (!d); eve_touch_set_extended(1); -#ifdef EOS_DEBUG if (rv) { - printf("EVE CALIBRATE ERR:%d\n", rv); + EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE ERR:%d\n", rv); return; } eve_touch_get_matrix(matrix); - printf("TOUCH MATRIX:\n"); - printf("uint32_t touch_matrix[6] = {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); -#endif + EOS_LOG(EOS_LOG_INFO, "TOUCH MATRIX:\n"); + EOS_LOG(EOS_LOG_INFO, "uint32_t touch_matrix[6] = {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); } int eve_select(void) { diff --git a/fw/fe310/eos/dev/eve.h b/fw/fe310/eos/dev/eve.h index 441cd5a..11d7cc9 100644 --- a/fw/fe310/eos/dev/eve.h +++ b/fw/fe310/eos/dev/eve.h @@ -1,21 +1,12 @@ #include <stdint.h> -#define EVE_GPIO_DIR 0x800f -#define EVE_GPIO_DEFAULT 0x2 /* EVEAUDIO_DIS */ -#define EVE_GPIO_MASK 0x800f - -#define EVE_GPIO_USR 0 -#define EVE_GPIO_EVEAUDIO_DIS 1 /* only when lspk is off */ -#define EVE_GPIO_LSGAIN_SEL 1 /* only when lspk is on */ -#define EVE_GPIO_LCD_EN 2 -#define EVE_GPIO_CAM_EN 3 -#define EVE_GPIO_DISP 15 - int eos_eve_handle_intr(void); int eos_eve_init(void); int eos_eve_run(void); +void _eos_eve_sleep(void); int eos_eve_sleep(void); +void _eos_eve_wake(void); int eos_eve_wake(void); void eve_calibrate(void); diff --git a/fw/fe310/eos/dev/eve_priv.h b/fw/fe310/eos/dev/eve_priv.h new file mode 100644 index 0000000..8baf6a4 --- /dev/null +++ b/fw/fe310/eos/dev/eve_priv.h @@ -0,0 +1,9 @@ +#define EVE_GPIO_DIR 0x800f +#define EVE_GPIO_DEFAULT 0x8002 /* DISP on, EVEAUDIO_DIS */ + +#define EVE_GPIO_USR 0 +#define EVE_GPIO_EVEAUDIO_DIS 1 /* only when lspk is off */ +#define EVE_GPIO_LSGAIN_SEL 1 /* only when lspk is on */ +#define EVE_GPIO_LCD_EN 2 +#define EVE_GPIO_CAM_EN 3 +#define EVE_GPIO_DISP 15 diff --git a/fw/fe310/eos/dev/flash.c b/fw/fe310/eos/dev/flash.c index c8f4c98..15811a2 100644 --- a/fw/fe310/eos/dev/flash.c +++ b/fw/fe310/eos/dev/flash.c @@ -9,6 +9,21 @@ #include "flash.h" +#define FLASH_RDSR 0x05 + +#define FLASH_NORD 0x03 +#define FLASH_FRD 0x0b + +#define FLASH_WREN 0x06 +#define FLASH_SER 0x20 +#define FLASH_PP 0x02 + +#define FLASH_QPIEN 0x35 +#define FLASH_QPIDI 0xF5 + +#define FLASH_WIP 0x01 +#define FLASH_WEL 0x02 + #define IDLE_TICKS 10 __attribute__ ((section (".itim.flash"))) @@ -42,7 +57,7 @@ void eos_flash_norm(void) { SPI0_REG(SPI_REG_SCKDIV) = 3; if (SPI0_REG(SPI_REG_FMT) & SPI_FMT_PROTO(SPI_PROTO_Q)) { - send(EOS_FLASH_QPIDI); + send(FLASH_QPIDI); while (!(SPI0_REG(SPI_REG_IP) & SPI_IP_TXWM)); } @@ -59,7 +74,7 @@ void eos_flash_norm(void) { SPI_INSN_CMD_PROTO(SPI_PROTO_S) | SPI_INSN_ADDR_PROTO(SPI_PROTO_S) | SPI_INSN_DATA_PROTO(SPI_PROTO_S) | - SPI_INSN_CMD_CODE(EOS_FLASH_NORD) | + SPI_INSN_CMD_CODE(FLASH_NORD) | SPI_INSN_PAD_CODE(0x00); mtime0 = *mtime; @@ -79,7 +94,7 @@ void eos_flash_fast(void) { SPI0_REG(SPI_REG_SCKDIV) = 2; if (!(SPI0_REG(SPI_REG_FMT) & SPI_FMT_PROTO(SPI_PROTO_Q))) { - send(EOS_FLASH_QPIEN); + send(FLASH_QPIEN); while (!(SPI0_REG(SPI_REG_IP) & SPI_IP_TXWM)); } @@ -96,7 +111,7 @@ void eos_flash_fast(void) { SPI_INSN_CMD_PROTO(SPI_PROTO_Q) | SPI_INSN_ADDR_PROTO(SPI_PROTO_Q) | SPI_INSN_DATA_PROTO(SPI_PROTO_Q) | - SPI_INSN_CMD_CODE(EOS_FLASH_FRD) | + SPI_INSN_CMD_CODE(FLASH_FRD) | SPI_INSN_PAD_CODE(0x00); mtime0 = *mtime; @@ -112,31 +127,31 @@ void eos_flash_wip(void) { do { SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - xfer(EOS_FLASH_RDSR); + xfer(FLASH_RDSR); status = xfer(0); SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; - } while (status & EOS_FLASH_WIP); + } while (status & FLASH_WIP); } __attribute__ ((section (".itim.flash"))) void eos_flash_wren(void) { uint8_t status; - xfer(EOS_FLASH_WREN); + xfer(FLASH_WREN); #if 0 do { SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - xfer(EOS_FLASH_RDSR); + xfer(FLASH_RDSR); status = xfer(0); SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; - } while (!(status & EOS_FLASH_WEL)); + } while (!(status & FLASH_WEL)); #endif } __attribute__ ((section (".itim.flash"))) void eos_flash_ser(uint32_t addr) { SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - xfer(EOS_FLASH_SER); + xfer(FLASH_SER); xfer(addr >> 16); xfer(addr >> 8); xfer(addr); @@ -149,7 +164,7 @@ void eos_flash_pp(uint32_t addr, uint8_t *buf) { SPI0_REG(SPI_REG_FMT) |= SPI_FMT_DIR(SPI_DIR_TX); SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - send(EOS_FLASH_PP); + send(FLASH_PP); send(addr >> 16); send(addr >> 8); send(addr); diff --git a/fw/fe310/eos/dev/flash.h b/fw/fe310/eos/dev/flash.h index 6f792cb..714e9bc 100644 --- a/fw/fe310/eos/dev/flash.h +++ b/fw/fe310/eos/dev/flash.h @@ -1,20 +1,5 @@ #include <stdint.h> -#define EOS_FLASH_RDSR 0x05 - -#define EOS_FLASH_NORD 0x03 -#define EOS_FLASH_FRD 0x0b - -#define EOS_FLASH_WREN 0x06 -#define EOS_FLASH_SER 0x20 -#define EOS_FLASH_PP 0x02 - -#define EOS_FLASH_QPIEN 0x35 -#define EOS_FLASH_QPIDI 0xF5 - -#define EOS_FLASH_WIP 0x01 -#define EOS_FLASH_WEL 0x02 - void eos_flash_init(void); void eos_flash_norm(void); void eos_flash_fast(void); diff --git a/fw/fe310/eos/dev/lcd.c b/fw/fe310/eos/dev/lcd.c index 6c005b9..9fb8767 100644 --- a/fw/fe310/eos/dev/lcd.c +++ b/fw/fe310/eos/dev/lcd.c @@ -13,9 +13,8 @@ #include "eve/eve.h" #include "egpio.h" +#include "egpio_priv.h" #include "spi.h" -#include "eve.h" -#include "pwr.h" #include "drv/ili9806e.h" #include "lcd.h" @@ -23,8 +22,6 @@ static int lcd_enable(void) { int rv; - if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; - rv = eos_egpio_set_val(EGPIO_PIN_LCD_EN, 1); return rv; } @@ -32,16 +29,18 @@ static int lcd_enable(void) { static int lcd_disable(void) { int rv; - if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; - rv = eos_egpio_set_val(EGPIO_PIN_LCD_EN, 0); return rv; } +static int lcd_enabled(void) { + return eos_egpio_get_val(EGPIO_PIN_LCD_EN); +} + static int lcd_select(void) { int rv; - if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; + if (eos_i2s_running()) return EOS_ERR_BUSY; GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << SPI_CSPIN_LCD); @@ -52,6 +51,7 @@ static int lcd_select(void) { GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << SPI_CSPIN_LCD); + return rv; } @@ -60,6 +60,7 @@ static int lcd_select(void) { static void lcd_deselect(void) { eos_spi_deselect(); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << SPI_CSPIN_LCD); @@ -80,13 +81,32 @@ static int lcd_init(void) { } rv = ili9806e_init(); - if (rv == EOS_ERR_NOTFOUND) eve_lcd_absent(); + if (rv == EOS_ERR_NOTFOUND) eve_lcd_set_absent(1); lcd_deselect(); if (rv) lcd_disable(); return rv; } +static int lcd_reset(void) { + int rv; + + if (!lcd_enabled()) return EOS_ERR; + + rv = lcd_disable(); + if (rv) return rv; + + eos_sleep(10); + + rv = lcd_init(); + if (rv) { + lcd_enable(); + return rv; + } + + return EOS_OK; +} + static int lcd_sleep(void) { int rv; @@ -104,6 +124,9 @@ int eos_lcd_init(void) { uint8_t wakeup_cause; int rv, rst; + if (!eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; + if (lcd_enabled()) return EOS_ERR; + wakeup_cause = eos_pwr_wakeup_cause(); rst = (wakeup_cause == EOS_PWR_WAKE_RST); if (rst) { @@ -118,6 +141,8 @@ int eos_lcd_init(void) { int eos_lcd_sleep(void) { int rv; + if (!lcd_enabled()) return EOS_ERR; + rv = lcd_sleep(); return rv; } @@ -125,6 +150,16 @@ int eos_lcd_sleep(void) { int eos_lcd_wake(void) { int rv; + if (lcd_enabled()) return EOS_ERR; + rv = lcd_init(); return rv; } + +int eos_lcd_take(void) { + return lcd_reset(); +} + +int eos_lcd_give(void) { + return lcd_reset(); +} diff --git a/fw/fe310/eos/dev/lcd.h b/fw/fe310/eos/dev/lcd.h index fafe2b4..f52ee8a 100644 --- a/fw/fe310/eos/dev/lcd.h +++ b/fw/fe310/eos/dev/lcd.h @@ -3,3 +3,5 @@ int eos_lcd_init(void); int eos_lcd_sleep(void); int eos_lcd_wake(void); +int eos_lcd_take(void); +int eos_lcd_give(void); diff --git a/fw/fe310/eos/dev/net.c b/fw/fe310/eos/dev/net.c index d340e29..7ab4947 100644 --- a/fw/fe310/eos/dev/net.c +++ b/fw/fe310/eos/dev/net.c @@ -3,13 +3,12 @@ #include "encoding.h" #include "platform.h" +#include "board.h" #include "eos.h" -#include "msgq.h" +#include "log.h" #include "event.h" -#include "board.h" - #include "soc/interrupt.h" #include "soc/timer.h" #include "soc/pwr.h" @@ -17,72 +16,77 @@ #include "soc/spi_priv.h" #include "spi.h" +#include "aon.h" #include "net.h" -#define NET_SIZE_HDR 3 -#define NET_STATE_FLAG_RUN 0x01 -#define NET_STATE_FLAG_INIT 0x02 -#define NET_STATE_FLAG_XCHG 0x04 -#define NET_STATE_FLAG_ONEW 0x10 -#define NET_STATE_FLAG_SYNC 0x20 -#define NET_STATE_FLAG_RTS 0x40 -#define NET_STATE_FLAG_CTS 0x80 +#define NET_DETECT_TIMEOUT 1000 + +#define NET_SIZE_HDR 3 +#define NET_SIZE_BUFQ 2 + +#define NET_STATE_FLAG_RUN 0x0001 +#define NET_STATE_FLAG_RTS 0x0002 +#define NET_STATE_FLAG_CTS 0x0004 +#define NET_STATE_FLAG_INIT 0x0010 +#define NET_STATE_FLAG_XCHG 0x0020 +#define NET_STATE_FLAG_ONEW 0x0040 +#define NET_STATE_FLAG_SYNC 0x0080 +#define NET_STATE_FLAG_SLEEP 0x0100 +#define NET_STATE_FLAG_SLEEP_REQ 0x0200 +#define NET_STATE_FLAG_ABSENT 0x0400 +#define NET_STATE_FLAG_ERR_SIZE 0x0800 #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) static EOSBufQ net_buf_q; -static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; -static unsigned char net_bufq_buffer[EOS_NET_SIZE_BUFQ][EOS_NET_SIZE_BUF] __attribute__((section (".itim2"))); +static unsigned char *net_bufq_array[NET_SIZE_BUFQ]; +static unsigned char net_bufq_buffer[NET_SIZE_BUFQ][EOS_NET_MTU] __attribute__((section (".itim2"))); static EOSMsgQ net_send_q; -static EOSMsgItem net_sndq_array[EOS_NET_SIZE_BUFQ]; +static EOSMsgItem net_sndq_array[NET_SIZE_BUFQ]; -static volatile uint8_t net_state_flags = 0; +static volatile uint16_t net_state_flags = 0; static volatile unsigned char net_state_type = 0; static uint32_t net_state_len_tx = 0; static volatile uint32_t net_state_len_rx = 0; static unsigned char *net_state_buf = NULL; +static uint16_t net_state_buf_sz = 0; static volatile uint8_t net_state_next_cnt = 0; static unsigned char * volatile net_state_next_buf = NULL; static eos_evt_handler_t net_handler[EOS_NET_MAX_MTYPE]; -static uint16_t net_wrapper_acq[EOS_EVT_MAX_EVT]; -static uint16_t net_flags_acq[EOS_EVT_MAX_EVT]; +static uint16_t net_wrapper_acq; +static uint16_t net_flags_acq[EOS_EVT_MAX]; -static int net_xchg_sleep(void) { - int i; - int rv = EOS_OK; +static void net_xchg_reset(void) { volatile uint32_t x = 0; + net_state_flags &= ~NET_STATE_FLAG_CTS; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - SPI1_REG(SPI_REG_TXFIFO) = 0xFF; + SPI1_REG(SPI_REG_TXFIFO) = 0; while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - if (x & 0xFF) rv = EOS_ERR_BUSY; - - for (i=0; i<7; i++) { - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = 0; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - } SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; - - return rv; } -static void net_xchg_wake(void) { - int i; +static void net_xchg_sleep_req(void) { volatile uint32_t x = 0; + int i; + net_state_flags &= ~NET_STATE_FLAG_CTS; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - for (i=0; i<8; i++) { + SPI1_REG(SPI_REG_TXFIFO) = EOS_NET_MTYPE_SLEEP | EOS_NET_MTYPE_FLAG_ONEW; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + + /* minimum 8 bytes for esp32 */ + for (i=0; i<7; i++) { while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); SPI1_REG(SPI_REG_TXFIFO) = 0; while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); @@ -91,20 +95,8 @@ static void net_xchg_wake(void) { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; } -static void net_xchg_reset(void) { - volatile uint32_t x = 0; - net_state_flags &= ~NET_STATE_FLAG_CTS; - - SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - - SPI1_REG(SPI_REG_TXFIFO) = 0; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - - SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; -} - -static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t len) { - net_state_flags &= ~NET_STATE_FLAG_CTS; +static void net_xchg_start(unsigned char type, EOSMessage *msg, uint16_t len) { + net_state_flags &= ~(NET_STATE_FLAG_CTS | NET_STATE_FLAG_ERR_SIZE); net_state_flags |= (NET_STATE_FLAG_INIT | NET_STATE_FLAG_XCHG); if (net_state_next_cnt && (net_state_next_buf == NULL)) type |= EOS_NET_MTYPE_FLAG_ONEW; @@ -113,7 +105,8 @@ static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t l net_state_type = type; net_state_len_tx = len; net_state_len_rx = 0; - net_state_buf = buffer; + net_state_buf = msg->buffer; + net_state_buf_sz = msg->size; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; SPI1_REG(SPI_REG_TXFIFO) = type; @@ -123,26 +116,27 @@ static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t l SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; } -static int net_xchg_next(unsigned char *_buffer) { +static int net_xchg_next(EOSMessage *_msg) { unsigned char type; - unsigned char *buffer = NULL; + EOSMessage msg; uint16_t len; - int ret = _buffer ? 1 : 0; + int do_release = _msg ? 1 : 0; - eos_msgq_pop(&net_send_q, &type, &buffer, &len); + eos_msgq_pop(&net_send_q, &type, &msg, &len); if (type) { - net_xchg_start(type, buffer, len); + net_xchg_start(type, &msg, len); } else if (net_state_flags & NET_STATE_FLAG_RTS) { - if (_buffer) { - buffer = _buffer; - ret = 0; + if (_msg) { + msg = *_msg; + do_release = 0; } else { - buffer = eos_bufq_pop(&net_buf_q); + msg.buffer = eos_bufq_pop(&net_buf_q); + msg.size = EOS_NET_MTU; } - if (buffer) net_xchg_start(0, buffer, 0); + if (msg.buffer) net_xchg_start(0, &msg, 0); } - return ret; + return do_release; } static void net_handle_xchg(void) { @@ -162,50 +156,69 @@ static void net_handle_xchg(void) { r3 = 0; } - net_state_type = (r1 & 0xFF); + net_state_type = r1; net_state_len_rx = (r2 & 0xFF) << 8; net_state_len_rx |= (r3 & 0xFF); len = MAX(net_state_len_tx, net_state_len_rx); - // esp32 dma workaraund + /* esp32 dma workaraund */ if (len < 8 - NET_SIZE_HDR) { len = 8 - NET_SIZE_HDR; } else if ((len + NET_SIZE_HDR) % 4 != 0) { len = ((len + NET_SIZE_HDR)/4 + 1) * 4 - NET_SIZE_HDR; } - if (len > EOS_NET_MTU) { + if (len > net_state_buf_sz) { + net_state_type = 0; + net_state_len_tx = 0; + net_state_len_rx = 0; + net_state_flags |= NET_STATE_FLAG_ERR_SIZE; net_state_flags &= ~NET_STATE_FLAG_XCHG; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; SPI1_REG(SPI_REG_IE) = 0x0; return; } - _eos_spi_xchg_init(net_state_buf, len, 0); + _eos_spi_xchg_init(net_state_buf, net_state_buf_sz, len, 0); SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM); SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM; return; } eos_spi_handle_xchg(); - if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_AUTO) { // exchange done + if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_AUTO) { + /* exchange done */ if (!(net_state_flags & NET_STATE_FLAG_SYNC)) { if (net_state_type) { - int r = eos_evtq_push_isr(EOS_EVT_NET | (net_state_type & ~EOS_NET_MTYPE_FLAG_MASK), net_state_buf, net_state_len_rx); - if (r) eos_bufq_push(&net_buf_q, net_state_buf); + if (net_state_type == EOS_NET_MTYPE_SLEEP) { + net_state_flags |= NET_STATE_FLAG_SLEEP; + eos_bufq_push(&net_buf_q, net_state_buf); + } else { + EOSMessage msg; + int rv; + + msg.buffer = net_state_buf; + msg.size = net_state_buf_sz; + rv = eos_evtq_push_isr(EOS_EVT_NET | (net_state_type & EOS_NET_MTYPE_MASK), &msg, net_state_len_rx); + if (rv) { + EOS_LOG(EOS_LOG_ERR, "NET XCHG EVTQ PUSH ERR:%d\n", rv); + eos_bufq_push(&net_buf_q, net_state_buf); + } + } } else if (((net_state_flags & NET_STATE_FLAG_ONEW) || net_state_next_cnt) && (net_state_next_buf == NULL)) { net_state_next_buf = net_state_buf; } else { eos_bufq_push(&net_buf_q, net_state_buf); } } - net_state_flags &= ~(NET_STATE_FLAG_ONEW | NET_STATE_FLAG_XCHG); + net_state_flags &= ~(NET_STATE_FLAG_XCHG | NET_STATE_FLAG_ONEW); } } static void net_handle_cts(void) { - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); + GPIO_REG(GPIO_FALL_IP) = (1 << NET_PIN_CTS); net_state_flags |= NET_STATE_FLAG_CTS; + net_state_flags &= ~NET_STATE_FLAG_SLEEP; if (net_state_flags & NET_STATE_FLAG_RUN) { net_xchg_next(NULL); @@ -215,25 +228,33 @@ static void net_handle_cts(void) { static void net_handle_rts(void) { uint32_t rts_offset = (1 << NET_PIN_RTS); - if (GPIO_REG(GPIO_RISE_IP) & rts_offset) { - GPIO_REG(GPIO_RISE_IP) = rts_offset; + if (GPIO_REG(GPIO_FALL_IP) & rts_offset) { + GPIO_REG(GPIO_FALL_IP) = rts_offset; net_state_flags |= NET_STATE_FLAG_RTS; if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) { net_xchg_reset(); } - } else if (GPIO_REG(GPIO_FALL_IP) & rts_offset) { - GPIO_REG(GPIO_FALL_IP) = rts_offset; + } + if (GPIO_REG(GPIO_RISE_IP) & rts_offset) { + GPIO_REG(GPIO_RISE_IP) = rts_offset; net_state_flags &= ~NET_STATE_FLAG_RTS; } } -static void net_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = (type & ~EOS_EVT_MASK) - 1; +static void net_handle_evt(unsigned char type, EOSMessage *msg, uint16_t len) { + unsigned char idx; - if (idx < EOS_NET_MAX_MTYPE) { - net_handler[idx](type, buffer, len); + idx = type & EOS_NET_MTYPE_FLAG_BRIDGE ? EOS_NET_MTYPE_BRIDGE : (type & ~EOS_EVT_MASK); + type &= ~EOS_EVT_MASK; + if (msg && (idx < EOS_NET_MAX_MTYPE)) { + net_handler[idx](type, msg, len); } else { - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, msg, len); + } + if (msg && msg->buffer) { + eos_net_free(msg, 0); + } else { + eos_net_release(); } } @@ -263,34 +284,48 @@ static int net_acquire(unsigned char reserved) { return ret; } -static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char idx, uint16_t flag) { - int ok; +static void evt_handler_wrapper(unsigned char type, EOSMessage *msg, uint16_t len, uint8_t idx) { + uint16_t flag = (uint16_t)1 << idx; + int rv; - ok = net_acquire(net_wrapper_acq[idx] & flag); - if (ok) { - eos_evtq_get_handler(type)(type, buffer, len); + rv = net_acquire(net_wrapper_acq & flag); + if (rv) { + eos_evtq_get_handler(type)(type, msg, len); eos_net_release(); - net_wrapper_acq[idx] &= ~flag; + net_wrapper_acq &= ~flag; } else { - net_wrapper_acq[idx] |= flag; - eos_evtq_push(type, buffer, len); + rv = eos_evtq_push_widx(type, msg, len, &idx); + if (rv) { + EOS_LOG(EOS_LOG_ERR, "NET WRAPPER EVTQ PUSH ERR:%d\n", rv); + return; + } + flag = (uint16_t)1 << idx; + net_wrapper_acq |= flag; } } -static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len) { +static void evt_handler(unsigned char type, EOSMessage *msg, uint16_t len, uint8_t _idx) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; - if (idx && (idx <= EOS_EVT_MAX_EVT)) { + if (idx && (idx <= EOS_EVT_MAX)) { uint16_t flag = (uint16_t)1 << (type & ~EOS_EVT_MASK); idx--; if (flag & net_flags_acq[idx]) { - evt_handler_wrapper(type, buffer, len, idx, flag); + evt_handler_wrapper(type, msg, len, _idx); } else { - eos_evtq_get_handler(type)(type, buffer, len); + eos_evtq_get_handler(type)(type, msg, len); } } else { - eos_evtq_bad_handler(type, buffer, len); + eos_evtq_bad_handler(type, msg, len); + } +} + +static void net_flushq(void) { + while (eos_msgq_len(&net_send_q)) { + asm volatile ("wfi"); + set_csr(mstatus, MSTATUS_MIE); + clear_csr(mstatus, MSTATUS_MIE); } } @@ -310,12 +345,55 @@ static void net_wait4cts(void) { } } +static int net_wake(void) { + uint32_t start, timeout; + + start = eos_get_tick(); + timeout = NET_DETECT_TIMEOUT; + while (net_state_flags & NET_STATE_FLAG_SLEEP) { + if (timeout && (eos_tdelta_ms(start) > timeout)) return EOS_ERR_NOTFOUND; + net_xchg_reset(); + eos_sleep(10); + set_csr(mstatus, MSTATUS_MIE); + clear_csr(mstatus, MSTATUS_MIE); + } + + return EOS_OK; +} + +static int net_select(int *dsel) { + int rv; + + *dsel = 0; + if (net_state_flags & NET_STATE_FLAG_ABSENT) return EOS_ERR_NOTFOUND; + if (net_state_flags & NET_STATE_FLAG_SLEEP_REQ) return EOS_ERR_BUSY; + + rv = EOS_OK; + if (!(net_state_flags & NET_STATE_FLAG_RUN)) { + set_csr(mstatus, MSTATUS_MIE); + rv = eos_spi_select(EOS_SPI_DEV_NET); + clear_csr(mstatus, MSTATUS_MIE); + if (rv) return rv; + *dsel = 1; + } + /* wake up remote if sleeping */ + if (net_state_flags & NET_STATE_FLAG_SLEEP) rv = net_wake(); + + return rv; +} + +static void net_deselect(void) { + eos_spi_deselect(); +} + static void net_pause(void) { net_state_flags &= ~NET_STATE_FLAG_RUN; net_wait4xchg(); } static void net_resume(void) { + if (net_state_flags & NET_STATE_FLAG_ABSENT) return; + net_state_flags |= NET_STATE_FLAG_RUN; if (net_state_flags & NET_STATE_FLAG_CTS) { net_xchg_next(NULL); @@ -331,62 +409,90 @@ static void net_stop(void) { eos_intr_set_handler(INT_SPI1_BASE, NULL); } -int eos_net_init(uint8_t wakeup_cause) { +int eos_net_init(void) { int i; - eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_BUFQ); - eos_bufq_init(&net_buf_q, net_bufq_array, EOS_NET_SIZE_BUFQ); - for (i=0; i<EOS_NET_SIZE_BUFQ; i++) { + eos_msgq_init(&net_send_q, net_sndq_array, NET_SIZE_BUFQ); + eos_bufq_init(&net_buf_q, net_bufq_array, NET_SIZE_BUFQ); + for (i=0; i<NET_SIZE_BUFQ; i++) { eos_bufq_push(&net_buf_q, net_bufq_buffer[i]); } for (i=0; i<EOS_NET_MAX_MTYPE; i++) { net_handler[i] = eos_net_bad_handler; } - eos_evtq_set_handler(0, evt_handler); + eos_evtq_set_handler_global(evt_handler); eos_evtq_set_handler(EOS_EVT_NET, net_handle_evt); + GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_CTS); GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_CTS); - GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_CTS); + GPIO_REG(GPIO_FALL_IE) |= (1 << NET_PIN_CTS); eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, IRQ_PRIORITY_NET_CTS, net_handle_cts); + /* XXX: pull-up not needed for new board */ + GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_RTS); GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_RTS); GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_RTS); GPIO_REG(GPIO_FALL_IE) |= (1 << NET_PIN_RTS); eos_intr_set(INT_GPIO_BASE + NET_PIN_RTS, IRQ_PRIORITY_NET_RTS, net_handle_rts); - /* set initial state */ - clear_csr(mstatus, MSTATUS_MIE); - if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS)) net_state_flags |= NET_STATE_FLAG_CTS; - if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS)) net_state_flags |= NET_STATE_FLAG_RTS; - set_csr(mstatus, MSTATUS_MIE); - return EOS_OK; } -int eos_net_run(uint8_t wakeup_cause) { +int eos_net_run(void) { + uint8_t wakeup_cause; + int rv, rst; + + rv = EOS_OK; net_start(); + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); + clear_csr(mstatus, MSTATUS_MIE); - if (wakeup_cause != EOS_PWR_WAKE_RST) { - if (wakeup_cause != EOS_PWR_WAKE_BTN) { - net_xchg_wake(); - } - if (!(net_state_flags & NET_STATE_FLAG_CTS)) { - while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) { - asm volatile ("wfi"); + if (rst) { + uint32_t start, timeout; + + start = eos_get_tick(); + timeout = NET_DETECT_TIMEOUT; + while (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS)) { + if (timeout && (eos_tdelta_ms(start) > timeout)) { + rv = EOS_ERR_NOTFOUND; + break; } - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); } - net_xchg_reset(); + } else { + if (eos_aon_load4net()) { + /* device previously declared as absent */ + rv = EOS_ERR_NOTFOUND; + } else { + net_state_flags |= NET_STATE_FLAG_SLEEP; + } + } + if (!rv) { + /* set initial state */ + if (!(GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS))) net_state_flags |= NET_STATE_FLAG_CTS; + if (!(GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS))) net_state_flags |= NET_STATE_FLAG_RTS; + GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << NET_PIN_CTS); + /* wake up remote */ + if (!rst) rv = net_wake(); + if (!rv) net_resume(); + } else { + net_state_flags |= NET_STATE_FLAG_ABSENT; + EOS_LOG(EOS_LOG_ERR, "NET DEVICE ABSENT\n"); } - net_resume(); set_csr(mstatus, MSTATUS_MIE); - return EOS_OK; + /* save absent state */ + if (rst) eos_aon_save4net(!!rv); + + if (rv) net_stop(); + return rv; } void eos_net_start(void) { + if (net_state_flags & NET_STATE_FLAG_ABSENT) return; + net_start(); clear_csr(mstatus, MSTATUS_MIE); @@ -395,6 +501,8 @@ void eos_net_start(void) { } void eos_net_stop(void) { + if (net_state_flags & NET_STATE_FLAG_ABSENT) return; + clear_csr(mstatus, MSTATUS_MIE); net_pause(); set_csr(mstatus, MSTATUS_MIE); @@ -402,64 +510,58 @@ void eos_net_stop(void) { net_stop(); } -int eos_net_sleep(uint32_t timeout) { - uint32_t start; - uint8_t done = 0; - int rv = EOS_OK; +int eos_net_sleep(void) { + int dsel = 0; + int rv; clear_csr(mstatus, MSTATUS_MIE); - if (!(net_state_flags & NET_STATE_FLAG_RUN)) rv = EOS_ERR; + rv = net_select(&dsel); + if (rv) { + set_csr(mstatus, MSTATUS_MIE); + return rv; + } + net_state_flags |= NET_STATE_FLAG_SLEEP_REQ; + net_flushq(); + net_pause(); + net_wait4cts(); + net_xchg_sleep_req(); + net_resume(); set_csr(mstatus, MSTATUS_MIE); + if (dsel) net_deselect(); - if (rv) return rv; - - start = eos_time_get_tick(); - do { - if (eos_time_delta_ms(start) > timeout) return EOS_ERR_TIMEOUT; - clear_csr(mstatus, MSTATUS_MIE); - eos_evtq_flush_isr(); - done = (eos_msgq_len(&net_send_q) == 0); - done = done && (!(net_state_flags & NET_STATE_FLAG_RTS) && (net_state_flags & NET_STATE_FLAG_CTS)); - if (done) done = (net_xchg_sleep() == EOS_OK); - if (!done) { - asm volatile ("wfi"); - set_csr(mstatus, MSTATUS_MIE); - } - } while (!done); - - while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) { - if (eos_time_delta_ms(start) > timeout) { - rv = EOS_ERR_TIMEOUT; - break; - } - asm volatile ("wfi"); - } + return EOS_OK; +} - if (!rv) { - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); - net_state_flags &= ~NET_STATE_FLAG_RUN; - } +int eos_net_sleep_rdy(void) { + int rv; + clear_csr(mstatus, MSTATUS_MIE); + rv = !!(net_state_flags & NET_STATE_FLAG_SLEEP); set_csr(mstatus, MSTATUS_MIE); return rv; } -void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) { - eos_evtq_bad_handler(type, buffer, len); - if (buffer) eos_net_free(buffer, 0); +void eos_net_wake(void) { + clear_csr(mstatus, MSTATUS_MIE); + net_state_flags &= ~NET_STATE_FLAG_SLEEP_REQ; + set_csr(mstatus, MSTATUS_MIE); +} + +void eos_net_bad_handler(unsigned char type, EOSMessage *msg, uint16_t len) { + eos_evtq_bad_handler(type, msg, len); } void eos_net_set_handler(unsigned char mtype, eos_evt_handler_t handler) { if (handler == NULL) handler = eos_net_bad_handler; - if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler; + if (mtype < EOS_NET_MAX_MTYPE) net_handler[mtype] = handler; } -void eos_net_acquire_for_evt(unsigned char type, char acq) { +void eos_net_acquire_for_evt(unsigned char type, int acq) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; uint16_t flag = type & ~EOS_EVT_MASK ? (uint16_t)1 << (type & ~EOS_EVT_MASK) : 0xFFFF; - if (idx && (idx <= EOS_EVT_MAX_EVT)) { + if (idx && (idx <= EOS_EVT_MAX)) { idx--; net_flags_acq[idx] &= ~flag; if (acq) net_flags_acq[idx] |= flag; @@ -467,7 +569,9 @@ void eos_net_acquire_for_evt(unsigned char type, char acq) { } void eos_net_acquire(void) { - unsigned char acq = net_acquire(0); + int acq; + + acq = net_acquire(0); if (!acq) net_acquire(1); } @@ -480,117 +584,118 @@ void eos_net_release(void) { set_csr(mstatus, MSTATUS_MIE); } -unsigned char *eos_net_alloc(void) { - unsigned char *ret = NULL; +void eos_net_alloc(EOSMessage *msg) { + msg->buffer = NULL; + msg->size = 0; - while (ret == NULL) { + while (msg->buffer == NULL) { clear_csr(mstatus, MSTATUS_MIE); if (net_state_next_buf) { - ret = net_state_next_buf; + msg->buffer = net_state_next_buf; + msg->size = EOS_NET_MTU; net_state_next_buf = NULL; } else { asm volatile ("wfi"); } set_csr(mstatus, MSTATUS_MIE); } - - return ret; } -void eos_net_free(unsigned char *buffer, unsigned char more) { - uint8_t do_release = 1; - +void eos_net_free(EOSMessage *msg, int more) { clear_csr(mstatus, MSTATUS_MIE); if ((more || net_state_next_cnt) && (net_state_next_buf == NULL)) { - net_state_next_buf = buffer; + net_state_next_buf = msg->buffer; } else { + int do_release = 1; + if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) { - do_release = net_xchg_next(buffer); + do_release = net_xchg_next(msg); } if (do_release) { - eos_bufq_push(&net_buf_q, buffer); + eos_bufq_push(&net_buf_q, msg->buffer); } } + msg->buffer = NULL; + msg->size = 0; set_csr(mstatus, MSTATUS_MIE); } -static int net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len, unsigned char flags) { +static int net_xchg(unsigned char *type, EOSMessage *msg, uint16_t *len, unsigned char flags) { int rv = EOS_OK; - int _sync = 0; - unsigned char _type = *type; + int sync = 0, dsel = 0; + unsigned char _type = *type & EOS_NET_MTYPE_MASK; uint16_t _len = *len; - uint8_t spi_dev = EOS_SPI_DEV_NET; - if (flags & EOS_NET_FLAG_ONEW) _type |= EOS_NET_MTYPE_FLAG_ONEW; - if (flags & EOS_NET_FLAG_REPL) _type |= EOS_NET_MTYPE_FLAG_REPL; - if (flags & EOS_NET_FLAG_SYNC) _sync = 1; + if ((flags & EOS_NET_FLAG_REPL) && (_type & EOS_NET_MTYPE_FLAG_BRIDGE)) return EOS_ERR; - clear_csr(mstatus, MSTATUS_MIE); - if ((flags & EOS_NET_FLAG_ONEW) && !(net_state_flags & NET_STATE_FLAG_RUN)) _sync = 1; + if (flags & EOS_NET_FLAG_REPL) flags |= EOS_NET_FLAG_SYNC; - if (_sync && !(net_state_flags & NET_STATE_FLAG_RUN)) { - int _rv; + if (flags & EOS_NET_FLAG_MORE) _type |= EOS_NET_MTYPE_FLAG_ONEW; + if (flags & EOS_NET_FLAG_REPL) _type |= EOS_NET_MTYPE_FLAG_REPL; + if (flags & EOS_NET_FLAG_SYNC) sync = 1; - set_csr(mstatus, MSTATUS_MIE); - spi_dev = eos_spi_dev(); - _rv = eos_spi_deselect(); - if (_rv) return _rv; - clear_csr(mstatus, MSTATUS_MIE); - } + clear_csr(mstatus, MSTATUS_MIE); + rv = net_select(&dsel); + if (rv) goto net_xchg_fin; - if (_sync) { + if (dsel) sync = 1; + if (sync) { + _type |= EOS_NET_MTYPE_FLAG_ONEW; net_pause(); net_wait4cts(); - if (flags & EOS_NET_FLAG_SYNC) { - net_state_flags |= NET_STATE_FLAG_SYNC; + net_state_flags |= NET_STATE_FLAG_SYNC; + net_xchg_start(_type, msg, _len); + if (flags & EOS_NET_FLAG_REPL) { + net_wait4cts(); + net_xchg_start(0, msg, 0); } - net_xchg_start(_type, buffer, _len); - if (flags & EOS_NET_FLAG_SYNC) { - if (flags & EOS_NET_FLAG_REPL) { - net_wait4cts(); - net_xchg_start(0, buffer, 0); + net_wait4xchg(); + net_state_flags &= ~NET_STATE_FLAG_SYNC; + if (flags & EOS_NET_FLAG_REPL) { + *type = 0; + *len = 0; + rv = (net_state_flags & NET_STATE_FLAG_ERR_SIZE) ? EOS_ERR_SIZE : EOS_OK; + if (!rv) { + *type = net_state_type & EOS_NET_MTYPE_MASK; + *len = net_state_len_rx; } - net_wait4xchg(); - net_state_flags &= ~NET_STATE_FLAG_SYNC; - *type = (net_state_type & ~EOS_NET_MTYPE_FLAG_MASK); - *len = net_state_len_rx; } net_resume(); } else { if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) { - net_xchg_start(_type, buffer, _len); + net_xchg_start(_type, msg, _len); } else { - rv = eos_msgq_push(&net_send_q, _type, buffer, _len); - if (rv) eos_bufq_push(&net_buf_q, buffer); + rv = eos_msgq_push(&net_send_q, _type, msg, _len); } } +net_xchg_fin: set_csr(mstatus, MSTATUS_MIE); - if (spi_dev != EOS_SPI_DEV_NET) eos_spi_select(spi_dev); + if (!(flags & EOS_NET_FLAG_SYNC)) { + if (sync || rv) { + eos_net_free(msg, !!(flags & EOS_NET_FLAG_MORE)); + } else { + msg->buffer = NULL; + msg->size = 0; + } + } + if (dsel) net_deselect(); return rv; } -int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) { - return net_xchg(type, buffer, len, (EOS_NET_FLAG_ONEW | EOS_NET_FLAG_SYNC | EOS_NET_FLAG_REPL)); +int eos_net_send(unsigned char type, EOSMessage *msg, uint16_t len, int more) { + return net_xchg(&type, msg, &len, more ? EOS_NET_FLAG_MORE : 0); } -int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len) { - return net_xchg(&type, buffer, &len, (EOS_NET_FLAG_ONEW | EOS_NET_FLAG_SYNC)); +int eos_net_send_sync(unsigned char type, EOSMessage *msg, uint16_t len) { + return net_xchg(&type, msg, &len, EOS_NET_FLAG_SYNC); } -int eos_net_send_async(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more) { - int rv; - - rv = net_xchg(&type, buffer, &len, more ? EOS_NET_FLAG_ONEW : 0); - if (rv) eos_net_free(buffer, more); - return rv; +int eos_net_xchg(unsigned char *type, EOSMessage *msg, uint16_t *len) { + return net_xchg(type, msg, len, EOS_NET_FLAG_REPL); } -int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more) { - if (async) { - return eos_net_send_async(type, buffer, len, more); - } else { - return eos_net_send(type, buffer, len); - } +int _eos_net_send(unsigned char type, EOSMessage *msg, uint16_t len, unsigned char flags) { + return net_xchg(&type, msg, &len, flags); } diff --git a/fw/fe310/eos/dev/net.h b/fw/fe310/eos/dev/net.h index 2482a32..ad544a3 100644 --- a/fw/fe310/eos/dev/net.h +++ b/fw/fe310/eos/dev/net.h @@ -1,47 +1,46 @@ #include <stdint.h> + #include "../event.h" -/* common */ #define EOS_NET_MTU 1500 -#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_BRIDGE 0 /* handler only */ +#define EOS_NET_MTYPE_WIFI 1 +#define EOS_NET_MTYPE_CELL 2 +#define EOS_NET_MTYPE_SOCK 3 +#define EOS_NET_MTYPE_RNG 4 -#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 0x20 /* 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_FLAG_ONEW 0x80 +#define EOS_NET_MTYPE_FLAG_REPL 0x40 +#define EOS_NET_MTYPE_FLAG_BRIDGE 0x08 -/* fe310 specific */ -#define EOS_NET_SIZE_BUFQ 2 +#define EOS_NET_MTYPE_MASK 0x0F /* must be the same as ~EOS_EVT_MASK */ -#define EOS_NET_FLAG_ONEW 0x1 -#define EOS_NET_FLAG_SYNC 0x2 -#define EOS_NET_FLAG_REPL 0x4 +#define EOS_NET_FLAG_MORE 0x01 +#define EOS_NET_FLAG_SYNC 0x02 +#define EOS_NET_FLAG_REPL 0x04 -int eos_net_init(uint8_t wakeup_cause); -int eos_net_run(uint8_t wakeup_cause); +int eos_net_init(void); +int eos_net_run(void); void eos_net_start(void); void eos_net_stop(void); -int eos_net_sleep(uint32_t timeout); +int eos_net_sleep(void); +int eos_net_sleep_rdy(void); +void eos_net_wake(void); -void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len); +void eos_net_bad_handler(unsigned char type, EOSMessage *msg, uint16_t len); void eos_net_set_handler(unsigned char type, eos_evt_handler_t handler); -void eos_net_acquire_for_evt(unsigned char type, char acq); +void eos_net_acquire_for_evt(unsigned char type, int acq); void eos_net_acquire(void); void eos_net_release(void); -unsigned char *eos_net_alloc(void); -void eos_net_free(unsigned char *buffer, unsigned char more); -int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len); -int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len); -int eos_net_send_async(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more); -int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more); +void eos_net_alloc(EOSMessage *msg); +void eos_net_free(EOSMessage *msg, int more); +int eos_net_send(unsigned char type, EOSMessage *msg, uint16_t len, int more); +int eos_net_send_sync(unsigned char type, EOSMessage *msg, uint16_t len); +int eos_net_xchg(unsigned char *type, EOSMessage *msg, uint16_t *len); +int _eos_net_send(unsigned char type, EOSMessage *msg, uint16_t len, unsigned char flags);
\ No newline at end of file diff --git a/fw/fe310/eos/dev/pwr.c b/fw/fe310/eos/dev/pwr.c new file mode 100644 index 0000000..b60e35c --- /dev/null +++ b/fw/fe310/eos/dev/pwr.c @@ -0,0 +1,47 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "eos.h" +#include "log.h" +#include "event.h" +#include "soc/pwr.h" +#include "eve/eve.h" +#include "eve/eve_touch_engine.h" + +#include "eve.h" +#include "lcd.h" +#include "ctp.h" +#include "net.h" +#include "flash.h" +#include "aon.h" + +#include "pwr.h" + +static void pwr_sleep_rdy(void) { + if ((eos_evtq_len() == 0) && eos_net_sleep_rdy()) { + eos_flash_norm(); +#ifdef EOS_DEBUG + EOS_LOG(EOS_LOG_INFO, "PWR SLEEP\n"); + eos_sleep(100); +#endif + eos_pwr_sleep(); + } +} + +void eos_pwr_sys_sleep(void) { + int rv; + + rv = eos_lcd_sleep(); + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: LCD SLEEP ERR:%d\n", rv); + + rv = eos_ctp_sleep(); + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: CTP SLEEP ERR:%d\n", rv); + + rv = eos_eve_sleep(); + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: EVE SLEEP ERR:%d\n", rv); + + eos_evtq_set_loopf(pwr_sleep_rdy); + + rv = eos_net_sleep(); + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: NET SLEEP REQ ERR:%d\n", rv); +} diff --git a/fw/fe310/eos/dev/pwr.h b/fw/fe310/eos/dev/pwr.h new file mode 100644 index 0000000..d3125f4 --- /dev/null +++ b/fw/fe310/eos/dev/pwr.h @@ -0,0 +1 @@ +void eos_pwr_sys_sleep(void); diff --git a/fw/fe310/eos/dev/sdc_crypto.c b/fw/fe310/eos/dev/sdc_crypto.c index f0e935d..0cb7a78 100644 --- a/fw/fe310/eos/dev/sdc_crypto.c +++ b/fw/fe310/eos/dev/sdc_crypto.c @@ -9,9 +9,9 @@ #define SDC_CRYPTO_BLK_SIZE 16 #define SDC_CRYPTO_HASH_SIZE 20 -EOSSDCCrypto *sdc_crypto; +static EOSSDCCrypto *sdc_crypto; -void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eve_sdcc_init_t init, eve_sdcc_crypt_t enc, eve_sdcc_crypt_t dec, void *ctx_essiv, eve_sdcc_init_t init_essiv, eve_sdcc_essiv_t enc_essiv) { +void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eos_sdcc_init_t init, eos_sdcc_crypt_t enc, eos_sdcc_crypt_t dec, void *ctx_essiv, eos_sdcc_init_t init_essiv, eos_sdcc_essiv_t enc_essiv) { char key_essiv[SDC_CRYPTO_HASH_SIZE]; sdc_crypto = crypto; @@ -28,7 +28,7 @@ void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eve_sdcc_init_ sdc_crypto->enc_essiv = enc_essiv; } -void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer) { +void eos_sdc_encrypt(uint32_t sect, uint8_t *buffer) { uint8_t iv[SDC_CRYPTO_BLK_SIZE]; if (sdc_crypto == NULL) return; @@ -39,7 +39,7 @@ void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer) { sdc_crypto->enc(sdc_crypto->ctx, iv, buffer, 512); } -void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer) { +void eos_sdc_decrypt(uint32_t sect, uint8_t *buffer) { uint8_t iv[SDC_CRYPTO_BLK_SIZE]; if (sdc_crypto == NULL) return; diff --git a/fw/fe310/eos/dev/sdc_crypto.h b/fw/fe310/eos/dev/sdc_crypto.h index 6442547..176483a 100644 --- a/fw/fe310/eos/dev/sdc_crypto.h +++ b/fw/fe310/eos/dev/sdc_crypto.h @@ -1,18 +1,18 @@ #include <stddef.h> #include <stdint.h> -typedef void (*eve_sdcc_init_t) (void *, uint8_t *); -typedef void (*eve_sdcc_crypt_t) (void *, uint8_t *, uint8_t *, size_t); -typedef void (*eve_sdcc_essiv_t) (void *, uint8_t *); +typedef void (*eos_sdcc_init_t) (void *, uint8_t *); +typedef void (*eos_sdcc_crypt_t) (void *, uint8_t *, uint8_t *, size_t); +typedef void (*eos_sdcc_essiv_t) (void *, uint8_t *); typedef struct EOSSDCCrypto { void *ctx; - eve_sdcc_crypt_t enc; - eve_sdcc_crypt_t dec; + eos_sdcc_crypt_t enc; + eos_sdcc_crypt_t dec; void *ctx_essiv; - eve_sdcc_essiv_t enc_essiv; + eos_sdcc_essiv_t enc_essiv; } EOSSDCCrypto; -void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eve_sdcc_init_t init, eve_sdcc_crypt_t enc, eve_sdcc_crypt_t dec, void *ctx_essiv, eve_sdcc_init_t init_essiv, eve_sdcc_essiv_t enc_essiv); -void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer); -void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer); +void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eos_sdcc_init_t init, eos_sdcc_crypt_t enc, eos_sdcc_crypt_t dec, void *ctx_essiv, eos_sdcc_init_t init_essiv, eos_sdcc_essiv_t enc_essiv); +void eos_sdc_encrypt(uint32_t sect, uint8_t *buffer); +void eos_sdc_decrypt(uint32_t sect, uint8_t *buffer); diff --git a/fw/fe310/eos/dev/sdcard.c b/fw/fe310/eos/dev/sdcard.c new file mode 100644 index 0000000..ebdc883 --- /dev/null +++ b/fw/fe310/eos/dev/sdcard.c @@ -0,0 +1,48 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "encoding.h" +#include "platform.h" +#include "board.h" + +#include "eos.h" + +#include "spi.h" + +#include "drv/sdcard.h" +#include "sdcard.h" + +#define SDC_DETECT_TIMEOUT 1000 + +int eos_sdc_init(void) { + clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << SPI_CSPIN_SDC); + set_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << SPI_CSPIN_SDC); + + return EOS_OK; +} + +int eos_sdc_insert(int sdc_det, uint32_t timeout) { + if (timeout == 0) timeout = SDC_DETECT_TIMEOUT; + if (sdc_det) { + int rv; + + eos_spi_set_div(EOS_SPI_DEV_SDC, 1024); // 100 - 400 kHz + + rv = eos_spi_select(EOS_SPI_DEV_SDC); + if (rv) goto sdc_insert_fin; + + rv = sdc_init(timeout); + if (rv) rv = EOS_ERR_NOTFOUND; + eos_spi_deselect(); + +sdc_insert_fin: + eos_spi_set_div(EOS_SPI_DEV_SDC, SPI_DIV_SDC); + if (rv) return rv; + } else { + sdc_clear(); + } + + return EOS_OK; +} diff --git a/fw/fe310/eos/dev/sdcard.h b/fw/fe310/eos/dev/sdcard.h new file mode 100644 index 0000000..4b338ea --- /dev/null +++ b/fw/fe310/eos/dev/sdcard.h @@ -0,0 +1,4 @@ +#include <stdint.h> + +int eos_sdc_init(void); +int eos_sdc_insert(int sdc_det, uint32_t timeout); diff --git a/fw/fe310/eos/dev/spi.c b/fw/fe310/eos/dev/spi.c index fef00e1..ea6d74a 100644 --- a/fw/fe310/eos/dev/spi.c +++ b/fw/fe310/eos/dev/spi.c @@ -5,7 +5,7 @@ #include "platform.h" #include "eos.h" -#include "msgq.h" +#include "log.h" #include "event.h" #include "board.h" @@ -13,33 +13,36 @@ #include "soc/interrupt.h" #include "soc/spi.h" #include "soc/spi_priv.h" +#include "soc/spi9bit.h" #include "net.h" #include "egpio.h" +#include "egpio_priv.h" #include "spi.h" #include "spi_cfg.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - static unsigned char spi_dstack[EOS_SPI_MAX_DSTACK]; static unsigned char spi_dstack_len; -static uint16_t spi_div[EOS_SPI_MAX_DEV]; +static uint16_t spi_div[SPI_MAX_DEV]; static uint8_t spi_dev(void) { return spi_dstack_len ? spi_dstack[spi_dstack_len - 1] : EOS_SPI_DEV_NET; } -static void spi_stop(unsigned char dev) { +static int spi_stop(unsigned char dev) { if (dev == EOS_SPI_DEV_NET) { eos_net_stop(); - } else if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) { - eos_spi_enable(); } else { - eos_spi_stop(); + if (eos_spi_get_cs()) return EOS_ERR_BUSY; + if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) { + eos_spi9bit_stop(); + eos_spi_enable(); + } else { + eos_spi_stop(); + } } + return EOS_OK; } static void spi_start(unsigned char dev) { @@ -48,6 +51,7 @@ static void spi_start(unsigned char dev) { } else if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) { eos_spi_configure(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt); eos_spi_disable(); + eos_spi9bit_start(); } else { eos_spi_start(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt); } @@ -56,7 +60,8 @@ static void spi_start(unsigned char dev) { int eos_spi_dev_init(void) { int i; - for (i=0; i<EOS_SPI_MAX_DEV; i++) { + /* dev modules are responsibile for configuring cs gpio */ + for (i=0; i<SPI_MAX_DEV; i++) { spi_div[i] = spi_cfg[i].div; } @@ -71,14 +76,10 @@ int eos_spi_select(unsigned char dev) { int rv; int dsel; - if (eos_spi_cs_get()) rv = EOS_ERR_BUSY; - if (!rv && (spi_dstack_len == EOS_SPI_MAX_DSTACK)) rv = EOS_ERR_FULL; - - if (rv) { -#ifdef EOS_DEBUG - printf("SPI SELECT DEV:%d ERR:%d\n", dev, rv); -#endif - return rv; + rv = EOS_OK; + if (spi_dstack_len == EOS_SPI_MAX_DSTACK) { + rv = EOS_ERR_FULL; + goto spi_select_fin; } dsel = 1; @@ -87,13 +88,21 @@ int eos_spi_select(unsigned char dev) { dsel = 0; } - if (dsel) spi_stop(spi_dev()); + if (dsel) { + rv = spi_stop(spi_dev()); + if (rv) goto spi_select_fin; + } spi_dstack[spi_dstack_len] = dev; spi_dstack_len++; if (dsel) spi_start(dev); +spi_select_fin: + if (rv) { + EOS_LOG(EOS_LOG_ERR, "SPI SELECT DEV:%d ERR:%d\n", dev, rv); + return rv; + } return EOS_OK; } @@ -101,23 +110,25 @@ void eos_spi_deselect(void) { int rv; int dsel; - if (eos_spi_cs_get()) rv = EOS_ERR_BUSY; - if (!rv && (spi_dstack_len == 0)) rv = EOS_ERR_EMPTY; - - if (rv) { -#ifdef EOS_DEBUG - printf("SPI DESELECT ERR:%d\n", rv); -#endif - return; + rv = EOS_OK; + if (spi_dstack_len == 0) { + rv = EOS_ERR_EMPTY; + goto spi_deselect_fin; } dsel = !(spi_dev() & EOS_SPI_DEV_FLAG_NDSEL); - if (dsel) spi_stop(spi_dev()); + if (dsel) { + rv = spi_stop(spi_dev()); + if (rv) goto spi_deselect_fin; + } spi_dstack_len--; spi_dstack[spi_dstack_len] = 0xff; if (dsel) spi_start(spi_dev()); + +spi_deselect_fin: + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI DESELECT ERR:%d\n", rv); } void eos_spi_dev_configure(unsigned char dev) { diff --git a/fw/fe310/eos/dev/spi_cfg.h b/fw/fe310/eos/dev/spi_cfg.h index 6ef92aa..906de24 100644 --- a/fw/fe310/eos/dev/spi_cfg.h +++ b/fw/fe310/eos/dev/spi_cfg.h @@ -10,9 +10,9 @@ typedef struct { #define SPI_DEV_FLAG_9BIT 0x01 -#define EOS_SPI_MAX_DEV 6 +#define SPI_MAX_DEV 6 -static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = { +static const SPIConfig spi_cfg[SPI_MAX_DEV] = { { // DEV_NET .div = SPI_DIV_NET, .csid = SPI_CSID_NET, @@ -32,14 +32,14 @@ static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = { .csid = SPI_CSID_SDC, .cspin = SPI_CSPIN_SDC, .flags = 0, - .evt = EOS_SPI_EVT_SDC, + .evt = EOS_SPI_ETYPE_SDC, }, { // DEV_CAM .div = SPI_DIV_CAM, .csid = SPI_CSID_CAM, .cspin = SPI_CSPIN_CAM, .flags = 0, - .evt = EOS_SPI_EVT_CAM, + .evt = EOS_SPI_ETYPE_CAM, }, { // DEV_HPAMP .div = SPI_DIV_HPAMP, diff --git a/fw/fe310/eos/eos.c b/fw/fe310/eos/eos.c index 6df8700..0f6aeb6 100644 --- a/fw/fe310/eos/eos.c +++ b/fw/fe310/eos/eos.c @@ -3,10 +3,12 @@ #include "encoding.h" #include "platform.h" #include "prci_driver.h" +#include "board.h" #include "event.h" #include "soc/interrupt.h" #include "soc/timer.h" +#include "soc/aon.h" #include "soc/pwr.h" #include "soc/i2s.h" #include "soc/i2c.h" @@ -16,18 +18,20 @@ #include "dev/flash.h" #include "dev/spi.h" #include "dev/net.h" +#include "dev/egpio.h" +#include "dev/egpio_priv.h" #include "dev/lcd.h" +#include "dev/ctp.h" #include "dev/sdcard.h" -#include "dev/gt911.h" -#include "dev/bq25895.h" +#include "dev/batt.h" #include "dev/eve.h" -#include "net/pwr.h" #include "net/wifi.h" #include "net/sock.h" #include "net/cell.h" #include "eos.h" +#include "log.h" uint8_t eos_init(void) { uint8_t wakeup_cause; @@ -36,65 +40,92 @@ uint8_t eos_init(void) { PRCI_use_default_clocks(); PRCI_use_pll(PLL_REFSEL_HFXOSC, 0, 1, 31, 1, -1, -1, -1); + /* enable printf */ + eos_uart_preinit(); + /* set flash driver */ eos_flash_init(); wakeup_cause = eos_pwr_wakeup_cause(); - eos_evtq_init(wakeup_cause); - eos_intr_init(wakeup_cause); - eos_timer_init(wakeup_cause); - eos_uart_init(wakeup_cause); + EOS_LOG(EOS_LOG_INFO, "INIT:%d\n", wakeup_cause); + EOS_LOG(EOS_LOG_INFO, "FREQ:%lu\n", PRCI_get_cpu_freq()); - printf("INIT:%d\n", wakeup_cause); + rv = eos_evtq_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EVTQ INIT ERR:%d\n", rv); + rv = eos_intr_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "INTR INIT ERR:%d\n", rv); + rv = eos_timer_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "TIMER INIT ERR:%d\n", rv); - rv = eos_pwr_init(wakeup_cause); - if (rv) printf("PWR INIT ERR:%d\n", rv); - rv = eos_i2s_init(wakeup_cause); - if (rv) printf("I2S INIT ERR:%d\n", rv); - rv = eos_i2c_init(wakeup_cause); - if (rv) printf("I2C INIT ERR:%d\n", rv); - rv = eos_spi_init(wakeup_cause); - if (rv) printf("SPI INIT ERR:%d\n", rv); - rv = eos_spi_dev_init(wakeup_cause); - if (rv) printf("SPI DEV INIT ERR:%d\n", rv); + rv = eos_aon_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "AON INIT ERR:%d\n", rv); + rv = eos_pwr_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR INIT ERR:%d\n", rv); + rv = eos_uart_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "UART INIT ERR:%d\n", rv); - rv = eos_bq25895_init(wakeup_cause); - if (rv) printf("BQ25895 INIT ERR:%d\n", rv); + rv = eos_i2s_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "I2S INIT ERR:%d\n", rv); + rv = eos_i2c_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "I2C INIT ERR:%d\n", rv); - rv = eos_net_init(wakeup_cause); - if (rv) printf("NET INIT ERR:%d\n", rv); + rv = eos_egpio_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO INIT ERR:%d\n", rv); - rv = eos_sdc_init(wakeup_cause); - if (rv) printf("SDC INIT ERR:%d\n", rv); + rv = eos_batt_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "BATT INIT ERR:%d\n", rv); - rv = eos_eve_init(wakeup_cause); - if (rv) printf("EVE INIT ERR:%d\n", rv); + rv = eos_spi_dev_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI DEV INIT ERR:%d\n", rv); + rv = eos_spi_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI INIT ERR:%d\n", rv); + rv = eos_sdc_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INIT ERR:%d\n", rv); - rv = eos_lcd_init(wakeup_cause); - if (rv) printf("LCD INIT ERR:%d\n", rv); + rv = eos_eve_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EVE INIT ERR:%d\n", rv); - rv = eos_eve_run(wakeup_cause); - if (rv) printf("EVE RUN ERR:%d\n", rv); + rv = eos_lcd_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "LCD INIT ERR:%d\n", rv); + + rv = eos_ctp_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "CTP INIT ERR:%d\n", rv); + + rv = eos_net_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "NET INIT ERR:%d\n", rv); - eos_pwr_net_init(); eos_wifi_init(); eos_sock_init(); eos_cell_init(); + rv = eos_sdc_insert(!eos_egpio_get_val(EGPIO_PIN_SDCARD_NDET), 0); + if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INSERT ERR:%d\n", rv); + return wakeup_cause; } -void eos_run(uint8_t wakeup_cause) { +void eos_run(void) { int rv; - rv = eos_net_run(wakeup_cause); - if (rv) printf("NET RUN ERR:%d\n", rv); + rv = eos_eve_run(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EVE RUN ERR:%d\n", rv); + + rv = eos_egpio_run(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO RUN ERR:%d\n", rv); + + rv = eos_net_run(); + if (rv) EOS_LOG(EOS_LOG_ERR, "NET RUN ERR:%d\n", rv); } +#include "dev/drv/gt911.h" +#include "eve/eve.h" + void eos_run_once(void) { - eos_gt911_cfg_print(); - eos_gt911_configure(); - eos_gt911_cfg_print(); + gt911_cfg_print(); + gt911_configure(); + gt911_cfg_print(); - eos_eve_calibrate(); + eve_select(); + eve_calibrate(); + eve_deselect(); } diff --git a/fw/fe310/eos/eos.h b/fw/fe310/eos/eos.h index 5158acd..75cd0cd 100644 --- a/fw/fe310/eos/eos.h +++ b/fw/fe310/eos/eos.h @@ -14,6 +14,8 @@ #define EOS_ERR_NET -20 +#define EOS_DEBUG 1 + uint8_t eos_init(void); -void eos_run(uint8_t wakeup_cause); +void eos_run(void); void eos_run_once(void);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/eve.c b/fw/fe310/eos/eve/eve.c index 45ac886..2f01358 100644 --- a/fw/fe310/eos/eve/eve.c +++ b/fw/fe310/eos/eve/eve.c @@ -12,86 +12,83 @@ static uint16_t cmd_offset; static char dl_burst; static uint32_t dl_addr; -static uint8_t power_state; -static int lcd_absent = 0; - void eve_command(uint8_t command, uint8_t parameter) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(((uint32_t)command << 16) | ((uint32_t)parameter << 8), 0); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } uint8_t eve_read8(uint32_t addr) { - uint8_t r; - eve_spi_cs_set(); + uint8_t rv; + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); - r = eve_spi_xchg8(0, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + rv = eve_spi_xchg8(0, EVE_SPI_FLAG_BSWAP); + eve_spi_clear_cs(); - return r; + return rv; } uint16_t eve_read16(uint32_t addr) { - uint16_t r; - eve_spi_cs_set(); + uint16_t rv; + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); - r = eve_spi_xchg16(0, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + rv = eve_spi_xchg16(0, EVE_SPI_FLAG_BSWAP); + eve_spi_clear_cs(); - return r; + return rv; } uint32_t eve_read32(uint32_t addr) { - uint32_t r; - eve_spi_cs_set(); + uint32_t rv; + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); - r = eve_spi_xchg32(0, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + rv = eve_spi_xchg32(0, EVE_SPI_FLAG_BSWAP); + eve_spi_clear_cs(); - return r; + return rv; } void eve_write8(uint32_t addr, uint8_t data) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); eve_spi_xchg8(data, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_write16(uint32_t addr, uint16_t data) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); eve_spi_xchg16(data, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_write32(uint32_t addr, uint32_t data) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); eve_spi_xchg32(data, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_readb(uint32_t addr, uint8_t *buf, size_t size) { int i; - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); for (i=0; i<size; i++) { buf[i] = eve_spi_xchg8(0, 0); } - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_writeb(uint32_t addr, uint8_t *buf, size_t size) { int i; - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); for (i=0; i<size; i++) { eve_spi_xchg8(buf[i], 0); } - eve_spi_cs_clear(); + eve_spi_clear_cs(); } static void dl_inc(uint32_t i) { @@ -102,8 +99,7 @@ void eve_dl_start(uint32_t addr, char burst) { dl_addr = addr; dl_burst = burst; if (burst) { - eve_spi_lock(); - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, EVE_SPI_FLAG_TX); } } @@ -120,8 +116,7 @@ void eve_dl_write(uint32_t dl) { void eve_dl_end(void) { if (dl_burst) { eve_spi_flush(); - eve_spi_cs_clear(); - eve_spi_unlock(); + eve_spi_clear_cs(); dl_burst = 0; } } @@ -142,7 +137,7 @@ static void cmd_inc(uint16_t i) { static void cmd_begin(uint32_t command, uint8_t flags) { if (!cmd_burst) { uint32_t addr = EVE_RAM_CMD + cmd_offset; - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); } eve_spi_xchg32(command, flags); @@ -150,7 +145,7 @@ static void cmd_begin(uint32_t command, uint8_t flags) { } static void cmd_end(void) { - if (!cmd_burst) eve_spi_cs_clear(); + if (!cmd_burst) eve_spi_clear_cs(); } static void cmd_string(const char *str, uint8_t flags) { @@ -256,44 +251,51 @@ void eve_cmd_dl(uint32_t dl) { } int eve_cmd_done(void) { - uint16_t r = eve_read16(REG_CMD_READ); + uint16_t rd = eve_read16(REG_CMD_READ); - if (r == 0xfff) { + if (rd == 0xfff) { eve_copro_reset(); return EVE_ERR; } - return (r == cmd_offset); + return (rd == cmd_offset); } int eve_cmd_exec(int w) { eve_write16(REG_CMD_WRITE, cmd_offset); if (w) { - int r; + int rv; + uint32_t start; + + start = eve_get_tick(); do { - r = eve_cmd_done(); - if (r < 0) break; - } while (!r); - if (r < 0) return EVE_ERR; + rv = eve_cmd_done(); + if (rv < 0) break; + if (eve_tdelta_ms(start) > EVE_CMD_EXEC_TO) break; + } while (!rv); + if (eve_tdelta_ms(start) > EVE_CMD_EXEC_TO) return EVE_ERR_TIMEOUT; + if (rv < 0) return EVE_ERR; } return EVE_OK; } +void eve_cmd_set_offset(void) { + cmd_offset = eve_read16(REG_CMD_READ); +} + void eve_cmd_burst_start(void) { uint32_t addr = EVE_RAM_CMD + cmd_offset; - eve_spi_lock(); - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, EVE_SPI_FLAG_TX); cmd_burst = 1; } void eve_cmd_burst_end(void) { eve_spi_flush(); - eve_spi_cs_clear(); - eve_spi_unlock(); + eve_spi_clear_cs(); cmd_burst = 0; } @@ -363,6 +365,7 @@ int eve_init(void) { eve_write8(REG_VOL_PB, 0x00); /* turn recorded audio volume off */ /* configure interrupts */ + eve_write8(REG_INT_EN, 0); eve_write16(REG_INT_MASK, 0); /* write a basic display-list to get things started */ @@ -378,28 +381,22 @@ int eve_init(void) { #endif /* nothing is being displayed yet... the pixel clock is still 0x00 */ + eve_pwr_set_state(EVE_PSTATE_ACTIVE); + return EVE_OK; } void eve_clk_start(void) { - uint16_t gpiox; - eve_write8(REG_PCLK, EVE_PCLK); /* start clocking data to the LCD panel */ - gpiox = eve_read16(REG_GPIOX) | 0x8000; - eve_write16(REG_GPIOX, gpiox); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIOX_DIR */ } void eve_clk_stop(void) { - uint16_t gpiox; - - gpiox = eve_read16(REG_GPIOX) & ~0x8000; - eve_write16(REG_GPIOX, gpiox); eve_write8(REG_PCLK, 0); } void eve_intr_enable(void) { - eve_write8(REG_INT_EN, 0x01); while(eve_read8(REG_INT_FLAGS)); + eve_write8(REG_INT_EN, 0x01); } void eve_intr_disable(void) { @@ -408,38 +405,53 @@ void eve_intr_disable(void) { } void eve_activate(void) { + if (eve_pwr_get_state() == EVE_PSTATE_ACTIVE) return; + eve_command(EVE_ACTIVE, 0); - eve_sleep(40); + if (eve_pwr_get_state() == EVE_PSTATE_SLEEP) { + eve_sleep(20); + } +} + +void eve_deactivate(void) { + switch (eve_pwr_get_state()) { + case EVE_PSTATE_ACTIVE: + return; + + case EVE_PSTATE_STANDBY: + eve_command(EVE_STANDBY, 0); + break; + + case EVE_PSTATE_SLEEP: + eve_command(EVE_SLEEP, 0); + break; + } } void eve_pwr_standby(void) { - if (power_state != EVE_PSTATE_ACTIVE) return; + if (eve_pwr_get_state() != EVE_PSTATE_ACTIVE) return; eve_command(EVE_STANDBY, 0); - power_state = EVE_PSTATE_STANDBY; + eve_pwr_set_state(EVE_PSTATE_STANDBY); } void eve_pwr_sleep(void) { - if (power_state != EVE_PSTATE_ACTIVE) return; - - eve_clk_stop(); - eve_intr_disable(); + if (eve_pwr_get_state() != EVE_PSTATE_ACTIVE) return; eve_command(EVE_SLEEP, 0); - power_state = EVE_PSTATE_SLEEP; + eve_pwr_set_state(EVE_PSTATE_SLEEP); } void eve_pwr_wake(void) { eve_activate(); - if (power_state == EVE_PSTATE_SLEEP) { - eve_intr_enable(); - eve_clk_start(); - } + eve_pwr_set_state(EVE_PSTATE_ACTIVE); +} - power_state = EVE_PSTATE_ACTIVE; +uint8_t eve_pwr_state(void) { + return eve_pwr_get_state(); } int eve_gpio_get(int gpio) { @@ -456,27 +468,44 @@ void eve_gpio_set(int gpio, int val) { eve_write16(REG_GPIOX, reg); } -uint8_t eve_gpio_get_dir(void) { +uint16_t eve_gpio_read(void) { + uint16_t reg = eve_read16(REG_GPIOX); + + return reg & EVE_GPIO_MASK; +} + +void eve_gpio_write(uint16_t gpio) { + uint16_t reg = eve_read16(REG_GPIOX); + + gpio &= EVE_GPIO_MASK; + reg &= ~EVE_GPIO_MASK; + reg |= gpio; + eve_write16(REG_GPIOX, reg); +} + +uint16_t eve_gpio_read_dir(void) { uint16_t reg = eve_read16(REG_GPIOX_DIR); - return reg & 0x000f; + return reg & EVE_GPIO_MASK; } -void eve_gpio_set_dir(uint8_t dir) { +void eve_gpio_write_dir(uint16_t dir) { uint16_t reg = eve_read16(REG_GPIOX_DIR); - reg &= 0xfff0; - reg |= dir & 0x0f; + dir &= EVE_GPIO_MASK; + reg &= ~EVE_GPIO_MASK; + reg |= dir; eve_write16(REG_GPIOX_DIR, reg); } -void eve_brightness(uint8_t b) { - if (lcd_absent) b = 0; +void eve_set_brightness(uint8_t b) { + if (eve_lcd_get_absent()) b = 0; + if (b > 0x80) b = 0x80; eve_write8(REG_PWM_DUTY, b); } -void eve_lcd_absent(void) { - lcd_absent = 1; +uint8_t eve_get_brightness(void) { + return eve_read8(REG_PWM_DUTY); } void eve_copro_reset(void) { @@ -490,5 +519,8 @@ void eve_copro_reset(void) { eve_write16(REG_CMD_DL, 0); eve_write8(REG_CPURESET, 0); eve_write16(REG_COPRO_PATCH_PTR, ptr); + /* From programming guide: + To enable coprocessor access flash content, send commands CMD_FLASHATTACH following CMD_FLASHFAST. + It will make sure flash enters full speed mode.*/ eve_write8(REG_PCLK, EVE_PCLK); } diff --git a/fw/fe310/eos/eve/eve.h b/fw/fe310/eos/eve/eve.h index ea4ec71..7936fc2 100644 --- a/fw/fe310/eos/eve/eve.h +++ b/fw/fe310/eos/eve/eve.h @@ -6,17 +6,15 @@ #include "eve_vtrack.h" #include "eve_platform.h" -#define EVE_OK 0 -#define EVE_ERR -1 - -#define EVE_ERR_FULL -10 -#define EVE_ERR_EMPTY -11 - -#define EVE_ERR_NOMEM -100 +/* defined in eve_platform.h */ +#define EVE_GPIO_MASK 0x800f #define EVE_PSTATE_ACTIVE 0 #define EVE_PSTATE_STANDBY 1 -#define EVE_PSTATE_SLEEP 3 +#define EVE_PSTATE_SLEEP 2 +#define EVE_PSTATE_PDOWN 3 + +#define EVE_CMD_EXEC_TO 1000 // 1s #define COLOR_RGBC(c) ((4UL<<24)|((c)&16777215UL)) #define CLEAR_COLOR_RGBC(c) ((2UL<<24)|((c)&16777215UL)) @@ -53,6 +51,7 @@ uint32_t eve_cmd_result(uint16_t offset); void eve_cmd_dl(uint32_t dl); int eve_cmd_done(void); int eve_cmd_exec(int w); +void eve_cmd_set_offset(void); void eve_cmd_burst_start(void); void eve_cmd_burst_end(void); @@ -65,15 +64,19 @@ void eve_intr_enable(void); void eve_intr_disable(void); void eve_activate(void); +void eve_deactivate(void); void eve_pwr_standby(void); void eve_pwr_sleep(void); void eve_pwr_wake(void); +uint8_t eve_pwr_state(void); int eve_gpio_get(int gpio); void eve_gpio_set(int gpio, int val); -uint8_t eve_gpio_get_dir(void); -void eve_gpio_set_dir(uint8_t dir); +uint16_t eve_gpio_read(void); +void eve_gpio_write(uint16_t gpio); +uint16_t eve_gpio_read_dir(void); +void eve_gpio_write_dir(uint16_t dir); -void eve_brightness(uint8_t b); -void eve_lcd_absent(void); +void eve_set_brightness(uint8_t b); +uint8_t eve_get_brightness(void); void eve_copro_reset(void); diff --git a/fw/fe310/eos/eve/eve_config.h b/fw/fe310/eos/eve/eve_config.h index 1126277..4a99992 100755 --- a/fw/fe310/eos/eve/eve_config.h +++ b/fw/fe310/eos/eve/eve_config.h @@ -3,31 +3,31 @@ /* FocusLCDs E50RG84885LWAM520-CA */ +#define EVE_HFP 8 /* horizontal front porch */ #define EVE_HLPW 6 /* horizontal low pulse width */ #define EVE_HBP 6 /* horizontal back porch */ -#define EVE_HFP 6 /* horizontal front porch */ #define EVE_HACT 480 /* horizontal active pixels */ -#define EVE_HTOT (EVE_HLPW + EVE_HBP + EVE_HFP + EVE_HACT + 10) +#define EVE_HTOT (EVE_HLPW + EVE_HBP + EVE_HFP + EVE_HACT) +#define EVE_HFPX (EVE_HFP - 2) /* refer to AN_336 - FT8xx - Selecting an LCD Display */ - -#define EVE_VLPW 6 /* vertical low pulse width */ -#define EVE_VBP 6 /* vertical back porch */ -#define EVE_VFP 6 /* vertical front porch */ +#define EVE_VFP 26 /* vertical front porch */ +#define EVE_VLPW 10 /* vertical low pulse width */ +#define EVE_VBP 10 /* vertical back porch */ #define EVE_VACT 854 /* vertical active pixels */ -#define EVE_VTOT (EVE_VLPW + EVE_VBP + EVE_VFP + EVE_VACT + 10) - +#define EVE_VTOT (EVE_VLPW + EVE_VBP + EVE_VFP + EVE_VACT) +#define EVE_VFPY (EVE_VFP - 2) /* refer to AN_336 - FT8xx - Selecting an LCD Display */ #define EVE_HCYCLE (EVE_HTOT) /* Th Total length of line (visible and non-visible) (in PCLKs) */ #define EVE_HSIZE (EVE_HACT) /* Length of visible part of line (in PCLKs) - display width */ -#define EVE_HOFFSET (EVE_HFP + EVE_HLPW + EVE_HBP) /* Length of non-visible part of line (in PCLK cycles) */ -#define EVE_HSYNC0 (EVE_HFP) /* Horizontal Front Porch */ -#define EVE_HSYNC1 (EVE_HFP + EVE_HLPW) /* Horizontal Front Porch plus Hsync Pulse width */ +#define EVE_HOFFSET (EVE_HFPX + EVE_HLPW + EVE_HBP) /* Length of non-visible part of line (in PCLK cycles) */ +#define EVE_HSYNC0 (EVE_HFPX) /* Horizontal Front Porch */ +#define EVE_HSYNC1 (EVE_HFPX + EVE_HLPW) /* Horizontal Front Porch plus Hsync Pulse width */ #define EVE_VCYCLE (EVE_VTOT) /* Total number of lines (visible and non-visible) (in lines) */ #define EVE_VSIZE (EVE_VACT) /* Number of visible lines (in lines) - display height */ -#define EVE_VOFFSET (EVE_VFP + EVE_VLPW + EVE_VBP) /* Number of non-visible lines (in lines) */ -#define EVE_VSYNC0 (EVE_VFP) /* Vertical Front Porch */ -#define EVE_VSYNC1 (EVE_VFP + EVE_VLPW) /* Vertical Front Porch plus Vsync Pulse width */ +#define EVE_VOFFSET (EVE_VFPY + EVE_VLPW + EVE_VBP) /* Number of non-visible lines (in lines) */ +#define EVE_VSYNC0 (EVE_VFPY) /* Vertical Front Porch */ +#define EVE_VSYNC1 (EVE_VFPY + EVE_VLPW) /* Vertical Front Porch plus Vsync Pulse width */ #define EVE_PCLKPOL 1 /* PCLK polarity (0 = rising edge, 1 = falling edge) */ #define EVE_SWIZZLE 0 /* Defines the arrangement of the RGB pins */ diff --git a/fw/fe310/eos/eve/eve_font.c b/fw/fe310/eos/eve/eve_font.c index 8f272bc..803c0d2 100644 --- a/fw/fe310/eos/eve/eve_font.c +++ b/fw/fe310/eos/eve/eve_font.c @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <string.h> #include "eve.h" #include "eve_font.h" @@ -19,57 +20,62 @@ int eve_font_ch_w(EVEFont *font, ucp_t ch) { return EVE_ERR; } -static int font_str_w(EVEFont *font, utf8_t *str, int *_str_w, size_t *_str_len) { - uint16_t r = 0; - size_t len = 0; +static int font_str_w(EVEFont *font, utf8_t *str, int *_str_w, size_t *_str_l) { + uint16_t w = 0; + size_t l = 0; ucp_t ch; int ch_w; int ch_l; - while (str[len]) { - ch_l = utf8_dec(str + len, &ch); + while (str[l]) { + ch_l = utf8_dec(str + l, &ch); ch_w = eve_font_ch_w(font, ch); if (ch_w < 0) { - if (_str_w) *_str_w = r; - if (_str_len) *_str_len = len; + if (_str_w) *_str_w = w; + if (_str_l) *_str_l = l; return EVE_ERR; } - r += ch_w; - len += ch_l; + w += ch_w; + l += ch_l; } - if (_str_w) *_str_w = r; - if (_str_len) *_str_len = len; + if (_str_w) *_str_w = w; + if (_str_l) *_str_l = l; return EVE_OK; } -static int font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *_buf_w, size_t *_buf_len) { - uint16_t r = 0; - size_t len = 0; +static int font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *_buf_w, size_t *_buf_l) { + uint16_t w = 0; + size_t l = 0; ucp_t ch; int ch_w; int ch_l; - while (len < buf_len) { - ch_l = utf8_dec(buf + len, &ch); + while (l < buf_len) { + ch_l = utf8_dec(buf + l, &ch); ch_w = eve_font_ch_w(font, ch); if (ch_w < 0) { - if (_buf_w) *_buf_w = r; - if (_buf_len) *_buf_len = len; + if (_buf_w) *_buf_w = w; + if (_buf_l) *_buf_l = l; return EVE_ERR; } - r += ch_w; - len += ch_l; + w += ch_w; + l += ch_l; } - if (_buf_w) *_buf_w = r; - if (_buf_len) *_buf_len = len; + if (_buf_w) *_buf_w = w; + if (_buf_l) *_buf_l = l; return EVE_OK; } -int eve_font_verify(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len) { +int eve_font_verify(EVEFont *font, utf8_t *str, size_t str_size, int *str_w, size_t *str_len) { int rv; + if (str_size == 0) str_size = strlen(str) + 1; + + rv = utf8_verify(str, str_size, str_len); + if (rv) return EVE_ERR; + rv = font_str_w(font, str, str_w, str_len); return rv; } diff --git a/fw/fe310/eos/eve/eve_font.h b/fw/fe310/eos/eve/eve_font.h index 7629106..57715ac 100644 --- a/fw/fe310/eos/eve/eve_font.h +++ b/fw/fe310/eos/eve/eve_font.h @@ -11,7 +11,7 @@ typedef struct EVEFont { void eve_font_init(EVEFont *font, uint8_t font_id); int eve_font_ch_w(EVEFont *font, ucp_t ch); -int eve_font_verify(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len); +int eve_font_verify(EVEFont *font, utf8_t *str, size_t str_size, int *str_w, size_t *str_len); int eve_font_str_w(EVEFont *font, utf8_t *str); int eve_font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len); uint8_t eve_font_h(EVEFont *font); diff --git a/fw/fe310/eos/eve/eve_kbd.c b/fw/fe310/eos/eve/eve_kbd.c index c8c1362..787e941 100644 --- a/fw/fe310/eos/eve/eve_kbd.c +++ b/fw/fe310/eos/eve/eve_kbd.c @@ -61,10 +61,10 @@ void eve_kbd_set_handler(EVEKbd *kbd, eve_kbd_input_handler_t putc, void *param) kbd->param = param; } -int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0) { - int ret; +int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt) { + int rv; - evt = eve_touch_evt(touch, evt, tag0, 1, 126); + evt = eve_touch_evt(touch, evt, 1, 126); if (touch && evt) { int8_t touch_idx = eve_touch_get_idx(touch); @@ -118,12 +118,12 @@ int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0) { } } } - ret = 1; + rv = 1; } else { - ret = 0; + rv = 0; } - return ret; + return rv; } uint8_t eve_kbd_draw(EVEKbd *kbd) { diff --git a/fw/fe310/eos/eve/eve_kbd.h b/fw/fe310/eos/eve/eve_kbd.h index b4f9874..a1f8abc 100644 --- a/fw/fe310/eos/eve/eve_kbd.h +++ b/fw/fe310/eos/eve/eve_kbd.h @@ -19,5 +19,5 @@ typedef struct EVEKbd { void eve_kbd_init(EVEKbd *kbd, EVERect *g, uint32_t mem_addr, uint32_t *mem_next); void eve_kbd_close(EVEKbd *kbd); void eve_kbd_set_handler(EVEKbd *kbd, eve_kbd_input_handler_t putc, void *param); -int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt); uint8_t eve_kbd_draw(EVEKbd *kbd); diff --git a/fw/fe310/eos/eve/eve_phy.c b/fw/fe310/eos/eve/eve_phy.c index cfddc80..8f170ba 100644 --- a/fw/fe310/eos/eve/eve_phy.c +++ b/fw/fe310/eos/eve/eve_phy.c @@ -11,69 +11,67 @@ void eve_phy_acc_init(EVEPhyAcc *param, int a) { int eve_phy_acc_start(EVEPhyAcc *param, int x0, int y0, uint32_t t0, int v0x, int v0y) { double v0; - uint32_t dt = eve_get_tick() - t0; v0 = sqrt(v0x * v0x + v0y * v0y); param->k = 2 * v0 / param->a * EVE_RTC_FREQ; - if ((param->k < 0) && (dt >= -param->k / 2)) { + if (param->k == 0) { return 0; } param->x0 = x0; param->y0 = y0; + param->t0 = t0; param->v0x = v0x; param->v0y = v0y; return 1; } -int eve_phy_acc_tick(EVEPhyAcc *param, uint32_t dt, int *x, int *y) { +int eve_phy_acc_tick(void *_param, int *x, int *y) { + EVEPhyAcc *param = (EVEPhyAcc *)_param; int k = param->k; int x0 = param->x0; int y0 = param->y0; int v0x = param->v0x; int v0y = param->v0y; - int _dt = dt; + uint32_t dt = eve_get_tick() - param->t0; int more = 1; - if (k == 0) { - if (x) *x = x0; - if (y) *y = y0; - return 0; - } - if ((k < 0) && (dt >= -k / 2)) { dt = -k / 2; more = 0; } - if (x) *x = x0 + (v0x * _dt + v0x * _dt / k * _dt) / EVE_RTC_FREQ; - if (y) *y = y0 + (v0y * _dt + v0y * _dt / k * _dt) / EVE_RTC_FREQ; + if (x) *x = x0 + (v0x * (int)dt + v0x * (int)dt / k * (int)dt) / EVE_RTC_FREQ; + if (y) *y = y0 + (v0y * (int)dt + v0y * (int)dt / k * (int)dt) / EVE_RTC_FREQ; return more; } /* Linear harmonic oscillator */ -void eve_phy_lho_init(EVEPhyLHO *param, int x, int y, uint32_t T, double d, uint32_t t_max) { +void eve_phy_lho_init(EVEPhyLHO *param, uint32_t T, double d, uint32_t t_max) { double f0 = 2 * M_PI / (T * EVE_RTC_FREQ / 1000); if (d < 0) d = 0; if (d > 1) d = 1; - param->x = x; - param->y = y; param->f = f0 * sqrt(1 - d * d); param->a = -d * f0; param->t_max = t_max * EVE_RTC_FREQ / 1000; } -int eve_phy_lho_start(EVEPhyLHO *param, int x0, int y0) { +int eve_phy_lho_start(EVEPhyLHO *param, int pivot_x, int pivot_y, int x0, int y0, uint32_t t0) { + param->pivot_x = pivot_x; + param->pivot_y = pivot_y; param->x0 = x0; param->y0 = y0; + param->t0 = t0; return 1; } -int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y) { - int ax = param->x0 - param->x; - int ay = param->y0 - param->y; +int eve_phy_lho_tick(void *_param, int *x, int *y) { + EVEPhyLHO *param = (EVEPhyLHO *)_param; + int ax = param->x0 - param->pivot_x; + int ay = param->y0 - param->pivot_y; + uint32_t dt = eve_get_tick() - param->t0; int more = 1; if (param->t_max && (dt >= param->t_max)) { @@ -86,8 +84,8 @@ int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y) { ay = ay * e; if ((ax == 0) && (ay == 0)) more = 0; } - if (x) *x = param->x + ax * cos(param->f * dt); - if (y) *y = param->y + ay * cos(param->f * dt); + if (x) *x = param->pivot_x + ax * cos(param->f * dt); + if (y) *y = param->pivot_y + ay * cos(param->f * dt); return more; } diff --git a/fw/fe310/eos/eve/eve_phy.h b/fw/fe310/eos/eve/eve_phy.h index e747b44..59f6299 100644 --- a/fw/fe310/eos/eve/eve_phy.h +++ b/fw/fe310/eos/eve/eve_phy.h @@ -5,24 +5,26 @@ typedef struct EVEPhyAcc { int k; int x0; int y0; + uint32_t t0; int v0x; int v0y; } EVEPhyAcc; void eve_phy_acc_init(EVEPhyAcc *param, int a); int eve_phy_acc_start(EVEPhyAcc *param, int x0, int y0, uint32_t t0, int v0x, int v0y); -int eve_phy_acc_tick(EVEPhyAcc *param, uint32_t dt, int *x, int *y); +int eve_phy_acc_tick(void *_param, int *x, int *y); typedef struct EVEPhyLHO { - int x; - int y; double f; double a; uint32_t t_max; + int pivot_x; + int pivot_y; int x0; int y0; + uint32_t t0; } EVEPhyLHO; -void eve_phy_lho_init(EVEPhyLHO *param, int x, int y, uint32_t T, double d, uint32_t t_max); -int eve_phy_lho_start(EVEPhyLHO *param, int x0, int y0); -int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y);
\ No newline at end of file +void eve_phy_lho_init(EVEPhyLHO *param, uint32_t T, double d, uint32_t t_max); +int eve_phy_lho_start(EVEPhyLHO *param, int x, int y, int x0, int y0, uint32_t t0); +int eve_phy_lho_tick(void *_param, int *x, int *y);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/eve_platform.c b/fw/fe310/eos/eve/eve_platform.c index 4c0d551..916b132 100644 --- a/fw/fe310/eos/eve/eve_platform.c +++ b/fw/fe310/eos/eve/eve_platform.c @@ -1,46 +1,35 @@ #include <stdlib.h> -#include <stdio.h> -#include "eos.h" - -#include "eve.h" #include "eve_platform.h" +// #ifdef EVE_DEBUG +#if 0 + void *eve_malloc(size_t size) { void *p = malloc(size); - printf("MALLOC:%p %d\n", p, size); + EVE_LOG(EVE_LOG_INFO, "MALLOC:%p %d\n", p, size); return p; } void eve_free(void *p) { - printf("FREE:%p\n", p); + EVE_LOG(EVE_LOG_INFO, "FREE:%p\n", p); free(p); } +#endif + void eve_sleep(uint32_t ms) { - eos_time_sleep(ms); + eos_sleep(ms); } uint32_t eve_get_tick(void) { - return eos_time_get_tick(); + return eos_get_tick(); } -void eve_sys_timer_set(uint32_t ms) { +void eve_ostimer_set(uint32_t ms) { eos_timer_set(EOS_TIMER_ETYPE_UI, ms); } -void eve_sys_timer_clear(void) { +void eve_ostimer_clear(void) { eos_timer_clear(EOS_TIMER_ETYPE_UI); } - -void eve_select(void) { - eos_spi_select(EOS_SPI_DEV_EVE); -} - -void eve_deselect(void) { - eos_spi_deselect(); -} - -int eve_selected(void) { - return (eos_spi_dev() == EOS_SPI_DEV_EVE); -} diff --git a/fw/fe310/eos/eve/eve_platform.h b/fw/fe310/eos/eve/eve_platform.h index cae7222..49c87dc 100644 --- a/fw/fe310/eos/eve/eve_platform.h +++ b/fw/fe310/eos/eve/eve_platform.h @@ -1,38 +1,61 @@ #include <stdint.h> #include <stdlib.h> +/* included from eve.h - needs relative includes */ +#include "../eos.h" +#include "../log.h" #include "../soc/timer.h" #include "../soc/spi.h" -#include "../dev/spi.h" +#include "../dev/aon.h" -#define EVE_ETYPE_INTR 1 +#ifdef EOS_DEBUG +#define EVE_DEBUG 1 +#endif #define EVE_RTC_FREQ EOS_TIMER_RTC_FREQ #define EVE_SPI_FLAG_BSWAP EOS_SPI_FLAG_BSWAP #define EVE_SPI_FLAG_TX EOS_SPI_FLAG_TX -void *eve_malloc(size_t); -void eve_free(void *); +#define EVE_OK EOS_OK +#define EVE_ERR EOS_ERR +#define EVE_ERR_TIMEOUT EOS_ERR_TIMEOUT + +#define EVE_ERR_FULL EOS_ERR_FULL +#define EVE_ERR_EMPTY EOS_ERR_EMPTY -//#define eve_malloc malloc -//#define eve_free free +#define EVE_ERR_NOMEM EOS_ERR_NOMEM -void eve_select(void); -void eve_deselect(void); -int eve_selected(void); +#define EVE_LOG_DEBUG EOS_LOG_DEBUG +#define EVE_LOG_INFO EOS_LOG_INFO +#define EVE_LOG_ERR EOS_LOG_ERR +#define EVE_LOG_NONE EOS_LOG_NONE +#define EVE_LOG_LEVEL EOS_LOG_LEVEL +#define EVE_LOG(l, ...) EOS_LOG(l, __VA_ARGS__) -#define eve_spi_cs_set eos_spi_cs_set -#define eve_spi_cs_clear eos_spi_cs_clear +// #ifdef EVE_DEBUG +#if 0 +void *eve_malloc(size_t); +void eve_free(void *); +#else +#define eve_malloc malloc +#define eve_free free +#endif + +#define eve_tdelta_ms eos_tdelta_ms +#define eve_spi_set_cs eos_spi_set_cs +#define eve_spi_clear_cs eos_spi_clear_cs #define eve_spi_flush eos_spi_flush #define eve_spi_xchg8 eos_spi_xchg8 #define eve_spi_xchg16 eos_spi_xchg16 #define eve_spi_xchg24 eos_spi_xchg24 #define eve_spi_xchg32 eos_spi_xchg32 -#define eve_spi_lock eos_spi_lock -#define eve_spi_unlock eos_spi_unlock +#define eve_pwr_get_state eos_aon_load4eve_pwr +#define eve_pwr_set_state eos_aon_save4eve_pwr +#define eve_lcd_get_absent eos_aon_load4eve_lcd +#define eve_lcd_set_absent eos_aon_save4eve_lcd void eve_sleep(uint32_t ms); uint32_t eve_get_tick(void); -void eve_sys_timer_set(uint32_t ms); -void eve_sys_timer_clear(void); +void eve_ostimer_set(uint32_t ms); +void eve_ostimer_clear(void); diff --git a/fw/fe310/eos/eve/eve_text.c b/fw/fe310/eos/eve/eve_text.c index b52678d..e31195a 100644 --- a/fw/fe310/eos/eve/eve_text.c +++ b/fw/fe310/eos/eve/eve_text.c @@ -119,8 +119,8 @@ void eve_text_scroll0(EVEText *box) { } } -int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt, uint8_t tag0) { - evt = eve_touch_evt(touch, evt, tag0, box->tag, 1); +int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt) { + evt = eve_touch_evt(touch, evt, box->tag, 1); if (touch && evt) { if ((evt & EVE_TOUCH_ETYPE_TRACK_START) && (box->line_top < 0)) { box->line_top = box->line0; @@ -148,7 +148,7 @@ uint8_t eve_text_draw(EVEText *box, uint8_t tag) { box->tag = tag; if (tag != EVE_NOTAG) { eve_cmd_dl(TAG(tag)); - eve_touch_set_opt(tag, EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_EXT_Y); + eve_tag_set_opt(tag, EVE_TOUCH_OPT_TRACK_Y | EVE_TOUCH_OPT_TRACK_EXT_Y); tag++; } eve_cmd(CMD_APPEND, "ww", box->mem_addr + box->w * 2 * box->line_size, box->dl_size * 4); @@ -161,14 +161,18 @@ void eve_text_putc(EVEText *box, int c) { int line_c, line_n; switch (c) { - case '\b': + case '\b': { eve_text_backspace(box); break; + } + case '\r': - case '\n': + case '\n': { eve_text_newline(box); break; - default: + } + + default: { line_c = box->ch_idx / 2 / box->w; eve_write16(box->mem_addr + box->ch_idx, 0x0200 | (c & 0xff)); @@ -178,6 +182,7 @@ void eve_text_putc(EVEText *box, int c) { line_n = box->ch_idx / 2 / box->w; if ((line_c != line_n) && (LINE_IDX_DIFF(line_n, box->line0, box->line_size) == box->h)) scroll1(box); break; + } } } diff --git a/fw/fe310/eos/eve/eve_text.h b/fw/fe310/eos/eve/eve_text.h index 3b282c9..6a160ad 100644 --- a/fw/fe310/eos/eve/eve_text.h +++ b/fw/fe310/eos/eve/eve_text.h @@ -23,7 +23,7 @@ void eve_text_init(EVEText *box, EVERect *g, uint16_t w, uint16_t h, uint16_t li void eve_text_update(EVEText *box); void eve_text_scroll0(EVEText *box); -int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt); uint8_t eve_text_draw(EVEText *box, uint8_t tag); void eve_text_putc(EVEText *box, int c); diff --git a/fw/fe310/eos/eve/eve_touch.c b/fw/fe310/eos/eve/eve_touch.c index a729346..d4e5cea 100644 --- a/fw/fe310/eos/eve/eve_touch.c +++ b/fw/fe310/eos/eve/eve_touch.c @@ -4,10 +4,9 @@ #include "eve.h" #include "eve_touch_engine.h" -static uint8_t touch_tag0; - static EVETouch touch_obj[EVE_MAX_TOUCH]; static EVETouchTimer touch_timer; +static EVEPhyAcc touch_acc; static eve_touch_handler_t touch_handler; static void *touch_handler_param; @@ -16,7 +15,6 @@ static uint8_t touch_tag_opt[256]; void eve_touch_init(void) { int i; - touch_tag0 = 0; memset(&touch_timer, 0, sizeof(touch_timer)); for (i=0; i<EVE_MAX_TOUCH; i++) { EVETouch *touch = &touch_obj[i]; @@ -24,7 +22,7 @@ void eve_touch_init(void) { memset(&touch_obj[i], 0, sizeof(EVETouch)); touch->eevt |= EVE_TOUCH_EETYPE_NOTOUCH; } - eve_vtrack_init(); + eve_phy_acc_init(&touch_acc, -EVE_TOUCH_ACC_A); } void eve_handle_touch(uint16_t intr_flags) { @@ -68,23 +66,17 @@ void eve_handle_touch(uint16_t intr_flags) { } } if (timer_evt & EVE_TOUCH_ETYPE_TRACK) { - EVEVTrack *vtrack = eve_vtrack_get(); - _eevt |= EVE_TOUCH_EETYPE_TRACK_ABORT; _touch_evt |= (EVE_TOUCH_ETYPE_TRACK_STOP | EVE_TOUCH_ETYPE_TRACK_ABORT); - if (vtrack->stop) vtrack->stop(touch, vtrack->param); - } - if (timer_evt & EVE_TOUCH_ETYPE_TIMER) { - _eevt |= EVE_TOUCH_EETYPE_TIMER_ABORT; - _touch_evt |= EVE_TOUCH_ETYPE_TIMER_ABORT; + eve_vtrack_stop(); } if (touch_handler && _touch_evt) { - touch_handler(touch_timer.touch, _touch_evt, touch_timer.tag0, touch_handler_param); + touch_handler(touch_timer.touch, _touch_evt, touch_handler_param); } eve_timer_clear(touch); } - touch_evt |= EVE_TOUCH_ETYPE_POINT | _evt; + touch_evt = EVE_TOUCH_ETYPE_POINT0 | _evt; touch->eevt = _eevt; touch->tag0 = 0; touch->tag = 0; @@ -104,10 +96,10 @@ void eve_handle_touch(uint16_t intr_flags) { touch->vx = vx; touch->vy = vy; - touch->t = now; } touch->x = touch_x; touch->y = touch_y; + touch->t = now; timer_evt = eve_timer_get_evt(touch); check_track = touch->tracker.tag && !touch->tracker.track; @@ -120,38 +112,31 @@ void eve_handle_touch(uint16_t intr_flags) { dx = dx < 0 ? -dx : dx; dy = dy < 0 ? -dy : dy; if (check_track) { - if ((dx > EVE_TOUCH_THRESHOLD_X) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X)) { - touch->tracker.tag = 0; - } - if ((dy > EVE_TOUCH_THRESHOLD_Y) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y)) { + if (((dx > EVE_TOUCH_THRESHOLD_X) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X)) || + ((dy > EVE_TOUCH_THRESHOLD_Y) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y))) { touch->tracker.tag = 0; } if (touch->tracker.tag && ((dx > EVE_TOUCH_THRESHOLD_X) || (dy > EVE_TOUCH_THRESHOLD_Y))) { - int track_x = 0; - - if ((dx > EVE_TOUCH_THRESHOLD_X) && (dx > EVE_TOUCH_THRESHOLD_Y) && ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY) == EVE_TOUCH_OPT_TRACK_XY)) { - if (dx > dy) { - track_x = 1; - } - } else if (dx > EVE_TOUCH_THRESHOLD_X) { - track_x = 1; - } - if (track_x) { - touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT; - } else { - touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP; - } + int track_x, track_y; + + track_x = 0; + track_y = 0; + if ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X) && (dx > EVE_TOUCH_THRESHOLD_X)) track_x = 1; + if ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y) && (dy > EVE_TOUCH_THRESHOLD_Y)) track_y = 1; + + if (track_x) touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT; + if (track_y) touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP; + touch_evt |= EVE_TOUCH_ETYPE_TRACK_START; touch->tracker.track = 1; - touch->t = now; } } if (check_timer && ((dx > EVE_TOUCH_THRESHOLD_X) || (dy > EVE_TOUCH_THRESHOLD_Y))) { eve_timer_set_evt(touch, timer_evt & ~(EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP2)); } } - if (touch->tracker.tag && touch->tracker.track) { - if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK) touch_evt |= EVE_TOUCH_ETYPE_TRACK; + if (touch->tracker.track) { + if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY) touch_evt |= EVE_TOUCH_ETYPE_TRACK; if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_REG) touch_evt |= EVE_TOUCH_ETYPE_TRACK_REG; } if (touch_evt & EVE_TOUCH_ETYPE_TRACK_REG) { @@ -171,19 +156,17 @@ void eve_handle_touch(uint16_t intr_flags) { if (timer_evt & EVE_TOUCH_ETYPE_LPRESS) { eve_timer_set_evt(touch, timer_evt & ~EVE_TOUCH_ETYPE_LPRESS); } - if (touch->tracker.tag && touch->tracker.track) { + if (touch->tracker.track) { int start = 0; uint8_t opt = touch_tag_opt[touch->tracker.tag]; uint8_t track_ext = ((opt & EVE_TOUCH_OPT_TRACK_EXT_X) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X)) || ((opt & EVE_TOUCH_OPT_TRACK_EXT_Y) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y)); if (!eve_timer_get_evt(NULL) && track_ext) { - EVEVTrack *vtrack = eve_vtrack_get(); - - if (vtrack->start) start = vtrack->start(touch, vtrack->param); + start = eve_phy_acc_start(&touch_acc, touch->x, touch->y, touch->t, touch->vx, touch->vy); } if (start) { - eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, touch_tag0, EVE_TOUCH_TIMEOUT_TRACK); + eos_vtrack_cont(&touch_acc, eve_phy_acc_tick, EVE_TOUCH_TIMEOUT_TRACK, touch); } else { touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP; } @@ -196,23 +179,22 @@ void eve_handle_touch(uint16_t intr_flags) { if (touch_tag != touch->tag) { if (touch_tag) { - if (!touch_tag0) touch_tag0 = touch_tag; if (!touch->tag0) { + touch_evt |= EVE_TOUCH_ETYPE_POINT; touch->tag0 = touch_tag; - if (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_REG)) { + if (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_REG)) { touch->tracker.tag = touch_tag; } if (touch->tracker.tag && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY)) { touch_evt |= EVE_TOUCH_ETYPE_TRACK_START; touch->tracker.track = 1; - touch->t = now; } if (!eve_timer_get_evt(NULL) && (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_LPRESS | EVE_TOUCH_OPT_TAP2))) { uint16_t _evt = 0; if (touch_tag_opt[touch_tag] & EVE_TOUCH_OPT_LPRESS) _evt |= EVE_TOUCH_ETYPE_LPRESS; if (touch_tag_opt[touch_tag] & EVE_TOUCH_OPT_TAP2) _evt |= EVE_TOUCH_ETYPE_TAP2; - eve_timer_set(touch, _evt, touch_tag0, EVE_TOUCH_TIMEOUT_TAP); + eve_timer_set(touch, _evt, EVE_TOUCH_TIMEOUT_TAP); } } } @@ -224,7 +206,7 @@ void eve_handle_touch(uint16_t intr_flags) { } if (touch_handler && touch_evt) { - touch_handler(touch, touch_evt, touch_tag0, touch_handler_param); + touch_handler(touch, touch_evt, touch_handler_param); } } } @@ -244,30 +226,19 @@ void eve_handle_time(void) { touch_evt |= EVE_TOUCH_ETYPE_TAP1; } if (touch_timer.evt & EVE_TOUCH_ETYPE_TRACK) { - EVEVTrack *vtrack = eve_vtrack_get(); - - if (vtrack->tick) { - touch_evt |= EVE_TOUCH_ETYPE_TRACK; - more = vtrack->tick(touch, vtrack->param); - } + touch_evt |= EVE_TOUCH_ETYPE_TRACK; + more = eve_vtrack_tick(&touch_evt); if (!more) { touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP; - if (vtrack->stop) vtrack->stop(touch, vtrack->param); } } - if (touch_timer.evt & EVE_TOUCH_ETYPE_TIMER) { - touch_evt |= EVE_TOUCH_ETYPE_TIMER; - more = 1; - } - if (more) { - eve_sys_timer_set(touch_timer.to); - } else { - touch_timer.evt = 0; + if (!more) { + eve_timer_reset(); } if (touch_handler && touch_evt) { - touch_handler(touch, touch_evt, touch_timer.tag0, touch_handler_param); + touch_handler(touch, touch_evt, touch_handler_param); } } } @@ -286,20 +257,17 @@ int8_t eve_touch_get_idx(EVETouch *touch) { return touch - touch_obj; } -uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_min, uint8_t tag_n) { +uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag_min, uint8_t tag_n) { int tag_max; uint8_t _tag; uint16_t _evt; if (tag_min == EVE_NOTAG) return 0; + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; tag_max = tag_min + tag_n; - if ((tag0 < tag_min) || (tag0 >= tag_max)) return 0; + if ((touch->tag0 < tag_min) || (touch->tag0 >= tag_max)) return 0; - _evt = evt & (EVE_TOUCH_ETYPE_TIMER_MASK | EVE_TOUCH_ETYPE_USR_MASK); - if (touch == NULL) return _evt; - - _evt |= evt & EVE_TOUCH_ETYPE_POINT_MASK; if (evt & EVE_TOUCH_ETYPE_TAG) { _tag = touch->tag; if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= EVE_TOUCH_ETYPE_TAG; @@ -312,79 +280,57 @@ uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_ _tag = touch->tracker.tag; if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= evt & EVE_TOUCH_ETYPE_TRACK_MASK; } - if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2)) { - _tag = touch->tag0; - if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2); + if (evt & (EVE_TOUCH_ETYPE_POINT_MASK | EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2 | EVE_TOUCH_ETYPE_USR_MASK)) { + _evt |= evt & (EVE_TOUCH_ETYPE_POINT_MASK | EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2 | EVE_TOUCH_ETYPE_USR_MASK); } return _evt; } -void eve_touch_set_opt(uint8_t tag, uint8_t opt) { +void eve_tag_set_opt(uint8_t tag, uint8_t opt) { + if (tag == EVE_NOTAG) return; touch_tag_opt[tag] = opt; } -uint8_t eve_touch_get_opt(uint8_t tag) { +uint8_t eve_tag_get_opt(uint8_t tag) { + if (tag == EVE_NOTAG) return 0; return touch_tag_opt[tag]; } -void eve_touch_clear_opt(void) { +void eve_tag_clear_opt(void) { memset(touch_tag_opt, 0, sizeof(touch_tag_opt)); } -void eve_timer_set(EVETouch *touch, uint16_t evt, uint8_t tag0, uint32_t to) { +void eve_timer_set(EVETouch *touch, uint16_t evt, uint32_t tick_ms) { touch_timer.touch = touch; touch_timer.evt = evt; - touch_timer.tag0 = tag0; - touch_timer.to = to; - eve_sys_timer_set(to); + eve_ostimer_set(tick_ms); } void eve_timer_clear(EVETouch *touch) { eve_timer_set_evt(touch, 0); } +void eve_timer_reset(void) { + touch_timer.touch = NULL; + touch_timer.evt = 0; +} + void eve_timer_set_evt(EVETouch *touch, uint16_t evt) { if ((touch == NULL) || (touch == touch_timer.touch)) { touch_timer.evt = evt; - } else if (touch_timer.touch == NULL) { - touch_timer.evt = evt; } if (!touch_timer.evt) { - eve_sys_timer_clear(); + eve_ostimer_clear(); touch_timer.touch = NULL; - touch_timer.tag0 = 0; - touch_timer.to = 0; } } uint16_t eve_timer_get_evt(EVETouch *touch) { - uint16_t ret = 0; + uint16_t rv = 0; if ((touch == NULL) || (touch_timer.touch == touch)) { - ret = touch_timer.evt; - } else if (touch_timer.touch == NULL) { - ret = touch_timer.evt; + rv = touch_timer.evt; } - return ret; -} - -EVETouchTimer *eve_timer_get_obj(void) { - return &touch_timer; -} - -void eve_timer_start(uint8_t tag0, uint32_t to) { - if (!touch_timer.evt) eve_timer_set(NULL, EVE_TOUCH_ETYPE_TIMER, tag0, to); -} - -void eve_timer_stop(void) { - if (touch_timer.touch == NULL) eve_timer_clear(NULL); -} - -int eve_timer_running(void) { - return (touch_timer.evt == EVE_TOUCH_ETYPE_TIMER); -} - -void eve_touch_clear_tag0(void) { - touch_tag0 = 0; + return rv; } diff --git a/fw/fe310/eos/eve/eve_touch.h b/fw/fe310/eos/eve/eve_touch.h index 8ec6e0e..1f639b3 100644 --- a/fw/fe310/eos/eve/eve_touch.h +++ b/fw/fe310/eos/eve/eve_touch.h @@ -1,5 +1,7 @@ #include <stdint.h> +#define EVE_TOUCH_ACC_A 10000 + #define EVE_TOUCH_TIMEOUT_TAP 1000 #define EVE_TOUCH_TIMEOUT_TRACK 20 @@ -13,23 +15,22 @@ /* events */ #define EVE_TOUCH_ETYPE_TAG 0x0001 #define EVE_TOUCH_ETYPE_TAG_UP 0x0002 -#define EVE_TOUCH_ETYPE_POINT 0x0004 -#define EVE_TOUCH_ETYPE_POINT_UP 0x0008 -#define EVE_TOUCH_ETYPE_TRACK 0x0010 -#define EVE_TOUCH_ETYPE_TRACK_START 0x0020 -#define EVE_TOUCH_ETYPE_TRACK_STOP 0x0040 -#define EVE_TOUCH_ETYPE_TRACK_ABORT 0x0080 -#define EVE_TOUCH_ETYPE_TIMER 0x0100 -#define EVE_TOUCH_ETYPE_TIMER_ABORT 0x0200 -#define EVE_TOUCH_ETYPE_TRACK_REG 0x0400 -#define EVE_TOUCH_ETYPE_LPRESS 0x0800 -#define EVE_TOUCH_ETYPE_TAP1 0x1000 -#define EVE_TOUCH_ETYPE_TAP2 0x2000 -#define EVE_TOUCH_ETYPE_USR 0x4000 -#define EVE_TOUCH_ETYPE_USR1 0x8000 +#define EVE_TOUCH_ETYPE_POINT0 0x0004 /* emitted without tag0, possibly useless */ +#define EVE_TOUCH_ETYPE_POINT 0x0008 +#define EVE_TOUCH_ETYPE_POINT_UP 0x0010 +#define EVE_TOUCH_ETYPE_TRACK 0x0020 +#define EVE_TOUCH_ETYPE_TRACK_START 0x0040 +#define EVE_TOUCH_ETYPE_TRACK_STOP 0x0080 +#define EVE_TOUCH_ETYPE_TRACK_ABORT 0x0100 +#define EVE_TOUCH_ETYPE_TRACK_REG 0x0200 +#define EVE_TOUCH_ETYPE_LPRESS 0x0400 +#define EVE_TOUCH_ETYPE_TAP1 0x0800 +#define EVE_TOUCH_ETYPE_TAP2 0x1000 +#define EVE_TOUCH_ETYPE_USR 0x2000 +#define EVE_TOUCH_ETYPE_USR1 0x4000 +#define EVE_TOUCH_ETYPE_EXT 0x8000 /* events emitted outside of eve_touch scope */ #define EVE_TOUCH_ETYPE_TRACK_MASK (EVE_TOUCH_ETYPE_TRACK | EVE_TOUCH_ETYPE_TRACK_START | EVE_TOUCH_ETYPE_TRACK_STOP | EVE_TOUCH_ETYPE_TRACK_ABORT | EVE_TOUCH_ETYPE_TRACK_REG) -#define EVE_TOUCH_ETYPE_TIMER_MASK (EVE_TOUCH_ETYPE_TIMER | EVE_TOUCH_ETYPE_TIMER_ABORT) #define EVE_TOUCH_ETYPE_POINT_MASK (EVE_TOUCH_ETYPE_POINT | EVE_TOUCH_ETYPE_POINT_UP) #define EVE_TOUCH_ETYPE_USR_MASK (EVE_TOUCH_ETYPE_USR | EVE_TOUCH_ETYPE_USR1) @@ -44,7 +45,6 @@ #define EVE_TOUCH_EETYPE_TRACK_DOWN 0x0080 #define EVE_TOUCH_EETYPE_TRACK_ABORT 0x0100 -#define EVE_TOUCH_EETYPE_TIMER_ABORT 0x0200 #define EVE_TOUCH_EETYPE_USR 0x1000 #define EVE_TOUCH_EETYPE_USR1 0x2000 @@ -54,11 +54,9 @@ #define EVE_TOUCH_EETYPE_TRACK_X (EVE_TOUCH_EETYPE_TRACK_LEFT | EVE_TOUCH_EETYPE_TRACK_RIGHT) #define EVE_TOUCH_EETYPE_TRACK_Y (EVE_TOUCH_EETYPE_TRACK_UP | EVE_TOUCH_EETYPE_TRACK_DOWN) #define EVE_TOUCH_EETYPE_TRACK_XY (EVE_TOUCH_EETYPE_TRACK_X | EVE_TOUCH_EETYPE_TRACK_Y) -#define EVE_TOUCH_EETYPE_ABORT (EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_TIMER_ABORT) /* tag options */ -#define EVE_TOUCH_OPT_TRACK 0x01 -#define EVE_TOUCH_OPT_TRACK_REG 0x02 +#define EVE_TOUCH_OPT_TRACK_REG 0x01 #define EVE_TOUCH_OPT_TRACK_X 0x04 #define EVE_TOUCH_OPT_TRACK_Y 0x08 #define EVE_TOUCH_OPT_TRACK_EXT_X 0x10 @@ -90,12 +88,10 @@ typedef struct EVETouch { typedef struct EVETouchTimer { EVETouch *touch; - uint32_t to; uint16_t evt; - uint8_t tag0; } EVETouchTimer; -typedef void (*eve_touch_handler_t) (EVETouch *, uint16_t, uint8_t, void *); +typedef void (*eve_touch_handler_t) (EVETouch *, uint16_t, void *); void eve_touch_init(void); void eve_handle_touch(uint16_t intr_flags); @@ -104,19 +100,14 @@ void eve_handle_time(void); void eve_touch_set_handler(eve_touch_handler_t handler, void *handler_param); EVETouch *eve_touch_get_obj(int i); int8_t eve_touch_get_idx(EVETouch *touch); -uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_min, uint8_t tag_n); +uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag_min, uint8_t tag_n); -void eve_touch_set_opt(uint8_t tag, uint8_t opt); -uint8_t eve_touch_get_opt(uint8_t tag); -void eve_touch_clear_opt(void); +void eve_tag_set_opt(uint8_t tag, uint8_t opt); +uint8_t eve_tag_get_opt(uint8_t tag); +void eve_tag_clear_opt(void); -void eve_timer_set(EVETouch *touch, uint16_t evt, uint8_t tag0, uint32_t to); +void eve_timer_set(EVETouch *touch, uint16_t evt, uint32_t to); void eve_timer_clear(EVETouch *touch); +void eve_timer_reset(void); void eve_timer_set_evt(EVETouch *touch, uint16_t evt); uint16_t eve_timer_get_evt(EVETouch *touch); -EVETouchTimer *eve_timer_get_obj(void); - -void eve_timer_start(uint8_t tag0, uint32_t to); -void eve_timer_stop(void); -int eve_timer_running(void); -void eve_touch_clear_tag0(void); diff --git a/fw/fe310/eos/eve/eve_touch_engine.c b/fw/fe310/eos/eve/eve_touch_engine.c index 2c75ca0..aadd07d 100644 --- a/fw/fe310/eos/eve/eve_touch_engine.c +++ b/fw/fe310/eos/eve/eve_touch_engine.c @@ -26,36 +26,71 @@ static const uint32_t _reg_track[] = { REG_TRACKER_4 }; -void eve_touch_init_engine(void) { +void eve_touch_init_engine(uint16_t engine) { /* configure touch */ eve_write8(REG_CPURESET, 2); /* touch engine reset */ - eve_write16(REG_TOUCH_CONFIG, 0x4000); /* host mode multi touch */ + eve_write16(REG_TOUCH_CONFIG, engine); /* set touch engine */ eve_write8(REG_CTOUCH_EXTENDED, 0x00); /* set extended mode */ eve_write8(REG_CPURESET, 0); /* clear reset */ - eve_touch_ehost_enter(0, 0x8000, 0x8000); - eve_touch_ehost_end(); + if (engine == EVE_TOUCH_ENGINE_HOST) { + eve_touch_ehost_enter(0, 0x8000, 0x8000); + eve_touch_ehost_end(); + } } -void eve_touch_start(void) { +uint16_t eve_touch_get_engine(void) { + return (eve_read16(REG_TOUCH_CONFIG) & EVE_TOUCH_ENGINE_MASK); +} + +void eve_touch_set_engine(uint16_t engine) { + uint16_t reg = eve_read16(REG_TOUCH_CONFIG); + + reg &= ~EVE_TOUCH_ENGINE_MASK; + reg |= engine; + + eve_write8(REG_CPURESET, 2); /* touch engine reset */ + eve_write8(REG_TOUCH_CONFIG, reg); /* set touch engine */ + eve_write8(REG_CPURESET, 0); /* clear reset */ + + if (engine == EVE_TOUCH_ENGINE_HOST) { + eve_touch_ehost_enter(0, 0x8000, 0x8000); + eve_touch_ehost_end(); + } +} + +void eve_touch_reset_engine(void) { + eve_write8(REG_CPURESET, 2); /* touch engine reset */ + eve_write8(REG_CPURESET, 0); /* clear reset */ +} + +void eve_touch_intr_enable(void) { uint16_t intr_mask; intr_mask = eve_read16(REG_INT_MASK); eve_write16(REG_INT_MASK, intr_mask | (EVE_INT_CONVCOMPLETE | EVE_INT_TAG)); - - eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS); } -void eve_touch_stop(void) { +void eve_touch_intr_disable(void) { uint16_t intr_mask; intr_mask = eve_read16(REG_INT_MASK); eve_write16(REG_INT_MASK, intr_mask & ~(EVE_INT_CONVCOMPLETE | EVE_INT_TAG)); - eve_timer_clear(NULL); +} +void eve_touch_start(void) { + eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS); +} + +void eve_touch_stop(void) { + eve_timer_clear(NULL); eve_write8(REG_TOUCH_MODE, EVE_TMODE_OFF); } +int eve_touch_get_extended(void) { + return !eve_read8(REG_CTOUCH_EXTENDED); +} + void eve_touch_set_extended(int extended) { eve_write8(REG_CPURESET, 2); /* touch engine reset */ eve_write8(REG_CTOUCH_EXTENDED, !extended); /* set / clear extended mode */ diff --git a/fw/fe310/eos/eve/eve_touch_engine.h b/fw/fe310/eos/eve/eve_touch_engine.h index 3a7508f..a144885 100644 --- a/fw/fe310/eos/eve/eve_touch_engine.h +++ b/fw/fe310/eos/eve/eve_touch_engine.h @@ -1,9 +1,21 @@ #include <stdint.h> -void eve_touch_init_engine(void); +#define EVE_TOUCH_ENGINE_HOST 0x4000 +#define EVE_TOUCH_ENGINE_FOCALTECH 0x0380 +#define EVE_TOUCH_ENGINE_GOODIX 0x05D0 + +#define EVE_TOUCH_ENGINE_MASK 0x4FF0 + +void eve_touch_init_engine(uint16_t engine); +uint16_t eve_touch_get_engine(void); +void eve_touch_set_engine(uint16_t engine); +void eve_touch_reset_engine(void); +void eve_touch_intr_enable(void); +void eve_touch_intr_disable(void); void eve_touch_start(void); void eve_touch_stop(void); +int eve_touch_get_extended(void); void eve_touch_set_extended(int extended); void eve_touch_get_matrix(uint32_t *touch_matrix); void eve_touch_set_matrix(const uint32_t *touch_matrix); diff --git a/fw/fe310/eos/eve/eve_vtrack.c b/fw/fe310/eos/eve/eve_vtrack.c index a7619fb..6cc3c76 100644 --- a/fw/fe310/eos/eve/eve_vtrack.c +++ b/fw/fe310/eos/eve/eve_vtrack.c @@ -4,53 +4,63 @@ #include "eve.h" static EVEVTrack vtrack; -static EVEPhyAcc vtrack_acc; void eve_vtrack_init(void) { - eve_phy_acc_init(&vtrack_acc, -EVE_VTRACK_ACC_A); eve_vtrack_reset(); } -EVEVTrack *eve_vtrack_get(void) { - return &vtrack; +void eve_vtrack_reset(void) { + vtrack.param = NULL; + vtrack.tick_f = NULL; + vtrack.tick_ms = 0; + vtrack.touch = NULL; } -void eve_vtrack_set(eve_vtrack_start_t start, eve_vtrack_tick_t tick, eve_vtrack_stop_t stop, void *param) { - vtrack.start = start; - vtrack.tick = tick; - vtrack.stop = stop; +static void vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag) { + eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, tick_ms); vtrack.param = param; + vtrack.tick_f = tick_f; + vtrack.tick_ms = tick_ms; + vtrack.touch = touch; + if (tag != EVE_NOTAG) { + touch->tracker.tag = tag; + touch->tracker.track = 1; + } } -void eve_vtrack_reset(void) { - eve_vtrack_set(eve_vtrack_acc_start, eve_vtrack_acc_tick, NULL, &vtrack_acc); -} - -int eve_vtrack_start(EVETouch *touch, uint8_t tag0, uint32_t to) { - if (vtrack.start) { - int start; - - start = vtrack.start(touch, vtrack.param); - if (start) eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, tag0, to); +void eve_vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag) { + vtrack_start(param, tick_f, tick_ms, touch, tag); - return start; - } - return 0; + /* ensure that track start event is emitted on first vtrack tick */ + touch->eevt &= ~EVE_TOUCH_EETYPE_TRACK_XY; } -void eve_vtrack_stop(EVETouch *touch) { - eve_timer_clear(touch); - eve_vtrack_reset(); +void eos_vtrack_cont(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch) { + vtrack_start(param, tick_f, tick_ms, touch, EVE_NOTAG); } -int eve_vtrack_acc_start(EVETouch *touch, void *p) { - EVEPhyAcc *param = (EVEPhyAcc *)p; +int eve_vtrack_tick(uint16_t *touch_evt) { + EVETouch *touch = vtrack.touch; + int more = 0; - return eve_phy_acc_start(param, touch->x, touch->y, touch->t, touch->vx, touch->vy); -} + if (vtrack.tick_f) { + more = vtrack.tick_f(vtrack.param, &touch->x, &touch->y); + } + if (more) { + eve_ostimer_set(vtrack.tick_ms); + if (!(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY)) { + if ((eve_tag_get_opt(touch->tracker.tag) & EVE_TOUCH_OPT_TRACK_X) && (touch->x != touch->x0)) touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT; + if ((eve_tag_get_opt(touch->tracker.tag) & EVE_TOUCH_OPT_TRACK_Y) && (touch->y != touch->y0)) touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP; + *touch_evt |= EVE_TOUCH_ETYPE_TRACK_START; + } + } else { + eve_timer_reset(); + eve_vtrack_reset(); + } -int eve_vtrack_acc_tick(EVETouch *touch, void *p) { - EVEPhyAcc *param = (EVEPhyAcc *)p; + return more; +} - return eve_phy_acc_tick(param, eve_get_tick() - touch->t, &touch->x, &touch->y); +void eve_vtrack_stop(void) { + eve_vtrack_reset(); } diff --git a/fw/fe310/eos/eve/eve_vtrack.h b/fw/fe310/eos/eve/eve_vtrack.h index 8455502..142d77b 100644 --- a/fw/fe310/eos/eve/eve_vtrack.h +++ b/fw/fe310/eos/eve/eve_vtrack.h @@ -1,24 +1,17 @@ #include <stdint.h> -#define EVE_VTRACK_ACC_A 10000 - -typedef int (*eve_vtrack_start_t) (EVETouch *, void *); -typedef int (*eve_vtrack_tick_t) (EVETouch *, void *); -typedef void (*eve_vtrack_stop_t) (EVETouch *, void *); +typedef int (*eve_vtrack_tick_t) (void *, int *, int *); typedef struct EVEVTrack { - eve_vtrack_start_t start; - eve_vtrack_tick_t tick; - eve_vtrack_stop_t stop; void *param; + eve_vtrack_tick_t tick_f; + uint32_t tick_ms; + EVETouch *touch; } EVEVTrack; void eve_vtrack_init(void); -EVEVTrack *eve_vtrack_get(void); -void eve_vtrack_set(eve_vtrack_start_t start, eve_vtrack_tick_t tick, eve_vtrack_stop_t stop, void *param); void eve_vtrack_reset(void); -int eve_vtrack_start(EVETouch *touch, uint8_t tag0, uint32_t to); -void eve_vtrack_stop(EVETouch *touch); - -int eve_vtrack_acc_start(EVETouch *touch, void *p); -int eve_vtrack_acc_tick(EVETouch *touch, void *p);
\ No newline at end of file +void eve_vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag); +void eos_vtrack_cont(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch); +int eve_vtrack_tick(uint16_t *touch_evt); +void eve_vtrack_stop(void);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/screen/form.c b/fw/fe310/eos/eve/screen/form.c index 3e5b97c..de03bfd 100644 --- a/fw/fe310/eos/eve/screen/form.c +++ b/fw/fe310/eos/eve/screen/form.c @@ -12,7 +12,8 @@ #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -static void widgets_destroy(EVEWidget *widget, uint16_t widget_size) { +static void widgets_destroy(EVEWidget *widgets, uint16_t widget_size) { + EVEWidget *widget = widgets; int i; for (i=0; i<widget_size; i++) { @@ -20,65 +21,60 @@ static void widgets_destroy(EVEWidget *widget, uint16_t widget_size) { eve_widget_destroy(widget); widget = eve_widget_next(widget); } + eve_free(widgets); } -EVEPage *eve_form_create(EVEWindow *window, EVEViewStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { +int eve_form_create(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { EVEWidget *widgets; EVEWidget *widget; EVELabel *label; - EVEPage *page; int w_size = 0; - int i, r; + int i, rv; if (uievt == NULL) uievt = eve_form_uievt; if (destructor == NULL) destructor = eve_form_destroy; - page = eve_malloc(sizeof(EVEPage)); - if (page == NULL) { - return NULL; - } - eve_form_init(page, window, stack, NULL, 0, uievt, destructor); for (i=0; i<spec_size; i++) { w_size += eve_widget_size(spec[i].widget.type); } widgets = eve_malloc(w_size); if (widgets == NULL) { - eve_free(page); - return NULL; + return EVE_ERR_NOMEM; } + eve_form_init(page, window, stack, NULL, 0, uievt, destructor); + widget = widgets; for (i=0; i<spec_size; i++) { - r = eve_widget_create(widget, &spec[i].widget, page); - if (r) { + rv = eve_widget_create(widget, &spec[i].widget, page); + if (rv) { widgets_destroy(widgets, i); - eve_free(widgets); - eve_free(page); - return NULL; + return rv; } if (spec[i].label.title) { + rv = EVE_OK; label = eve_malloc(sizeof(EVELabel)); - if (label == NULL) { + if (label) rv = eve_label_create(label, &spec[i].label, page); + if ((label == NULL) || rv) { + if (label) eve_free(label); eve_widget_destroy(widget); widgets_destroy(widgets, i); - eve_free(widgets); - eve_free(page); - return NULL; + return label ? rv : EVE_ERR_NOMEM; } - eve_label_create(label, &spec[i].label, page); eve_widget_set_label(widget, label); } - if (widget->g.w == 0) widget->g.w = window->g.w - (widget->label ? widget->label->g.w : 0); + if ((widget->g.w == 0) && widget->label) widget->g.w = window->g.w - widget->label->g.w; + if (widget->g.w == 0) widget->g.w = window->g.w; widget = eve_widget_next(widget); } eve_form_set_widget(page, widgets, spec_size); - return page; + return EVE_OK; } -void eve_form_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { - eve_page_init(page, window, stack, NULL, 0, EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_BACK | EVE_PAGE_OPT_TRACK_EXT_Y, eve_page_draw, eve_page_touch, uievt, destructor); - if (widget) eve_form_set_widget(page, widget, widget_size); +void eve_form_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { + eve_page_init(page, window, stack, widget, widget_size, EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_BACK | EVE_PAGE_OPT_TRACK_EXT_Y, eve_page_draw, eve_page_touch, uievt, destructor); + if (widget) eve_form_update_g(page, NULL); } void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) { @@ -88,42 +84,24 @@ void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) void eve_form_destroy(EVEPage *page) { widgets_destroy(page->widget, page->widget_size); - eve_free(page->widget); - eve_free(page); } -int eve_form_uievt(EVEPage *page, uint16_t evt, void *param) { +void eve_form_uievt(EVEPage *page, uint16_t evt, void *param) { switch (evt) { case EVE_UIEVT_WIDGET_UPDATE_G: eve_form_update_g(page, (EVEWidget *)param); break; - case EVE_UIEVT_WIDGET_FOCUS_IN: - break; - - case EVE_UIEVT_WIDGET_FOCUS_OUT: - break; - - case EVE_UIEVT_GEST_SCROLL_START: - break; - - case EVE_UIEVT_GEST_SCROLL_STOP: - break; - - case EVE_UIEVT_GEST_TRACK_START: - break; - case EVE_UIEVT_GEST_TRACK_STOP: { EVEUIEvtTouch *touch_p = (EVEUIEvtTouch *)param; if (touch_p->touch->eevt & EVE_TOUCH_EETYPE_TRACK_RIGHT) { eve_page_close(page); - return 1; + return; } break; } } - return 0; } void eve_form_update_g(EVEPage *page, EVEWidget *_widget) { diff --git a/fw/fe310/eos/eve/screen/form.h b/fw/fe310/eos/eve/screen/form.h index bc81d2d..c4b8493 100644 --- a/fw/fe310/eos/eve/screen/form.h +++ b/fw/fe310/eos/eve/screen/form.h @@ -7,10 +7,10 @@ typedef struct EVEFormSpec { EVEWidgetSpec widget; } EVEFormSpec; -EVEPage *eve_form_create(EVEWindow *window, EVEViewStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); -void eve_form_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +int eve_form_create(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +void eve_form_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size); void eve_form_destroy(EVEPage *page); -int eve_form_uievt(EVEPage *page, uint16_t evt, void *param); +void eve_form_uievt(EVEPage *page, uint16_t evt, void *param); void eve_form_update_g(EVEPage *page, EVEWidget *_widget); diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c index 93b81c5..8c02538 100644 --- a/fw/fe310/eos/eve/screen/page.c +++ b/fw/fe310/eos/eve/screen/page.c @@ -14,15 +14,36 @@ #define PAGE_TMODE_TRACK 1 #define PAGE_TMODE_SCROLL 2 -void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { +void eve_page_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { memset(page, 0, sizeof(EVEPage)); eve_view_init(&page->v, window, (eve_view_draw_t)draw, (eve_view_touch_t)touch, (eve_view_uievt_t)uievt, NULL); + eve_phy_lho_init(&page->lho, 100, 0.5, 0); page->stack = stack; page->opt = opt; page->destructor = destructor; eve_page_set_widget(page, widget, widget_size); } +void eve_page_attach(EVEPage *page, EVEWindow *window, void *page_id) { + eve_view_attach(&page->v, window, page_id); +} + +void eve_page_detach(EVEPage *page) { + eve_view_detach(&page->v); +} + +void eve_page_set_param(EVEPage *page, void *param) { + eve_view_set_param(&page->v, param); +} + +EVEView *eve_page_view(EVEPage *page) { + return &page->v; +} + +EVEPage *eve_page_from_view(EVEView *view) { + return (EVEPage *)view; +} + EVEWidget *eve_page_widget(EVEPage *page, uint16_t _idx) { EVEWidget *w = page->widget; int i, idx; @@ -62,53 +83,81 @@ void eve_page_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) page->widget_size = widget_size; } -void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) { - EVEWindow *window = parent->v.window; - EVEViewStack *stack = parent->stack; - eve_page_destructor_t destructor = parent->destructor; - - eve_page_set_focus(parent, NULL); - if (destructor) destructor(parent); - eve_stack_create_view(stack, window, constructor); -} - -void eve_page_close(EVEPage *page) { +static void page_destroy(EVEPage *page) { EVEWindow *window = page->v.window; - EVEViewStack *stack = page->stack; eve_page_destructor_t destructor = page->destructor; - if (stack->level <= 1) return; - eve_page_set_focus(page, NULL); - if (eve_timer_running()) { - eve_timer_stop(); - } - if (eve_window_scroll(window->root, NULL) == window) { + if (eve_window_scroll(window, NULL) == window) { eve_window_scroll_stop(window); } eve_window_kbd_detach(window); + eve_page_detach(page); + if (destructor) destructor(page); - eve_stack_back(stack, window); +} + +void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) { + EVEWindow *window = parent->v.window; + EVEVStack *stack = parent->stack; + int rv; + + if (eve_vstack_full(stack)) return; + + page_destroy(parent); + rv = eve_vstack_create_view(stack, window, constructor); + if (rv) { + EVEView *view = NULL; + + do { + constructor = eve_vstack_get(stack); + if (constructor) view = constructor(window, stack); + if (view == NULL) eve_vstack_pull(stack); + } while ((view == NULL) && constructor); + if (view) eve_view_attach(view, window, constructor); + } +} + +void eve_page_close(EVEPage *page) { + EVEWindow *window = page->v.window; + EVEVStack *stack = page->stack; + int rv; + + if (eve_vstack_level(stack) == 1) return; + + page_destroy(page); + rv = eve_vstack_back(stack, window); + if (rv) { + eve_view_constructor_t constructor; + EVEView *view = NULL; + + do { + eve_vstack_pull(stack); + constructor = eve_vstack_get(stack); + if (constructor) view = constructor(window, stack); + } while ((view == NULL) && constructor); + if (view) eve_view_attach(view, window, constructor); + } } /* Screen to page coordinates */ int16_t eve_page_x(EVEPage *page, int16_t x) { - return x + page->g.x - page->v.window->g.x; + return x - page->g.x - page->v.window->g.x; } int16_t eve_page_y(EVEPage *page, int16_t y) { - return y + page->g.y - page->v.window->g.y; + return y - page->g.y - page->v.window->g.y; } /* Page to window coordinates */ int16_t eve_page_win_x(EVEPage *page, int16_t x) { - return x - page->g.x; + return x + page->g.x; } int16_t eve_page_win_y(EVEPage *page, int16_t y) { - return y - page->g.y; + return y + page->g.y; } /* Page to screen coordinates */ @@ -120,49 +169,57 @@ int16_t eve_page_scr_y(EVEPage *page, int16_t y) { return eve_page_win_y(page, y) + page->v.window->g.y; } -int eve_page_rect_visible(EVEPage *page, EVERect *g) { - uint16_t w = page->v.window->g.w; - uint16_t h = page->v.window->g.h; +int eve_page_rect_visible(EVEPage *page, EVERect *rect) { + EVERect win_g; - if (((g->x + g->w) >= page->g.x) && ((g->y + g->h) >= page->g.y) && (g->x <= (page->g.x + w)) && (g->y <= (page->g.y + h))) return 1; - return 0; + eve_window_visible_g(page->v.window, &win_g); + win_g.x -= page->v.window->g.x; + win_g.y -= page->v.window->g.y; + + if ((page->g.x + rect->x + rect->w < win_g.x) || + (page->g.y + rect->y + rect->h < win_g.y) || + (page->g.x + rect->x > win_g.x + win_g.w) || + (page->g.y + rect->y > win_g.y + win_g.h)) return 0; + + return 1; } void eve_page_show_rect(EVEPage *page, EVERect *rect) { - EVERect g; + EVERect win_g; - eve_window_visible_g(page->v.window, &g); - g.x -= page->v.window->g.x; - g.y -= page->v.window->g.y; + eve_window_visible_g(page->v.window, &win_g); + win_g.x -= page->v.window->g.x; + win_g.y -= page->v.window->g.y; - if (rect->x < page->g.x + g.x) { - page->g.x = rect->x - g.x; + if (page->g.x + rect->x < win_g.x) { + page->g.x = win_g.x - rect->x; } - if (rect->y < page->g.y + g.y) { - page->g.y = rect->y - g.y; + if (page->g.y + rect->y < win_g.y) { + page->g.y = win_g.y - rect->y; } - if ((rect->x + rect->w) > (page->g.x + g.x + g.w)) { - page->g.x = (rect->x + rect->w) - (g.x + g.w); + + if (page->g.x + rect->x + rect->w > win_g.x + win_g.w) { + page->g.x = win_g.x + win_g.w - (rect->x + rect->w); } - if ((rect->y + rect->h) > (page->g.y + g.y + g.h)) { - page->g.y = (rect->y + rect->h) - (g.y + g.h); + if (page->g.y + rect->y + rect->h > win_g.y + win_g.h) { + page->g.y = win_g.y + win_g.h - (rect->y + rect->h); } } /* returns true if x or y are out of page bounds for window */ -int eve_page_oob(EVEPage *page, int *_max_x, int *_max_y) { - int max_x, max_y; - EVERect vg; +int eve_page_oob(EVEPage *page, int *min_x, int *min_y) { + int _min_x, _min_y; + EVERect win_g; - eve_window_visible_g(page->v.window, &vg); - max_x = page->g.w > vg.w ? page->g.w - vg.w : 0; - max_y = page->g.h > vg.h ? page->g.h - vg.h : 0; + eve_window_visible_g(page->v.window, &win_g); + _min_x = -(page->g.w > win_g.w ? page->g.w - win_g.w : 0); + _min_y = -(page->g.h > win_g.h ? page->g.h - win_g.h : 0); - if (_max_x) *_max_x = max_x; - if (_max_y) *_max_y = max_y; + if (min_x) *min_x = _min_x; + if (min_y) *min_y = _min_y; - return ((page->g.x < 0) || (page->g.x > max_x) || - (page->g.y < 0) || (page->g.y > max_y)); + return ((page->g.x > 0) || (page->g.x < _min_x) || + (page->g.y > 0) || (page->g.y < _min_y)); } EVEWidget *eve_page_focus(EVEPage *page) { @@ -174,159 +231,150 @@ void eve_page_set_focus(EVEPage *page, EVEWidget *widget) { EVEWindow *window = page->v.window; EVEWidget *widget_f = page->widget_f; - if (widget_f && widget_f->putc) { - widget_f->putc(widget_f, EVE_PAGE_KBDCH_CLOSE); - if (!(widget && widget->putc)) eve_window_kbd_detach(window); + if ((widget_f && widget_f->putc) && !(widget && widget->putc)) { + eve_window_kbd_detach(window); } if (widget && widget->putc) { EVEKbd *kbd = eve_window_kbd(window); if (kbd) eve_kbd_set_handler(kbd, widget->putc, widget); - if (!(widget_f && widget_f->putc)) eve_window_kbd_attach(window); + if (!(widget_f && widget_f->putc)) { + eve_window_kbd_attach(window); + eve_page_show_rect(page, &widget->g); + } + } + if (widget_f) { + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, widget_f); + widget_f->touch(widget_f, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_OUT); } - if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, page->widget_f); page->widget_f = widget; - if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, page->widget_f); + if (widget) { + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, widget); + widget->touch(widget, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_IN); + } } } -static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) { +static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) { EVEView *view = &page->v; EVEWindow *window = view->window; int scroll_x = 0, scroll_y = 0, scroll; - int ret = 0; - - if (touch) { - if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) { - scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY); - } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) { - scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X); - } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) { - scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y); - } + int rv = 0; + + if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) { + scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY); + } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) { + scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X); + } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) { + scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y); + } - scroll = scroll_x || scroll_y; + scroll = scroll_x || scroll_y; - if ((tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT))) { - int _ret = 0; + if ((touch->tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT))) { + eve_page_set_focus(page, NULL); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt); + if (eve_window_dirty(window)) return 1; + rv = 1; + } - eve_page_set_focus(page, NULL); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt, tag0); - if (_ret) return _ret; - ret = 1; + /* Scroll / track start */ + if (evt & EVE_TOUCH_ETYPE_TRACK_START) { + if (page->track_mode == PAGE_TMODE_NONE) { + if (scroll) { + page->track_mode = PAGE_TMODE_SCROLL; + eve_window_scroll_start(window, touch->tag0); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt); + } else { + page->track_mode = PAGE_TMODE_TRACK; + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt); + } + if (eve_window_dirty(window)) return 1; + } + if (scroll_x) { + page->x0 = touch->x0 - page->g.x; + } + if (scroll_y) { + page->y0 = touch->y0 - page->g.y; } + rv = 1; + } - /* Scroll / track start */ - if (evt & EVE_TOUCH_ETYPE_TRACK_START) { - int _ret = 0; - - if (!(touch->eevt & EVE_TOUCH_EETYPE_ABORT)) { - if (scroll) { - page->track_mode = PAGE_TMODE_SCROLL; - eve_window_scroll_start(window, touch->tracker.tag); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt, tag0); - } else { - page->track_mode = PAGE_TMODE_TRACK; - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt, tag0); - } - if (_ret) return _ret; - } - if (scroll_x) { - page->x0 = page->g.x; - } - if (scroll_y) { - page->y0 = page->g.y; - } - ret = 1; + if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) { + if (scroll_x) { + page->g.x = touch->x - page->x0; } + if (scroll_y) { + page->g.y = touch->y - page->y0; + } + rv = 1; + } - /* Scroll / track stop */ - if (((evt & EVE_TOUCH_ETYPE_TRACK_STOP) && !(evt & EVE_TOUCH_ETYPE_TRACK_ABORT)) || - ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) { - if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { - int max_x, max_y; - int oob; - - oob = eve_page_oob(page, &max_x, &max_y); - if (oob) { - int lho_x, lho_y; - uint8_t _tag; - EVEPhyLHO *lho = &page->lho; - - lho_x = page->g.x < 0 ? 0 : max_x; - lho_y = page->g.y < 0 ? 0 : max_y; - eve_window_scroll(window->root, &_tag); - - page->lho_t0 = eve_get_tick(); - eve_phy_lho_init(lho, lho_x, lho_y, 100, 0.5, 0); - eve_phy_lho_start(lho, page->g.x, page->g.y); - eve_timer_start(_tag, 20); + /* Scroll / track stop */ + if (((evt & EVE_TOUCH_ETYPE_TRACK_STOP) && !(evt & EVE_TOUCH_ETYPE_TRACK_ABORT)) || + ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) { + int start = 0; + + if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { + int min_gx, min_gy; + int oob; + + oob = eve_page_oob(page, &min_gx, &min_gy); + if (oob) { + int pivot_x, pivot_y, x0, y0; + int scroll_x, scroll_y; + EVEPhyLHO *lho = &page->lho; + uint8_t scroll_tag; + + pivot_x = touch->x0 - page->g.x + (page->g.x < min_gx ? min_gx : 0); + pivot_y = touch->y0 - page->g.y + (page->g.y < min_gy ? min_gy : 0); + x0 = touch->x0; + y0 = touch->y0; + + scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X; + scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y; + if (!scroll_x) pivot_x = x0; + if (!scroll_y) pivot_y = y0; + + eve_window_scroll(window, &scroll_tag); + start = eve_phy_lho_start(lho, pivot_x, pivot_y, x0, y0, eve_get_tick()); + if (start) { + eve_vtrack_start(lho, eve_phy_lho_tick, EVE_TOUCH_TIMEOUT_TRACK, touch, scroll_tag); } } + } - if (!eve_timer_running()) { - int _ret = 0; - - switch (page->track_mode) { - case PAGE_TMODE_SCROLL: { - page->track_mode = PAGE_TMODE_NONE; - eve_window_scroll_stop(window); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0); - break; - } - - case PAGE_TMODE_TRACK: { - page->track_mode = PAGE_TMODE_NONE; - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt, tag0); - break; - } + if (!start) { + switch (page->track_mode) { + case PAGE_TMODE_SCROLL: { + page->track_mode = PAGE_TMODE_NONE; + eve_window_scroll_stop(window); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt); + break; } - if (_ret) return _ret; - } - ret = 1; - } - if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) { - if (scroll_x) { - page->g.x = page->x0 + touch->x0 - touch->x; - } - if (scroll_y) { - page->g.y = page->y0 + touch->y0 - touch->y; + case PAGE_TMODE_TRACK: { + page->track_mode = PAGE_TMODE_NONE; + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt); + break; + } } - ret = 1; - } - } else if ((evt & EVE_TOUCH_ETYPE_TIMER) && (page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { - EVEPhyLHO *lho = &page->lho; - int scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X; - int scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y; - int x, y, more; - - more = eve_phy_lho_tick(lho, eve_get_tick() - page->lho_t0, scroll_x ? &x : NULL, scroll_y ? &y : NULL); - if (scroll_x) page->g.x = x; - if (scroll_y) page->g.y = y; - if (!more) { - int _ret = 0; - - page->track_mode = PAGE_TMODE_NONE; - eve_timer_stop(); - eve_window_scroll_stop(window); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0); - if (_ret) return _ret; + if (eve_window_dirty(window)) return 1; } - ret = 1; + rv = 1; } - return ret; + return rv; } uint8_t eve_page_draw(EVEPage *page, uint8_t tag0) { EVEView *view = &page->v; EVEWidget *widget = page->widget; int i; - uint8_t tagN = tag0; + uint8_t tagN; uint8_t tag_opt; - tag_opt = EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY; + tag_opt = EVE_TOUCH_OPT_TRACK_XY; if (page->opt & EVE_PAGE_OPT_TRACK_EXT_X) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_X; if (page->opt & EVE_PAGE_OPT_TRACK_EXT_Y) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_Y; @@ -354,52 +402,41 @@ draw_nextw: eve_cmd_dl(RESTORE_CONTEXT()); for (i=tag0; i<tagN; i++) { - if (i != EVE_NOTAG) eve_touch_set_opt(i, eve_touch_get_opt(i) | tag_opt); + if (i != EVE_NOTAG) eve_tag_set_opt(i, eve_tag_get_opt(i) | tag_opt); } return tagN; } -int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) { +int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) { EVEWidget *widget = page->widget; - EVEViewStack *stack = page->stack; + EVEWindow *window = page->v.window; int8_t touch_idx = eve_touch_get_idx(touch); uint16_t _evt; - int i, ret; + int i, rv; if (touch_idx > 0) return 0; - _evt = eve_touch_evt(touch, evt, tag0, page->v.tag, 1); + _evt = eve_touch_evt(touch, evt, page->v.tag, 1); if (_evt) { - ret = page_touch(page, touch, _evt, tag0); - if (stack->dirty) { - stack->dirty = 0; - return 1; - } - if (ret) return 1; + rv = page_touch(page, touch, _evt); + if (rv || eve_window_dirty(window)) return 1; } for (i=0; i<page->widget_size; i++) { if (!eve_page_rect_visible(page, &widget->g) || (widget->flags & (EVE_WIDGET_FLAG_SKIP | EVE_WIDGET_FLAG_RO | EVE_WIDGET_FLAG_HIDDEN))) goto touch_nextw; - _evt = eve_touch_evt(touch, evt, tag0, widget->tag0, widget->tagN - widget->tag0); + _evt = eve_touch_evt(touch, evt, widget->tag0, widget->tagN - widget->tag0); if (_evt) { if (page->track_mode == PAGE_TMODE_NONE) { - ret = widget->touch(widget, touch, _evt); - if (stack->dirty) { - stack->dirty = 0; + rv = widget->touch(widget, touch, _evt); + if (eve_window_dirty(window)) return 1; + if (rv) { + eve_page_set_focus(page, widget); return 1; } - if (ret) { - eve_widget_set_focus(widget); - return 1; - } - } - ret = page_touch(page, touch, _evt, tag0); - if (stack->dirty) { - stack->dirty = 0; - return 1; } - if (ret) return 1; + rv = page_touch(page, touch, _evt); + if (rv || eve_window_dirty(window)) return 1; } touch_nextw: diff --git a/fw/fe310/eos/eve/screen/page.h b/fw/fe310/eos/eve/screen/page.h index 6874a2d..067565b 100644 --- a/fw/fe310/eos/eve/screen/page.h +++ b/fw/fe310/eos/eve/screen/page.h @@ -1,7 +1,5 @@ #include <stdint.h> -#define EVE_PAGE_KBDCH_CLOSE 0x1a - #define EVE_PAGE_OPT_SCROLL_X 0x01 #define EVE_PAGE_OPT_SCROLL_Y 0x02 #define EVE_PAGE_OPT_SCROLL_BACK 0x04 @@ -15,8 +13,8 @@ struct EVEWidget; struct EVEPage; typedef uint8_t (*eve_page_draw_t) (struct EVEPage *, uint8_t); -typedef int (*eve_page_touch_t) (struct EVEPage *, EVETouch *, uint16_t, uint8_t); -typedef int (*eve_page_uievt_t) (struct EVEPage *, uint16_t, void *); +typedef int (*eve_page_touch_t) (struct EVEPage *, EVETouch *, uint16_t); +typedef void (*eve_page_uievt_t) (struct EVEPage *, uint16_t, void *); typedef void (*eve_page_destructor_t) (struct EVEPage *); typedef struct EVEPage { @@ -24,19 +22,23 @@ typedef struct EVEPage { EVERect g; int16_t x0; int16_t y0; - EVEViewStack *stack; + EVEVStack *stack; eve_page_destructor_t destructor; struct EVEWidget *widget; uint16_t widget_size; struct EVEWidget *widget_f; EVEPhyLHO lho; - uint32_t lho_t0; uint8_t track_mode; uint8_t opt; } EVEPage; -void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, struct EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +void eve_page_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, struct EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +void eve_page_attach(EVEPage *page, EVEWindow *window, void *page_id); +void eve_page_detach(EVEPage *page); +void eve_page_set_param(EVEPage *page, void *param); +EVEView *eve_page_view(EVEPage *page); +EVEPage *eve_page_from_view(EVEView *view); struct EVEWidget *eve_page_widget(EVEPage *page, uint16_t idx); struct EVEWidget *eve_page_widget_search(EVEPage *page, char *label); void eve_page_set_widget(EVEPage *page, struct EVEWidget *widget, uint16_t widget_size); @@ -53,12 +55,12 @@ int16_t eve_page_win_y(EVEPage *page, int16_t y); /* Page to screen coordinates */ int16_t eve_page_scr_x(EVEPage *page, int16_t x); int16_t eve_page_scr_y(EVEPage *page, int16_t y); -int eve_page_rect_visible(EVEPage *page, EVERect *g); +int eve_page_rect_visible(EVEPage *page, EVERect *rect); void eve_page_show_rect(EVEPage *page, EVERect *rect); -int eve_page_oob(EVEPage *page, int *_max_x, int *_max_y); +int eve_page_oob(EVEPage *page, int *min_x, int *min_y); struct EVEWidget *eve_page_focus(EVEPage *page); void eve_page_set_focus(EVEPage *page, struct EVEWidget *widget); uint8_t eve_page_draw(EVEPage *page, uint8_t tag0); -int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt); diff --git a/fw/fe310/eos/eve/screen/uievt.h b/fw/fe310/eos/eve/screen/uievt.h index 8e1e682..e40624a 100644 --- a/fw/fe310/eos/eve/screen/uievt.h +++ b/fw/fe310/eos/eve/screen/uievt.h @@ -5,12 +5,12 @@ #define EVE_UIEVT_GEST_TRACK_STOP 5 #define EVE_UIEVT_WIN_UPDATE_G 6 #define EVE_UIEVT_PAGE_UPDATE_G 7 -#define EVE_UIEVT_WIDGET_UPDATE_G 8 -#define EVE_UIEVT_WIDGET_FOCUS_IN 9 -#define EVE_UIEVT_WIDGET_FOCUS_OUT 10 +#define EVE_UIEVT_WIDGET_UPDATE 8 +#define EVE_UIEVT_WIDGET_UPDATE_G 9 +#define EVE_UIEVT_WIDGET_FOCUS_IN 10 +#define EVE_UIEVT_WIDGET_FOCUS_OUT 11 typedef struct EVEUIEvtTouch { EVETouch *touch; uint16_t evt; - uint8_t tag0; } EVEUIEvtTouch; diff --git a/fw/fe310/eos/eve/screen/view.c b/fw/fe310/eos/eve/screen/view.c index d6e9ede..a1290f0 100644 --- a/fw/fe310/eos/eve/screen/view.c +++ b/fw/fe310/eos/eve/screen/view.c @@ -15,7 +15,19 @@ void eve_view_init(EVEView *view, EVEWindow *window, eve_view_draw_t draw, eve_v view->window = window; view->color_bg = 0x000000; view->color_fg = 0xffffff; - window->view = view; +} + +void eve_view_attach(EVEView *view, EVEWindow *window, void *view_id) { + view->window = window; + eve_window_attach_view(window, view, view_id); +} + +void eve_view_detach(EVEView *view) { + eve_window_detach_view(view->window); +} + +void eve_view_set_param(EVEView *view, void *param) { + view->param = param; } void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) { @@ -29,78 +41,121 @@ void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) { uint8_t eve_view_clear(EVEView *view, uint8_t tag0, uint8_t tag_opt) { EVEWindow *win_scroll = NULL; EVEWindow *window = view->window; - uint8_t _tag; + uint8_t scroll_tag; - win_scroll = eve_window_scroll(window->root, &_tag); + win_scroll = eve_window_scroll(window, &scroll_tag); eve_cmd_dl(CLEAR_COLOR_RGBC(view->color_bg)); eve_cmd_dl(COLOR_RGBC(view->color_fg)); if (win_scroll == window) { - view->tag = _tag; - eve_touch_set_opt(view->tag, tag_opt); - eve_cmd_dl(TAG(view->tag)); - eve_cmd_dl(CLEAR_TAG(view->tag)); + view->tag = scroll_tag; } else if (win_scroll) { view->tag = EVE_NOTAG; - eve_cmd_dl(TAG(view->tag)); - eve_cmd_dl(CLEAR_TAG(view->tag)); } else { view->tag = tag0; if (tag0 != EVE_NOTAG) { - eve_touch_set_opt(tag0, tag_opt); - eve_cmd_dl(CLEAR_TAG(tag0)); + eve_tag_set_opt(tag0, tag_opt); tag0++; } } + eve_cmd_dl(CLEAR_TAG(view->tag)); eve_cmd_dl(CLEAR(1,1,1)); return tag0; } -int eve_view_uievt_push(EVEView *view, uint16_t evt, void *param) { - if (view->uievt) return view->uievt(view, evt, param); - return 0; +uint8_t eve_view_tag(EVEView *view, uint8_t tag, uint8_t tag_opt) { + if (tag != EVE_NOTAG) { + eve_tag_set_opt(tag, tag_opt); + eve_cmd_dl(TAG(tag)); + tag++; + } + return tag; } -int eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0) { - if (view->uievt) { - EVEUIEvtTouch param; +void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param) { + if (view->uievt) view->uievt(view, evt, param); +} - param.touch = touch; - param.evt = t_evt; - param.tag0 = tag0; - return view->uievt(view, evt, ¶m); - } - return 0; +void eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt) { + EVEUIEvtTouch param; + + if (view->uievt == NULL) return; + + param.touch = touch; + param.evt = t_evt; + view->uievt(view, evt, ¶m); } -void eve_stack_init(EVEViewStack *stack) { - memset(stack, 0, sizeof(EVEViewStack)); +void eve_vstack_init(EVEVStack *stack) { + memset(stack, 0, sizeof(EVEVStack)); } -void eve_stack_create_view(EVEViewStack *stack, EVEWindow *window, eve_view_constructor_t constructor) { - int rv; +int eve_vstack_push(EVEVStack *stack, eve_view_constructor_t constructor) { + if (stack->level == EVE_VIEW_SIZE_STACK) return EVE_ERR_FULL; - stack->dirty = 1; - if (stack->level < EVE_VIEW_SIZE_STACK - 1) { - stack->constructor[stack->level] = constructor; - stack->level++; - rv = constructor(window, stack); - if (rv) eve_stack_back(stack, window); - } + stack->constructor[stack->level] = constructor; + stack->level++; + + return EVE_OK; } -void eve_stack_back(EVEViewStack *stack, EVEWindow *window) { +eve_view_constructor_t eve_vstack_pull(EVEVStack *stack) { eve_view_constructor_t constructor; - int rv = 1; - stack->dirty = 1; - while ((stack->level > 1) && rv) { + constructor = eve_vstack_get(stack); + if (stack->level) { stack->level--; - constructor = stack->constructor[stack->level - 1]; - rv = constructor(window, stack); + stack->constructor[stack->level] = NULL; } + return constructor; } -eve_view_constructor_t eve_stack_get(EVEViewStack *stack) { +eve_view_constructor_t eve_vstack_get(EVEVStack *stack) { if (stack->level) return stack->constructor[stack->level - 1]; return NULL; } + +int eve_vstack_empty(EVEVStack *stack) { + return (stack->level == 0); +} + +int eve_vstack_full(EVEVStack *stack) { + return (stack->level == EVE_VIEW_SIZE_STACK); +} + +int eve_vstack_level(EVEVStack *stack) { + return stack->level; +} + +int eve_vstack_create_view(EVEVStack *stack, EVEWindow *window, eve_view_constructor_t constructor) { + EVEView *view; + int rv; + + rv = eve_vstack_push(stack, constructor); + if (rv) return rv; + + view = constructor(window, stack); + if (view == NULL) { + eve_vstack_pull(stack); + return EVE_ERR; + } + + eve_view_attach(view, window, constructor); + + return EVE_OK; +} + +int eve_vstack_back(EVEVStack *stack, EVEWindow *window) { + EVEView *view; + eve_view_constructor_t constructor; + + eve_vstack_pull(stack); + constructor = eve_vstack_get(stack); + if (constructor == NULL) return EVE_ERR_EMPTY; + + view = constructor(window, stack); + if (view == NULL) return EVE_ERR; + + eve_view_attach(view, window, constructor); + + return EVE_OK; +} diff --git a/fw/fe310/eos/eve/screen/view.h b/fw/fe310/eos/eve/screen/view.h index 3e8c0a0..c40a620 100644 --- a/fw/fe310/eos/eve/screen/view.h +++ b/fw/fe310/eos/eve/screen/view.h @@ -5,13 +5,13 @@ #define EVE_VIEW_SIZE_STACK 16 struct EVEView; -struct EVEViewStack; +struct EVEVStack; struct EVEWindow; typedef uint8_t (*eve_view_draw_t) (struct EVEView *, uint8_t); -typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t, uint8_t); -typedef int (*eve_view_uievt_t) (struct EVEView *, uint16_t, void *); -typedef int (*eve_view_constructor_t) (struct EVEWindow *window, struct EVEViewStack *); +typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t); +typedef void (*eve_view_uievt_t) (struct EVEView *, uint16_t, void *); +typedef struct EVEView *(*eve_view_constructor_t) (struct EVEWindow *window, struct EVEVStack *); typedef struct EVEView { eve_view_draw_t draw; @@ -24,21 +24,29 @@ typedef struct EVEView { uint8_t tag; } EVEView; -typedef struct EVEViewStack { +typedef struct EVEVStack { eve_view_constructor_t constructor[EVE_VIEW_SIZE_STACK]; uint8_t level; - uint8_t dirty; -} EVEViewStack; +} EVEVStack; void eve_view_init(EVEView *view, struct EVEWindow *window, eve_view_draw_t draw, eve_view_touch_t touch, eve_view_uievt_t uievt, void *param); +void eve_view_attach(EVEView *view, struct EVEWindow *window, void *view_id); +void eve_view_detach(EVEView *view); +void eve_view_set_param(EVEView *view, void *param); void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b); void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b); uint8_t eve_view_clear(EVEView *view, uint8_t tag0, uint8_t tag_opt); - -int eve_view_uievt_push(EVEView *view, uint16_t evt, void *param); -int eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0); - -void eve_stack_init(EVEViewStack *stack); -void eve_stack_create_view(EVEViewStack *stack, struct EVEWindow *window, eve_view_constructor_t constructor); -void eve_stack_back(EVEViewStack *stack, struct EVEWindow *window); -eve_view_constructor_t eve_stack_get(EVEViewStack *stack);
\ No newline at end of file +uint8_t eve_view_tag(EVEView *view, uint8_t tag, uint8_t tag_opt); + +void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param); +void eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt); + +void eve_vstack_init(EVEVStack *stack); +int eve_vstack_push(EVEVStack *stack, eve_view_constructor_t constructor); +eve_view_constructor_t eve_vstack_pull(EVEVStack *stack); +eve_view_constructor_t eve_vstack_get(EVEVStack *stack); +int eve_vstack_empty(EVEVStack *stack); +int eve_vstack_full(EVEVStack *stack); +int eve_vstack_level(EVEVStack *stack); +int eve_vstack_create_view(EVEVStack *stack, struct EVEWindow *window, eve_view_constructor_t constructor); +int eve_vstack_back(EVEVStack *stack, struct EVEWindow *window); diff --git a/fw/fe310/eos/eve/screen/window.c b/fw/fe310/eos/eve/screen/window.c index 34d265a..90f4e20 100644 --- a/fw/fe310/eos/eve/screen/window.c +++ b/fw/fe310/eos/eve/screen/window.c @@ -1,6 +1,5 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> #include "eve.h" #include "eve_kbd.h" @@ -28,7 +27,7 @@ void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont * root->font = font; root->win_kbd = NULL; root->win_scroll = NULL; - root->tag0 = EVE_NOTAG; + root->tag_scroll = EVE_NOTAG; eve_touch_set_handler(eve_window_root_touch, root); } @@ -41,10 +40,10 @@ static uint8_t kbd_draw(EVEView *view, uint8_t tag0) { return tag0; } -static int kbd_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0) { +static int kbd_touch(EVEView *view, EVETouch *touch, uint16_t evt) { EVEKbd *kbd = view->param; - return eve_kbd_touch(kbd, touch, evt, tag0); + return eve_kbd_touch(kbd, touch, evt); } void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd) { @@ -55,6 +54,7 @@ void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, win_kbd->kbd = kbd; root->win_kbd = win_kbd; eve_view_init(&win_kbd->v, _window, kbd_draw, kbd_touch, NULL, kbd); + eve_view_attach(&win_kbd->v, _window, NULL); } void eve_window_set_parent(EVEWindow *window, EVEWindow *parent) { @@ -62,6 +62,26 @@ void eve_window_set_parent(EVEWindow *window, EVEWindow *parent) { window->root = parent->root; } +void eve_window_attach_view(EVEWindow *window, EVEView *view, void *view_id) { + if (window->view) window->dirty = 1; + window->view = view; + window->view_id = view_id; +} + +void eve_window_detach_view(EVEWindow *window) { + if (window->view) window->dirty = 1; + window->view = NULL; + window->view_id = NULL; +} + +int eve_window_dirty(EVEWindow *window) { + return window->dirty; +} + +void eve_window_clean(EVEWindow *window) { + window->dirty = 0; +} + int eve_window_visible(EVEWindow *window) { if (window->g.x >= window->root->w.g.w) return 0; if (window->g.y >= window->root->w.g.h) return 0; @@ -70,31 +90,32 @@ int eve_window_visible(EVEWindow *window) { return 1; } -static void window_visible_g(EVEWindow *w, EVERect *g) { - while (w) { - if (eve_window_visible(w)) { - if (w->g.x > g->x) g->w = MIN(g->w, w->g.x - g->x); - if (w->g.y > g->y) g->h = MIN(g->h, w->g.y - g->y); - if (w->g.x + w->g.w < g->x + g->w) { - uint16_t x0 = g->w - MIN(g->w, (g->x + g->w) - (w->g.x + w->g.w)); - g->x += x0; - g->w -= x0; +static void window_visible_g(EVEWindow *win, EVERect *rect) { + while (win) { + if (eve_window_visible(win)) { + if (win->g.x > rect->x) rect->w = MIN(rect->w, win->g.x - rect->x); + if (win->g.y > rect->y) rect->h = MIN(rect->h, win->g.y - rect->y); + if (win->g.x + win->g.w < rect->x + rect->w) { + uint16_t x0 = rect->w - MIN(rect->w, (rect->x + rect->w) - (win->g.x + win->g.w)); + rect->x += x0; + rect->w -= x0; } - if (w->g.y + w->g.h < g->y + g->h) { - uint16_t y0 = g->h - MIN(g->h, (g->y + g->h) - (w->g.y + w->g.h)); - g->y += y0; - g->h -= y0; + if (win->g.y + win->g.h < rect->y + rect->h) { + uint16_t y0 = rect->h - MIN(rect->h, (rect->y + rect->h) - (win->g.y + win->g.h)); + rect->y += y0; + rect->h -= y0; } + if ((rect->w == 0) || (rect->h == 0)) return; } - if (w->child_head) window_visible_g(w->child_head, g); - w = w->next; + if (win->child_head) window_visible_g(win->child_head, rect); + win = win->next; } } -void eve_window_visible_g(EVEWindow *window, EVERect *g) { - *g = window->g; - if (window->child_head) window_visible_g(window->child_head, g); - window_visible_g(window->next, g); +void eve_window_visible_g(EVEWindow *window, EVERect *rect) { + *rect = window->g; + if (window->child_head) window_visible_g(window->child_head, rect); + window_visible_g(window->next, rect); } void eve_window_append(EVEWindow *window) { @@ -160,8 +181,8 @@ EVEWindow *eve_window_search(EVEWindow *window, char *name) { while (window) { if (window->name && (strcmp(name, window->name) == 0)) return window; if (window->child_head) { - EVEWindow *ret = eve_window_search(window->child_head, name); - if (ret) return ret; + EVEWindow *rv = eve_window_search(window->child_head, name); + if (rv) return rv; } window = window->next; } @@ -198,17 +219,18 @@ uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0) { return tag0; } -int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0) { - int ret = 0; +int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt) { + int rv = 0; while (window) { if (window->child_tail) { - ret = eve_window_touch(window->child_tail, touch, evt, tag0); - if (ret) return 1; + rv = eve_window_touch(window->child_tail, touch, evt); + if (rv) return 1; } if (eve_window_visible(window) && window->view) { - ret = window->view->touch(window->view, touch, evt, tag0); - if (ret) return 1; + rv = window->view->touch(window->view, touch, evt); + window->dirty = 0; + if (rv) return 1; } window = window->prev; } @@ -223,24 +245,31 @@ void eve_window_root_draw(EVEWindowRoot *root) { eve_cmd_burst_start(); eve_cmd_dl(CMD_DLSTART); - if (root->tag0 != EVE_NOTAG) tag0 = EVE_NOTAG; + if (root->tag_scroll != EVE_NOTAG) tag0 = EVE_NOTAG; eve_window_draw(&root->w, tag0); eve_cmd_dl(DISPLAY()); eve_cmd_dl(CMD_SWAP); eve_cmd_burst_end(); rv = eve_cmd_exec(1); - if (rv) printf("EVE EXEC ERR\n"); + if (rv) EVE_LOG(EVE_LOG_ERR, "EVE CMD EXEC ERR:%d\n", rv); } -void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win) { +void eve_window_root_touch(EVETouch *touch, uint16_t evt, void *win) { EVEWindowRoot *root = (EVEWindowRoot *)win; - int ret; + int rv; - if (root->tag0 != EVE_NOTAG) tag0 = root->tag0; - ret = eve_window_touch(&root->w, touch, evt, tag0); - if (ret) { - eve_touch_clear_opt(); + rv = eve_window_touch(&root->w, touch, evt); + if (rv) { + uint8_t tag_opt = 0; + + if (root->tag_scroll != EVE_NOTAG) { + tag_opt = eve_tag_get_opt(root->tag_scroll); + } + eve_tag_clear_opt(); + if (root->tag_scroll != EVE_NOTAG) { + eve_tag_set_opt(root->tag_scroll, tag_opt); + } eve_window_root_draw(root); } } @@ -275,14 +304,10 @@ void eve_window_kbd_detach(EVEWindow *window) { } } -EVEFont *eve_window_font(EVEWindow *window) { +EVEWindow *eve_window_scroll(EVEWindow *window, uint8_t *tag) { EVEWindowRoot *root = window->root; - return root->font; -} - -EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag) { - if (tag) *tag = root->tag0; + if (tag) *tag = root->tag_scroll; return root->win_scroll; } @@ -290,12 +315,18 @@ void eve_window_scroll_start(EVEWindow *window, uint8_t tag) { EVEWindowRoot *root = window->root; root->win_scroll = window; - root->tag0 = tag; + root->tag_scroll = tag; } void eve_window_scroll_stop(EVEWindow *window) { EVEWindowRoot *root = window->root; root->win_scroll = NULL; - root->tag0 = EVE_NOTAG; + root->tag_scroll = EVE_NOTAG; +} + +EVEFont *eve_window_font(EVEWindow *window) { + EVEWindowRoot *root = window->root; + + return root->font; } diff --git a/fw/fe310/eos/eve/screen/window.h b/fw/fe310/eos/eve/screen/window.h index 27465c4..ac52fb8 100644 --- a/fw/fe310/eos/eve/screen/window.h +++ b/fw/fe310/eos/eve/screen/window.h @@ -8,12 +8,14 @@ typedef struct EVEWindow { EVERect g; char *name; EVEView *view; + void *view_id; struct EVEWindowRoot *root; struct EVEWindow *parent; struct EVEWindow *next; struct EVEWindow *prev; struct EVEWindow *child_head; struct EVEWindow *child_tail; + int dirty; } EVEWindow; typedef struct EVEWindowKbd { @@ -28,7 +30,7 @@ typedef struct EVEWindowRoot { EVEFont *font; EVEWindowKbd *win_kbd; EVEWindow *win_scroll; - uint8_t tag0; + uint8_t tag_scroll; } EVEWindowRoot; void eve_window_init(EVEWindow *window, EVERect *g, EVEWindow *parent, char *name); @@ -36,8 +38,13 @@ void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont * void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd); void eve_window_set_parent(EVEWindow *window, EVEWindow *parent); +void eve_window_attach_view(EVEWindow *window, EVEView *view, void *view_id); +void eve_window_detach_view(EVEWindow *window); +int eve_window_dirty(EVEWindow *window); +void eve_window_clean(EVEWindow *window); + int eve_window_visible(EVEWindow *window); -void eve_window_visible_g(EVEWindow *window, EVERect *g); +void eve_window_visible_g(EVEWindow *window, EVERect *rect); void eve_window_append(EVEWindow *window); void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev); @@ -46,15 +53,16 @@ void eve_window_remove(EVEWindow *window); EVEWindow *eve_window_search(EVEWindow *window, char *name); uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0); -int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt); void eve_window_root_draw(EVEWindowRoot *root); -void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win); +void eve_window_root_touch(EVETouch *touch, uint16_t evt, void *win); EVEKbd *eve_window_kbd(EVEWindow *window); void eve_window_kbd_attach(EVEWindow *window); void eve_window_kbd_detach(EVEWindow *window); -EVEFont *eve_window_font(EVEWindow *window); -EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag); +EVEWindow *eve_window_scroll(EVEWindow *window, uint8_t *tag); void eve_window_scroll_start(EVEWindow *window, uint8_t tag); void eve_window_scroll_stop(EVEWindow *window); + +EVEFont *eve_window_font(EVEWindow *window); diff --git a/fw/fe310/eos/eve/widget/freew.c b/fw/fe310/eos/eve/widget/freew.c index 11b8e50..f88f81e 100644 --- a/fw/fe310/eos/eve/widget/freew.c +++ b/fw/fe310/eos/eve/widget/freew.c @@ -10,22 +10,28 @@ #include "widget.h" -void eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc) { +int eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc) { EVEWidget *_widget = &widget->w; memset(widget, 0, sizeof(EVEFreeWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_FREE, g, page, eve_freew_draw, eve_freew_touch, putc); widget->_draw = draw; widget->_touch = touch; + + return EVE_OK; +} + +void eve_freew_set_uievt_handler(EVEFreeWidget *widget, eve_freew_uievt_t handler) { + widget->_uievt = handler; } int eve_freew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEFreeWidget *widget = (EVEFreeWidget *)_widget; EVEFreeSpec *tspec = &spec->tspec.free; + int rv; - eve_freew_init(widget, &spec->g, page, tspec->draw, tspec->touch, tspec->putc); - - return EVE_OK; + rv = eve_freew_init(widget, &spec->g, page, tspec->draw, tspec->touch, tspec->putc); + return rv; } uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0) { @@ -42,27 +48,53 @@ uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0) { int eve_freew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEFreeWidget *widget = (EVEFreeWidget *)_widget; - int ret; + int rv; + + /* widget received non-touch event */ + if (evt & EVE_TOUCH_ETYPE_EXT) { + evt &= ~EVE_TOUCH_ETYPE_EXT; + if (widget->_uievt) widget->_uievt(widget, evt); - ret = widget->_touch(widget, touch, evt); - return ret; + /* always return 0 for non-touch events */ + return 0; + } + + rv = widget->_touch(widget, touch, evt); + return rv; } -uint8_t eve_freew_tag(EVEFreeWidget *widget) { +uint8_t eve_freew_tag0(EVEFreeWidget *widget) { + EVEWidget *_widget = &widget->w; + + return _widget->tag0; +} + +void eve_freew_tag(EVEFreeWidget *widget, uint8_t tag_opt) { EVEWidget *_widget = &widget->w; - uint8_t ret = EVE_NOTAG; if (_widget->tagN != EVE_NOTAG) { - ret = _widget->tagN; - eve_cmd_dl(TAG(ret)); + eve_tag_set_opt(_widget->tagN, tag_opt); + eve_cmd_dl(TAG(_widget->tagN)); _widget->tagN++; } +} - return ret; +void eve_freew_tag_idx(EVEFreeWidget *widget, uint8_t i) { + EVEWidget *_widget = &widget->w; + uint8_t tag = _widget->tag0; + + if (tag != EVE_NOTAG) { + tag += i; + + /* prevents overflow */ + if ((tag >= _widget->tag0) && (tag < _widget->tagN)) { + eve_cmd_dl(TAG(tag)); + } + } } -uint8_t eve_widget_tag_index(EVEFreeWidget *widget, uint8_t tag) { +uint8_t eve_freew_get_tag_idx(EVEFreeWidget *widget, uint8_t tag) { EVEWidget *_widget = &widget->w; return tag - _widget->tag0; -}
\ No newline at end of file +} diff --git a/fw/fe310/eos/eve/widget/freew.h b/fw/fe310/eos/eve/widget/freew.h index cbcd08b..82038c4 100644 --- a/fw/fe310/eos/eve/widget/freew.h +++ b/fw/fe310/eos/eve/widget/freew.h @@ -5,11 +5,13 @@ struct EVEWidgetSpec; typedef void (*eve_freew_draw_t) (struct EVEFreeWidget *); typedef int (*eve_freew_touch_t) (struct EVEFreeWidget *, EVETouch *, uint16_t); +typedef void (*eve_freew_uievt_t) (struct EVEFreeWidget *, uint16_t); typedef struct EVEFreeWidget { EVEWidget w; eve_freew_draw_t _draw; eve_freew_touch_t _touch; + eve_freew_uievt_t _uievt; } EVEFreeWidget; typedef struct EVEFreeSpec { @@ -18,11 +20,14 @@ typedef struct EVEFreeSpec { eve_kbd_input_handler_t putc; } EVEFreeSpec; -void eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc); +int eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc); +void eve_freew_set_uievt_handler(EVEFreeWidget *widget, eve_freew_uievt_t handler); int eve_freew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0); int eve_freew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt); -uint8_t eve_freew_tag(EVEFreeWidget *widget); -uint8_t eve_widget_tag_index(EVEFreeWidget *widget, uint8_t tag);
\ No newline at end of file +uint8_t eve_freew_tag0(EVEFreeWidget *widget); +void eve_freew_tag(EVEFreeWidget *widget, uint8_t tag_opt); +void eve_freew_tag_idx(EVEFreeWidget *widget, uint8_t i); +uint8_t eve_freew_get_tag_idx(EVEFreeWidget *widget, uint8_t tag); diff --git a/fw/fe310/eos/eve/widget/label.c b/fw/fe310/eos/eve/widget/label.c index 43c710c..d596677 100644 --- a/fw/fe310/eos/eve/widget/label.c +++ b/fw/fe310/eos/eve/widget/label.c @@ -10,26 +10,31 @@ #include "label.h" -void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) { +int eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) { size_t title_len; int title_w, rv; - memset(label, 0, sizeof(EVELabel)); - if (g) label->g = *g; + if (font == NULL) return EVE_ERR; - rv = eve_font_verify(font, label->title, &title_w, &title_len); - if (rv) title[title_len] = '\0'; + rv = eve_font_verify(font, title, 0, &title_w, &title_len); + if (rv) return rv; + memset(label, 0, sizeof(EVELabel)); + if (g) label->g = *g; label->font = font; label->title = title; if (label->g.h == 0) label->g.h = eve_font_h(font); if (label->g.w == 0) label->g.w = title_w + EVE_LABEL_MARGIN; + + return EVE_OK; } -void eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page) { +int eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page) { EVEFont *font = spec->font ? spec->font : eve_window_font(page->v.window); + int rv; - eve_label_init(label, &spec->g, font, spec->title); + rv = eve_label_init(label, &spec->g, font, spec->title); + return rv; } void eve_label_draw(EVELabel *label) { diff --git a/fw/fe310/eos/eve/widget/label.h b/fw/fe310/eos/eve/widget/label.h index 9992f8c..f9c192b 100644 --- a/fw/fe310/eos/eve/widget/label.h +++ b/fw/fe310/eos/eve/widget/label.h @@ -15,7 +15,7 @@ typedef struct EVELabelSpec { int16_t margin; } EVELabelSpec; -void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title); +int eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title); -void eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page); +int eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page); void eve_label_draw(EVELabel *label);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/widget/pagew.c b/fw/fe310/eos/eve/widget/pagew.c index 77e8f01..0ce4e82 100644 --- a/fw/fe310/eos/eve/widget/pagew.c +++ b/fw/fe310/eos/eve/widget/pagew.c @@ -10,8 +10,12 @@ #include "widget.h" -void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor) { +int eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor) { EVEWidget *_widget = &widget->w; + int title_w, rv; + + rv = eve_font_verify(font, title, 0, &title_w, NULL); + if (rv) return rv; memset(widget, 0, sizeof(EVEPageWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_PAGE, g, page, eve_pagew_draw, eve_pagew_touch, NULL); @@ -19,16 +23,19 @@ void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *f widget->title = title; widget->constructor = constructor; if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font); + if (_widget->g.w == 0) _widget->g.w = title_w; + + return EVE_OK; } int eve_pagew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEPageWidget *widget = (EVEPageWidget *)_widget; EVEPageSpec *tspec = &spec->tspec.page; EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); + int rv; - eve_pagew_init(widget, &spec->g, page, font, tspec->title, tspec->constructor); - - return EVE_OK; + rv = eve_pagew_init(widget, &spec->g, page, font, tspec->title, tspec->constructor); + return rv; } uint8_t eve_pagew_draw(EVEWidget *_widget, uint8_t tag0) { @@ -50,6 +57,9 @@ int eve_pagew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEPage *parent = _widget->page; EVEPageWidget *widget = (EVEPageWidget *)_widget; + /* widget received non-touch event, always return 0 */ + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; + if (evt & EVE_TOUCH_ETYPE_TAG_UP) { eve_page_open(parent, widget->constructor); return 1; diff --git a/fw/fe310/eos/eve/widget/pagew.h b/fw/fe310/eos/eve/widget/pagew.h index b1a91b2..9a1f1a1 100644 --- a/fw/fe310/eos/eve/widget/pagew.h +++ b/fw/fe310/eos/eve/widget/pagew.h @@ -15,7 +15,7 @@ typedef struct EVEPageSpec { eve_view_constructor_t constructor; } EVEPageSpec; -void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor); +int eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor); int eve_pagew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_pagew_draw(EVEWidget *_widget, uint8_t tag0); diff --git a/fw/fe310/eos/eve/widget/selectw.c b/fw/fe310/eos/eve/widget/selectw.c index f0dfed9..ee924c7 100644 --- a/fw/fe310/eos/eve/widget/selectw.c +++ b/fw/fe310/eos/eve/widget/selectw.c @@ -14,37 +14,42 @@ #define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) -static int selectw_verify(utf8_t *option, uint16_t option_size) { - size_t o_len; - uint16_t o_curr; +static int selectw_verify(utf8_t *option, uint16_t option_size, EVEFont *font, size_t *len) { + size_t _len, curr; int rv; - o_curr = 0; - while (o_curr < option_size) { - rv = utf8_verify(option + o_curr, option_size - o_curr, &o_len); - if (rv) return EVE_ERR; - if (o_len == 0) return EVE_OK; - o_curr += o_len + 1; + curr = 0; + while (curr < option_size) { + rv = eve_font_verify(font, option + curr, option_size - curr, NULL, &_len); + if (rv) { + if (len) *len = curr; + return rv; + } + curr += _len + 1; + if (_len == 0) { + if (len) *len = curr; + return EVE_OK; + } } + if (len) *len = curr; return EVE_OK; } static int selectw_count(EVESelectWidget *widget) { - int o_len; - int o_curr; + size_t len, curr; int i; - o_curr = 0; + curr = 0; i = 0; do { - o_len = strnlen(widget->option + o_curr, widget->option_size - o_curr); - if (o_len == widget->option_size - o_curr) return i; - if (o_len) { - o_curr += o_len + 1; + len = strnlen(widget->option + curr, widget->option_size - curr); + if (len == widget->option_size - curr) return i; + if (len) { + curr += len + 1; i++; } - } while (o_len); + } while (len); return i; } @@ -57,28 +62,32 @@ static void selectw_update_sz(EVESelectWidget *widget, int uievt) { if (uievt) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE_G, _widget); } -void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi) { +int eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi) { EVEWidget *_widget = &widget->w; int rv; + rv = selectw_verify(option, option_size, font, NULL); + if (rv) return rv; + memset(widget, 0, sizeof(EVESelectWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_SELECT, g, page, eve_selectw_draw, eve_selectw_touch, NULL); + widget->font = font; - rv = selectw_verify(option, option_size); - if (rv == EVE_OK) { - widget->option = option; - widget->option_size = option_size; - widget->option_count = selectw_count(widget); - selectw_update_sz(widget, 0); - } + widget->option = option; + widget->option_size = option_size; + widget->option_count = selectw_count(widget); + selectw_update_sz(widget, 0); + widget->multi = multi; widget->select = widget->multi ? 0 : SELECTW_NOSELECT; + + return EVE_OK; } int eve_selectw_update(EVESelectWidget *widget) { int rv, i; - rv = selectw_verify(widget->option, widget->option_size); + rv = selectw_verify(widget->option, widget->option_size, widget->font, NULL); if (rv) return rv; widget->option_count = selectw_count(widget); @@ -92,6 +101,7 @@ int eve_selectw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVESelectSpec *tspec = &spec->tspec.select; EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); utf8_t *option; + int rv; option = eve_malloc(tspec->option_size); if (option == NULL) { @@ -99,9 +109,8 @@ int eve_selectw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { } memset(option, 0, tspec->option_size); - eve_selectw_init(widget, &spec->g, page, font, option, tspec->option_size, tspec->multi); - - return EVE_OK; + rv = eve_selectw_init(widget, &spec->g, page, font, option, tspec->option_size, tspec->multi); + return rv; } void eve_selectw_destroy(EVEWidget *_widget) { @@ -113,11 +122,10 @@ void eve_selectw_destroy(EVEWidget *_widget) { uint8_t eve_selectw_draw(EVEWidget *_widget, uint8_t tag0) { EVESelectWidget *widget = (EVESelectWidget *)_widget; EVEPage *page = _widget->page; - int o_len; - int o_curr; - int i, s; + size_t len, curr; int16_t x1, x2, y1, y2; uint16_t new_h; + int i, s; int line0, lineN; @@ -132,11 +140,11 @@ uint8_t eve_selectw_draw(EVEWidget *_widget, uint8_t tag0) { _widget->tagN = tag0; widget->line0 = line0; - o_curr = 0; + curr = 0; i = 0; do { - o_len = strnlen(widget->option + o_curr, widget->option_size - o_curr); - if (!o_len || (o_len == widget->option_size - o_curr)) break; + len = strnlen(widget->option + curr, widget->option_size - curr); + if (!len || (len == widget->option_size - curr)) break; if ((i >= line0) && (i < lineN)) { if (_widget->tagN != EVE_NOTAG) { eve_cmd_dl(TAG(_widget->tagN)); @@ -159,19 +167,23 @@ uint8_t eve_selectw_draw(EVEWidget *_widget, uint8_t tag0) { } eve_cmd_dl(END()); if (s) eve_cmd_dl(COLOR_RGBC(page->v.color_bg)); - eve_cmd(CMD_TEXT, "hhhhs", x1, y1, widget->font->id, 0, widget->option + o_curr); + eve_cmd(CMD_TEXT, "hhhhs", x1, y1, widget->font->id, 0, widget->option + curr); if (s) eve_cmd_dl(COLOR_RGBC(page->v.color_fg)); } - o_curr += o_len + 1; + curr += len + 1; i++; - } while (o_len); + } while (len); return _widget->tagN; } int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVESelectWidget *widget = (EVESelectWidget *)_widget; + EVEPage *page = _widget->page; + + /* widget received non-touch event, always return 0 */ + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; if (evt & EVE_TOUCH_ETYPE_TAG_UP) { int i = touch->tag0 - _widget->tag0 + widget->line0; @@ -192,6 +204,8 @@ int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { } } + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget); + return 1; } @@ -199,19 +213,18 @@ int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { } utf8_t *eve_selectw_option(EVESelectWidget *widget, int idx) { - int o_len; - int o_curr; + size_t len, curr; int i; - o_curr = 0; + curr = 0; i = 0; do { - o_len = strnlen(widget->option + o_curr, widget->option_size - o_curr); - if (o_len == widget->option_size - o_curr) return NULL; - if (o_len && (i == idx)) return widget->option + o_curr; - o_curr += o_len + 1; + len = strnlen(widget->option + curr, widget->option_size - curr); + if (len == widget->option_size - curr) return NULL; + if (len && (i == idx)) return widget->option + curr; + curr += len + 1; i++; - } while (o_len); + } while (len); return NULL; } @@ -222,26 +235,25 @@ utf8_t *eve_selectw_option_selected(EVESelectWidget *widget) { } int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option) { - int o_len; - int o_curr; + size_t len, curr; int rv, i; - rv = utf8_verify(option, strlen(option) + 1, NULL); - if (rv) return EVE_ERR; + rv = eve_font_verify(widget->font, option, 0, NULL, NULL); + if (rv) return rv; - o_curr = 0; + curr = 0; i = 0; do { - o_len = strnlen(widget->option + o_curr, widget->option_size - o_curr); - if (o_len == widget->option_size - o_curr) return EVE_ERR_FULL; - if (o_len) { - o_curr += o_len + 1; + len = strnlen(widget->option + curr, widget->option_size - curr); + if (len == widget->option_size - curr) return EVE_ERR_FULL; + if (len) { + curr += len + 1; i++; } - } while (o_len); + } while (len); - if (o_curr + strlen(option) + 1 > widget->option_size) return EVE_ERR_FULL; - strcpy(widget->option + o_curr, option); + if (curr + strlen(option) + 1 > widget->option_size) return EVE_ERR_FULL; + strcpy(widget->option + curr, option); widget->option_count = i + 1; selectw_update_sz(widget, 1); @@ -249,18 +261,39 @@ int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option) { return EVE_OK; } -int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size) { +int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t len) { int rv, i; - rv = selectw_verify(option, option_size); + if (len > widget->option_size) return EVE_ERR_FULL; + + rv = selectw_verify(option, len, widget->font, NULL); if (rv) return rv; - if (option_size > widget->option_size) return EVE_ERR_FULL; - memcpy(widget->option, option, option_size); - memset(widget->option + option_size, 0, widget->option_size - option_size); + memcpy(widget->option, option, len); + memset(widget->option + len, 0, widget->option_size - len); widget->option_count = selectw_count(widget); selectw_update_sz(widget, 1); return EVE_OK; } + +void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t len) { + size_t good_l, bad_l; + int rv; + + do { + rv = selectw_verify(option, len, widget->font, &good_l); + if (rv == EVE_OK) return; + + option += good_l; + len -= good_l; + + bad_l = strnlen(option, len); + if (bad_l != len) { + bad_l++; + } + memmove(option, option + bad_l, len - bad_l); + memset(option + len - bad_l, 0, bad_l); + } while (bad_l != len); +} diff --git a/fw/fe310/eos/eve/widget/selectw.h b/fw/fe310/eos/eve/widget/selectw.h index aa49866..577fb86 100644 --- a/fw/fe310/eos/eve/widget/selectw.h +++ b/fw/fe310/eos/eve/widget/selectw.h @@ -19,7 +19,7 @@ typedef struct EVESelectSpec { uint8_t multi; } EVESelectSpec; -void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi); +int eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi); int eve_selectw_update(EVESelectWidget *widget); int eve_selectw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); @@ -30,4 +30,5 @@ int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt); utf8_t *eve_selectw_option(EVESelectWidget *widget, int idx); utf8_t *eve_selectw_option_selected(EVESelectWidget *widget); int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option); -int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size); +int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t len); +void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t len); diff --git a/fw/fe310/eos/eve/widget/spacerw.c b/fw/fe310/eos/eve/widget/spacerw.c index aa5bec1..f597a2d 100644 --- a/fw/fe310/eos/eve/widget/spacerw.c +++ b/fw/fe310/eos/eve/widget/spacerw.c @@ -10,15 +10,18 @@ #include "widget.h" -void eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page) { +int eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page) { memset(widget, 0, sizeof(EVEWidget)); eve_widget_init(widget, EVE_WIDGET_TYPE_SPACER, g, page, eve_spacerw_draw, eve_spacerw_touch, NULL); + + return EVE_OK; } int eve_spacerw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { - eve_spacerw_init(_widget, &spec->g, page); + int rv; - return EVE_OK; + rv = eve_spacerw_init(_widget, &spec->g, page); + return rv; } uint8_t eve_spacerw_draw(EVEWidget *_widget, uint8_t tag0) { diff --git a/fw/fe310/eos/eve/widget/spacerw.h b/fw/fe310/eos/eve/widget/spacerw.h index 621b45b..ae97479 100644 --- a/fw/fe310/eos/eve/widget/spacerw.h +++ b/fw/fe310/eos/eve/widget/spacerw.h @@ -2,7 +2,7 @@ struct EVEWidgetSpec; -void eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page); +int eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page); int eve_spacerw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_spacerw_draw(EVEWidget *_widget, uint8_t tag0); diff --git a/fw/fe310/eos/eve/widget/strw.c b/fw/fe310/eos/eve/widget/strw.c index 6a2692b..847de49 100644 --- a/fw/fe310/eos/eve/widget/strw.c +++ b/fw/fe310/eos/eve/widget/strw.c @@ -12,7 +12,7 @@ #include "widget.h" -#define STRW_TOUCH_OPT EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_X | EVE_TOUCH_OPT_TRACK_EXT_X | EVE_TOUCH_OPT_LPRESS +#define STRW_TOUCH_OPT EVE_TOUCH_OPT_TRACK_X | EVE_TOUCH_OPT_TRACK_EXT_X | EVE_TOUCH_OPT_LPRESS #define STRW_TMODE_NONE 0 #define STRW_TMODE_CRSR 1 @@ -27,37 +27,33 @@ #define CHAR_VALID_INPUT(c) ((c >= 0x20) && (c < 0x7f)) -void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) { +int eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) { EVEWidget *_widget = &widget->w; size_t str_len; int str_w, rv; + rv = eve_font_verify(font, str, str_size, &str_w, &str_len); + if (rv) return rv; + memset(widget, 0, sizeof(EVEStrWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_STR, g, page, eve_strw_draw, eve_strw_touch, eve_strw_putc); - rv = utf8_verify(str, str_size, &str_len); - if (rv) str[str_len] = '\0'; - - rv = eve_font_verify(font, str, &str_w, &str_len); - if (rv) str[str_len] = '\0'; - widget->font = font; widget->str = str; widget->str_size = str_size; widget->str_len = str_len; widget->str_g.w = str_w; if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font); + + return EVE_OK; } int eve_strw_update(EVEStrWidget *widget) { size_t str_len; int str_w, rv; - rv = utf8_verify(widget->str, widget->str_size, &str_len); - if (rv) widget->str[str_len] = '\0'; - - rv = eve_font_verify(widget->font, widget->str, &str_w, &str_len); - if (rv) widget->str[str_len] = '\0'; + rv = eve_font_verify(widget->font, widget->str, widget->str_size, &str_w, &str_len); + if (rv) return rv; widget->str_len = str_len; widget->str_g.w = str_w; @@ -71,14 +67,15 @@ int eve_strw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); utf8_t *str; uint16_t *line; + int rv; str = eve_malloc(tspec->str_size); if (str == NULL) return EVE_ERR_NOMEM; str[0] = '\0'; - eve_strw_init(widget, &spec->g, page, font, str, tspec->str_size); - - return EVE_OK; + rv = eve_strw_init(widget, &spec->g, page, font, str, tspec->str_size); + if (rv) eve_free(str); + return rv; } void eve_strw_destroy(EVEWidget *_widget) { @@ -87,15 +84,20 @@ void eve_strw_destroy(EVEWidget *_widget) { eve_free(widget->str); } -static void show_rect(EVEStrWidget *widget) { +static void show_text(EVEStrWidget *widget, EVEStrCursor *cursor, int del_w) { EVEWidget *_widget = &widget->w; - EVERect focus; + int w0 = widget->font->w; + int w1 = _widget->g.w - widget->font->w; - focus.x = _widget->g.x; - focus.y = _widget->g.y; - focus.w = _widget->g.w; - focus.h = 2 * widget->font->h; - eve_page_show_rect(_widget->page, &focus); + if (del_w && (widget->str_g.w - widget->str_g.x < w1)) { + widget->str_g.x = (widget->str_g.x > del_w ? widget->str_g.x - del_w : 0); + } + if (cursor->x - widget->str_g.x < w0) { + widget->str_g.x = (cursor->x > w0 ? cursor->x - w0 : 0); + } + if (cursor->x - widget->str_g.x > w1) { + widget->str_g.x = cursor->x - w1; + } } static EVEStrCursor *cursor_prox(EVEStrWidget *widget, EVEStrCursor *cursor, EVETouch *touch, short *dx) { @@ -156,7 +158,7 @@ uint8_t eve_strw_draw(EVEWidget *_widget, uint8_t tag0) { _widget->tag0 = tag0; if (tag0 != EVE_NOTAG) { eve_cmd_dl(TAG(tag0)); - eve_touch_set_opt(tag0, STRW_TOUCH_OPT); + eve_tag_set_opt(tag0, STRW_TOUCH_OPT); tag0++; } _widget->tagN = tag0; @@ -228,7 +230,22 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEPage *page = _widget->page; EVEStrCursor *t_cursor = NULL; short dx; - int ret = 0; + int rv = 0; + + /* widget received non-touch event */ + if (evt & EVE_TOUCH_ETYPE_EXT) { + evt &= ~EVE_TOUCH_ETYPE_EXT; + switch (evt) { + case EVE_UIEVT_WIDGET_FOCUS_OUT: { + if (widget->cursor1.on) eve_strw_cursor_clear(widget, &widget->cursor1); + if (widget->cursor2.on) eve_strw_cursor_clear(widget, &widget->cursor2); + break; + } + } + + /* always return 0 for non-touch events */ + return 0; + } if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TRACK_START)) { if (widget->cursor2.on) { @@ -266,10 +283,11 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { case STRW_TMODE_CRSR: eve_strw_cursor_set(widget, widget->track.cursor, eve_page_x(page, touch->x) + widget->track.dx); + show_text(widget, widget->track.cursor, 0); break; } } - ret = 1; + rv = 1; } else { if (evt & EVE_TOUCH_ETYPE_LPRESS) { if (widget->cursor2.on) { @@ -283,13 +301,12 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { } else { // select } - ret = 1; + rv = 1; } - if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { + if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { eve_strw_cursor_set(widget, &widget->cursor1, eve_page_x(page, touch->x0)); if (widget->cursor2.on) eve_strw_cursor_clear(widget, &widget->cursor2); - show_rect(widget); - ret = 1; + rv = 1; } } @@ -299,7 +316,7 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { widget->track.dx = 0; } - return ret; + return rv; } void eve_strw_putc(void *w, int c) { @@ -309,19 +326,18 @@ void eve_strw_putc(void *w, int c) { EVEStrCursor *cursor2 = &widget->cursor2; utf8_t *str; utf8_t *clipb = NULL; - int w0 = widget->font->w; - int w1 = _widget->g.w - widget->font->w; int ins_c = 0, del_c = 0; int ins_w = 0, del_w = 0; - if (c == EVE_PAGE_KBDCH_CLOSE) { - if (cursor1->on) eve_strw_cursor_clear(widget, cursor1); - if (cursor2->on) eve_strw_cursor_clear(widget, cursor2); + if (!cursor1->on) return; + + if (c == '\n') { + EVEPage *page = _widget->page; + + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget); return; } - if (!cursor1->on) return; - if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) { ucp_t uc; @@ -349,10 +365,6 @@ void eve_strw_putc(void *w, int c) { } break; } - if (widget->str_g.w - widget->str_g.x < w1) { - widget->str_g.x -= del_w; - if (widget->str_g.x < 0) widget->str_g.x = 0; - } } else { EVEStrCursor *c1 = cursor1; EVEStrCursor *c2 = cursor1; @@ -387,9 +399,8 @@ void eve_strw_putc(void *w, int c) { clipb = eve_clipb_get(); if (clipb) { - rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len); - if (!rv) ins_w = eve_font_str_w(widget->font, clipb); - if (rv || (ins_w < 0)) { + rv = eve_font_verify(widget->font, clipb, EVE_CLIPB_SIZE_BUF, &ins_w, &clipb_len); + if (rv) { clipb = NULL; clipb_len = 0; ins_w = 0; @@ -419,8 +430,7 @@ void eve_strw_putc(void *w, int c) { if (cursor2->on) eve_strw_cursor_clear(widget, cursor2); } - if (cursor1->x - widget->str_g.x < w0) widget->str_g.x = cursor1->x > w0 ? cursor1->x - w0 : 0; - if (cursor1->x - widget->str_g.x > w1) widget->str_g.x = cursor1->x - w1; + show_text(widget, cursor1, del_w); } void eve_strw_cursor_set(EVEStrWidget *widget, EVEStrCursor *cursor, int16_t x) { diff --git a/fw/fe310/eos/eve/widget/strw.h b/fw/fe310/eos/eve/widget/strw.h index acfd74b..a2817d0 100644 --- a/fw/fe310/eos/eve/widget/strw.h +++ b/fw/fe310/eos/eve/widget/strw.h @@ -33,7 +33,7 @@ typedef struct EVEStrSpec { uint16_t str_size; } EVEStrSpec; -void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size); +int eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size); int eve_strw_update(EVEStrWidget *widget); int eve_strw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); diff --git a/fw/fe310/eos/eve/widget/textw.c b/fw/fe310/eos/eve/widget/textw.c index 7998e75..0a6a700 100644 --- a/fw/fe310/eos/eve/widget/textw.c +++ b/fw/fe310/eos/eve/widget/textw.c @@ -12,7 +12,7 @@ #include "widget.h" -#define TEXTW_TOUCH_OPT EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_XY | EVE_TOUCH_OPT_LPRESS +#define TEXTW_TOUCH_OPT EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_XY | EVE_TOUCH_OPT_LPRESS #define CH_BS 0x08 #define CH_DEL 0x7f @@ -30,20 +30,17 @@ #define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) -void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size) { +int eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size) { EVEWidget *_widget = &widget->w; size_t text_len; int rv; + rv = eve_font_verify(font, text, text_size, NULL, &text_len); + if (rv) return rv; + memset(widget, 0, sizeof(EVETextWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_TEXT, g, page, eve_textw_draw, eve_textw_touch, eve_textw_putc); - rv = utf8_verify(text, text_size, &text_len); - if (rv) text[text_len] = '\0'; - - rv = eve_font_verify(font, text, NULL, &text_len); - if (rv) text[text_len] = '\0'; - widget->font = font; widget->text = text; widget->text_size = text_size; @@ -52,17 +49,16 @@ void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *f widget->line_size = line_size; memset(widget->line, 0xff, line_size * sizeof(uint16_t)); eve_textw_text_update(widget, 0, 0); + + return EVE_OK; } int eve_textw_update(EVETextWidget *widget) { size_t text_len; int rv; - rv = utf8_verify(widget->text, widget->text_size, &text_len); - if (rv) widget->text[text_len] = '\0'; - - rv = eve_font_verify(widget->font, widget->text, NULL, &text_len); - if (rv) widget->text[text_len] = '\0'; + rv = eve_font_verify(widget->font, widget->text, widget->text_size, NULL, &text_len); + if (rv) return rv; widget->text_len = text_len; memset(widget->line, 0xff, widget->line_size * sizeof(uint16_t)); @@ -77,6 +73,7 @@ int eve_textw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); utf8_t *text; uint16_t *line; + int rv; text = eve_malloc(tspec->text_size); if (text == NULL) { @@ -89,9 +86,12 @@ int eve_textw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { return EVE_ERR_NOMEM; } - eve_textw_init(widget, &spec->g, page, font, text, tspec->text_size, line, tspec->line_size); - - return EVE_OK; + rv = eve_textw_init(widget, &spec->g, page, font, text, tspec->text_size, line, tspec->line_size); + if (rv) { + eve_free(line); + eve_free(text); + } + return rv; } void eve_textw_destroy(EVEWidget *_widget) { @@ -214,7 +214,7 @@ uint8_t eve_textw_draw(EVEWidget *_widget, uint8_t tag0) { for (i=line0; i<lineN; i++) { if (_widget->tagN != EVE_NOTAG) { eve_cmd_dl(TAG(_widget->tagN)); - eve_touch_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); + eve_tag_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); _widget->tagN++; } if (!s && c1 && (c1->line == i)) { @@ -257,7 +257,7 @@ uint8_t eve_textw_draw(EVEWidget *_widget, uint8_t tag0) { if (lineNvisible) { if (_widget->tagN != EVE_NOTAG) { eve_cmd_dl(TAG(_widget->tagN)); - eve_touch_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); + eve_tag_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); _widget->tagN++; } draw_line(widget, lineN, 0, 0, 0, _widget->g.w, 0); @@ -276,7 +276,27 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEPage *page = _widget->page; EVETextCursor *t_cursor = NULL; short dx, dl; - int ret = 0; + int rv = 0; + + /* widget received non-touch event */ + if (evt & EVE_TOUCH_ETYPE_EXT) { + evt &= ~EVE_TOUCH_ETYPE_EXT; + switch (evt) { + case EVE_UIEVT_WIDGET_FOCUS_IN: { + if (widget->cursor1.on) show_rect(widget, &widget->cursor1); + break; + } + + case EVE_UIEVT_WIDGET_FOCUS_OUT: { + if (widget->cursor1.on) eve_textw_cursor_clear(widget, &widget->cursor1); + if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2); + break; + } + } + + /* always return 0 for non-touch events */ + return 0; + } if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TRACK_START)) { if (widget->cursor2.on) { @@ -294,7 +314,7 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { if (widget->track.cursor) { if (evt & EVE_TOUCH_ETYPE_TRACK) eve_textw_cursor_set(widget, widget->track.cursor, touch->tag + widget->track.dl, eve_page_x(page, touch->x) + widget->track.dx); - ret = 1; + rv = 1; } else { if (evt & EVE_TOUCH_ETYPE_LPRESS) { if (widget->cursor2.on) { @@ -308,13 +328,12 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { } else { // select } - ret = 1; + rv = 1; } - if ((evt & EVE_TOUCH_ETYPE_TAG_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { + if ((evt & EVE_TOUCH_ETYPE_TAG_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { eve_textw_cursor_set(widget, &widget->cursor1, touch->tag_up, eve_page_x(page, touch->x0)); if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2); - show_rect(widget, &widget->cursor1); - ret = 1; + rv = 1; } } @@ -324,7 +343,7 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { widget->track.dl = 0; } - return ret; + return rv; } void eve_textw_putc(void *w, int c) { @@ -334,16 +353,10 @@ void eve_textw_putc(void *w, int c) { EVETextCursor *cursor2 = &widget->cursor2; utf8_t *text; utf8_t *clipb = NULL; - int i, r; + int i, line; int ins_c = 0, del_c = 0; int ch_w = 0; - if (c == EVE_PAGE_KBDCH_CLOSE) { - if (cursor1->on) eve_textw_cursor_clear(widget, cursor1); - if (cursor2->on) eve_textw_cursor_clear(widget, cursor2); - return; - } - if (!cursor1->on) return; if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) { @@ -401,9 +414,8 @@ void eve_textw_putc(void *w, int c) { clipb = eve_clipb_get(); if (clipb) { - rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len); - if (!rv) ch_w = eve_font_str_w(widget->font, clipb); - if (rv || (ch_w < 0)) { + rv = eve_font_verify(widget->font, clipb, EVE_CLIPB_SIZE_BUF, &ch_w, &clipb_len); + if (rv) { clipb = NULL; clipb_len = 0; ch_w = 0; @@ -437,9 +449,9 @@ void eve_textw_putc(void *w, int c) { widget->line[i] += ins_c - del_c; } - r = cursor1->line; - if (cursor1->line) r = eve_textw_text_update(widget, cursor1->line - 1, 1); - if (r == cursor1->line) eve_textw_text_update(widget, cursor1->line, 1); + line = cursor1->line; + if (cursor1->line) line = eve_textw_text_update(widget, cursor1->line - 1, 1); + if (line == cursor1->line) eve_textw_text_update(widget, cursor1->line, 1); if (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) { while (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) cursor1->line--; @@ -449,7 +461,7 @@ void eve_textw_putc(void *w, int c) { while ((cursor1->line != widget->line_len - 1) && (cursor1->ch > LINE_END(widget, cursor1->line))) cursor1->line++; eve_textw_cursor_update(widget, cursor1); show_rect(widget, cursor1); - } else if ((cursor1->line) && (r != cursor1->line)) { + } else if ((cursor1->line) && (line != cursor1->line)) { eve_textw_cursor_update(widget, cursor1); } else { cursor1->x += ch_w; diff --git a/fw/fe310/eos/eve/widget/textw.h b/fw/fe310/eos/eve/widget/textw.h index 0fb3505..d3d544b 100644 --- a/fw/fe310/eos/eve/widget/textw.h +++ b/fw/fe310/eos/eve/widget/textw.h @@ -34,7 +34,7 @@ typedef struct EVETextSpec { uint16_t line_size; } EVETextSpec; -void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size); +int eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size); int eve_textw_update(EVETextWidget *widget); int eve_textw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); diff --git a/fw/fe310/eos/eve/widget/togglew.c b/fw/fe310/eos/eve/widget/togglew.c index c68e191..06d5fc3 100644 --- a/fw/fe310/eos/eve/widget/togglew.c +++ b/fw/fe310/eos/eve/widget/togglew.c @@ -10,7 +10,7 @@ #include "widget.h" -void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels) { +int eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels) { EVEWidget *_widget = &widget->w; memset(widget, 0, sizeof(EVEToggleWidget)); @@ -18,16 +18,18 @@ void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFon widget->font = font; widget->labels = labels; if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font); + + return EVE_OK; } int eve_togglew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEToggleWidget *widget = (EVEToggleWidget *)_widget; EVEToggleSpec *tspec = &spec->tspec.toggle; EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); + int rv; - eve_togglew_init(widget, &spec->g, page, font, tspec->labels); - - return EVE_OK; + rv = eve_togglew_init(widget, &spec->g, page, font, tspec->labels); + return rv; } uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0) { @@ -46,23 +48,30 @@ uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0) { int eve_togglew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEToggleWidget *widget = (EVEToggleWidget *)_widget; + EVEPage *page = _widget->page; + + /* widget received non-touch event, always return 0 */ + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; if (evt & EVE_TOUCH_ETYPE_TAG_UP) { widget->state = !widget->state; + + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget); + return 1; } return 0; } +uint8_t eve_togglew_get(EVEToggleWidget *widget) { + return widget->state; +} + void eve_togglew_set(EVEToggleWidget *widget) { widget->state = 1; } -void eve_togglew_clr(EVEToggleWidget *widget) { +void eve_togglew_clear(EVEToggleWidget *widget) { widget->state = 0; } - -uint8_t eve_togglew_get(EVEToggleWidget *widget) { - return widget->state; -}
\ No newline at end of file diff --git a/fw/fe310/eos/eve/widget/togglew.h b/fw/fe310/eos/eve/widget/togglew.h index aa5485d..af37672 100644 --- a/fw/fe310/eos/eve/widget/togglew.h +++ b/fw/fe310/eos/eve/widget/togglew.h @@ -17,12 +17,12 @@ typedef struct EVEToggleSpec { uint8_t state; } EVEToggleSpec; -void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels); +int eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels); int eve_togglew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0); int eve_togglew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt); +uint8_t eve_togglew_get(EVEToggleWidget *widget); void eve_togglew_set(EVEToggleWidget *widget); -void eve_togglew_clr(EVEToggleWidget *widget); -uint8_t eve_togglew_get(EVEToggleWidget *widget);
\ No newline at end of file +void eve_togglew_clear(EVEToggleWidget *widget); diff --git a/fw/fe310/eos/eve/widget/widget.c b/fw/fe310/eos/eve/widget/widget.c index 88b90a9..8b0a2e4 100644 --- a/fw/fe310/eos/eve/widget/widget.c +++ b/fw/fe310/eos/eve/widget/widget.c @@ -49,16 +49,10 @@ void eve_widget_destroy(EVEWidget *widget) { if (_eve_widget_destroy[widget->type]) _eve_widget_destroy[widget->type](widget); } -void eve_widget_set_focus(EVEWidget *widget) { - EVEPage *page = widget->page; - - eve_page_set_focus(page, widget); -} - void eve_widget_set_flags(EVEWidget *widget, uint8_t flags) { widget->flags |= flags; } -void eve_widget_clr_flags(EVEWidget *widget, uint8_t flags) { +void eve_widget_clear_flags(EVEWidget *widget, uint8_t flags) { widget->flags &= ~flags; } diff --git a/fw/fe310/eos/eve/widget/widget.h b/fw/fe310/eos/eve/widget/widget.h index a565b53..e7ab2f2 100644 --- a/fw/fe310/eos/eve/widget/widget.h +++ b/fw/fe310/eos/eve/widget/widget.h @@ -45,6 +45,5 @@ size_t eve_widget_size(uint8_t type); void eve_widget_set_label(EVEWidget *widget, EVELabel *label); EVEWidget *eve_widget_next(EVEWidget *widget); -void eve_widget_set_focus(EVEWidget *widget); void eve_widget_set_flags(EVEWidget *widget, uint8_t flags); -void eve_widget_clr_flags(EVEWidget *widget, uint8_t flags);
\ No newline at end of file +void eve_widget_clear_flags(EVEWidget *widget, uint8_t flags);
\ No newline at end of file diff --git a/fw/fe310/eos/event.c b/fw/fe310/eos/event.c index f76384a..1af51da 100644 --- a/fw/fe310/eos/event.c +++ b/fw/fe310/eos/event.c @@ -1,102 +1,100 @@ #include <stdlib.h> #include <stdint.h> #include <unistd.h> -#include <stdio.h> #include "encoding.h" #include "platform.h" #include "eos.h" -#include "msgq.h" +#include "log.h" + #include "event.h" EOSMsgQ _eos_event_q; static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q]; -static eos_evt_handler_t evt_handler[EOS_EVT_MAX_EVT + 1]; +static eos_evt_handler_t evt_handler[EOS_EVT_MAX]; +static eos_evt_handler_global_t evt_handler_global; +static eos_evt_loopf_t evt_loop_f; -static void evtq_handler(unsigned char type, unsigned char *buffer, uint16_t len) { +static void evtq_handler(unsigned char type, EOSMessage *msg, uint16_t len, uint8_t _idx) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; - if (idx && (idx <= EOS_EVT_MAX_EVT)) { - evt_handler[idx](type, buffer, len); + if (idx && (idx <= EOS_EVT_MAX)) { + evt_handler[idx - 1](type, msg, len); } else { - eos_evtq_bad_handler(type, buffer, len); + eos_evtq_bad_handler(type, msg, len); } } -int eos_evtq_init(uint8_t wakeup_cause) { +int eos_evtq_init(void) { int i; - evt_handler[0] = evtq_handler; - for (i=0; i<EOS_EVT_MAX_EVT; i++) { - evt_handler[i + 1] = eos_evtq_bad_handler; + evt_handler_global = evtq_handler; + for (i=0; i<EOS_EVT_MAX; i++) { + evt_handler[i] = eos_evtq_bad_handler; } eos_msgq_init(&_eos_event_q, event_q_array, EOS_EVT_SIZE_Q); return EOS_OK; } -int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len) { +int eos_evtq_len(void) { + int rv; + clear_csr(mstatus, MSTATUS_MIE); - int ret = eos_msgq_push(&_eos_event_q, type, buffer, len); + rv = eos_msgq_len(&_eos_event_q); set_csr(mstatus, MSTATUS_MIE); - return ret; + + return rv; } -int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len) { - return eos_msgq_push(&_eos_event_q, type, buffer, len); +int eos_evtq_push(unsigned char type, EOSMessage *msg, uint16_t len) { + int rv; + + clear_csr(mstatus, MSTATUS_MIE); + rv = eos_msgq_push(&_eos_event_q, type, msg, len); + set_csr(mstatus, MSTATUS_MIE); + + return rv; } -void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len) { +int eos_evtq_push_widx(unsigned char type, EOSMessage *msg, uint16_t len, uint8_t *idx) { + int rv; + clear_csr(mstatus, MSTATUS_MIE); - eos_msgq_pop(&_eos_event_q, type, buffer, len); + rv = eos_msgq_push_widx(&_eos_event_q, type, msg, len, idx); set_csr(mstatus, MSTATUS_MIE); + + return rv; } -void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len) { - eos_msgq_pop(&_eos_event_q, type, buffer, len); +int eos_evtq_push_isr(unsigned char type, EOSMessage *msg, uint16_t len) { + return eos_msgq_push(&_eos_event_q, type, msg, len); } -int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len) { - int rv = 0; +int eos_evtq_push_widx_isr(unsigned char type, EOSMessage *msg, uint16_t len, uint8_t *idx) { + return eos_msgq_push_widx(&_eos_event_q, type, msg, len, idx); +} +void eos_evtq_pop(unsigned char *type, EOSMessage *msg, uint16_t *len) { clear_csr(mstatus, MSTATUS_MIE); - rv = eos_msgq_find(&_eos_event_q, type, NULL, 0, buffer, len); + eos_msgq_pop(&_eos_event_q, type, msg, len); set_csr(mstatus, MSTATUS_MIE); } -int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { - int rv = 0; - +void eos_evtq_pop_widx(unsigned char *type, EOSMessage *msg, uint16_t *len, uint8_t *idx) { clear_csr(mstatus, MSTATUS_MIE); - rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len); + eos_msgq_pop_widx(&_eos_event_q, type, msg, len, idx); set_csr(mstatus, MSTATUS_MIE); } -void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { - int rv = 0; - - while(!rv) { - clear_csr(mstatus, MSTATUS_MIE); - rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len); - if (!rv) { - unsigned char _type; - unsigned char *_buffer; - uint16_t _len; - - eos_msgq_pop(&_eos_event_q, &_type, &_buffer, &_len); - if (_type) { - set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](_type, _buffer, _len); - } else { - asm volatile ("wfi"); - set_csr(mstatus, MSTATUS_MIE); - } - } else { - set_csr(mstatus, MSTATUS_MIE); - } - } +void eos_evtq_pop_isr(unsigned char *type, EOSMessage *msg, uint16_t *len) { + eos_msgq_pop(&_eos_event_q, type, msg, len); +} + +void eos_evtq_pop_widx_isr(unsigned char *type, EOSMessage *msg, uint16_t *len, uint8_t *idx) { + eos_msgq_pop_widx(&_eos_event_q, type, msg, len, idx); } void eos_evtq_flush(void) { @@ -107,14 +105,15 @@ void eos_evtq_flush(void) { void eos_evtq_flush_isr(void) { unsigned char type; - unsigned char *buffer; + EOSMessage msg; uint16_t len; + uint8_t idx; do { - eos_msgq_pop(&_eos_event_q, &type, &buffer, &len); + eos_msgq_pop_widx(&_eos_event_q, &type, &msg, &len, &idx); if (type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](type, buffer, len); + evt_handler_global(type, &msg, len, idx); clear_csr(mstatus, MSTATUS_MIE); } } while (type); @@ -125,40 +124,53 @@ void eos_evtq_loop(void) { while(foo) { eos_evtq_exec(); + if (evt_loop_f) evt_loop_f(); } } void eos_evtq_exec(void) { unsigned char type; - unsigned char *buffer; + EOSMessage msg; uint16_t len; + uint8_t idx; clear_csr(mstatus, MSTATUS_MIE); - eos_msgq_pop(&_eos_event_q, &type, &buffer, &len); + eos_msgq_pop_widx(&_eos_event_q, &type, &msg, &len, &idx); if (type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](type, buffer, len); + evt_handler_global(type, &msg, len, idx); } else { asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); } +} +void eos_evtq_set_loopf(eos_evt_loopf_t loop_f) { + evt_loop_f = loop_f; } -void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) { - printf("EVT BAD HANDLER:0x%x\n", type); +void eos_evtq_bad_handler(unsigned char type, EOSMessage *msg, uint16_t len) { + EOS_LOG(EOS_LOG_ERR, "EVT BAD HANDLER:0x%.2X\n", type); } void eos_evtq_set_handler(unsigned char type, eos_evt_handler_t handler) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; if (handler == NULL) handler = eos_evtq_bad_handler; - if (idx <= EOS_EVT_MAX_EVT) evt_handler[idx] = handler; + if (idx && (idx <= EOS_EVT_MAX)) evt_handler[idx - 1] = handler; } eos_evt_handler_t eos_evtq_get_handler(unsigned char type) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; - if (idx <= EOS_EVT_MAX_EVT) return evt_handler[idx]; + if (idx && (idx <= EOS_EVT_MAX)) return evt_handler[idx - 1]; return NULL; } + +void eos_evtq_set_handler_global(eos_evt_handler_global_t handler) { + evt_handler_global = handler; +} + +eos_evt_handler_global_t eos_evtq_get_handler_global(void) { + return evt_handler_global; +} diff --git a/fw/fe310/eos/event.h b/fw/fe310/eos/event.h index 9501a15..df2f546 100644 --- a/fw/fe310/eos/event.h +++ b/fw/fe310/eos/event.h @@ -1,22 +1,35 @@ #include <stdint.h> #include "evt_def.h" +#include "msgq.h" -typedef void (*eos_evt_handler_t) (unsigned char, unsigned char *, uint16_t); +typedef void (*eos_evt_handler_t) (unsigned char, EOSMessage *, uint16_t); +typedef void (*eos_evt_handler_global_t) (unsigned char, EOSMessage *, uint16_t, uint8_t); +typedef void (*eos_evt_simple_handler_t) (unsigned char); + +typedef void (*eos_evt_loopf_t) (void); + +int eos_evtq_init(void); +int eos_evtq_len(void); + +int eos_evtq_push(unsigned char type, EOSMessage *msg, uint16_t len); +int eos_evtq_push_widx(unsigned char type, EOSMessage *msg, uint16_t len, uint8_t *idx); +int eos_evtq_push_isr(unsigned char type, EOSMessage *msg, uint16_t len); +int eos_evtq_push_widx_isr(unsigned char type, EOSMessage *msg, uint16_t len, uint8_t *idx); + +void eos_evtq_pop(unsigned char *type, EOSMessage *msg, uint16_t *len); +void eos_evtq_pop_widx(unsigned char *type, EOSMessage *msg, uint16_t *len, uint8_t *idx) ; +void eos_evtq_pop_isr(unsigned char *type, EOSMessage *msg, uint16_t *len); +void eos_evtq_pop_widx_isr(unsigned char *type, EOSMessage *msg, uint16_t *len, uint8_t *idx); -int eos_evtq_init(uint8_t wakeup_cause); -int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len); -int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len); -void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len); -void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len); -int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len); -int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); -void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); void eos_evtq_flush(void); void eos_evtq_flush_isr(void); void eos_evtq_loop(void); void eos_evtq_exec(void); +void eos_evtq_set_loopf(eos_evt_loopf_t loop_f); -void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len); +void eos_evtq_bad_handler(unsigned char type, EOSMessage *msg, uint16_t len); void eos_evtq_set_handler(unsigned char type, eos_evt_handler_t handler); eos_evt_handler_t eos_evtq_get_handler(unsigned char type); +void eos_evtq_set_handler_global(eos_evt_handler_global_t handler); +eos_evt_handler_global_t eos_evtq_get_handler_global(void); diff --git a/fw/fe310/eos/evt_def.h b/fw/fe310/eos/evt_def.h index e34b2d2..0105457 100644 --- a/fw/fe310/eos/evt_def.h +++ b/fw/fe310/eos/evt_def.h @@ -3,11 +3,11 @@ #define EOS_EVT_NET 0x30 #define EOS_EVT_SPI 0x40 #define EOS_EVT_UART 0x50 -#define EOS_EVT_EVE 0x60 -#define EOS_EVT_CTP 0x70 -#define EOS_EVT_USER 0x80 +#define EOS_EVT_EGPIO 0x60 +#define EOS_EVT_USER 0x70 +#define EOS_EVT_USER1 0x80 -#define EOS_EVT_MAX_EVT 8 +#define EOS_EVT_MAX 8 #define EOS_EVT_MASK 0xF0 #define EOS_EVT_SIZE_Q 4 diff --git a/fw/fe310/eos/irq_def.h b/fw/fe310/eos/irq_def.h index fc16489..62a2b90 100644 --- a/fw/fe310/eos/irq_def.h +++ b/fw/fe310/eos/irq_def.h @@ -1,8 +1,7 @@ -#define IRQ_PRIORITY_I2S_SD 7 - -#define IRQ_PRIORITY_EVE 5 -#define IRQ_PRIORITY_CTP 5 +#define IRQ_PRIORITY_I2S 7 +#define IRQ_PRIORITY_CTP 6 +#define IRQ_PRIORITY_EGPIO 5 #define IRQ_PRIORITY_SPI_XCHG 5 #define IRQ_PRIORITY_NET_CTS 4 diff --git a/fw/fe310/eos/log.h b/fw/fe310/eos/log.h new file mode 100644 index 0000000..be9b024 --- /dev/null +++ b/fw/fe310/eos/log.h @@ -0,0 +1,15 @@ +#include <stdio.h> + +#define EOS_LOG_DEBUG 1 +#define EOS_LOG_INFO 2 +#define EOS_LOG_ERR 3 + +#define EOS_LOG_NONE 255 + +#ifdef EOS_DEBUG +#define EOS_LOG_LEVEL EOS_LOG_DEBUG +#else +#define EOS_LOG_LEVEL EOS_LOG_NONE +#endif + +#define EOS_LOG(l, ...) ((l) >= EOS_LOG_LEVEL ? printf(__VA_ARGS__) : 0 ) diff --git a/fw/fe310/eos/msgq.c b/fw/fe310/eos/msgq.c index a483a58..8964046 100644 --- a/fw/fe310/eos/msgq.c +++ b/fw/fe310/eos/msgq.c @@ -3,13 +3,19 @@ #include <string.h> #include "eos.h" -#include "msgq.h" + +#include "event.h" #define IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) #define IDX_HALF ((uint8_t)1 << (sizeof(uint8_t) * 8 - 1)) #define IDX_LT(a,b) ((uint8_t)((uint8_t)(a) - (uint8_t)(b)) > IDX_HALF) #define IDX_LTE(a,b) ((uint8_t)((uint8_t)(b) - (uint8_t)(a)) < IDX_HALF) +void eos_msg_init(EOSMessage *msg, unsigned char *buffer, uint16_t size) { + msg->buffer = buffer; + msg->size = size; +} + void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->idx_r = 0; msgq->idx_w = 0; @@ -17,86 +23,58 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->array = array; } -int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) { +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, EOSMessage *msg, uint16_t len) { + return eos_msgq_push_widx(msgq, type, msg, len, NULL); +} + +int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, EOSMessage *msg, uint16_t len, uint8_t *_idx) { + uint8_t idx; + if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL; - uint8_t idx = IDX_MASK(msgq->idx_w, msgq->size); + idx = IDX_MASK(msgq->idx_w, msgq->size); msgq->array[idx].type = type; - msgq->array[idx].buffer = buffer; - msgq->array[idx].len = len; + if (msg) { + msgq->array[idx].buffer = msg->buffer; + msgq->array[idx].size = msg->size; + msgq->array[idx].len = len; + } else { + msgq->array[idx].buffer = NULL; + msgq->array[idx].size = 0; + msgq->array[idx].len = 0; + } msgq->idx_w++; + if (_idx) *_idx = idx; + return EOS_OK; } -void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len) { +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len) { + eos_msgq_pop_widx(msgq, type, msg, len, NULL); +} + +void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len, uint8_t *_idx) { if (msgq->idx_r == msgq->idx_w) { *type = 0; - *buffer = NULL; + msg->buffer = NULL; + msg->size = 0; *len = 0; } else { uint8_t idx = IDX_MASK(msgq->idx_r, msgq->size); + *type = msgq->array[idx].type; - *buffer = msgq->array[idx].buffer; + msg->buffer = msgq->array[idx].buffer; + msg->size = msgq->array[idx].size; *len = msgq->array[idx].len; msgq->idx_r++; + if (_idx) *_idx = idx; } } -int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { - uint8_t i, j, idx; - unsigned char *_buffer; - uint16_t _len; - - if (msgq->idx_r == msgq->idx_w) { - if (buffer && len) { - *buffer = NULL; - *len = 0; - } - return 0; - } - - idx = IDX_MASK(msgq->idx_r, msgq->size); - if (type == msgq->array[idx].type) { - _buffer = msgq->array[idx].buffer; - _len = msgq->array[idx].len; - if ((selector == NULL) || (sel_len == 0) || ((sel_len <= _len) && (memcmp(selector, _buffer, sel_len) == 0))) { - msgq->idx_r++; - if (buffer && len) { - *buffer = _buffer; - *len = _len; - } - return 1; - } - } - for (i = msgq->idx_r + 1; IDX_LT(i, msgq->idx_w); i++) { - idx = IDX_MASK(i, msgq->size); - if (type== msgq->array[idx].type) { - _buffer = msgq->array[idx].buffer; - _len = msgq->array[idx].len; - if ((selector == NULL) || (sel_len == 0) || ((sel_len <= _len) && (memcmp(selector, _buffer, sel_len) == 0))) { - for (j = i + 1; IDX_LT(j, msgq->idx_w); j++) { - msgq->array[IDX_MASK(j - 1, msgq->size)] = msgq->array[IDX_MASK(j, msgq->size)]; - } - msgq->idx_w--; - if (buffer && len) { - *buffer = _buffer; - *len = _len; - } - return 1; - } - } - } - if (buffer && len) { - *buffer = NULL; - *len = 0; - } - return 0; -} - -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; @@ -104,6 +82,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; @@ -116,7 +98,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/fe310/eos/msgq.h b/fw/fe310/eos/msgq.h index 7e3b5e5..3a4084c 100644 --- a/fw/fe310/eos/msgq.h +++ b/fw/fe310/eos/msgq.h @@ -1,8 +1,19 @@ #include <stdint.h> +#ifndef _EOS_MSGQ_H_ +#define _EOS_MSGQ_H_ + +typedef struct EOSMessage { + unsigned char *buffer; + uint16_t size; +} EOSMessage; + +void eos_msg_init(EOSMessage *msg, unsigned char *buffer, uint16_t size); + typedef struct EOSMsgItem { unsigned char type; unsigned char *buffer; + uint16_t size; uint16_t len; } EOSMsgItem; @@ -14,10 +25,11 @@ typedef struct EOSMsgQ { } EOSMsgQ; void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); -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); -int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); uint8_t eos_msgq_len(EOSMsgQ *msgq); +int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, EOSMessage *msg, uint16_t len); +int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, EOSMessage *msg, uint16_t len, uint8_t *_idx); +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len); +void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len, uint8_t *_idx); typedef struct EOSBufQ { uint8_t idx_r; @@ -27,6 +39,8 @@ 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); + +#endif /* _EOS_MSGQ_H_ */ diff --git a/fw/fe310/eos/msgq_priv.h b/fw/fe310/eos/msgq_priv.h index 2ad5fc5..bce7d3c 100644 --- a/fw/fe310/eos/msgq_priv.h +++ b/fw/fe310/eos/msgq_priv.h @@ -7,4 +7,5 @@ #define MSGQ_ITEM_OFF_TYPE 0 #define MSGQ_ITEM_OFF_BUF 4 #define MSGQ_ITEM_OFF_SIZE 8 +#define MSGQ_ITEM_OFF_LEN 10 #define MSGQ_ITEM_SIZE 12 diff --git a/fw/fe310/eos/net/Makefile b/fw/fe310/eos/net/Makefile index fc65454..d743a54 100644 --- a/fw/fe310/eos/net/Makefile +++ b/fw/fe310/eos/net/Makefile @@ -1,6 +1,6 @@ include ../../common.mk -obj = rng.o pwr.o wifi.o sock.o cell.o +obj = rng.o wifi.o cell.o sock.o lib = ../../libeos-net.a diff --git a/fw/fe310/eos/net/cell.c b/fw/fe310/eos/net/cell.c index 96216ba..aa1200d 100644 --- a/fw/fe310/eos/net/cell.c +++ b/fw/fe310/eos/net/cell.c @@ -10,21 +10,21 @@ static eos_evt_handler_t evt_handler[EOS_CELL_MAX_MTYPE]; -static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { +static void cell_handle_msg(unsigned char type, EOSMessage *msg, uint16_t len) { unsigned char mtype; unsigned char idx; - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); + if ((msg == NULL) || (len < 1)) { + eos_net_bad_handler(type, msg, len); return; } - mtype = buffer[0]; + mtype = msg->buffer[0]; idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4; if ((idx < EOS_CELL_MAX_MTYPE) && evt_handler[idx]) { - evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, buffer, len); + evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, msg, len); } else { - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, msg, len); } } @@ -50,12 +50,9 @@ eos_evt_handler_t eos_cell_get_handler(unsigned char mtype) { return NULL; } -int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync) { - buffer -= offset; - return eos_net_send_async(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, 1); -} +int eos_cell_status_parse(EOSMessage *msg, uint16_t len, uint8_t *status, uint8_t *connected) { + unsigned char *buffer = msg->buffer; -int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected) { if (len < 2) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET; @@ -75,127 +72,110 @@ int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, return EOS_OK; } -int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) { +int eos_cell_status(uint8_t *status, uint8_t *connected, EOSMessage *msg) { unsigned char type; uint16_t len; - int do_release; int rv; - do_release = 0; - if (buffer == NULL) { - buffer = eos_net_alloc(); - do_release = 1; - } + if (msg->size < 1) return EOS_ERR_SIZE; type = EOS_NET_MTYPE_CELL; len = 1; - buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; + msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; - rv = eos_net_xchg(&type, buffer, &len); - if (rv) goto cell_status_fin; + rv = eos_net_xchg(&type, msg, &len); + if (rv) return rv; - if (type != EOS_NET_MTYPE_CELL) { - rv = EOS_ERR_NET; - goto cell_status_fin; - } + if (type != EOS_NET_MTYPE_CELL) return EOS_ERR_NET; - rv = eos_cell_status_parse(buffer, len, status, connected); + return eos_cell_status_parse(msg, len, status, connected); +} + +int eos_cell_uart_take(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; -cell_status_fin: - if (do_release) eos_net_free(buffer, 1); - return rv; + msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_TAKE; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } -int eos_cell_uart_take(unsigned char *buffer, int sync) { - int async; +int eos_cell_uart_give(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_TAKE; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); + msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_GIVE; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } -int eos_cell_uart_give(unsigned char *buffer, int sync) { - int async; +unsigned char *eos_cell_uart_msg2data(EOSMessage *msg, uint16_t *len, uint16_t *size) { + if (len && (*len < 1)) return NULL; + if (msg->size < 1) return NULL; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_GIVE; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); + if (len && (msg->buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA))) return NULL; + + if (len) *len -= 1; + if (size) *size = msg->size - 1; + return msg->buffer + 1; } -unsigned char *eos_cell_uart_data_buffer(uint16_t *offset) { - unsigned char *buffer; +int eos_cell_uart_send(EOSMessage *msg, uint16_t len) { + msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, len + 1); +} - buffer = eos_net_alloc(); - buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; - *offset = 1; - return buffer + *offset; +int eos_cell_uart_send_async(EOSMessage *msg, uint16_t len, int more) { + msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; + return eos_net_send(EOS_NET_MTYPE_CELL, msg, len + 1, more); } -int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync) { +int eos_cell_voice_dial(char *num, EOSMessage *msg) { int async; size_t num_len; num_len = strlen(num); if (num_len > EOS_CELL_SIZE_PHNUM) return EOS_ERR_SIZE; + if (msg->size < 1 + num_len) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_DIAL; - memcpy(buffer + 1, num, num_len); - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1 + num_len, async, 1); + msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_DIAL; + memcpy(msg->buffer + 1, num, num_len); + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1 + num_len); } -int eos_cell_voice_answer(unsigned char *buffer, int sync) { - int async; +int eos_cell_voice_answer(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_ANSWER; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); + msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_ANSWER; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } -int eos_cell_voice_hangup(unsigned char *buffer, int sync) { - int async; +int eos_cell_voice_hangup(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_HANGUP; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); + msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_HANGUP; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } -unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) { - unsigned char *buffer; +unsigned char *eos_cell_voice_msg2pcm(EOSMessage *msg, uint16_t *len, uint16_t *size) { + if (len && (*len < 1)) return NULL; + if (msg->size < 1) return NULL; + + if (len && (msg->buffer[0] != (EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM))) return NULL; - buffer = eos_net_alloc(); - buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; - *offset = 1; - return buffer + *offset; + if (len) *len -= 1; + if (size) *size = msg->size - 1; + return msg->buffer + 1; } -int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) { - int async; +int eos_cell_voice_pcm_send(EOSMessage *msg, uint16_t len) { + msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, len + 1); +} + +int eos_cell_voice_pcm_send_async(EOSMessage *msg, uint16_t len, int more) { + msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; + return eos_net_send(EOS_NET_MTYPE_CELL, msg, len + 1, more); +} + +int eos_cell_sms_send(char *addr, char *txt, EOSMessage *msg) { + unsigned char *buffer = msg->buffer; size_t addr_len, txt_len; uint16_t len; @@ -203,13 +183,8 @@ int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) { txt_len = strlen(txt); if (addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE; if (txt_len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; + if (msg->size < 5) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; buffer[1] = 0; buffer[2] = 0; @@ -221,15 +196,25 @@ int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) { buffer[3] = EOS_CELL_SMS_ADDRTYPE_OTHER; } buffer[4] = addr_len; + + buffer += 5; len = 5; - memcpy(buffer + len, addr, addr_len); + + if (msg->size < 5 + addr_len + txt_len) return EOS_ERR_SIZE; + + memcpy(buffer, addr, addr_len); + buffer += addr_len; len += addr_len; - memcpy(buffer + len, txt, txt_len); + + memcpy(buffer, txt, txt_len); + buffer += txt_len; len += txt_len; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, len, async, 1); + + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, len); } -int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) { +int _eos_cell_sms_parse(EOSMessage *msg, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) { + unsigned char *buffer = msg->buffer; uint16_t _addr_len; if (len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE; @@ -257,13 +242,14 @@ int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16 return EOS_OK; } -int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) { +int eos_cell_sms_parse(EOSMessage *msg, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) { char *_addr, *_txt; uint16_t _addr_len, _txt_len; int rv; - rv = _eos_cell_sms_parse(buffer, len, &_addr, &_addr_len, &_txt, &_txt_len); + rv = _eos_cell_sms_parse(msg, len, &_addr, &_addr_len, &_txt, &_txt_len); if (rv) return rv; + if (addr_size < _addr_len + 1) return EOS_ERR_SIZE; if (txt_size < _txt_len + 1) return EOS_ERR_SIZE; memcpy(addr, _addr, _addr_len); @@ -274,107 +260,89 @@ int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t return EOS_OK; } -int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer) { +char *eos_cell_sms_msg2txt(EOSMessage *msg, uint16_t *len) { + char *txt; + uint16_t txt_len; + int rv; + + rv = _eos_cell_sms_parse(msg, *len, NULL, NULL, &txt, &txt_len); + if (rv) return NULL; + + *len = txt_len; + return txt; +} + +int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, EOSMessage *msg) { unsigned char type; uint16_t len; - int do_release; int rv; - do_release = 0; - if (buffer == NULL) { - buffer = eos_net_alloc(); - do_release = 1; - } + if (msg->size < 1) return EOS_ERR_SIZE; type = EOS_NET_MTYPE_CELL; len = 1; - buffer[0] = EOS_CELL_MTYPE_PDP | atype; + msg->buffer[0] = EOS_CELL_MTYPE_PDP | atype; - rv = eos_net_xchg(&type, buffer, &len); - if (rv) goto cell_pdp_get_fin; + rv = eos_net_xchg(&type, msg, &len); + if (rv) return rv; - if ((type != EOS_NET_MTYPE_CELL) || (len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) { - rv = EOS_ERR_NET; - goto cell_pdp_get_fin; - } + if ((type != EOS_NET_MTYPE_CELL) || (len < 1) || (msg->buffer[0] != EOS_CELL_MTYPE_PDP | atype)) return EOS_ERR_NET; len--; - if ((len > EOS_CELL_PDP_SIZE_ARG) || (len > arg_size - 1)) { - rv = EOS_ERR_SIZE; - goto cell_pdp_get_fin; - } - memcpy(buffer + 1, arg, len); + if ((len > EOS_CELL_PDP_SIZE_ARG) || (len > arg_size - 1)) return EOS_ERR_SIZE; + + memcpy(msg->buffer + 1, arg, len); arg[len] = '\0'; -cell_pdp_get_fin: - if (do_release) eos_net_free(buffer, 1); - return rv; + return EOS_OK; } -int eos_cell_pdp_set(unsigned char atype, char *arg, unsigned char *buffer, int sync) { - int async; +int eos_cell_pdp_set(unsigned char atype, char *arg, EOSMessage *msg) { size_t arg_len; arg_len = strlen(arg); if (arg_len > EOS_CELL_PDP_SIZE_ARG) return EOS_ERR_SIZE; + if (msg->size < 1 + arg_len) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_PDP | atype; - memcpy(buffer + 1, arg, arg_len); - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1 + arg_len, async, 1); + msg->buffer[0] = EOS_CELL_MTYPE_PDP | atype; + memcpy(msg->buffer + 1, arg, arg_len); + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1 + arg_len); } -int eos_cell_pdp_get_apn(char *apn, uint16_t apn_size, unsigned char *buffer) { - return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_APN, apn, apn_size, buffer); +int eos_cell_pdp_get_apn(char *apn, uint16_t apn_size, EOSMessage *msg) { + return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_APN, apn, apn_size, msg); } -int eos_cell_pdp_set_apn(char *apn, unsigned char *buffer, int sync) { - return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_APN, apn, buffer, sync); +int eos_cell_pdp_set_apn(char *apn, EOSMessage *msg) { + return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_APN, apn, msg); } -int eos_cell_pdp_get_usr(char *usr, uint16_t usr_size, unsigned char *buffer) { - return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_USR, usr, usr_size, buffer); +int eos_cell_pdp_get_usr(char *usr, uint16_t usr_size, EOSMessage *msg) { + return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_USR, usr, usr_size, msg); } -int eos_cell_pdp_set_usr(char *usr, unsigned char *buffer, int sync) { - return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_USR, usr, buffer, sync); +int eos_cell_pdp_set_usr(char *usr, EOSMessage *msg) { + return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_USR, usr, msg); } -int eos_cell_pdp_get_pwd(char *pwd, uint16_t pwd_size, unsigned char *buffer) { - return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_PWD, pwd, pwd_size, buffer); +int eos_cell_pdp_get_pwd(char *pwd, uint16_t pwd_size, EOSMessage *msg) { + return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_PWD, pwd, pwd_size, msg); } -int eos_cell_pdp_set_pwd(char *pwd, unsigned char *buffer, int sync) { - return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_PWD, pwd, buffer, sync); +int eos_cell_pdp_set_pwd(char *pwd, EOSMessage *msg) { + return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_PWD, pwd, msg); } -int eos_cell_pdp_connect(unsigned char *buffer, int sync) { - int async; +int eos_cell_pdp_connect(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_CONNECT; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); + msg->buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_CONNECT; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } -int eos_cell_pdp_disconnect(unsigned char *buffer, int sync) { - int async; +int eos_cell_pdp_disconnect(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_DISCONNECT; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); + msg->buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_DISCONNECT; + return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } diff --git a/fw/fe310/eos/net/cell.h b/fw/fe310/eos/net/cell.h index ac334e9..9517d8e 100644 --- a/fw/fe310/eos/net/cell.h +++ b/fw/fe310/eos/net/cell.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_CELL_MTYPE_DEV 0x10 @@ -27,7 +28,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 @@ -71,30 +71,35 @@ void eos_cell_init(void); void eos_cell_set_handler(unsigned char mtype, eos_evt_handler_t handler); eos_evt_handler_t eos_cell_get_handler(unsigned char mtype); -int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync); - -int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected); -int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer); - -int eos_cell_uart_take(unsigned char *buffer, int sync); -int eos_cell_uart_give(unsigned char *buffer, int sync); -unsigned char *eos_cell_uart_data_buffer(uint16_t *offset); - -int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync); -int eos_cell_voice_answer(unsigned char *buffer, int sync); -int eos_cell_voice_hangup(unsigned char *buffer, int sync); -unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset); -int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync); -int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len); -int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size); - -int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer); -int eos_cell_pdp_set(unsigned char atype, char *arg, unsigned char *buffer, int sync); -int eos_cell_pdp_get_apn(char *apn, uint16_t apn_size, unsigned char *buffer); -int eos_cell_pdp_set_apn(char *apn, unsigned char *buffer, int sync); -int eos_cell_pdp_get_usr(char *usr, uint16_t usr_size, unsigned char *buffer); -int eos_cell_pdp_set_usr(char *usr, unsigned char *buffer, int sync); -int eos_cell_pdp_get_pwd(char *pwd, uint16_t pwd_size, unsigned char *buffer); -int eos_cell_pdp_set_pwd(char *pwd, unsigned char *buffer, int sync); -int eos_cell_pdp_connect(unsigned char *buffer, int sync); -int eos_cell_pdp_disconnect(unsigned char *buffer, int sync); + +int eos_cell_status_parse(EOSMessage *msg, uint16_t len, uint8_t *status, uint8_t *connected); +int eos_cell_status(uint8_t *status, uint8_t *connected, EOSMessage *msg); + +int eos_cell_uart_take(EOSMessage *msg); +int eos_cell_uart_give(EOSMessage *msg); +unsigned char *eos_cell_uart_msg2data(EOSMessage *msg, uint16_t *len, uint16_t *size); +int eos_cell_uart_send(EOSMessage *msg, uint16_t len); +int eos_cell_uart_send_async(EOSMessage *msg, uint16_t len, int more); + +int eos_cell_voice_dial(char *num, EOSMessage *msg); +int eos_cell_voice_answer(EOSMessage *msg); +int eos_cell_voice_hangup(EOSMessage *msg); +unsigned char *eos_cell_voice_msg2pcm(EOSMessage *msg, uint16_t *len, uint16_t *size); +int eos_cell_voice_pcm_send(EOSMessage *msg, uint16_t len); +int eos_cell_voice_pcm_send_async(EOSMessage *msg, uint16_t len, int more); + +int eos_cell_sms_send(char *addr, char *txt, EOSMessage *msg); +int _eos_cell_sms_parse(EOSMessage *msg, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len); +int eos_cell_sms_parse(EOSMessage *msg, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size); +char *eos_cell_sms_msg2txt(EOSMessage *msg, uint16_t *len); + +int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, EOSMessage *msg); +int eos_cell_pdp_set(unsigned char atype, char *arg, EOSMessage *msg); +int eos_cell_pdp_get_apn(char *apn, uint16_t apn_size, EOSMessage *msg); +int eos_cell_pdp_set_apn(char *apn, EOSMessage *msg); +int eos_cell_pdp_get_usr(char *usr, uint16_t usr_size, EOSMessage *msg); +int eos_cell_pdp_set_usr(char *usr, EOSMessage *msg); +int eos_cell_pdp_get_pwd(char *pwd, uint16_t pwd_size, EOSMessage *msg); +int eos_cell_pdp_set_pwd(char *pwd, EOSMessage *msg); +int eos_cell_pdp_connect(EOSMessage *msg); +int eos_cell_pdp_disconnect(EOSMessage *msg); diff --git a/fw/fe310/eos/net/pwr.c b/fw/fe310/eos/net/pwr.c deleted file mode 100644 index 308a05a..0000000 --- a/fw/fe310/eos/net/pwr.c +++ /dev/null @@ -1,80 +0,0 @@ -#include <stdlib.h> -#include <stdint.h> - -#include "eos.h" -#include "event.h" -#include "dev/net.h" - -#include "soc/pwr.h" -#include "soc/spi.h" -#include "dev/spi.h" -#include "dev/net.h" -#include "dev/lcd.h" -#include "eve/eve.h" -#include "dev/flash.h" - -#include "pwr.h" - -static eos_evt_handler_t evt_handler[EOS_PWR_MAX_MTYPE]; -static unsigned char power_btn_down; - -static void pwr_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char mtype; - - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); - return; - } - - mtype = buffer[0]; - if ((mtype < EOS_PWR_MAX_MTYPE) && evt_handler[mtype]) { - evt_handler[mtype](mtype, buffer, len); - } else { - eos_net_bad_handler(type, buffer, len); - } -} - -static void pwr_handle_btn(unsigned char type, unsigned char *buffer, uint16_t len) { - int rv; - unsigned char level = buffer[1]; - - eos_net_free(buffer, 0); - if (!level) { - power_btn_down = 1; - return; - } - if (!power_btn_down) return; - - rv = eos_lcd_sleep(); - - rv = eos_spi_select(EOS_SPI_DEV_EVE); - if (!rv) { - eve_pwr_sleep(); - eos_spi_deselect(); - } - - rv = eos_net_sleep(1000); - - eos_flash_norm(); - - eos_pwr_sleep(); -} - -void eos_pwr_net_init(void) { - int i; - - for (i=0; i<EOS_PWR_MAX_MTYPE; i++) { - evt_handler[i] = NULL; - } - eos_net_set_handler(EOS_NET_MTYPE_POWER, pwr_handle_msg); - eos_pwr_set_handler(EOS_PWR_MTYPE_BUTTON, pwr_handle_btn); -} - -void eos_pwr_set_handler(unsigned char mtype, eos_evt_handler_t handler) { - if (mtype < EOS_PWR_MAX_MTYPE) evt_handler[mtype] = handler; -} - -eos_evt_handler_t eos_pwr_get_handler(unsigned char mtype) { - if (mtype < EOS_PWR_MAX_MTYPE) return evt_handler[mtype]; - return NULL; -} diff --git a/fw/fe310/eos/net/pwr.h b/fw/fe310/eos/net/pwr.h deleted file mode 100644 index b82a96b..0000000 --- a/fw/fe310/eos/net/pwr.h +++ /dev/null @@ -1,10 +0,0 @@ -#include <stdint.h> -#include "../event.h" - -#define EOS_PWR_MTYPE_BUTTON 1 - -#define EOS_PWR_MAX_MTYPE 2 - -void eos_pwr_net_init(void); -void eos_pwr_set_handler(unsigned char mtype, eos_evt_handler_t handler); -eos_evt_handler_t eos_pwr_get_handler(unsigned char mtype); diff --git a/fw/fe310/eos/net/rng.c b/fw/fe310/eos/net/rng.c index 7d05a81..414a6fa 100644 --- a/fw/fe310/eos/net/rng.c +++ b/fw/fe310/eos/net/rng.c @@ -2,26 +2,34 @@ #include <stdint.h> #include <string.h> +#include "eos.h" +#include "event.h" #include "dev/net.h" int getentropy(unsigned char *b, size_t sz) { unsigned char type; - unsigned char *buffer; + EOSMessage msg; uint16_t len; int rv; - buffer = eos_net_alloc(); - type = EOS_NET_MTYPE_RNG; len = sizeof(uint16_t); - buffer[0] = sz >> 8; - buffer[1] = sz; - rv = eos_net_xchg(&type, buffer, &len); + eos_net_alloc(&msg); + + if ((msg.size < len) || (msg.size < sz)) { + eos_net_free(&msg, 1); + return -1; + } + + msg.buffer[0] = sz >> 8; + msg.buffer[1] = sz; + + rv = eos_net_xchg(&type, &msg, &len); if (rv || (len != sz)) rv = -1; - if (!rv) memcpy(b, buffer, sz); - eos_net_free(buffer, 1); + if (!rv) memcpy(b, msg.buffer, sz); + eos_net_free(&msg, 1); return rv; } diff --git a/fw/fe310/eos/net/sock.c b/fw/fe310/eos/net/sock.c index c9934e8..0c2f07d 100644 --- a/fw/fe310/eos/net/sock.c +++ b/fw/fe310/eos/net/sock.c @@ -10,26 +10,41 @@ static eos_evt_handler_t evt_handler[EOS_SOCK_MAX_SOCK]; -static void sock_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { +static void sock_handle_msg(unsigned char type, EOSMessage *msg, uint16_t len) { unsigned char sock; + int i; - if ((buffer == NULL) || (len < 2)) { - eos_net_bad_handler(type, buffer, len); - return; - } - - sock = buffer[1]; - if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { - eos_net_bad_handler(type, buffer, len); + if ((msg == NULL) || (len < 2)) { + eos_net_bad_handler(type, msg, len); return; } - switch(buffer[0]) { - case EOS_SOCK_MTYPE_PKT: - evt_handler[sock - 1](type, buffer, len); + switch(msg->buffer[0]) { + case EOS_SOCK_MTYPE_PKT: { + sock = msg->buffer[1]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { + eos_net_bad_handler(type, msg, len); + return; + } + evt_handler[sock - 1](type, msg, len); break; + } + + case EOS_SOCK_MTYPE_CLOSE: { + for (i=1; i<len; i++) { + sock = msg->buffer[i]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { + eos_net_bad_handler(type, msg, len); + continue; + } + evt_handler[sock - 1](type, msg, len); + evt_handler[sock - 1] = NULL; + } + break; + } + default: - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, msg, len); break; } } @@ -52,63 +67,44 @@ eos_evt_handler_t eos_sock_get_handler(unsigned char sock) { return NULL; } -int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer) { +int eos_sock_open_udp(eos_evt_handler_t handler, EOSMessage *msg) { unsigned char type; uint16_t len; - int do_release; int rv, sock; - do_release = 0; - if (buffer == NULL) { - buffer = eos_net_alloc(); - do_release = 1; - } + if (msg->size < 2) return EOS_ERR_SIZE; type = EOS_NET_MTYPE_SOCK; len = 1; - buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM; + msg->buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM; - rv = eos_net_xchg(&type, buffer, &len); - if (rv) goto sock_open_udp_fin; + rv = eos_net_xchg(&type, msg, &len); + if (rv) return rv; - if (type != EOS_NET_MTYPE_SOCK) { - rv = EOS_ERR_NET; - goto sock_open_udp_fin; - } - if (len < 2) { - rv = EOS_ERR_SIZE; - goto sock_open_udp_fin; - } + if (type != EOS_NET_MTYPE_SOCK) return EOS_ERR_NET; + if (len < 2) return EOS_ERR_SIZE; - sock = buffer[1]; - if (sock == 0) { - rv = EOS_ERR_NET; - goto sock_open_udp_fin; - } + sock = msg->buffer[1]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return EOS_ERR_NET; - rv = sock; eos_sock_set_handler(sock, handler); - -sock_open_udp_fin: - if (do_release) eos_net_free(buffer, 1); - return rv; + return sock; } -void eos_sock_close(unsigned char sock, unsigned char *buffer) { - int async; +void eos_sock_close(unsigned char sock, EOSMessage *msg) { + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return; + if (msg->size < 2) return; - async = 0; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } - buffer[0] = EOS_SOCK_MTYPE_CLOSE; - buffer[1] = sock; - _eos_net_send(EOS_NET_MTYPE_SOCK, buffer, 2, async, 1); + msg->buffer[0] = EOS_SOCK_MTYPE_CLOSE; + msg->buffer[1] = sock; + eos_net_send_sync(EOS_NET_MTYPE_SOCK, msg, 2); eos_sock_set_handler(sock, NULL); } -static int sock_send(unsigned char sock, unsigned char *msg, uint16_t msg_len, EOSNetAddr *addr, unsigned char *buffer) { +static void sock_sendto(unsigned char sock, EOSNetAddr *addr, EOSMessage *msg) { + unsigned char *buffer; + + buffer = msg->buffer; buffer[0] = EOS_SOCK_MTYPE_PKT; buffer[1] = sock; buffer += 2; @@ -117,47 +113,60 @@ static int sock_send(unsigned char sock, unsigned char *msg, uint16_t msg_len, E buffer[0] = addr->port >> 8; buffer[1] = addr->port; buffer += sizeof(addr->port); - if (msg) { - if (msg_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_SIZE_BUF) return EOS_ERR_SIZE; - memcpy(buffer, msg, msg_len); - } - - return EOS_OK; } -int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer) { - int rv; - - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; +int eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, EOSMessage *msg, uint16_t pkt_len) { + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return EOS_ERR_NET; - return eos_net_send(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR); + sock_sendto(sock, addr, msg); + return eos_net_send_sync(EOS_NET_MTYPE_SOCK, msg, pkt_len + EOS_SOCK_SIZE_UDP_HDR); } -int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more) { - int rv; +int eos_sock_sendto_async(unsigned char sock, EOSNetAddr *addr, EOSMessage *msg, uint16_t pkt_len, int more) { + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return EOS_ERR_NET; - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; - - return eos_net_send_async(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR, more); + sock_sendto(sock, addr, msg); + return eos_net_send(EOS_NET_MTYPE_SOCK, msg, pkt_len + EOS_SOCK_SIZE_UDP_HDR, more); } -int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr) { +int eos_sock_recvfrom(EOSMessage *msg, uint16_t len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size) { + char *buffer = msg->buffer; + if (len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; + if (buffer[0] == EOS_SOCK_MTYPE_CLOSE) return EOS_SOCK_ERR_CLOSED; if (buffer[0] != EOS_SOCK_MTYPE_PKT) return EOS_ERR_NET; buffer += 2; - memcpy(addr->host, buffer, sizeof(addr->host)); + if (addr) { + memcpy(addr->host, buffer, sizeof(addr->host)); + } buffer += sizeof(addr->host); - addr->port = (uint16_t)buffer[0] << 8; - addr->port |= (uint16_t)buffer[1]; + if (addr) { + addr->port = (uint16_t)buffer[0] << 8; + addr->port |= (uint16_t)buffer[1]; + } buffer += sizeof(addr->port); - if (msg) { - if (msg_size < len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; - memcpy(msg, buffer, len - EOS_SOCK_SIZE_UDP_HDR); + if (pkt) { + if (pkt_size < len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; + memcpy(pkt, buffer, len - EOS_SOCK_SIZE_UDP_HDR); } return EOS_OK; } + +unsigned char *eos_sock_msg2pkt(EOSMessage *msg, uint16_t *len, uint16_t *pkt_size) { + if (len && (*len < EOS_SOCK_SIZE_UDP_HDR)) return NULL; + if (msg->size < EOS_SOCK_SIZE_UDP_HDR) return NULL; + + if (len && (msg->buffer[0] != EOS_SOCK_MTYPE_PKT)) return NULL; + + if (len) *len -= EOS_SOCK_SIZE_UDP_HDR; + if (pkt_size) *pkt_size = msg->size - EOS_SOCK_SIZE_UDP_HDR; + return msg->buffer + EOS_SOCK_SIZE_UDP_HDR; +} + +void eos_sock_pkt2msg(EOSMessage *msg, unsigned char *pkt, uint16_t pkt_size) { + msg->buffer = pkt - EOS_SOCK_SIZE_UDP_HDR; + msg->size = pkt_size + EOS_SOCK_SIZE_UDP_HDR; +} diff --git a/fw/fe310/eos/net/sock.h b/fw/fe310/eos/net/sock.h index e2f8637..e873a7d 100644 --- a/fw/fe310/eos/net/sock.h +++ b/fw/fe310/eos/net/sock.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_SOCK_MTYPE_PKT 0 @@ -11,6 +12,8 @@ #define EOS_IPv4_ADDR_SIZE 4 +#define EOS_SOCK_ERR_CLOSED -1021 + typedef struct EOSNetAddr { unsigned char host[EOS_IPv4_ADDR_SIZE]; uint16_t port; @@ -20,9 +23,12 @@ void eos_sock_init(void); void eos_sock_set_handler(unsigned char sock, eos_evt_handler_t handler); eos_evt_handler_t eos_sock_get_handler(unsigned char sock); -int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer); -void eos_sock_close(unsigned char sock, unsigned char *buffer); +int eos_sock_open_udp(eos_evt_handler_t handler, EOSMessage *msg); +void eos_sock_close(unsigned char sock, EOSMessage *msg); + +int eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, EOSMessage *msg, uint16_t pkt_len); +int eos_sock_sendto_async(unsigned char sock, EOSNetAddr *addr, EOSMessage *msg, uint16_t pkt_len, int more); +int eos_sock_recvfrom(EOSMessage *msg, uint16_t len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size); -int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer); -int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more); -int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr); +unsigned char *eos_sock_msg2pkt(EOSMessage *msg, uint16_t *len, uint16_t *pkt_size); +void eos_sock_pkt2msg(EOSMessage *msg, unsigned char *pkt, uint16_t pkt_size); diff --git a/fw/fe310/eos/net/wifi.c b/fw/fe310/eos/net/wifi.c index ebbb9ca..59f149c 100644 --- a/fw/fe310/eos/net/wifi.c +++ b/fw/fe310/eos/net/wifi.c @@ -10,19 +10,19 @@ static eos_evt_handler_t evt_handler[EOS_WIFI_MAX_MTYPE]; -static void wifi_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { +static void wifi_handle_msg(unsigned char type, EOSMessage *msg, uint16_t len) { unsigned char mtype; - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); + if ((msg == NULL) || (len < 1)) { + eos_net_bad_handler(type, msg, len); return; } - mtype = buffer[0]; + mtype = msg->buffer[0]; if ((mtype < EOS_WIFI_MAX_MTYPE) && evt_handler[mtype]) { - evt_handler[mtype](mtype, buffer, len); + evt_handler[mtype](mtype, msg, len); } else { - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, msg, len); } } @@ -44,7 +44,9 @@ eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype) { return NULL; } -int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size) { +int eos_wifi_status_parse(EOSMessage *msg, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size) { + unsigned char *buffer = msg->buffer; + if (len < 2) return EOS_ERR_SIZE; if (buffer[0] != EOS_WIFI_MTYPE_STATUS) return EOS_ERR_NET; @@ -72,119 +74,86 @@ int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, return EOS_OK; } -int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, unsigned char *buffer) { +int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, EOSMessage *msg) { unsigned char type; uint16_t len; - int do_release; int rv; - do_release = 0; - if (buffer == NULL) { - buffer = eos_net_alloc(); - do_release = 1; - } + if (msg->size < 1) return EOS_ERR_SIZE; type = EOS_NET_MTYPE_WIFI; len = 1; - buffer[0] = EOS_WIFI_MTYPE_STATUS; + msg->buffer[0] = EOS_WIFI_MTYPE_STATUS; - rv = eos_net_xchg(&type, buffer, &len); - if (rv) goto wifi_status_fin; + rv = eos_net_xchg(&type, msg, &len); + if (rv) return rv; - if (type != EOS_NET_MTYPE_WIFI) { - rv = EOS_ERR_NET; - goto wifi_status_fin; - } - rv = eos_wifi_status_parse(buffer, len, status, ip_addr, ssid, ssid_size); + if (type != EOS_NET_MTYPE_WIFI) return EOS_ERR_NET; -wifi_status_fin: - if (do_release) eos_net_free(buffer, 1); - return rv; + return eos_wifi_status_parse(msg, len, status, ip_addr, ssid, ssid_size); } -int eos_wifi_start(unsigned char *buffer, int sync) { - int async; +int eos_wifi_start(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_WIFI_MTYPE_START; - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); + msg->buffer[0] = EOS_WIFI_MTYPE_START; + return eos_net_send_sync(EOS_NET_MTYPE_WIFI, msg, 1); } -int eos_wifi_stop(unsigned char *buffer, int sync) { - int async; +int eos_wifi_stop(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_WIFI_MTYPE_STOP; - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); + msg->buffer[0] = EOS_WIFI_MTYPE_STOP; + return eos_net_send_sync(EOS_NET_MTYPE_WIFI, msg, 1); } -int eos_wifi_scan(unsigned char *buffer, int sync) { - int async; +int eos_wifi_scan(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_WIFI_MTYPE_SCAN; - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); + msg->buffer[0] = EOS_WIFI_MTYPE_SCAN; + return eos_net_send_sync(EOS_NET_MTYPE_WIFI, msg, 1); +} + +unsigned char *eos_wifi_scan2data(EOSMessage *msg, uint16_t *len) { + if (*len < 1) return NULL; + + if (msg->buffer[0] != EOS_WIFI_MTYPE_SCAN) return NULL; + + if (len) *len -= 1; + return msg->buffer + 1; } -int eos_wifi_connect(char *ssid, char *pwd, unsigned char *buffer, int sync) { - unsigned char *buf; +int eos_wifi_connect(char *ssid, char *pwd, EOSMessage *msg) { + unsigned char *buffer = msg->buffer; size_t ssid_len, pwd_len; - int async; ssid_len = strlen(ssid); pwd_len = strlen(pwd); if (ssid_len > EOS_WIFI_SIZE_SSID) return EOS_ERR_SIZE; if (pwd_len > EOS_WIFI_SIZE_PWD) return EOS_ERR_SIZE; + if (msg->size < 3 + ssid_len + pwd_len) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buf = buffer; - buf[0] = EOS_WIFI_MTYPE_CONNECT; - buf++; + buffer[0] = EOS_WIFI_MTYPE_CONNECT; + buffer++; - *buf = ssid_len; - buf++; + *buffer = ssid_len; + buffer++; - memcpy(buf, ssid, ssid_len); - buf += ssid_len; + memcpy(buffer, ssid, ssid_len); + buffer += ssid_len; - *buf = pwd_len; - buf++; + *buffer = pwd_len; + buffer++; - memcpy(buf, pwd, pwd_len); - buf += pwd_len; + memcpy(buffer, pwd, pwd_len); + buffer += pwd_len; - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 3 + ssid_len + pwd_len, async, 1); + return eos_net_send_sync(EOS_NET_MTYPE_WIFI, msg, 3 + ssid_len + pwd_len); } -int eos_wifi_disconnect(unsigned char *buffer, int sync) { - int async; +int eos_wifi_disconnect(EOSMessage *msg) { + if (msg->size < 1) return EOS_ERR_SIZE; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } else { - async = !sync; - } - buffer[0] = EOS_WIFI_MTYPE_DISCONNECT; - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); + msg->buffer[0] = EOS_WIFI_MTYPE_DISCONNECT; + return eos_net_send_sync(EOS_NET_MTYPE_WIFI, msg, 1); } diff --git a/fw/fe310/eos/net/wifi.h b/fw/fe310/eos/net/wifi.h index 93d2fc4..1f64d73 100644 --- a/fw/fe310/eos/net/wifi.h +++ b/fw/fe310/eos/net/wifi.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_WIFI_MTYPE_STATUS 0 @@ -24,10 +25,11 @@ void eos_wifi_init(void); void eos_wifi_set_handler(unsigned char mtype, eos_evt_handler_t handler); eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype); -int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size); -int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, unsigned char *buffer); -int eos_wifi_start(unsigned char *buffer, int sync); -int eos_wifi_stop(unsigned char *buffer, int sync); -int eos_wifi_scan(unsigned char *buffer, int sync); -int eos_wifi_connect(char *ssid, char *pwd, unsigned char *buffer, int sync); -int eos_wifi_disconnect(unsigned char *buffer, int sync);
\ No newline at end of file +int eos_wifi_status_parse(EOSMessage *msg, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size); +int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, EOSMessage *msg); +int eos_wifi_start(EOSMessage *msg); +int eos_wifi_stop(EOSMessage *msg); +int eos_wifi_scan(EOSMessage *msg); +unsigned char *eos_wifi_scan2data(EOSMessage *msg, uint16_t *len); +int eos_wifi_connect(char *ssid, char *pwd, EOSMessage *msg); +int eos_wifi_disconnect(EOSMessage *msg); diff --git a/fw/fe310/eos/soc/Makefile b/fw/fe310/eos/soc/Makefile index f5f072a..39d8b8c 100644 --- a/fw/fe310/eos/soc/Makefile +++ b/fw/fe310/eos/soc/Makefile @@ -1,7 +1,7 @@ include ../../common.mk CFLAGS += -I$(bsp_dir)/include -I$(bsp_dir)/drivers -obj = trap_entry.o interrupt.o timer.o pwr.o i2s.o i2c.o uart.o spi.o spi9bit.o +obj = trap_entry.o interrupt.o timer.o pwr.o aon.o gpio.o i2s.o i2c.o uart.o spi.o spi9bit.o lib = ../../libeos-soc.a diff --git a/fw/fe310/eos/soc/aon.c b/fw/fe310/eos/soc/aon.c new file mode 100644 index 0000000..a11259e --- /dev/null +++ b/fw/fe310/eos/soc/aon.c @@ -0,0 +1,46 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "pwr.h" + +#include "aon.h" + +#define AON_MAX_BACKUP 16 + +int eos_aon_init(void) { + uint8_t wakeup_cause; + int i, rst; + + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); + if (rst) { + for (i=0; i<AON_MAX_BACKUP; i++) { + eos_aon_set_reg(i, 0); + } + } + + return EOS_OK; +} + +uint32_t eos_aon_get_reg(int idx) { + uint32_t addr; + + if ((idx < 0) || (idx >= AON_MAX_BACKUP)) return -1; + + addr = AON_BACKUP0 + sizeof(uint32_t) * idx; + return AON_REG(addr); +} + +void eos_aon_set_reg(int idx, uint32_t reg) { + uint32_t addr; + + if ((idx < 0) || (idx > 15)) return; + + addr = AON_BACKUP0 + sizeof(uint32_t) * idx; + AON_REG(addr) = reg; +} + diff --git a/fw/fe310/eos/soc/aon.h b/fw/fe310/eos/soc/aon.h new file mode 100644 index 0000000..41bdfab --- /dev/null +++ b/fw/fe310/eos/soc/aon.h @@ -0,0 +1,5 @@ +#include <stdint.h> + +int eos_aon_init(void); +uint32_t eos_aon_get_reg(int idx); +void eos_aon_set_reg(int idx, uint32_t reg);
\ No newline at end of file diff --git a/fw/fe310/eos/soc/gpio.c b/fw/fe310/eos/soc/gpio.c new file mode 100644 index 0000000..4fa93dd --- /dev/null +++ b/fw/fe310/eos/soc/gpio.c @@ -0,0 +1,20 @@ +#include <stdint.h> + +#include "encoding.h" +#include "platform.h" + +int eos_gpio_get(uint32_t reg, int pin) { + return !!(GPIO_REG(reg) & (1 << pin)); +} + +void eos_gpio_set(uint32_t reg, int pin) { + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(reg) |= (1 << pin); + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) set_csr(mstatus, MSTATUS_MIE); +} + +void eos_gpio_clear(uint32_t reg, int pin) { + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(reg) &= ~(1 << pin); + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) set_csr(mstatus, MSTATUS_MIE); +} diff --git a/fw/fe310/eos/soc/gpio.h b/fw/fe310/eos/soc/gpio.h new file mode 100644 index 0000000..2ba5787 --- /dev/null +++ b/fw/fe310/eos/soc/gpio.h @@ -0,0 +1,5 @@ +#include <stdint.h> + +int eos_gpio_get(uint32_t reg, int pin); +void eos_gpio_set(uint32_t reg, int pin); +void eos_gpio_clear(uint32_t reg, int pin); diff --git a/fw/fe310/eos/soc/i2c.c b/fw/fe310/eos/soc/i2c.c index 553a9bf..feed936 100644 --- a/fw/fe310/eos/soc/i2c.c +++ b/fw/fe310/eos/soc/i2c.c @@ -9,7 +9,7 @@ #include "i2s.h" #include "i2c.h" -int eos_i2c_init(uint8_t wakeup_cause) { +int eos_i2c_init(void) { eos_i2c_speed(EOS_I2C_SPEED); eos_i2c_enable(); diff --git a/fw/fe310/eos/soc/i2c.h b/fw/fe310/eos/soc/i2c.h index 5032988..a99b8ee 100644 --- a/fw/fe310/eos/soc/i2c.h +++ b/fw/fe310/eos/soc/i2c.h @@ -2,7 +2,7 @@ #define EOS_I2C_SPEED 100000 -int eos_i2c_init(uint8_t wakeup_cause); +int eos_i2c_init(void); void eos_i2c_enable(void); void eos_i2c_disable(void); int eos_i2c_enabled(void); diff --git a/fw/fe310/eos/soc/i2s.c b/fw/fe310/eos/soc/i2s.c index bcce0b7..52c7a8b 100644 --- a/fw/fe310/eos/soc/i2s.c +++ b/fw/fe310/eos/soc/i2s.c @@ -3,17 +3,19 @@ #include "encoding.h" #include "platform.h" +#include "board.h" #include "prci_driver.h" #include "eos.h" +#include "log.h" #include "event.h" #include "interrupt.h" -#include "board.h" - -#include "dev/eve.h" - #include "uart.h" +#include "dev/egpio.h" +#include "dev/egpio_priv.h" + +#include "dev/hpamp.h" #include "i2s.h" #include "i2s_priv.h" @@ -29,90 +31,73 @@ #define EOS_ABUF_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) -static eos_i2s_handler_t i2s_mic_handler = NULL; -static eos_i2s_handler_t i2s_spk_handler = NULL; +static eos_evt_simple_handler_t i2s_mic_handler = NULL; +static eos_evt_simple_handler_t i2s_spk_handler = NULL; static uint32_t i2s_clk_period; -static uint8_t i2s_mic_volume = 0; /* 0 - 8 */ -static uint8_t i2s_spk_volume = 16; /* 0 - 16 */ +static uint8_t i2s_mic_volume = 0; /* 0 - 8 */ +static uint8_t i2s_spk_volume = 16; /* 0 - 16 */ EOSABuf _eos_i2s_mic_buf; EOSABuf _eos_i2s_spk_buf; uint32_t _eos_i2s_drvr[] = { - EOS_I2S_FMT_PCM16, /* I2S_FMT */ - EOS_I2S_MODE_STEREO, /* I2S_MODE */ - 0, /* I2S_MIC_WM */ - 0, /* I2S_SPK_WM */ - 0, /* I2S_MIC_EVT */ - 0, /* I2S_SPK_EVT */ + 0, /* I2S_MIC_WM */ + 0, /* I2S_SPK_WM */ + 0, /* I2S_MIC_EVT */ + 0, /* I2S_SPK_EVT */ }; -#define I2S_FMT 0 -#define I2S_MODE 1 -#define I2S_MIC_WM 2 -#define I2S_SPK_WM 3 -#define I2S_MIC_EVT 4 -#define I2S_SPK_EVT 5 +#define I2S_MIC_WM 0 +#define I2S_SPK_WM 1 +#define I2S_MIC_EVT 2 +#define I2S_SPK_EVT 3 -static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) { +static void _abuf_init(EOSABuf *buf, uint16_t *array, uint16_t size) { buf->idx_r = 0; buf->idx_w = 0; buf->size = size; buf->array = array; } -static int _abuf_push8(EOSABuf *buf, uint8_t sample) { - if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL; - - buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample; - buf->idx_w++; - return EOS_OK; +static void _abuf_flush(EOSABuf *buf) { + buf->idx_r = 0; + buf->idx_w = 0; } -static int _abuf_push16(EOSABuf *buf, uint16_t sample) { - if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL; - - buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample >> 8; - buf->array[EOS_ABUF_IDX_MASK(buf->idx_w + 1, buf->size)] = sample & 0xFF; - buf->idx_w += 2; - return EOS_OK; +static uint16_t _abuf_len(EOSABuf *buf) { + return (uint16_t)(buf->idx_w - buf->idx_r); } -static int _abuf_pop8(EOSABuf *buf, uint8_t *sample) { - if (buf->idx_r == buf->idx_w) { - return EOS_ERR_EMPTY; - } else { - *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)]; - buf->idx_r++; - return EOS_OK; - } +static uint16_t _abuf_size(EOSABuf *buf) { + return buf->size; } -static int _abuf_pop16(EOSABuf *buf, uint16_t *sample) { - if (buf->idx_r == buf->idx_w) { - return EOS_ERR_EMPTY; - } else { - *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)] << 8; - *sample |= buf->array[EOS_ABUF_IDX_MASK(buf->idx_r + 1, buf->size)]; - buf->idx_r += 2; - return EOS_OK; - } -} +/* mic buffer only */ +static int _mbuf_pop(uint16_t *sample) { + if (_eos_i2s_mic_buf.idx_r == _eos_i2s_mic_buf.idx_w) return EOS_ERR_EMPTY; -static void _abuf_flush(EOSABuf *buf) { - buf->idx_r = 0; - buf->idx_w = 0; + *sample = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r, _eos_i2s_mic_buf.size)]; + _eos_i2s_mic_buf.idx_r += 1; + return EOS_OK; } -static uint16_t _abuf_len(EOSABuf *buf) { - return buf->idx_w - buf->idx_r; +/* spk buffer only */ +static int _sbuf_push(uint16_t sample) { + if ((uint16_t)(_eos_i2s_spk_buf.idx_w - _eos_i2s_spk_buf.idx_r) == _eos_i2s_spk_buf.size) return EOS_ERR_FULL; + + if (_eos_i2s_spk_buf.idx_r != _eos_i2s_spk_buf.idx_w) { + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w - 1, _eos_i2s_spk_buf.size)] |= sample >> 15; + } + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w, _eos_i2s_spk_buf.size)] = sample << 1; + _eos_i2s_spk_buf.idx_w += 1; + return EOS_OK; } -static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { +static void i2s_handle_evt(unsigned char type, EOSMessage *msg, uint16_t len) { switch(type & ~EOS_EVT_MASK) { case EOS_I2S_ETYPE_MIC: if (i2s_mic_handler) { - i2s_mic_handler(type); + i2s_mic_handler(type & ~EOS_EVT_MASK); clear_csr(mstatus, MSTATUS_MIE); _eos_i2s_drvr[I2S_MIC_EVT] = 1; set_csr(mstatus, MSTATUS_MIE); @@ -121,7 +106,7 @@ static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l case EOS_I2S_ETYPE_SPK: if (i2s_spk_handler) { - i2s_spk_handler(type); + i2s_spk_handler(type & ~EOS_EVT_MASK); clear_csr(mstatus, MSTATUS_MIE); _eos_i2s_drvr[I2S_SPK_EVT] = 1; set_csr(mstatus, MSTATUS_MIE); @@ -129,13 +114,15 @@ static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l break; default: - eos_evtq_bad_handler(type, buffer, len); + eos_evtq_bad_handler(type, msg, len); break; } } static void i2s_set_cmp(void) { - int spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume; + int spk_ws_offset; + + spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume; /* adjust spk ws relative to mic ws */ if (spk_ws_offset <= 0) { @@ -147,36 +134,50 @@ static void i2s_set_cmp(void) { I2S_REG_WS(PWM_CMP2) = spk_ws_offset * i2s_clk_period - i2s_clk_period / 2; I2S_REG_WS(PWM_CMP3) = (32 + spk_ws_offset) * i2s_clk_period - i2s_clk_period / 2; - I2S_REG_SR_SEL(PWM_CMP1) = (1 + i2s_mic_volume) * i2s_clk_period; - I2S_REG_SR_SEL(PWM_CMP2) = (17 + i2s_mic_volume) * i2s_clk_period - (i2s_clk_period / 4); + I2S_REG_SR_SEL(PWM_CMP1) = (1 + i2s_mic_volume) * i2s_clk_period + i2s_clk_period / 4; + I2S_REG_SR_SEL(PWM_CMP2) = (17 + i2s_mic_volume) * i2s_clk_period - i2s_clk_period / 4; } -extern void _eos_i2s_start_pwm(void); +extern void _eos_i2s_start_pwm(unsigned int); -int eos_i2s_init(uint8_t wakeup_cause) { +int eos_i2s_init(void) { eos_evtq_set_handler(EOS_EVT_I2S, i2s_handle_evt); I2S_REG_CK(PWM_CFG) = 0; I2S_REG_WS(PWM_CFG) = 0; I2S_REG_SR_SEL(PWM_CFG) = 0; + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_SEL); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SR_CK); + GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SD_OUT); + set_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_SR_SEL); GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_SR_CK); GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); + GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_OUT); + GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_INT); return EOS_OK; } -void eos_i2s_start(uint32_t sample_rate) { - uint32_t iof_mask; +int eos_i2s_start(uint32_t sample_rate, int mode) { + unsigned int scale_ck; + int rv; + i2s_clk_period = PRCI_get_cpu_freq() / (sample_rate * 64); - i2s_clk_period = (i2s_clk_period & ~I2S_PWM_SCALE_CK_MASK) + 1; + i2s_clk_period &= ~0x01; /* clear last bit */ - I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> I2S_PWM_SCALE_CK; + /* if half of clock period does not fit in 8 bits we need to scale clock */ + scale_ck = 0; + if ((i2s_clk_period >> 1) & ~0xFF) { + scale_ck = 1; + i2s_clk_period &= ~0x03; /* clear last two bits */ + } + + I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> (1 + scale_ck); /* master clock: double bit clock frequency */ I2S_REG_CK(PWM_CMP1) = I2S_REG_CK(PWM_CMP0) / 2; I2S_REG_CK(PWM_CMP2) = 0; I2S_REG_CK(PWM_CMP3) = 0; @@ -184,42 +185,64 @@ void eos_i2s_start(uint32_t sample_rate) { I2S_REG_WS(PWM_CMP0) = i2s_clk_period * 64 - 1; I2S_REG_WS(PWM_CMP1) = i2s_clk_period * 32; - I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 32 - 1; + if (mode == EOS_I2S_MODE_STEREO) { + I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 32 - 1; + } else { + I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 64 - 1; + } I2S_REG_SR_SEL(PWM_CMP3) = 0; i2s_set_cmp(); - I2S_REG_CK(PWM_COUNT) = 0; + I2S_REG_CK(PWM_COUNT) = I2S_REG_CK(PWM_CMP1); /* master clock starts high */ I2S_REG_WS(PWM_COUNT) = 0; - I2S_REG_SR_SEL(PWM_COUNT) = 0; + if (mode == EOS_I2S_MODE_MONO_R) { + I2S_REG_SR_SEL(PWM_COUNT) = i2s_clk_period * 32; + } else { + I2S_REG_SR_SEL(PWM_COUNT) = 0; + } - eos_eve_intr_disable(); eos_uart_disable(); + rv = eos_egpio_i2s_start(); + if (rv) { + eos_i2s_stop(); + return rv; + } + + GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM; + GPIO_REG(GPIO_IOF_EN) |= I2S_PIN_PWM; - GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_INT); GPIO_REG(GPIO_FALL_IE) |= (1 << I2S_PIN_INT); + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_CK); + set_csr(mstatus, MSTATUS_MIE); - iof_mask = I2S_PIN_PWM; - if (_eos_i2s_mic_buf.size == 0) { - iof_mask &= ~(1 << I2S_PIN_WS_MIC); - } - if (_eos_i2s_spk_buf.size == 0) { - iof_mask &= ~(1 << I2S_PIN_WS_SPK); + /* XXX should set stereo pin to 1 !!! */ + + eos_intr_set_priority(I2S_IRQ_ID, IRQ_PRIORITY_I2S); + eos_intr_enable(I2S_IRQ_ID); + + /* initialise headphones if present */ + if (!eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { + rv = eos_hpamp_init(); + if (rv) { + eos_i2s_stop(); + return rv; + } } - GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM; - GPIO_REG(GPIO_IOF_EN) |= iof_mask; - eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD); - eos_intr_enable(I2S_IRQ_SD_ID); - _eos_i2s_start_pwm(); + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_start_pwm(scale_ck); + set_csr(mstatus, MSTATUS_MIE); /* - I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK; + I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | scale_ck; I2S_REG_WS(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG; I2S_REG_SR_SEL(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG; */ } void eos_i2s_stop(void) { + int rv; + I2S_REG_CK(PWM_CFG) = 0; I2S_REG_WS(PWM_CFG) = 0; I2S_REG_SR_SEL(PWM_CFG) = 0; @@ -227,17 +250,18 @@ void eos_i2s_stop(void) { I2S_REG_WS(PWM_COUNT) = 0; I2S_REG_SR_SEL(PWM_COUNT) = 0; - eos_intr_disable(I2S_IRQ_SD_ID); + eos_intr_disable(I2S_IRQ_ID); GPIO_REG(GPIO_FALL_IE) &= ~(1 << I2S_PIN_INT); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_INT); - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_SEL); + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SR_CK); + set_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK); GPIO_REG(GPIO_IOF_EN) &= ~I2S_PIN_PWM; eos_uart_enable(); - eos_eve_intr_enable(); + rv = eos_egpio_i2s_stop(); + if (rv) EOS_LOG(EOS_LOG_ERR, "I2S STOP: EGPIO ERR:%d\n", rv); _eos_i2s_drvr[I2S_MIC_EVT] = 0; _eos_i2s_drvr[I2S_SPK_EVT] = 0; @@ -253,15 +277,11 @@ int eos_i2s_running(void) { return !!(GPIO_REG(GPIO_IOF_EN) & (1 << I2S_PIN_CK)); } -void eos_i2s_set_fmt(unsigned char fmt) { - _eos_i2s_drvr[I2S_FMT] = fmt; +int eos_i2s_set_lsgain(int gain) { + return eos_egpio_set_val(EGPIO_PIN_LSGAIN_SEL, gain); } -void eos_i2s_set_mode(unsigned char mode) { - _eos_i2s_drvr[I2S_MODE] = mode; -} - -void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) { +void eos_i2s_mic_set_handler(eos_evt_simple_handler_t handler, uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); if ((i2s_mic_handler == NULL) && handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1; if (i2s_mic_handler && (handler == NULL)) _eos_i2s_drvr[I2S_MIC_EVT] = 0; @@ -270,72 +290,55 @@ void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) { set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size) { - int run = eos_i2s_running(); - +void eos_i2s_mic_set_buf(uint16_t *mic_arr, uint16_t mic_arr_size) { clear_csr(mstatus, MSTATUS_MIE); _abuf_init(&_eos_i2s_mic_buf, mic_arr, mic_arr_size); - if (run) { - if (mic_arr_size == 0) { - GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_MIC); - } else { - GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_MIC); - } - } set_csr(mstatus, MSTATUS_MIE); } -uint8_t *eos_i2s_mic_get_buf(void) { +uint16_t *eos_i2s_mic_get_buf(void) { return _eos_i2s_mic_buf.array; } uint16_t eos_i2s_mic_len(void) { - uint16_t ret; + uint16_t rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_len(&_eos_i2s_mic_buf); + rv = _abuf_len(&_eos_i2s_mic_buf); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } -uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { - uint16_t i; - uint16_t _ssize = 0; +uint16_t eos_i2s_mic_read(uint16_t *smpl_buf, uint16_t buf_size) { + int i; + uint16_t smpl_len; clear_csr(mstatus, MSTATUS_MIE); - _ssize = MIN(ssize, _abuf_len(&_eos_i2s_mic_buf)); + smpl_len = MIN(buf_size, _abuf_len(&_eos_i2s_mic_buf)); set_csr(mstatus, MSTATUS_MIE); - for (i=0; i<_ssize; i++) { - sample[i] = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r + i, _eos_i2s_mic_buf.size)]; - } - - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_mic_buf.idx_r += _ssize; - set_csr(mstatus, MSTATUS_MIE); - - return _ssize; -} + if (smpl_len == 0) return 0; -int eos_i2s_mic_pop8(uint8_t *sample) { - int ret; + for (i=0; i<smpl_len; i++) { + smpl_buf[i] = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r + i, _eos_i2s_mic_buf.size)]; + } clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_pop8(&_eos_i2s_mic_buf, sample); + _eos_i2s_mic_buf.idx_r += smpl_len; set_csr(mstatus, MSTATUS_MIE); - return ret; + return smpl_len; } -int eos_i2s_mic_pop16(uint16_t *sample) { - int ret; +int eos_i2s_mic_pop(uint16_t *sample) { + int rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_pop16(&_eos_i2s_mic_buf, sample); + rv = _mbuf_pop(sample); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } int eos_i2s_mic_get_vol(void) { @@ -352,7 +355,7 @@ void eos_i2s_mic_set_vol(int vol) { set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm) { +void eos_i2s_spk_set_handler(eos_evt_simple_handler_t handler, uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); if ((i2s_spk_handler == NULL) && handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1; if (i2s_spk_handler && (handler == NULL)) _eos_i2s_drvr[I2S_SPK_EVT] = 0; @@ -361,95 +364,65 @@ void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm) { set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size) { - int run = eos_i2s_running(); - +void eos_i2s_spk_set_buf(uint16_t *spk_arr, uint16_t spk_arr_size) { clear_csr(mstatus, MSTATUS_MIE); _abuf_init(&_eos_i2s_spk_buf, spk_arr, spk_arr_size); - if (run) { - if (spk_arr_size == 0) { - GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_SPK); - } else { - GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_SPK); - } - } set_csr(mstatus, MSTATUS_MIE); } -uint8_t *eos_i2s_spk_get_buf(void) { +uint16_t *eos_i2s_spk_get_buf(void) { return _eos_i2s_spk_buf.array; } uint16_t eos_i2s_spk_len(void) { - uint16_t ret; + uint16_t rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_len(&_eos_i2s_spk_buf); + rv = _abuf_len(&_eos_i2s_spk_buf); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } -uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform) { - uint16_t i; - uint16_t abuf_free; - uint8_t transform_l, transform_r; +uint16_t eos_i2s_spk_write(uint16_t *smpl_buf, uint16_t buf_len) { + int i; + uint16_t sample; + uint16_t abuf_size, abuf_len, smpl_len; clear_csr(mstatus, MSTATUS_MIE); - abuf_free = _eos_i2s_spk_buf.size - _abuf_len(&_eos_i2s_spk_buf); - if (transform) abuf_free = abuf_free / 2; - ssize = MIN(ssize, abuf_free); - set_csr(mstatus, MSTATUS_MIE); - - transform_l = (transform == EOS_I2S_TRANS_MONO2D) || (transform == EOS_I2S_TRANS_MONO2L); - transform_r = (transform == EOS_I2S_TRANS_MONO2D) || (transform == EOS_I2S_TRANS_MONO2R); - if (transform) { - if (_eos_i2s_drvr[I2S_FMT] == EOS_I2S_FMT_PCM16) { - for (i=0; i<ssize / 2; i++) { - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4, _eos_i2s_spk_buf.size)] = transform_l ? sample[i * 2] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 2, _eos_i2s_spk_buf.size)] = transform_r ? sample[i * 2] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 1, _eos_i2s_spk_buf.size)] = transform_l ? sample[i * 2 + 1] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 3, _eos_i2s_spk_buf.size)] = transform_r ? sample[i * 2 + 1] : 0; - } - } else { - for (i=0; i<ssize; i++) { - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 2, _eos_i2s_spk_buf.size)] = transform_l ? sample[i] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 2 + 1, _eos_i2s_spk_buf.size)] = transform_r ? sample[i] : 0; - } - } - } else { - for (i=0; i<ssize; i++) { - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample[i]; - } + abuf_size = _abuf_size(&_eos_i2s_spk_buf); + abuf_len = _abuf_len(&_eos_i2s_spk_buf); + smpl_len = MIN(buf_len, abuf_size - abuf_len); + if (smpl_len && abuf_len) { + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w - 1, _eos_i2s_spk_buf.size)] |= smpl_buf[0] >> 15; } - - if (transform) ssize *= 2; - - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_spk_buf.idx_w += ssize; set_csr(mstatus, MSTATUS_MIE); - return ssize; -} + if (smpl_len == 0) return 0; -int eos_i2s_spk_push8(uint8_t sample) { - int ret; + for (i=0; i<smpl_len; i++) { + sample = smpl_buf[i] << 1; + if (i + 1 < smpl_len) { + sample |= (smpl_buf[i + 1] >> 15); + } + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample; + } clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_push8(&_eos_i2s_spk_buf, sample); + _eos_i2s_spk_buf.idx_w += smpl_len; set_csr(mstatus, MSTATUS_MIE); - return ret; + return smpl_len; } -int eos_i2s_spk_push16(uint16_t sample) { - int ret; +int eos_i2s_spk_push(uint16_t sample) { + int rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_push16(&_eos_i2s_spk_buf, sample); + rv = _sbuf_push(sample); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } int eos_i2s_spk_get_vol(void) { @@ -465,3 +438,15 @@ void eos_i2s_spk_set_vol(int vol) { i2s_set_cmp(); set_csr(mstatus, MSTATUS_MIE); } + +void eos_i2s_hp_change(int hp_det) { + if (hp_det) { + int rv; + + rv = eos_hpamp_init(); + if (rv) { + EOS_LOG(EOS_LOG_ERR, "I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv); + return; + } + } +} diff --git a/fw/fe310/eos/soc/i2s.h b/fw/fe310/eos/soc/i2s.h index c5e92b7..ef2b966 100644 --- a/fw/fe310/eos/soc/i2s.h +++ b/fw/fe310/eos/soc/i2s.h @@ -1,40 +1,41 @@ #include <stdint.h> #include "i2s_def.h" +#include "../event.h" + +#define EOS_I2S_MODE_STEREO 0 +#define EOS_I2S_MODE_MONO_L 1 +#define EOS_I2S_MODE_MONO_R 2 typedef struct EOSABuf { uint16_t idx_r; uint16_t idx_w; uint16_t size; - uint8_t *array; + uint16_t *array; } EOSABuf; -typedef void (*eos_i2s_handler_t) (unsigned char); - -int eos_i2s_init(uint8_t wakeup_cause); -void eos_i2s_init_mux(void); -void eos_i2s_start(uint32_t sample_rate); +int eos_i2s_init(void); +int eos_i2s_start(uint32_t sample_rate, int mode); void eos_i2s_stop(void); int eos_i2s_running(void); -void eos_i2s_set_fmt(unsigned char fmt); -void eos_i2s_set_mode(unsigned char mode); +int eos_i2s_set_lsgain(int gain); -void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm); -void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size); -uint8_t *eos_i2s_mic_get_buf(void); +void eos_i2s_mic_set_handler(eos_evt_simple_handler_t handler, uint16_t wm); +void eos_i2s_mic_set_buf(uint16_t *mic_arr, uint16_t mic_arr_size); +uint16_t *eos_i2s_mic_get_buf(void); uint16_t eos_i2s_mic_len(void); -uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize); -int eos_i2s_mic_pop8(uint8_t *sample); -int eos_i2s_mic_pop16(uint16_t *sample); +uint16_t eos_i2s_mic_read(uint16_t *smpl_buf, uint16_t buf_size); +int eos_i2s_mic_pop(uint16_t *sample); int eos_i2s_mic_get_vol(void); void eos_i2s_mic_set_vol(int vol); -void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm); -void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size); -uint8_t *eos_i2s_spk_get_buf(void); +void eos_i2s_spk_set_handler(eos_evt_simple_handler_t handler, uint16_t wm); +void eos_i2s_spk_set_buf(uint16_t *spk_arr, uint16_t spk_arr_size); +uint16_t *eos_i2s_spk_get_buf(void); uint16_t eos_i2s_spk_len(void); -uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform); -int eos_i2s_spk_push8(uint8_t sample); -int eos_i2s_spk_push16(uint16_t sample); +uint16_t eos_i2s_spk_write(uint16_t *smpl_buf, uint16_t buf_len); +int eos_i2s_spk_push(uint16_t sample); int eos_i2s_spk_get_vol(void); void eos_i2s_spk_set_vol(int vol); + +void eos_i2s_hp_change(int hp_det); diff --git a/fw/fe310/eos/soc/i2s_def.h b/fw/fe310/eos/soc/i2s_def.h index 44eed25..d8c4b4b 100644 --- a/fw/fe310/eos/soc/i2s_def.h +++ b/fw/fe310/eos/soc/i2s_def.h @@ -1,13 +1,2 @@ -#define EOS_I2S_FMT_PCM16 0 -#define EOS_I2S_FMT_ALAW 1 - -#define EOS_I2S_MODE_STEREO 0 -#define EOS_I2S_MODE_MONO 1 - #define EOS_I2S_ETYPE_MIC 1 #define EOS_I2S_ETYPE_SPK 2 - -#define EOS_I2S_TRANS_NONE 0 -#define EOS_I2S_TRANS_MONO2D 1 -#define EOS_I2S_TRANS_MONO2L 2 -#define EOS_I2S_TRANS_MONO2R 3
\ No newline at end of file diff --git a/fw/fe310/eos/soc/i2s_priv.h b/fw/fe310/eos/soc/i2s_priv.h index 25014a5..6927c36 100644 --- a/fw/fe310/eos/soc/i2s_priv.h +++ b/fw/fe310/eos/soc/i2s_priv.h @@ -1,13 +1,10 @@ -#define I2S_PWM_SCALE_CK 2 -#define I2S_PWM_SCALE_CK_MASK 0x0003 - /* asm */ #define I2S_ABUF_OFF_IDXR 0 #define I2S_ABUF_OFF_IDXW 2 #define I2S_ABUF_OFF_SIZE 4 #define I2S_ABUF_OFF_ARRAY 8 -#define I2S_IRQ_SD_ID INT_GPIO_BASE + I2S_PIN_INT +#define I2S_IRQ_ID INT_GPIO_BASE + I2S_PIN_INT #define I2S_CTRL_ADDR_CK PWM0_CTRL_ADDR #define I2S_CTRL_ADDR_WS PWM1_CTRL_ADDR diff --git a/fw/fe310/eos/soc/interrupt.c b/fw/fe310/eos/soc/interrupt.c index dab6fab..2243f0a 100644 --- a/fw/fe310/eos/soc/interrupt.c +++ b/fw/fe310/eos/soc/interrupt.c @@ -1,13 +1,13 @@ #include <stdlib.h> #include <stdint.h> #include <unistd.h> -#include <stdio.h> #include "encoding.h" #include "platform.h" #include "plic_driver.h" #include "eos.h" +#include "log.h" #include "interrupt.h" // Global Instance data for the PLIC @@ -20,13 +20,13 @@ uintptr_t eos_intr_handle(uintptr_t int_num) { if ((int_num >=1) && (int_num <= PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num-1])) { ext_interrupt_handler[int_num-1](); } else { - printf("INTR ERROR:%d\n", int_num); + EOS_LOG(EOS_LOG_ERR, "INTR ERROR:%d\n", int_num); exit(int_num); } return int_num; } -int eos_intr_init(uint8_t wakeup_cause) { +int eos_intr_init(void) { for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){ ext_interrupt_handler[i] = NULL; } diff --git a/fw/fe310/eos/soc/interrupt.h b/fw/fe310/eos/soc/interrupt.h index c6252b5..6cb446f 100644 --- a/fw/fe310/eos/soc/interrupt.h +++ b/fw/fe310/eos/soc/interrupt.h @@ -4,7 +4,7 @@ typedef void (*eos_intr_handler_t) (void); -int eos_intr_init(uint8_t wakeup_cause); +int eos_intr_init(void); void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_handler_t handler); void eos_intr_set_handler(uint8_t int_num, eos_intr_handler_t handler); void eos_intr_set_priority(uint8_t int_num, uint8_t priority); diff --git a/fw/fe310/eos/soc/pwr.c b/fw/fe310/eos/soc/pwr.c index db9f273..84915ef 100644 --- a/fw/fe310/eos/soc/pwr.c +++ b/fw/fe310/eos/soc/pwr.c @@ -12,8 +12,8 @@ #define PWR_RTC_SCALE 15 #define PWR_RTC_SFREQ (EOS_TIMER_RTC_FREQ >> PWR_RTC_SCALE) -int eos_pwr_init(uint8_t wakeup_cause) { - AON_REG(AON_PMUKEY) = 0x51F15E; +int eos_pwr_init(void) { + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUIE) = 0x5; AON_REG(AON_RTCCMP) = 0xFFFFFFFF; @@ -33,7 +33,7 @@ uint8_t eos_pwr_reset_cause(void) { } void eos_pwr_sleep(void) { - AON_REG(AON_PMUKEY) = 0x51F15E; + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUSLEEP) = 1; } @@ -43,8 +43,8 @@ void eos_pwr_wake_at(uint32_t msec) { AON_REG(AON_RTCCFG) |= AON_RTCCFG_ENALWAYS; AON_REG(AON_RTCCMP) = msec * PWR_RTC_SFREQ / 1000; - pmuie = AON_REG(AON_PMUIE) | 0x2; - AON_REG(AON_PMUKEY) = 0x51F15E; + pmuie = AON_REG(AON_PMUIE) | (1 << AON_WAKEUPCAUSE_RTC); + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUIE) = pmuie; } @@ -56,7 +56,7 @@ void eos_pwr_wake_disable(void) { AON_REG(AON_RTCHI) = 0; AON_REG(AON_RTCLO) = 0; - pmuie = AON_REG(AON_PMUIE) & ~0x2; - AON_REG(AON_PMUKEY) = 0x51F15E; + pmuie = AON_REG(AON_PMUIE) & ~(1 << AON_WAKEUPCAUSE_RTC); + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUIE) = pmuie; } diff --git a/fw/fe310/eos/soc/pwr.h b/fw/fe310/eos/soc/pwr.h index 0af4c1b..8aeb0a8 100644 --- a/fw/fe310/eos/soc/pwr.h +++ b/fw/fe310/eos/soc/pwr.h @@ -2,13 +2,13 @@ #define EOS_PWR_WAKE_RST 0 #define EOS_PWR_WAKE_RTC 1 -#define EOS_PWR_WAKE_BTN 2 +#define EOS_PWR_WAKE_PIN 2 #define EOS_PWR_RST_PWRON 0 #define EOS_PWR_RST_EXT 1 #define EOS_PWR_RST_WDOG 2 -int eos_pwr_init(uint8_t wakeup_cause); +int eos_pwr_init(void); uint8_t eos_pwr_wakeup_cause(void); uint8_t eos_pwr_reset_cause(void); void eos_pwr_sleep(void); diff --git a/fw/fe310/eos/soc/spi.c b/fw/fe310/eos/soc/spi.c index 1806f50..a337924 100644 --- a/fw/fe310/eos/soc/spi.c +++ b/fw/fe310/eos/soc/spi.c @@ -3,13 +3,15 @@ #include "encoding.h" #include "platform.h" +#include "board.h" #include "eos.h" -#include "msgq.h" +#include "log.h" #include "interrupt.h" #include "event.h" -#include "board.h" +#include "dev/egpio.h" +#include "dev/egpio_priv.h" #include "spi.h" #include "spi_priv.h" @@ -21,37 +23,36 @@ #define SPI_FLAG_XCHG 0x10 -#define SPI_CSID_NONE 1 - #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) static uint8_t spi_cspin; static volatile uint8_t spi_state_flags; static unsigned char spi_evt; -static unsigned char spi_in_xchg; static uint32_t spi_state_len = 0; static uint32_t spi_state_idx_tx = 0; static uint32_t spi_state_idx_rx = 0; static unsigned char *spi_state_buf = NULL; +static uint16_t spi_state_buf_sz = 0; -static eos_evt_handler_t evt_handler[EOS_SPI_MAX_EVT]; +static eos_evt_handler_t spi_handler[EOS_SPI_MAX_ETYPE]; -static void spi_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = (type & ~EOS_EVT_MASK) - 1; - if (idx < EOS_SPI_MAX_EVT) { - evt_handler[idx](type, buffer, len); +static void spi_handle_evt(unsigned char type, EOSMessage *msg, uint16_t len) { + unsigned char idx = type & ~EOS_EVT_MASK; + + if (idx && (idx <= EOS_SPI_MAX_ETYPE) && spi_handler[idx - 1]) { + spi_handler[idx - 1](type & ~EOS_EVT_MASK, msg, len); } else { - eos_evtq_bad_handler(type, buffer, len); + eos_evtq_bad_handler(type, msg, len); } } -int eos_spi_init(uint8_t wakeup_cause) { +int eos_spi_init(void) { int i; - for (i=0; i<EOS_SPI_MAX_EVT; i++) { - evt_handler[i] = eos_evtq_bad_handler; + for (i=0; i<EOS_SPI_MAX_ETYPE; i++) { + spi_handler[i] = eos_evtq_bad_handler; } eos_evtq_set_handler(EOS_EVT_SPI, spi_handle_evt); eos_intr_set_priority(INT_SPI1_BASE, IRQ_PRIORITY_SPI_XCHG); @@ -63,31 +64,31 @@ int eos_spi_init(uint8_t wakeup_cause) { SPI_FMT_DIR(SPI_DIR_RX) | SPI_FMT_LEN(8); - /* for spi 9bit protocol */ - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_SCK); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_MOSI); - GPIO_REG(GPIO_INPUT_EN) |= (1 << IOF_SPI1_MISO); + /* CS assert to SCK: 1 clock cycles + SCK to CS deassert: 0 clock cycles */ + SPI1_REG(SPI_REG_DCSSCK) = 0x01; + + GPIO_REG(GPIO_OUTPUT_XOR) |= SPI_IOF_CSXOR; eos_spi_enable(); return EOS_OK; } -void eos_spi_configure(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt) { +void eos_spi_configure(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt) { spi_state_flags = 0; spi_evt = evt; SPI1_REG(SPI_REG_SCKDIV) = div; - if (csid != -1) { - SPI1_REG(SPI_REG_CSID) = csid; + SPI1_REG(SPI_REG_CSID) = csid; + if (csid != SPI_CSID_NONE) { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; } else { spi_cspin = cspin; - SPI1_REG(SPI_REG_CSID) = SPI_CSID_NONE; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_OFF; } } -void eos_spi_start(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt) { +void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt) { eos_spi_configure(div, csid, cspin, evt); eos_intr_set_handler(INT_SPI1_BASE, eos_spi_handle_xchg); } @@ -113,20 +114,21 @@ void eos_spi_disable(void) { void eos_spi_set_handler(unsigned char evt, eos_evt_handler_t handler) { if (handler == NULL) handler = eos_evtq_bad_handler; - if (evt && (evt <= EOS_SPI_MAX_EVT)) evt_handler[evt - 1] = handler; + if (evt && (evt <= EOS_SPI_MAX_ETYPE)) spi_handler[evt - 1] = handler; } -void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags) { +void _eos_spi_xchg_init(unsigned char *buffer, uint16_t size, uint16_t len, uint8_t flags) { spi_state_flags &= 0xF0; spi_state_flags |= (SPI_FLAG_XCHG | flags); spi_state_buf = buffer; + spi_state_buf_sz = size; spi_state_len = len; spi_state_idx_tx = 0; spi_state_idx_rx = 0; } static void spi_wait4xchg(void) { - uint8_t done = 0; + int done = 0; while (!done) { clear_csr(mstatus, MSTATUS_MIE); @@ -134,23 +136,25 @@ static void spi_wait4xchg(void) { if (!done) asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); } - spi_in_xchg = 0; } -void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags) { - if (spi_in_xchg) spi_wait4xchg(); +int eos_spi_xchg(EOSMessage *msg, uint16_t len, uint8_t flags) { + if (!spi_evt) return EOS_ERR; - spi_in_xchg = 1; - _eos_spi_xchg_init(buffer, len, flags); + spi_wait4xchg(); - eos_spi_cs_set(); + _eos_spi_xchg_init(msg->buffer, msg->size, len, flags); + + eos_spi_set_cs(); SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM); SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM; + + return EOS_OK; } void eos_spi_handle_xchg(void) { - int i; uint16_t sz_chunk = MIN(spi_state_len - spi_state_idx_tx, SPI_SIZE_CHUNK); + int i; for (i=0; i<sz_chunk; i++) { volatile uint32_t x = SPI1_REG(SPI_REG_TXFIFO); @@ -174,10 +178,21 @@ void eos_spi_handle_xchg(void) { SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); return; } - spi_state_flags &= ~SPI_FLAG_XCHG; - if (!(spi_state_flags & EOS_SPI_FLAG_MORE)) eos_spi_cs_clear(); - SPI1_REG(SPI_REG_IE) = 0x0; - if (spi_evt) eos_evtq_push_isr(EOS_EVT_SPI | spi_evt, spi_state_buf, spi_state_len); + SPI1_REG(SPI_REG_IE) = 0; + if (!(spi_state_flags & EOS_SPI_FLAG_MORE)) eos_spi_clear_cs(); + + /* clear SPI_FLAG_XCHG flag and all of EOS_SPI_FLAG_* */ + spi_state_flags &= (~SPI_FLAG_XCHG & 0xF0); + + if (spi_evt) { + EOSMessage msg; + int rv; + + msg.buffer = spi_state_buf; + msg.size = spi_state_buf_sz; + rv = eos_evtq_push_isr(EOS_EVT_SPI | spi_evt, &msg, spi_state_len); + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI XCHG EVTQ PUSH ERR:%d\n", rv); + } } else { SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_state_len - spi_state_idx_rx - 1, SPI_SIZE_WM - 1)); SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; @@ -185,23 +200,40 @@ void eos_spi_handle_xchg(void) { } } -void eos_spi_cs_set(void) { - /* cs low */ +int eos_spi_get_cs(void) { if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { - clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << spi_cspin); - set_csr(mstatus, MSTATUS_MIE); + if (spi_cspin & SPI_CSFLAG_EGPIO) { + return !eos_egpio_get_val(spi_cspin & ~SPI_CSFLAG_EGPIO); + } else { + return !(GPIO_REG(GPIO_OUTPUT_VAL) & (1 << spi_cspin)); + } + } else { + return (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_HOLD); + } +} + +void eos_spi_set_cs(void) { + /* cs low */ + if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { + if (spi_cspin & SPI_CSFLAG_EGPIO) { + eos_egpio_set_val(spi_cspin & ~SPI_CSFLAG_EGPIO, 0); + } else { + GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << spi_cspin); + } } else { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; } } -void eos_spi_cs_clear(void) { - /* cs high */ +/* can be called from interrupt handler */ +void eos_spi_clear_cs(void) { + /* cs high */ if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { - clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cspin); - set_csr(mstatus, MSTATUS_MIE); + if (spi_cspin & SPI_CSFLAG_EGPIO) { + eos_egpio_set_val(spi_cspin & ~SPI_CSFLAG_EGPIO, 1); + } else { + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cspin); + } } else { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; } @@ -360,11 +392,18 @@ uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags) { } void eos_spi_flush(void) { - if (spi_in_xchg) { - spi_wait4xchg(); - } else { - SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); - while (!(SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM)); - while (!(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY)); - } + uint32_t mcycle_start, mcycle_wait; + + spi_wait4xchg(); + + SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); + while (!(SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM)); + + /* wait for last frame to be transmitted: 9 spi clock cycles */ + mcycle_wait = 9*2*((SPI1_REG(SPI_REG_SCKDIV) & 0xFFF)+1); + mcycle_start = read_csr(mcycle); + + while ((read_csr(mcycle) - mcycle_start) < mcycle_wait); + + while (!(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY)); } diff --git a/fw/fe310/eos/soc/spi.h b/fw/fe310/eos/soc/spi.h index 0c2de4b..6ded15f 100644 --- a/fw/fe310/eos/soc/spi.h +++ b/fw/fe310/eos/soc/spi.h @@ -1,30 +1,32 @@ #include <stdint.h> + #include "../event.h" #define EOS_SPI_FLAG_TX 0x01 #define EOS_SPI_FLAG_MORE 0x02 #define EOS_SPI_FLAG_BSWAP 0x04 -#define EOS_SPI_EVT_SDC 1 -#define EOS_SPI_EVT_CAM 2 +#define EOS_SPI_ETYPE_SDC 1 +#define EOS_SPI_ETYPE_CAM 2 -#define EOS_SPI_MAX_EVT 2 +#define EOS_SPI_MAX_ETYPE 2 -int eos_spi_init(uint8_t wakeup_cause); -void eos_spi_configure(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt); -void eos_spi_start(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt); +int eos_spi_init(void); +void eos_spi_configure(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt); +void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt); void eos_spi_stop(void); void eos_spi_enable(void); void eos_spi_disable(void); void eos_spi_set_handler(unsigned char evt, eos_evt_handler_t handler); -void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags); -void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags); +void _eos_spi_xchg_init(unsigned char *buffer, uint16_t size, uint16_t len, uint8_t flags); +int eos_spi_xchg(EOSMessage *msg, uint16_t len, uint8_t flags); void eos_spi_handle_xchg(void); -void eos_spi_cs_set(void); -void eos_spi_cs_clear(void); +int eos_spi_get_cs(void); +void eos_spi_set_cs(void); +void eos_spi_clear_cs(void); uint8_t eos_spi_xchg8(uint8_t data, uint8_t flags); uint16_t eos_spi_xchg16(uint16_t data, uint8_t flags); uint32_t eos_spi_xchg24(uint32_t data, uint8_t flags); diff --git a/fw/fe310/eos/soc/spi9bit.c b/fw/fe310/eos/soc/spi9bit.c index e48e9e2..a536637 100644 --- a/fw/fe310/eos/soc/spi9bit.c +++ b/fw/fe310/eos/soc/spi9bit.c @@ -11,10 +11,10 @@ #include "spi9bit.h" #define BIT_GET ((GPIO_REG(GPIO_INPUT_VAL) & (1 << IOF_SPI1_MISO)) >> IOF_SPI1_MISO) -#define BIT_PUT(b) { clear_csr(mstatus, MSTATUS_MIE); if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); set_csr(mstatus, MSTATUS_MIE); } +#define BIT_PUT(b) { if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); } -#define SCK_UP { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); } -#define SCK_DN { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); } +#define SCK_UP { GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_SCK); } +#define SCK_DN { GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_SCK); } static inline void _sleep(int n) { volatile int x = n; @@ -22,7 +22,19 @@ static inline void _sleep(int n) { while(x) x--; } -/* sck frequency for r/w operations is 0.8Mhz */ +void eos_spi9bit_start(void) { + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_SCK); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_MOSI); + GPIO_REG(GPIO_INPUT_EN) |= (1 << IOF_SPI1_MISO); +} + +void eos_spi9bit_stop(void) { + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << IOF_SPI1_SCK); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << IOF_SPI1_MOSI); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << IOF_SPI1_MISO); +} + +/* sck frequency for r/w operations is ~ 0.8Mhz */ void eos_spi9bit_read(uint8_t *data) { int i; diff --git a/fw/fe310/eos/soc/spi9bit.h b/fw/fe310/eos/soc/spi9bit.h index dd3c254..fb89856 100644 --- a/fw/fe310/eos/soc/spi9bit.h +++ b/fw/fe310/eos/soc/spi9bit.h @@ -1,4 +1,6 @@ #include <stdint.h> +void eos_spi9bit_start(void); +void eos_spi9bit_stop(void); void eos_spi9bit_read(uint8_t *data); void eos_spi9bit_write(uint8_t dc, uint8_t data); diff --git a/fw/fe310/eos/soc/spi_priv.h b/fw/fe310/eos/soc/spi_priv.h index 17081a3..20e4088 100644 --- a/fw/fe310/eos/soc/spi_priv.h +++ b/fw/fe310/eos/soc/spi_priv.h @@ -3,3 +3,6 @@ /* DO NOT TOUCH THEESE */ #define SPI_SIZE_CHUNK 4 #define SPI_SIZE_WM 2 + +#define SPI_CSFLAG_EGPIO 0x80 +#define SPI_CSID_NONE 1 diff --git a/fw/fe310/eos/soc/timer.c b/fw/fe310/eos/soc/timer.c index 8d74c6d..f26f601 100644 --- a/fw/fe310/eos/soc/timer.c +++ b/fw/fe310/eos/soc/timer.c @@ -5,23 +5,22 @@ #include "platform.h" #include "eos.h" -#include "msgq.h" #include "event.h" #include "timer.h" #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -static eos_timer_handler_t timer_handler[EOS_TIMER_MAX_ETYPE + 1]; +static eos_evt_simple_handler_t timer_handler[EOS_TIMER_MAX_ETYPE + 1]; static uint64_t timer_next[EOS_TIMER_MAX_ETYPE + 1]; -static void timer_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = (type & ~EOS_EVT_MASK); +static void timer_handle_evt(unsigned char type, EOSMessage *msg, uint16_t len) { + unsigned char idx = type & ~EOS_EVT_MASK; if (idx && (idx <= EOS_TIMER_MAX_ETYPE) && timer_handler[idx]) { - timer_handler[idx](type); + timer_handler[idx](type & ~EOS_EVT_MASK); } else { - eos_evtq_bad_handler(type, buffer, len); + eos_evtq_bad_handler(type, msg, len); } } @@ -48,7 +47,7 @@ void _eos_timer_handle(void) { if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); } -int eos_timer_init(uint8_t wakeup_cause) { +int eos_timer_init(void) { uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); int i; @@ -63,7 +62,7 @@ int eos_timer_init(uint8_t wakeup_cause) { return EOS_OK; } -void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler) { +void eos_timer_set_handler(unsigned char evt, eos_evt_simple_handler_t handler) { uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); if (!evt && (*mtimecmp != 0)) clear_csr(mie, MIP_MTIP); @@ -75,18 +74,18 @@ uint32_t eos_timer_get(unsigned char evt) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); uint64_t now; - uint32_t ret; + uint32_t rv; if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); now = *mtime; if (timer_next[evt]) { - ret = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0; + rv = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0; } else { - ret = EOS_TIMER_NONE; + rv = EOS_TIMER_NONE; } if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); - return ret; + return rv; } void eos_timer_set(unsigned char evt, uint32_t msec) { @@ -121,24 +120,24 @@ void eos_timer_clear(unsigned char evt) { if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } -void eos_time_sleep(uint32_t msec) { +void eos_sleep(uint32_t msec) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); uint32_t mtime0 = *mtime; while ((*mtime - mtime0) < (msec * EOS_TIMER_RTC_FREQ / 1000 + 1)); } -uint32_t eos_time_get_tick(void) { +uint32_t eos_get_tick(void) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); return *mtime; } -uint64_t eos_time_get_tick64(void) { +uint64_t eos_get_tick64(void) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); return *mtime; } -uint32_t eos_time_delta_ms(uint32_t tick) { - return (eos_time_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ; +uint32_t eos_tdelta_ms(uint32_t tick) { + return (eos_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ; } diff --git a/fw/fe310/eos/soc/timer.h b/fw/fe310/eos/soc/timer.h index 227aeee..ef4005c 100644 --- a/fw/fe310/eos/soc/timer.h +++ b/fw/fe310/eos/soc/timer.h @@ -1,5 +1,7 @@ #include <stdint.h> +#include "../event.h" + #define EOS_TIMER_ETYPE_UI 1 #define EOS_TIMER_ETYPE_EVE 2 #define EOS_TIMER_ETYPE_ECP 3 @@ -10,16 +12,14 @@ #define EOS_TIMER_NONE -1 #define EOS_TIMER_RTC_FREQ 32768 -typedef void (*eos_timer_handler_t) (unsigned char); - -int eos_timer_init(uint8_t wakeup_cause); -void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler); +int eos_timer_init(void); +void eos_timer_set_handler(unsigned char evt, eos_evt_simple_handler_t handler); uint32_t eos_timer_get(unsigned char evt); void eos_timer_set(unsigned char evt, uint32_t msec); void eos_timer_clear(unsigned char evt); -void eos_time_sleep(uint32_t msec); -uint32_t eos_time_get_tick(void); -uint64_t eos_time_get_tick64(void); -uint32_t eos_time_delta_ms(uint32_t tick); +void eos_sleep(uint32_t msec); +uint32_t eos_get_tick(void); +uint64_t eos_get_tick64(void); +uint32_t eos_tdelta_ms(uint32_t tick); diff --git a/fw/fe310/eos/soc/trap_entry.S b/fw/fe310/eos/soc/trap_entry.S index 98f9267..19f4502 100644 --- a/fw/fe310/eos/soc/trap_entry.S +++ b/fw/fe310/eos/soc/trap_entry.S @@ -28,12 +28,10 @@ #define INT_PWM1_BASE 44 #define INT_PWM2_BASE 48 -#define I2S_FMT (0*4) -#define I2S_MODE (1*4) -#define I2S_MIC_WM (2*4) -#define I2S_SPK_WM (3*4) -#define I2S_MIC_EVT (4*4) -#define I2S_SPK_EVT (5*4) +#define I2S_MIC_WM (0*4) +#define I2S_SPK_WM (1*4) +#define I2S_MIC_EVT (2*4) +#define I2S_SPK_EVT (3*4) #include "board.h" #include "irq_def.h" @@ -57,8 +55,8 @@ eos_trap_vector: STORE x22, 6*REGBYTES(sp) STORE x23, 7*REGBYTES(sp) STORE x24, 8*REGBYTES(sp) - STORE x25, 9*REGBYTES(sp) # channel: 0 - left; 1 - right - STORE x26, 10*REGBYTES(sp) # format: 0 - PCM16; 1 - ALAW + STORE x25, 9*REGBYTES(sp) + STORE x26, 10*REGBYTES(sp) # unused STORE x27, 11*REGBYTES(sp) # _eos_i2s_drvr addr csrr x8, mcause @@ -66,7 +64,7 @@ eos_trap_vector: bne x8, x18, handle_intr li x18, PLIC_CLAIM lw x9, 0(x18) - li x18, I2S_IRQ_SD_ID + li x18, I2S_IRQ_ID beq x9, x18, i2s_handle_sd j handle_intr @@ -82,30 +80,22 @@ evtq_push: addi x20, x20, -1 and x20, x20, x19 + + addi x19, x19, 1 + sb x19, MSGQ_OFF_IDXW(x9) + li x18, MSGQ_ITEM_SIZE mul x20, x20, x18 lw x21, MSGQ_OFF_ARRAY(x9) add x21, x21, x20 - - addi x19, x19, 1 - sb x19, MSGQ_OFF_IDXW(x9) jalr x0, x22 0: - mv x20, x0 - jalr x0, x21 + mv x21, x0 + jalr x0, x22 i2s_handle_sd: - # store channel bit to x25 - li x18, I2S_CTRL_ADDR_WS - lw x18, PWM_CFG(x18) - # 29th - pwmcmp1ip bit - li x19, (1 << 29) - and x25, x18, x19 - srli x25, x25, 29 - la x27, _eos_i2s_drvr - lw x26, I2S_FMT(x27) i2s_abuf_pop: # pop from spk buf -> x8 @@ -115,107 +105,55 @@ i2s_abuf_pop: lhu x20, I2S_ABUF_OFF_SIZE(x9) beqz x20, i2s_sd_xchg - beq x18, x19, 2f + beq x18, x19, 0f addi x20, x20, -1 and x20, x20, x18 - lw x21, I2S_ABUF_OFF_ARRAY(x9) - add x21, x21, x20 - beqz x26, 0f - mv x22, x18 - lbu x8, 0(x21) + addi x18, x18, 1 - j 1f -0: - srli x22, x18, 1 - lb x8, 0(x21) - lbu x20, 1(x21) - slli x8, x8, 8 - or x8, x8, x20 - addi x18, x18, 2 -1: sh x18, I2S_ABUF_OFF_IDXR(x9) - # check if buf data is for correct channel if mode is stereo - lw x21, I2S_MODE(x27) - bnez x21, 2f - andi x22, x22, 1 - xor x22, x22, x25 - beqz x22, i2s_abuf_pop + # uint16_t array + slli x20, x20, 1 + lw x21, I2S_ABUF_OFF_ARRAY(x9) + add x21, x21, x20 + lh x8, 0(x21) -2: +0: li x21, 0xffff sub x18, x19, x18 and x18, x18, x21 # check for push to event queue lw x9, I2S_SPK_WM(x27) - bgtu x18, x9, i2s_decode + bgtu x18, x9, i2s_sd_xchg lw x9, I2S_SPK_EVT(x27) - beqz x9, i2s_decode + beqz x9, i2s_sd_xchg sw x0, I2S_SPK_EVT(x27) # push to event queue jal x22, evtq_push - beqz x21, i2s_decode + beqz x21, i2s_sd_xchg li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_SPK) sb x18, MSGQ_ITEM_OFF_TYPE(x21) -i2s_decode: - beqz x26, 3f - # aLaw decode -> x8 - xori x8, x8, 0x55 - andi x9, x8, 0x80 - beqz x9, 0f - li x9, (1 << 7) - not x9, x9 - and x8, x8, x9 - li x9, -1 -0: - andi x18, x8, 0xf0 - srli x18, x18, 4 - addi x18, x18, 4 - - li x19, 4 - beq x18, x19, 1f - - andi x8, x8, 0x0f - addi x19, x18, -4 - sll x8, x8, x19 - - li x19, 1 - sll x19, x19, x18 - or x8, x8, x19 - - li x19, 1 - addi x18, x18, -5 - sll x19, x19, x18 - or x8, x8, x19 - j 2f -1: - slli x8, x8, 1 - ori x8, x8, 1 -2: - beqz x9, 3f - mul x8, x8, x9 -3: - i2s_sd_xchg: # read/write shift reg: x8 -> sr -> x8 + # values of GPIO_OUTPUT_EN, GPIO_INPUT_EN, GPIO_OUTPUT_VAL registers are NOT changed (no need for clear_csr / set_csr guards outside of interrupt) li x18, GPIO_CTRL_ADDR li x19, (1 << I2S_PIN_SD_IN) li x20, (1 << I2S_PIN_SD_OUT) li x21, (1 << I2S_PIN_SR_CK) lw x22, GPIO_OUTPUT_VAL(x18) - # disable intpu, enable output for I2S_PIN_SD_OUT (pin is low) - lw x9, GPIO_OUTPUT_EN(x18) - or x9, x9, x20 + # disable intput, enable output for I2S_PIN_SD_OUT (pin is low) + lw x24, GPIO_OUTPUT_EN(x18) + or x9, x24, x20 sw x9, GPIO_OUTPUT_EN(x18) not x20, x20 - lw x9, GPIO_INPUT_EN(x18) - and x9, x9, x20 + lw x25, GPIO_INPUT_EN(x18) + and x9, x25, x20 sw x9, GPIO_INPUT_EN(x18) # I2S_PIN_SR_CK bit low (was high) @@ -268,58 +206,19 @@ i2s_sd_xchg: addi x23, x23, -1 bnez x23, 0b - # I2S_PIN_SD_OUT pin low (has pull-dn) + # I2S_PIN_SD_OUT pin low (was low) and x22, x22, x20 # I2S_PIN_SR_CK pin high (74HC595 ck low) xor x22, x22, x21 sw x22, GPIO_OUTPUT_VAL(x18) - # disable output, enable input for I2S_PIN_SD_OUT - lw x9, GPIO_OUTPUT_EN(x18) - xor x9, x9, x20 - sw x9, GPIO_OUTPUT_EN(x18) - lw x9, GPIO_INPUT_EN(x18) - xor x9, x9, x20 - sw x9, GPIO_INPUT_EN(x18) + # restore input/output for I2S_PIN_SD_OUT + sw x24, GPIO_OUTPUT_EN(x18) + sw x25, GPIO_INPUT_EN(x18) slli x8, x8, 16 srai x8, x8, 16 - # skip right mic channel - bnez x25, i2s_sd_complete - -i2s_encode: - beqz x26, i2s_abuf_push - # aLaw encode -> x8 - li x18, 0x800 - li x19, 7 - bgez x8, 0f - neg x8, x8 - lui x9, 0x80000 - or x8, x8, x9 -0: - and x9, x8, x18 - beq x9, x18, 1f - beqz x19, 1f - srli x18, x18, 1 - addi x19, x19, -1 - j 0b -1: - mv x9, x19 - bnez x9, 2f - addi x9, x9, 1 -2: - sra x8, x8, x9 - li x9, 0x8000000f - and x8, x8, x9 - slli x19, x19, 4 - or x8, x8, x19 - bgez x8, 3f - ori x8, x8, 0x80 -3: - xori x8, x8, 0x55 - andi x8, x8, 0xff - i2s_abuf_push: # push to mic buf la x9, _eos_i2s_mic_buf @@ -331,27 +230,22 @@ i2s_abuf_push: sub x18, x19, x18 and x18, x18, x21 - beq x18, x20, 2f + beq x18, x20, 0f addi x20, x20, -1 and x20, x20, x19 + + addi x19, x19, 1 + sh x19, I2S_ABUF_OFF_IDXW(x9) + + # uint16_t array + slli x20, x20, 1 lw x21, I2S_ABUF_OFF_ARRAY(x9) add x21, x21, x20 - beqz x26, 0f - sb x8, 0(x21) - addi x19, x19, 1 + sh x8, 0(x21) addi x18, x18, 1 - j 1f -0: - sb x8, 1(x21) - srli x8, x8, 8 - sb x8, 0(x21) - addi x19, x19, 2 - addi x18, x18, 2 -1: - sh x19, I2S_ABUF_OFF_IDXW(x9) -2: +0: # check for push to event queue lw x9, I2S_MIC_WM(x27) bltu x18, x9, i2s_sd_complete @@ -371,7 +265,7 @@ i2s_sd_complete: li x19, (1 << I2S_PIN_INT) sw x19, GPIO_FALL_IP(x18) - li x18, I2S_IRQ_SD_ID + li x18, I2S_IRQ_ID li x19, PLIC_CLAIM sw x18, 0(x19) @@ -393,7 +287,8 @@ _eos_i2s_start_pwm: li x18, I2S_CTRL_ADDR_CK li x19, I2S_CTRL_ADDR_WS li x20, I2S_CTRL_ADDR_SR_SEL - li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK + li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP + or x21, x21, a0 li x22, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG li x23, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG sw x21, PWM_CFG(x18) @@ -414,8 +309,8 @@ _eos_i2s_start_pwm: trap_exit_data: # Remain in M-mode after mret - li x18, MSTATUS_MPP - csrs mstatus, x18 + # li x18, MSTATUS_MPP + # csrs mstatus, x18 LOAD x8, 0*REGBYTES(sp) LOAD x9, 1*REGBYTES(sp) @@ -483,8 +378,8 @@ handle_ext: trap_exit_text: # Remain in M-mode after mret - li t0, MSTATUS_MPP - csrs mstatus, t0 + # li t0, MSTATUS_MPP + # csrs mstatus, t0 LOAD x1, 0*REGBYTES(sp) LOAD x2, 1*REGBYTES(sp) diff --git a/fw/fe310/eos/soc/uart.c b/fw/fe310/eos/soc/uart.c index 1cff781..a5ba35f 100644 --- a/fw/fe310/eos/soc/uart.c +++ b/fw/fe310/eos/soc/uart.c @@ -13,15 +13,15 @@ #include "uart.h" -static eos_uart_handler_t uart_handler[EOS_UART_MAX_ETYPE]; +static eos_evt_simple_handler_t uart_handler[EOS_UART_MAX_ETYPE]; -static void uart_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = (type & ~EOS_EVT_MASK) - 1; +static void uart_handle_evt(unsigned char type, EOSMessage *msg, uint16_t len) { + unsigned char idx = type & ~EOS_EVT_MASK; - if ((idx < EOS_UART_MAX_ETYPE) && uart_handler[idx]) { - uart_handler[idx](type); + if (idx && (idx <= EOS_UART_MAX_ETYPE) && uart_handler[idx - 1]) { + uart_handler[idx - 1](type & ~EOS_EVT_MASK); } else { - eos_evtq_bad_handler(type, buffer, len); + eos_evtq_bad_handler(type, msg, len); } } @@ -36,7 +36,12 @@ static void uart_handle_intr(void) { } } -int eos_uart_init(uint8_t wakeup_cause) { +void eos_uart_preinit(void) { + eos_uart_speed(EOS_UART_SPEED); + eos_uart_enable(); +} + +int eos_uart_init(void) { int i; for (i=0; i<EOS_UART_MAX_ETYPE; i++) { @@ -45,10 +50,6 @@ int eos_uart_init(uint8_t wakeup_cause) { eos_evtq_set_handler(EOS_EVT_UART, uart_handle_evt); eos_intr_set(INT_UART0_BASE, IRQ_PRIORITY_UART, uart_handle_intr); - eos_uart_speed(EOS_UART_SPEED); - - eos_uart_enable(); - return EOS_OK; } @@ -75,7 +76,7 @@ void eos_uart_speed(uint32_t baud_rate) { UART0_REG(UART_REG_DIV) = PRCI_get_cpu_freq() / baud_rate - 1; } -void eos_uart_set_handler(unsigned char type, eos_uart_handler_t handler) { +void eos_uart_set_handler(unsigned char type, eos_evt_simple_handler_t handler) { if (type && (type <= EOS_UART_MAX_ETYPE)) uart_handler[type - 1] = handler; } diff --git a/fw/fe310/eos/soc/uart.h b/fw/fe310/eos/soc/uart.h index 41329fb..93866af 100644 --- a/fw/fe310/eos/soc/uart.h +++ b/fw/fe310/eos/soc/uart.h @@ -1,5 +1,7 @@ #include <stdint.h> +#include "../event.h" + #define EOS_UART_ETYPE_TX 1 #define EOS_UART_ETYPE_RX 2 @@ -7,15 +9,14 @@ #define EOS_UART_SPEED 115200 -typedef void (*eos_uart_handler_t) (unsigned char); - -int eos_uart_init(uint8_t wakeup_cause); +void eos_uart_preinit(void); +int eos_uart_init(void); void eos_uart_enable(void); void eos_uart_disable(void); int eos_uart_enabled(void); void eos_uart_speed(uint32_t baud_rate); -void eos_uart_set_handler(unsigned char type, eos_uart_handler_t handler); +void eos_uart_set_handler(unsigned char type, eos_evt_simple_handler_t handler); void eos_uart_txwm_set(uint8_t wm); void eos_uart_txwm_clear(void); diff --git a/fw/fe310/eos/unicode.c b/fw/fe310/eos/unicode.c index af41d24..ce02ddb 100644 --- a/fw/fe310/eos/unicode.c +++ b/fw/fe310/eos/unicode.c @@ -107,6 +107,7 @@ int utf8_verify(utf8_t *str, size_t str_size, size_t *str_len) { size_t len = 0; int ch_l, rv; + ch_l = 0; while (len < str_size) { if (str_size - len < 4) { rv = utf8_len_str(str + len); |
