diff options
194 files changed, 6073 insertions, 3715 deletions
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index 2cef860..b5610c8 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -3167,8 +3167,6 @@ int ecp_pld_set_pts(unsigned char *pld, size_t pld_size, ecp_pts_t pts) { } unsigned char *ecp_pld_get_msg(unsigned char *pld, size_t pld_size) { - size_t offset; - if (pld_size < ECP_SIZE_MTYPE) return NULL; if (pld_size < (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]))) return NULL; diff --git a/ecp/src/ecp/dir/dir_client.c b/ecp/src/ecp/dir/dir_client.c index cf82754..a9bc9e3 100644 --- a/ecp/src/ecp/dir/dir_client.c +++ b/ecp/src/ecp/dir/dir_client.c @@ -185,7 +185,7 @@ void ecp_dir_set_unavailable(ECPDirList *dir_list, ecp_ecdh_public_t *public) { } } -int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPNetAddr *addr) { +int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) { ECPDHPub *key; uint16_t dir_cnt; uint32_t rnd_sel; @@ -215,7 +215,7 @@ int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPN #ifdef ECP_WITH_VCONN -ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr) { +ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, ecp_tr_addr_t *addr) { unsigned char tmp_hash[ECP_SIZE_HASH_DIGEST]; unsigned char hrw_hash[ECP_SIZE_HASH_DIGEST]; ecp_ecdh_public_t public[2]; diff --git a/ecp/src/ecp/dir/dir_client.h b/ecp/src/ecp/dir/dir_client.h index 8efed1c..a76915e 100644 --- a/ecp/src/ecp/dir/dir_client.h +++ b/ecp/src/ecp/dir/dir_client.h @@ -15,8 +15,8 @@ int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_handle int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region); void ecp_dir_set_unavailable(ECPDirList *dir_list, ecp_ecdh_public_t *public); -int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPNetAddr *addr); +int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr); #ifdef ECP_WITH_VCONN -ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr); +ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, ecp_tr_addr_t *addr); #endif diff --git a/ecp/src/platform/fe310/time.c b/ecp/src/platform/fe310/time.c index 4bf530c..5f92d7f 100644 --- a/ecp/src/platform/fe310/time.c +++ b/ecp/src/platform/fe310/time.c @@ -24,15 +24,15 @@ int ecp_tm_init(ECPContext *ctx) { } ecp_sts_t ecp_tm_get_s(void) { - return eos_time_get_tick() / EOS_TIMER_RTC_FREQ; + return eos_get_tick() / EOS_TIMER_RTC_FREQ; } ecp_sts_t ecp_tm_get_ms(void) { - return eos_time_get_tick() * 1000 / EOS_TIMER_RTC_FREQ; + return eos_get_tick() * 1000 / EOS_TIMER_RTC_FREQ; } void ecp_tm_sleep(ecp_sts_t msec) { - eos_time_sleep(msec); + eos_sleep(msec); } void ecp_tm_timer_set(ecp_sts_t next) { diff --git a/ecp/src/platform/fe310/transport.c b/ecp/src/platform/fe310/transport.c index 1ae0f56..2180e2e 100644 --- a/ecp/src/platform/fe310/transport.c +++ b/ecp/src/platform/fe310/transport.c @@ -10,31 +10,34 @@ ECPSocket *_ecp_tr_sock = NULL; unsigned char pld_buf[ECP_MAX_PLD]; -static void packet_handler(unsigned char type, unsigned char *buffer, uint16_t len) { - ECPContext *ctx; +static void packet_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) { ECP2Buffer bufs; ECPBuffer packet; ECPBuffer payload; ecp_tr_addr_t addr; + size_t hdr_size; ssize_t rv; + unsigned char *_packet; + int _rv; + + _rv = eos_sock_recvfrom(buffer, buf_len, &addr, NULL, 0); + if (!_rv) _packet = eos_sock_buf2pkt(buffer, buf_len); + if (_rv || _packet == NULL) { + if (_rv == EOS_SOCK_ERR_CLOSED) _ecp_tr_sock->sock = 0; + eos_net_free(buffer, 0); + return; + } bufs.packet = &packet; bufs.payload = &payload; - packet.buffer = buffer+EOS_SOCK_SIZE_UDP_HDR; - packet.size = EOS_NET_MTU-EOS_SOCK_SIZE_UDP_HDR; + hdr_size = _packet - buffer; + packet.buffer = _packet; + packet.size = EOS_NET_MTU - hdr_size; payload.buffer = pld_buf; payload.size = ECP_MAX_PLD; - if (len < EOS_SOCK_SIZE_UDP_HDR) { - eos_net_free(buffer, 0); - return; - } - - eos_sock_recvfrom(buffer, len, NULL, 0, &addr); - - ctx = _ecp_tr_sock->ctx; - rv = ecp_pkt_handle(_ecp_tr_sock, NULL, &addr, &bufs, len-EOS_SOCK_SIZE_UDP_HDR); + rv = ecp_pkt_handle(_ecp_tr_sock, NULL, &addr, &bufs, buf_len - hdr_size); if (rv < 0) ECP_LOG_ERR(_ecp_tr_sock, "packet_handler: err:%d\n", (int)rv); if (bufs.packet->buffer) { @@ -81,24 +84,25 @@ void ecp_tr_close(ECPSocket *sock) { } ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr, unsigned char flags) { - unsigned char *buf = NULL; + unsigned char *buffer = NULL; int reply; int rv; + if (sock->sock == 0) return ECP_ERR_CLOSED; + reply = 0; if (flags & ECP_SEND_FLAG_REPLY) { if (flags & ECP_SEND_FLAG_MORE) return ECP_ERR; - if (packet->buffer) { - buf = packet->buffer-EOS_SOCK_SIZE_UDP_HDR; - packet->buffer = NULL; - reply = 1; - } + if (packet->buffer == NULL) return ECP_ERR; + buffer = packet->buffer; + packet->buffer = NULL; + reply = 1; } else { - buf = eos_net_alloc(); + rv = eos_sock_pkt_alloc(&buffer, packet->buffer, pkt_size); + if (rv) return ECP_ERR; } - if (buf == NULL) return ECP_ERR_ALLOC; - rv = eos_sock_sendto_async(sock->sock, reply ? NULL : packet->buffer, pkt_size, addr, buf, !!(flags & ECP_SEND_FLAG_MORE)); + rv = eos_sock_sendto(sock->sock, addr, buffer, pkt_size, !!(flags & ECP_SEND_FLAG_MORE)); if (rv) return ECP_ERR_SEND; return pkt_size; @@ -110,7 +114,7 @@ ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ecp_tr_addr_t *addr, int void ecp_tr_release(ECPBuffer *packet, unsigned char more) { if (packet->buffer) { - eos_net_free(packet->buffer-EOS_SOCK_SIZE_UDP_HDR, more); + eos_net_free(eos_sock_pkt2buf(packet->buffer), more); packet->buffer = NULL; } else if (!more) { eos_net_release(); diff --git a/ext/fsfat/diskio.c b/ext/fsfat/diskio.c index 90a12e6..1c93466 100644 --- a/ext/fsfat/diskio.c +++ b/ext/fsfat/diskio.c @@ -10,7 +10,7 @@ #include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
-#include <eos/dev/sdcard.h>
+#include <eos/dev/drv/sdcard.h>
#define TIMEOUT 1000
#define TIMEOUT_TRIM 60000
@@ -23,7 +23,7 @@ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
- if (pdrv || (eos_sdc_type() == 0)) return STA_NOINIT;
+ if (pdrv || (sdc_get_type() == 0)) return STA_NOINIT;
return 0;
}
@@ -37,7 +37,7 @@ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
- if (pdrv || (eos_sdc_type() == 0)) return STA_NOINIT;
+ if (pdrv || (sdc_get_type() == 0)) return STA_NOINIT;
return 0;
}
@@ -57,9 +57,9 @@ DRESULT disk_read ( int rv;
if (pdrv) return RES_PARERR;
- if (eos_sdc_type() == 0) return RES_NOTRDY;
+ if (sdc_get_type() == 0) return RES_NOTRDY;
- rv = eos_sdc_sect_read(sector, count, (uint8_t *)buff);
+ rv = sdc_sect_read(sector, count, (uint8_t *)buff);
return rv ? RES_ERROR : RES_OK;
}
@@ -81,9 +81,9 @@ DRESULT disk_write ( int rv;
if (pdrv) return RES_PARERR;
- if (eos_sdc_type() == 0) return RES_NOTRDY;
+ if (sdc_get_type() == 0) return RES_NOTRDY;
- rv = eos_sdc_sect_write(sector, count, (uint8_t *)buff);
+ rv = sdc_sect_write(sector, count, (uint8_t *)buff);
return rv ? RES_ERROR : RES_OK;
}
@@ -105,18 +105,18 @@ DRESULT disk_ioctl ( int rv;
if (pdrv) return RES_PARERR;
- if (eos_sdc_type() == 0) return RES_NOTRDY;
+ if (sdc_get_type() == 0) return RES_NOTRDY;
res = RES_ERROR;
switch (cmd) {
case CTRL_SYNC:
- rv = eos_sdc_sync(TIMEOUT);
+ rv = sdc_sync(TIMEOUT);
if (!rv) res = RES_OK;
break;
case GET_SECTOR_COUNT:
- rv = eos_sdc_get_sect_count(TIMEOUT, &ret);
+ rv = sdc_get_sect_count(&ret, TIMEOUT);
if (!rv) {
*(LBA_t*)buff = ret;
res = RES_OK;
@@ -124,7 +124,7 @@ DRESULT disk_ioctl ( break;
case GET_BLOCK_SIZE:
- rv = eos_sdc_get_blk_size(TIMEOUT, &ret);
+ rv = sdc_get_blk_size(&ret, TIMEOUT);
if (!rv) {
*(DWORD*)buff = ret;
res = RES_OK;
@@ -132,7 +132,7 @@ DRESULT disk_ioctl ( break;
case CTRL_TRIM:
- rv = eos_sdc_erase(((LBA_t*)buff)[0], ((LBA_t*)buff)[1], TIMEOUT_TRIM);
+ rv = sdc_erase(((LBA_t*)buff)[0], ((LBA_t*)buff)[1], TIMEOUT_TRIM);
if (!rv) res = RES_OK;
break;
}
diff --git a/fw/esp32/CMakeLists.txt b/fw/esp32/CMakeLists.txt new file mode 100644 index 0000000..c81db52 --- /dev/null +++ b/fw/esp32/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(eos_app) diff --git a/fw/esp32/components/eos/CMakeLists.txt b/fw/esp32/components/eos/CMakeLists.txt new file mode 100644 index 0000000..404b855 --- /dev/null +++ b/fw/esp32/components/eos/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "app_main.c" "msgq.c" "unicode.c" "gsm.c" "gsm_cp.c" "at_cmd.c" "cell.c" "cell_modem.c" "cell_pcm.c" "cell_voice.c" "cell_ussd.c" "cell_sms.c" "cell_pdp.c" "wifi.c" "net.c" "power.c" "rng.c" "sock.c" "app.c" "tun.c" + INCLUDE_DIRS "include" + REQUIRES esp_driver_gpio esp_driver_spi esp_driver_uart esp_driver_i2s esp_event esp_netif esp_wifi esp_timer vfs) diff --git a/fw/esp32/components/eos/app.c b/fw/esp32/components/eos/app.c index 8396376..662da17 100644 --- a/fw/esp32/components/eos/app.c +++ b/fw/esp32/components/eos/app.c @@ -15,209 +15,142 @@ #include "eos.h" #include "msgq.h" +#include "power.h" #include "app.h" +#include "net_priv.h" -#define SPI_GPIO_CTS 26 -#define SPI_GPIO_RTS 27 -#define SPI_GPIO_MOSI 13 -#define SPI_GPIO_MISO 12 -#define SPI_GPIO_SCLK 14 -#define SPI_GPIO_CS 15 +#define SPI_GPIO_CTS 9 +#define SPI_GPIO_RTS 47 +#define SPI_GPIO_MOSI 11 +#define SPI_GPIO_MISO 13 +#define SPI_GPIO_SCLK 12 +#define SPI_GPIO_CS 10 -#define SPI_SIZE_BUF (EOS_APP_SIZE_BUF + 8) +#define SPI_SIZE_BUF (EOS_APP_SIZE_BUF + 4) #define SPI_SIZE_HDR 3 +#define SPI_HOST SPI2_HOST + static EOSBufQ app_buf_q; static unsigned char *app_bufq_array[EOS_APP_SIZE_BUFQ]; static EOSMsgQ app_send_q; static EOSMsgItem app_sndq_array[EOS_APP_SIZE_SNDQ]; -static SemaphoreHandle_t mutex; -static SemaphoreHandle_t semaph; -static TaskHandle_t app_xchg_task_handle; -static const char *TAG = "EOS APP"; +static NETConfig app_config; +static eos_net_handler_t app_handler[EOS_APP_MAX_MTYPE]; + +static spi_bus_config_t app_spi_bus_cfg; +static spi_slave_interface_config_t app_spi_iface_cfg; +static spi_slave_transaction_t app_spi_tr_cfg; -static eos_app_fptr_t app_handler[EOS_APP_MAX_MTYPE]; +static const char *TAG = "EOS APP"; static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { - ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len); + ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, len); } -// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. -static void _post_setup_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 1); -} +static void app_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { + uint8_t idx; -// Called after transaction is sent/received. We use this to set the handshake line low. -static void _post_trans_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 0); -} - -static void app_xchg_task(void *pvParameters) { - unsigned char mtype = 0; - unsigned char *buffer; - uint16_t len; - unsigned char *buf_send = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); - unsigned char *buf_recv = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); - esp_err_t ret; - size_t trans_len; - - static spi_slave_transaction_t spi_tr; - - //Configuration for the SPI bus - static spi_bus_config_t spi_bus_cfg = { - .mosi_io_num = SPI_GPIO_MOSI, - .miso_io_num = SPI_GPIO_MISO, - .sclk_io_num = SPI_GPIO_SCLK - }; - - //Configuration for the SPI slave interface - static spi_slave_interface_config_t spi_slave_cfg = { - .mode = 0, - .spics_io_num = SPI_GPIO_CS, - .queue_size = 2, - .flags = 0, - .post_setup_cb = _post_setup_cb, - .post_trans_cb = _post_trans_cb - }; - - //Initialize SPI slave interface - ret = spi_slave_initialize(HSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); - assert(ret == ESP_OK); - - memset(&spi_tr, 0, sizeof(spi_tr)); - spi_tr.tx_buffer = buf_send; - spi_tr.rx_buffer = buf_recv; - spi_tr.length = SPI_SIZE_BUF * 8; - - while (1) { - xSemaphoreTake(mutex, portMAX_DELAY); - - eos_msgq_pop(&app_send_q, &mtype, &buffer, &len); - if (mtype) { - buf_send[0] = mtype; - buf_send[1] = len >> 8; - buf_send[2] = len & 0xFF; - if (buffer) { - memcpy(buf_send + SPI_SIZE_HDR, buffer, len); - eos_bufq_push(&app_buf_q, buffer); - xSemaphoreGive(semaph); - } - } else { - gpio_set_level(SPI_GPIO_RTS, 0); - buf_send[0] = 0; - buf_send[1] = 0; - buf_send[2] = 0; - len = 0; - } - - xSemaphoreGive(mutex); - - buf_recv[0] = 0; - buf_recv[1] = 0; - buf_recv[2] = 0; - spi_slave_transmit(HSPI_HOST, &spi_tr, portMAX_DELAY); - - trans_len = spi_tr.trans_len / 8; - if (trans_len < SPI_SIZE_HDR) continue; - - if (len + SPI_SIZE_HDR > trans_len) { - spi_tr.tx_buffer = buf_send + trans_len; - spi_tr.rx_buffer = buf_recv + trans_len; - spi_tr.length = (SPI_SIZE_BUF - trans_len) * 8; - spi_slave_transmit(HSPI_HOST, &spi_tr, portMAX_DELAY); - spi_tr.tx_buffer = buf_send; - spi_tr.rx_buffer = buf_recv; - spi_tr.length = SPI_SIZE_BUF * 8; - } - mtype = buf_recv[0] & ~EOS_APP_MTYPE_FLAG_MASK; - len = (uint16_t)buf_recv[1] << 8; - len |= (uint16_t)buf_recv[2] & 0xFF; - buffer = buf_recv + 3; - - if (mtype == 0x00) continue; - - if ((mtype <= EOS_APP_MAX_MTYPE) && (len <= EOS_APP_MTU)) { - app_handler[mtype - 1](mtype, buffer, len); - } else { - bad_handler(mtype, buffer, len); - } + idx = mtype & EOS_NET_MTYPE_MASK; + if (idx && (idx <= EOS_APP_MAX_MTYPE) && (buf_len <= EOS_APP_MTU)) { + app_handler[idx - 1](mtype, buffer, buf_len); + } else { + bad_handler(mtype, buffer, buf_len); } - vTaskDelete(NULL); } void eos_app_init(void) { + SemaphoreHandle_t mutex; + SemaphoreHandle_t bufq_mutex; + SemaphoreHandle_t bufq_semaph; int i; - // Configuration for the handshake lines - gpio_config_t io_conf = {}; - - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_CTS); - gpio_config(&io_conf); - gpio_set_level(SPI_GPIO_CTS, 0); - - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_RTS); - gpio_config(&io_conf); - gpio_set_level(SPI_GPIO_RTS, 0); - eos_msgq_init(&app_send_q, app_sndq_array, EOS_APP_SIZE_SNDQ); eos_bufq_init(&app_buf_q, app_bufq_array, EOS_APP_SIZE_BUFQ); for (i=0; i<EOS_APP_SIZE_BUFQ; i++) { - eos_bufq_push(&app_buf_q, malloc(EOS_APP_SIZE_BUF)); + unsigned char *buffer; + + buffer = malloc(EOS_APP_SIZE_BUF); + assert(buffer != NULL); + eos_bufq_push(&app_buf_q, buffer); } for (i=0; i<EOS_APP_MAX_MTYPE; i++) { app_handler[i] = bad_handler; } - semaph = xSemaphoreCreateCounting(EOS_APP_SIZE_BUFQ, EOS_APP_SIZE_BUFQ); mutex = xSemaphoreCreateBinary(); + assert(mutex != NULL); + bufq_mutex = xSemaphoreCreateBinary(); + assert(bufq_mutex != NULL); + bufq_semaph = xSemaphoreCreateCounting(EOS_APP_SIZE_BUFQ, EOS_APP_SIZE_BUFQ); + assert(bufq_semaph != NULL); + xSemaphoreGive(mutex); - xTaskCreate(&app_xchg_task, "app_xchg", EOS_TASK_SSIZE_APP_XCHG, NULL, EOS_TASK_PRIORITY_APP_XCHG, &app_xchg_task_handle); + xSemaphoreGive(bufq_mutex); + + app_config.sleep = 0; + app_config.sleep_req = 0; + app_config.present = 0; + app_config.dev = NET_DEV_APP; + app_config.gpio_mosi = SPI_GPIO_MOSI; + app_config.gpio_miso = SPI_GPIO_MISO; + app_config.gpio_sclk = SPI_GPIO_SCLK; + app_config.gpio_cs = SPI_GPIO_CS; + app_config.gpio_rts = SPI_GPIO_RTS; + app_config.gpio_cts = SPI_GPIO_CTS; + app_config.spi_host = SPI_HOST; + app_config.spi_bus_cfg = &app_spi_bus_cfg; + app_config.spi_iface_cfg = &app_spi_iface_cfg; + app_config.spi_tr_cfg = &app_spi_tr_cfg; + app_config.mutex = mutex; + app_config.bufq_mutex = bufq_mutex; + app_config.bufq_semaph = bufq_semaph; + app_config.buf_q = &app_buf_q; + app_config.send_q = &app_send_q; + app_config.msg_handler = app_msg_handler; + + _eos_net_init_gpio(&app_config); + + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + gpio_hold_dis(app_config.gpio_cts); + } + ESP_LOGI(TAG, "INIT"); } -unsigned char *eos_app_alloc(void) { - unsigned char *ret; +void eos_app_run(void) { + BaseType_t rv; - xSemaphoreTake(semaph, portMAX_DELAY); - xSemaphoreTake(mutex, portMAX_DELAY); - ret = eos_bufq_pop(&app_buf_q); - xSemaphoreGive(mutex); + rv = xTaskCreate(&eos_net_xchg_task, "app_xchg", EOS_TASK_SSIZE_APP, &app_config, EOS_TASK_PRIORITY_APP, &app_config.xchg_task_handle); + assert(rv == pdPASS); - return ret; + ESP_LOGI(TAG, "RUN"); } -void eos_app_free(unsigned char *buf) { - xSemaphoreTake(mutex, portMAX_DELAY); - eos_bufq_push(&app_buf_q, buf); - xSemaphoreGive(semaph); - xSemaphoreGive(mutex); +unsigned char *eos_app_alloc(void) { + return _eos_net_alloc(&app_config); } -int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t len) { - int rv = EOS_OK; +void eos_app_free(unsigned char *buf) { + _eos_net_free(&app_config, buf); +} - xSemaphoreTake(mutex, portMAX_DELAY); - gpio_set_level(SPI_GPIO_RTS, 1); - rv = eos_msgq_push(&app_send_q, mtype, buffer, len); - xSemaphoreGive(mutex); +int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { + return _eos_net_send(&app_config, mtype, buffer, buf_len); +} - if (rv) eos_app_free(buffer); +void eos_app_sleep_req(void) { + _eos_net_sleep_req(&app_config); +} - return rv; +void eos_app_wake(void) { + _eos_net_wake(&app_config); } -void eos_app_set_handler(unsigned char mtype, eos_app_fptr_t handler) { +void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler) { if (handler == NULL) handler = bad_handler; if (mtype && (mtype <= EOS_APP_MAX_MTYPE)) app_handler[mtype - 1] = handler; } diff --git a/fw/esp32/main/app_main.c b/fw/esp32/components/eos/app_main.c index 79f76ab..941e01c 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 "net.h" #include "wifi.h" #include "sock.h" #include "rng.h" -#ifdef EOS_WITH_APP #include "app.h" #include "tun.h" -#endif #include "power.h" #define ESP_INTR_FLAG_DEFAULT 0 -// Main application +/* main application */ void app_main() { esp_err_t ret; @@ -31,21 +30,28 @@ void app_main() { ret = esp_event_loop_create_default(); assert(ret == ESP_OK); - eos_net_init(); + ret = gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); + assert(ret == ESP_OK); - eos_cell_pcm_init(); - gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); + eos_power_init(); + + eos_net_init(); + eos_app_init(); + eos_tun_init(); eos_modem_init(); eos_cell_init(); + eos_cell_pcm_init(); eos_wifi_init(); eos_sock_init(); eos_rng_init(); -#ifdef EOS_WITH_APP - eos_app_init(); - eos_tun_init(); -#endif - eos_power_init(); + eos_power_run(); + eos_net_run(); + eos_app_run(); + eos_modem_run(); + eos_cell_run(); + eos_wifi_run(); + eos_sock_run(); } diff --git a/fw/esp32/components/eos/at_cmd.c b/fw/esp32/components/eos/at_cmd.c index a1c329e..d9ec228 100644 --- a/fw/esp32/components/eos/at_cmd.c +++ b/fw/esp32/components/eos/at_cmd.c @@ -36,6 +36,7 @@ void at_init(void) { memset(&urc_list, 0, sizeof(ATURCList)); mutex = xSemaphoreCreateBinary(); + assert(mutex != NULL); xSemaphoreGive(mutex); } diff --git a/fw/esp32/components/eos/cell.c b/fw/esp32/components/eos/cell.c index d34172e..8665616 100644 --- a/fw/esp32/components/eos/cell.c +++ b/fw/esp32/components/eos/cell.c @@ -17,8 +17,6 @@ static const char *TAG = "EOS CELL"; -static uint8_t cell_mode; - static EOSBufQ cell_buf_q; static unsigned char *cell_bufq_array[CELL_SIZE_QUEUE]; @@ -28,8 +26,6 @@ static QueueHandle_t cell_queue; static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { uint8_t mtype; - if (buf_len < 1) return; - mtype = buffer[0]; switch (mtype & EOS_CELL_MTYPE_MASK) { case EOS_CELL_MTYPE_DEV: { @@ -43,29 +39,47 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t } case EOS_CELL_MTYPE_RESET: { + int rv; + + rv = eos_modem_take(1000); + if (rv) { + ESP_LOGE(TAG, "Reset modem failed: %d", rv); + break; + } eos_modem_reset(); + eos_modem_give(); break; } case EOS_CELL_MTYPE_UART_TAKE: { - uint8_t mode; - - mode = eos_modem_get_mode(); - if (mode == EOS_CELL_UART_MODE_NONE) break; + int rv; - eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY); - cell_mode = mode; + if (eos_modem_get_mode() == EOS_CELL_UART_MODE_ATCMD) { + rv = eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY); + if (rv) ESP_LOGE(TAG, "Set RELAY mode failed: %d", rv); + } break; } case EOS_CELL_MTYPE_UART_GIVE: { - eos_modem_atinit(); - eos_modem_set_mode(cell_mode); + int rv; + + if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) { + rv = eos_modem_take(1000); + if (!rv) { + eos_modem_atinit(); + eos_modem_give(); + } + rv = eos_modem_set_mode(EOS_CELL_UART_MODE_ATCMD); + if (rv) ESP_LOGE(TAG, "Set ATCMD mode failed: %d", rv); + } break; } case EOS_CELL_MTYPE_UART_DATA: { - if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer + 1, buf_len - 1); + if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) { + eos_modem_write(buffer + 1, buf_len - 1); + } break; } } @@ -108,23 +122,30 @@ static void cell_handler_task(void *pvParameters) { vTaskDelete(NULL); } -static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t len) { +static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) { EOSMsgItem mi; - unsigned char *buf; + unsigned char *_buffer; + + if (buf_len < 1) return; + + if (type & EOS_NET_MTYPE_FLAG_REPL) { + _cell_handler(type, buffer, buf_len); + return; + } xSemaphoreTake(mutex, portMAX_DELAY); - buf = eos_bufq_pop(&cell_buf_q); + _buffer = eos_bufq_pop(&cell_buf_q); xSemaphoreGive(mutex); - if (buf == NULL) { - if (len) ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]); + if (_buffer == NULL) { + ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]); return; } - memcpy(buf, buffer, len); + memcpy(_buffer, buffer, buf_len); mi.type = type; - mi.buffer = buf; - mi.len = len; + mi.buffer = _buffer; + mi.len = buf_len; xQueueSend(cell_queue, &mi, portMAX_DELAY); } @@ -133,13 +154,30 @@ void eos_cell_init(void) { eos_bufq_init(&cell_buf_q, cell_bufq_array, CELL_SIZE_QUEUE); for (i=0; i<CELL_SIZE_QUEUE; i++) { - eos_bufq_push(&cell_buf_q, malloc(EOS_NET_SIZE_BUF)); + unsigned char *buffer; + + buffer = malloc(EOS_NET_SIZE_BUF); + assert(buffer != NULL); + eos_bufq_push(&cell_buf_q, buffer); } mutex = xSemaphoreCreateBinary(); + assert(mutex != NULL); xSemaphoreGive(mutex); + cell_queue = xQueueCreate(CELL_SIZE_QUEUE, sizeof(EOSMsgItem)); - xTaskCreate(cell_handler_task, "cell_handler", EOS_TASK_SSIZE_CELL, NULL, EOS_TASK_PRIORITY_CELL, NULL); + assert(cell_queue != NULL); eos_net_set_handler(EOS_NET_MTYPE_CELL, cell_handler); + + ESP_LOGI(TAG, "INIT"); +} + +void eos_cell_run(void) { + BaseType_t rv; + + rv = xTaskCreate(cell_handler_task, "cell_handler", EOS_TASK_SSIZE_CELL, NULL, EOS_TASK_PRIORITY_CELL, NULL); + assert(rv == pdPASS); + + ESP_LOGI(TAG, "RUN"); } diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c index b279db1..4f8efd1 100644 --- a/fw/esp32/components/eos/cell_modem.c +++ b/fw/esp32/components/eos/cell_modem.c @@ -5,12 +5,15 @@ #include <freertos/semphr.h> #include <freertos/task.h> #include <freertos/queue.h> + #include <netif/ppp/pppos.h> #include <netif/ppp/pppapi.h> + #include <driver/uart.h> #include <driver/gpio.h> + +#include <esp_system.h> #include <esp_timer.h> -#include <esp_sleep.h> #include <esp_log.h> #include "eos.h" @@ -24,30 +27,37 @@ #define UART_SIZE_IO_BUF 8192 -#define UART_GPIO_TXD 16 +// XXX: TXD and RXD switched for Quectel, fixed in new revision +#define UART_GPIO_TXD 18 #define UART_GPIO_RXD 17 -#define UART_GPIO_DTR 32 -#define UART_GPIO_RI 35 +#define UART_GPIO_DTR 15 +#define UART_GPIO_RI 16 +#define MODEM_GPIO_RST 6 +#define MODEM_GPIO_USB_EN 7 +#define MODEM_GPIO_USB_S 14 + +#define UART_PORT UART_NUM_1 #define MODEM_ETYPE_ATINIT 1 #define MODEM_ETYPE_STATUS 2 #define MODEM_ETYPE_RING 3 -#define AT_CMD_INIT_SIZE 5 - #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -static const char *TAG = "EOS MODEM"; - -static char *at_cmd_init[AT_CMD_INIT_SIZE] = { - "AT+CFGRI=1\r", - "AT+CSCLK=1\r", +static char *at_cmd_init[] = { + // "AT+CFGRI=1\r", + // "AT+CSCLK=1\r", + "AT+QSCLK=1\r", + "AT+QCFG=\"risignaltype\",\"physical\"\r", + "AT+QURCCFG=\"urcport\",\"uart1\"\r", "AT+CLIP=1\r", "AT+CMGF=0\r", "AT+CPMS=\"ME\",\"ME\",\"ME\"\r" }; +static const char *TAG = "EOS CELL MODEM"; + static SemaphoreHandle_t mutex; static QueueHandle_t modem_queue; @@ -84,8 +94,6 @@ typedef struct { size_t param_len; } modem_event_t; -static void modem_send_status(void); - static void atcmd_read(size_t bsize) { char *ln_end; int rd = 0; @@ -94,6 +102,9 @@ static void atcmd_read(size_t bsize) { char *uart_curr = uart_buf + uart_buf_len; int _rd = eos_modem_read(uart_curr, MIN(bsize - rd, sizeof(uart_buf) - uart_buf_len - 1), 100); + /* after sleep one 0xff character is emitted */ + if ((_rd == 1) && (*uart_curr == 0xff)) return; + rd += _rd; uart_buf_len += _rd; uart_buf[uart_buf_len] = '\0'; @@ -123,7 +134,7 @@ static void uart_data_read(uint8_t mode) { int rd; size_t bsize; - uart_get_buffered_data_len(UART_NUM_2, &bsize); + uart_get_buffered_data_len(UART_PORT, &bsize); switch (mode) { case EOS_CELL_UART_MODE_ATCMD: { atcmd_read(bsize); @@ -132,7 +143,6 @@ static void uart_data_read(uint8_t mode) { case EOS_CELL_UART_MODE_PPP: { rd = 0; - do { int _rd = eos_modem_read(uart_buf, MIN(bsize - rd, sizeof(uart_buf)), 100); if (ppp_handle) pppos_input_tcpip(ppp_handle, (uint8_t *)uart_buf, _rd); @@ -143,15 +153,17 @@ static void uart_data_read(uint8_t mode) { case EOS_CELL_UART_MODE_RELAY: { unsigned char *buf; - rd = 0; + int rv; + rd = 0; do { int _rd; buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; _rd = eos_modem_read(buf + 1, MIN(bsize - rd, EOS_NET_SIZE_BUF - 1), 100); - eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); rd += _rd; } while (rd != bsize); break; @@ -160,36 +172,20 @@ static void uart_data_read(uint8_t mode) { } static void uart_event_task(void *pvParameters) { - char mode; - char _mode; + uint8_t mode, _mode; uart_event_t event; - eos_power_wait4wake(); - xSemaphoreTake(mutex, portMAX_DELAY); - _mode = uart_mode; - xSemaphoreTake(uart_mutex, portMAX_DELAY); - if (!modem_initialized) { - int r; - - at_cmd("\r\rAT\r"); - r = at_expect("^OK", NULL, 500); - if (!r) { - r = eos_modem_atinit(); - if (!r) { - modem_present = 1; - } else { - _mode = EOS_CELL_UART_MODE_NONE; - ESP_LOGE(TAG, "Modem init failed"); - } - } + eos_modem_reset(); } - - if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex); - mode = _mode; + mode = _mode = uart_mode; xSemaphoreGive(mutex); + if (mode != EOS_CELL_UART_MODE_NONE) { + xSemaphoreTake(uart_mutex, portMAX_DELAY); + } + while (1) { /* Waiting for UART event. */ @@ -198,6 +194,8 @@ static void uart_event_task(void *pvParameters) { case UART_DATA: { /* Event of UART receiving data */ + + ESP_LOGI(TAG, "UART DATA READ"); if (mode != EOS_CELL_UART_MODE_NONE) uart_data_read(mode); if ((mode != _mode) && (uart_buf_len == 0)) { if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex); @@ -244,27 +242,6 @@ static void IRAM_ATTR uart_ring_handler(void *arg) { xQueueSendFromISR(modem_queue, &evt, NULL); } -static void modem_init_gpio(void) { - // Configuration for the DTR/RI lines - gpio_config_t io_conf = {}; - - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_DTR); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - gpio_set_level(UART_GPIO_DTR, 0); - - io_conf.intr_type = GPIO_INTR_NEGEDGE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_RI); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); -} - static size_t modem_get_status(unsigned char *buffer) { size_t len; @@ -310,12 +287,14 @@ static void modem_atinit_handler(char *urc, regmatch_t m[]) { xQueueSend(modem_queue, &evt, portMAX_DELAY); } -static int modem_atinit(void) { +static int modem_atinit_evt(void) { int r; + vTaskDelay(500 / portTICK_PERIOD_MS); + xSemaphoreTake(mutex, portMAX_DELAY); uart_change_mode(EOS_CELL_UART_MODE_NONE); - r = xSemaphoreTake(uart_mutex, 1000); + r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS); if (r == pdFALSE) { uart_change_mode(uart_mode); xSemaphoreGive(mutex); @@ -323,6 +302,8 @@ static int modem_atinit(void) { } r = eos_modem_atinit(); + modem_send_status(); + uart_change_mode(uart_mode); xSemaphoreGive(uart_mutex); xSemaphoreGive(mutex); @@ -337,10 +318,10 @@ static void modem_event_task(void *pvParameters) { if (xQueueReceive(modem_queue, &evt, portMAX_DELAY)) { switch (evt.type) { case MODEM_ETYPE_ATINIT: { - int r; + int rv; - r = modem_atinit(); - if (!r) { + rv = modem_atinit_evt(); + if (!rv) { modem_present = 1; } else { ESP_LOGE(TAG, "Modem init failed"); @@ -350,11 +331,13 @@ static void modem_event_task(void *pvParameters) { case MODEM_ETYPE_STATUS: { unsigned char *buf; + int rv; buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; memcpy(buf + 1, evt.param, evt.param_len); - eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); break; } @@ -365,7 +348,7 @@ static void modem_event_task(void *pvParameters) { } /* Obsolete uint64_t t_start = esp_timer_get_time(); - if (xQueueReceive(modem_queue, &level, 200 / portTICK_RATE_MS) && (level == 1)) { + if (xQueueReceive(modem_queue, &level, 200 / portTICK_PERIOD_MS) && (level == 1)) { uint64_t t_end = esp_timer_get_time(); ESP_LOGI(TAG, "URC:%u", (uint32_t)(t_end - t_start)); } else { @@ -399,11 +382,11 @@ static char *memstr(char *mem, size_t size, char *str) { return NULL; } -static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *ctx) { +static uint32_t ppp_output_cb(ppp_pcb *pcb, const void *data, uint32_t len, void *ctx) { size_t rv; xSemaphoreTake(ppp_mutex, portMAX_DELAY); - rv = eos_modem_write(data, len); + rv = eos_modem_write((uint8_t *)data, len); xSemaphoreGive(ppp_mutex); return rv; @@ -412,15 +395,16 @@ static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *c /* PPP status callback */ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { struct netif *pppif = ppp_netif(pcb); + int r; LWIP_UNUSED_ARG(ctx); switch (err_code) { case PPPERR_NONE: { ESP_LOGI(TAG, "status_cb: Connect"); - ESP_LOGI(TAG," our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr)); - ESP_LOGI(TAG," his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw)); - ESP_LOGI(TAG," netmask = %s\n", ipaddr_ntoa(&pppif->netmask)); + ESP_LOGI(TAG," local ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr)); + ESP_LOGI(TAG," remote ipaddr = %s\n", ipaddr_ntoa(&pppif->gw)); + ESP_LOGI(TAG," netmask = %s\n", ipaddr_ntoa(&pppif->netmask)); xSemaphoreTake(mutex, portMAX_DELAY); ppp_connected = 1; @@ -485,18 +469,26 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { } xSemaphoreTake(mutex, portMAX_DELAY); + ppp_connected = 0; + ip_addr_set_zero(&ppp_ipaddr); + modem_send_status(); + uart_change_mode(EOS_CELL_UART_MODE_NONE); + r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS); + if (r == pdFALSE) { + uart_mode = EOS_CELL_UART_MODE_NONE; + uart_mode_next = EOS_CELL_UART_MODE_NONE; + xSemaphoreGive(mutex); + ESP_LOGE(TAG, "status_cb: Obtaining UART mutex failed"); + + return; + } + if (uart_mode_next != EOS_CELL_UART_MODE_NONE) { uart_mode = uart_mode_next; uart_mode_next = EOS_CELL_UART_MODE_NONE; } else { uart_mode = EOS_CELL_UART_MODE_ATCMD; } - ppp_connected = 0; - ip_addr_set_zero(&ppp_ipaddr); - modem_send_status(); - uart_change_mode(EOS_CELL_UART_MODE_NONE); - xSemaphoreTake(uart_mutex, portMAX_DELAY); - ppp_handle = NULL; uart_change_mode(uart_mode); @@ -607,6 +599,12 @@ static int ppp_setup(void) { return EOS_ERR_TIMEOUT; } + if (ppp_handle) { + uart_change_mode(uart_mode); + xSemaphoreGive(uart_mutex); + return EOS_ERR; + } + at_cmd(cmd); r = at_expect("^OK", "^(ERROR|NO CARRIER)", 1000); if (r) { @@ -636,6 +634,7 @@ static int ppp_setup(void) { } void eos_modem_init(void) { + gpio_config_t io_conf = {}; uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, @@ -643,37 +642,91 @@ void eos_modem_init(void) { .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE }; - uart_param_config(UART_NUM_2, &uart_config); - uart_set_pin(UART_NUM_2, UART_GPIO_TXD, UART_GPIO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - uart_driver_install(UART_NUM_2, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0); + esp_err_t ret; + int rv; - if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) { - uart_mode = EOS_CELL_UART_MODE_ATCMD; + ret = uart_param_config(UART_PORT, &uart_config); + assert(ret == ESP_OK); + ret = uart_set_pin(UART_PORT, UART_GPIO_TXD, UART_GPIO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + assert(ret == ESP_OK); + ret = uart_driver_install(UART_PORT, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0); + assert(ret == ESP_OK); + + // Configuration for the RST/DTR/USB/RI lines + gpio_set_level(MODEM_GPIO_RST, 1); + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT_OD; + io_conf.pin_bit_mask = BIT64(MODEM_GPIO_RST); + io_conf.pull_up_en = 0; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); + + gpio_set_level(UART_GPIO_DTR, 0); + /* enable USB MUX and grab signals */ + gpio_set_level(MODEM_GPIO_USB_EN, 0); + gpio_set_level(MODEM_GPIO_USB_S, 1); + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = BIT64(UART_GPIO_DTR) | BIT64(MODEM_GPIO_USB_EN) | BIT64(MODEM_GPIO_USB_S); + io_conf.pull_up_en = 0; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); + + io_conf.intr_type = GPIO_INTR_NEGEDGE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = BIT64(UART_GPIO_RI); + io_conf.pull_up_en = 1; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); + + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + gpio_hold_dis(UART_GPIO_DTR); + gpio_hold_dis(MODEM_GPIO_USB_EN); + gpio_hold_dis(MODEM_GPIO_USB_S); + } else { modem_present = 0; modem_initialized = 0; - modem_init_gpio(); } mutex = xSemaphoreCreateBinary(); + assert(mutex != NULL); xSemaphoreGive(mutex); uart_mutex = xSemaphoreCreateBinary(); + assert(uart_mutex != NULL); xSemaphoreGive(uart_mutex); ppp_mutex = xSemaphoreCreateBinary(); + assert(ppp_mutex != NULL); xSemaphoreGive(ppp_mutex); modem_queue = xQueueCreate(4, sizeof(modem_event_t)); - xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL); - xTaskCreate(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL); + assert(modem_queue != NULL); at_init(); - at_urc_insert("^PB DONE", modem_atinit_handler, REG_EXTENDED); - at_urc_insert("^\\+CME ERROR: SIM not inserted", modem_atinit_handler, REG_EXTENDED); + rv = at_urc_insert("^RDY", modem_atinit_handler, REG_EXTENDED); + assert(rv == EOS_OK); + + eos_cell_sms_init(); + eos_cell_ussd_init(); + eos_cell_voice_init(); ESP_LOGI(TAG, "INIT"); } +void eos_modem_run(void) { + BaseType_t rv; + + gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); + + rv = xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL); + assert(rv == pdPASS); + rv = xTaskCreate(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL); + assert(rv == pdPASS); + + ESP_LOGI(TAG, "RUN"); +} + int eos_modem_atinit(void) { int echo_on = 0; int tries = 3; @@ -706,32 +759,36 @@ int eos_modem_atinit(void) { r = at_expect("^ATE0", NULL, 1000); r = at_expect("^OK", "^ERROR", 1000); - for (i=0; i<AT_CMD_INIT_SIZE; i++) { + for (i=0; i<sizeof(at_cmd_init)/sizeof(char *); i++) { at_cmd(at_cmd_init[i]); - r = at_expect("^OK", "^ERROR", 1000); + r = at_expect("^OK", "ERROR", 1000); } + modem_present = 1; modem_initialized = 1; - eos_cell_voice_init(); - eos_cell_sms_init(); - eos_cell_ussd_init(); + return EOS_OK; +} - modem_send_status(); +void eos_modem_reset(void) { + gpio_set_level(MODEM_GPIO_RST, 0); + vTaskDelay(500 / portTICK_PERIOD_MS); + gpio_set_level(MODEM_GPIO_RST, 1); - return EOS_OK; + modem_initialized = 0; + uart_mode = EOS_CELL_UART_MODE_ATCMD; } void eos_modem_flush(void){ - uart_wait_tx_done(UART_NUM_2, portMAX_DELAY); + uart_wait_tx_done(UART_PORT, portMAX_DELAY); } size_t eos_modem_write(void *data, size_t size) { - return uart_write_bytes(UART_NUM_2, (const char *)data, size); + return uart_write_bytes(UART_PORT, (const char *)data, size); } size_t eos_modem_read(void *data, size_t size, uint32_t timeout) { - return uart_read_bytes(UART_NUM_2, (uint8_t *)data, size, timeout / portTICK_RATE_MS); + return uart_read_bytes(UART_PORT, (uint8_t *)data, size, timeout / portTICK_PERIOD_MS); } int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout) { @@ -791,6 +848,16 @@ int eos_modem_present(void) { return rv; } +int eos_modem_initialized(void) { + int rv; + + xSemaphoreTake(mutex, portMAX_DELAY); + rv = modem_initialized; + xSemaphoreGive(mutex); + + return rv; +} + uint8_t eos_modem_get_mode(void) { uint8_t ret; @@ -832,7 +899,6 @@ int eos_modem_set_mode(uint8_t mode) { } if (!rv) { uart_mode = mode; - modem_send_status(); } } } @@ -876,71 +942,53 @@ void eos_modem_give(void) { xSemaphoreGive(mutex); } -void eos_modem_sleep(void) { - int r; +void eos_modem_sleep_req(void) { + int rv; + gpio_set_level(UART_GPIO_DTR, 1); xSemaphoreTake(mutex, portMAX_DELAY); uart_change_mode(EOS_CELL_UART_MODE_NONE); - r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS); - if (r == pdFALSE) { - ESP_LOGE(TAG, "Obtaining mutex before sleep failed"); - } - gpio_set_level(UART_GPIO_DTR, 1); -} - -void eos_modem_deep_sleep(void) { + rv = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS); + if (rv == pdFALSE) ESP_LOGE(TAG, "Obtaining UART mutex before sleep failed"); + gpio_isr_handler_remove(UART_GPIO_RI); + gpio_reset_pin(UART_GPIO_RI); + /* for deep sleep */ gpio_hold_en(UART_GPIO_DTR); + gpio_hold_en(MODEM_GPIO_USB_EN); + gpio_hold_en(MODEM_GPIO_USB_S); + eos_power_sleep_rdy(EOS_PWR_DEV_MODEM); } -void eos_modem_wake(uint8_t source, uint8_t mode) { - if (source == EOS_PWR_WAKE_UART) { - modem_event_t evt; +void eos_modem_wake(void) { + gpio_config_t io_conf = { + .pin_bit_mask = BIT64(UART_GPIO_RI), + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_NEGEDGE, + }; + uint32_t dev; - evt.type = MODEM_ETYPE_RING; - xQueueSend(modem_queue, &evt, portMAX_DELAY); - } + gpio_hold_dis(UART_GPIO_DTR); + gpio_hold_dis(MODEM_GPIO_USB_EN); + gpio_hold_dis(MODEM_GPIO_USB_S); - switch (mode) { - case EOS_PWR_SMODE_LIGHT: { - gpio_set_intr_type(UART_GPIO_RI, GPIO_INTR_NEGEDGE); - gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); - gpio_set_level(UART_GPIO_DTR, 0); + gpio_config(&io_conf); + gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); - uart_change_mode(uart_mode); - xSemaphoreGive(uart_mutex); - xSemaphoreGive(mutex); + uart_change_mode(uart_mode); + xSemaphoreGive(uart_mutex); + xSemaphoreGive(mutex); - break; - } + gpio_set_level(UART_GPIO_DTR, 0); - case EOS_PWR_SMODE_DEEP: { - gpio_hold_dis(UART_GPIO_DTR); - modem_init_gpio(); + dev = eos_power_wakeup_source(); + if (dev == EOS_PWR_DEV_MODEM) { + modem_event_t evt; - break; - } + evt.type = MODEM_ETYPE_RING; + xQueueSend(modem_queue, &evt, portMAX_DELAY); } } -int eos_modem_reset(void) { - int rv; - - rv = eos_modem_take(1000); - if (rv) return rv; - - at_cmd("AT+CRESET\r"); - at_expect("^OK", NULL, 1000); - - uart_change_mode(EOS_CELL_UART_MODE_ATCMD); - xSemaphoreGive(uart_mutex); - - uart_mode = EOS_CELL_UART_MODE_ATCMD; - modem_initialized = 0; - modem_send_status(); - xSemaphoreGive(mutex); - - return EOS_OK; -} void eos_ppp_get_apn(char *apn) { xSemaphoreTake(mutex, portMAX_DELAY); diff --git a/fw/esp32/components/eos/cell_pcm.c b/fw/esp32/components/eos/cell_pcm.c index b993021..3f5089d 100644 --- a/fw/esp32/components/eos/cell_pcm.c +++ b/fw/esp32/components/eos/cell_pcm.c @@ -1,309 +1,137 @@ +#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) { + unsigned char *buffer; + 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) { + buffer = eos_net_alloc(); + buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; + ret = i2s_channel_read(rx_chan, buffer + 1, PCM_RX_WM, &size_r, 1000); + switch (ret) { + case ESP_OK: { + assert(size_r == PCM_RX_WM); + break; + } - case 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, buffer, size_r + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); + } else { + eos_net_free(buffer); + } } vTaskDelete(NULL); } -void eos_cell_pcm_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_sms.c b/fw/esp32/components/eos/cell_sms.c index 5145cd7..1cd4cda 100644 --- a/fw/esp32/components/eos/cell_sms.c +++ b/fw/esp32/components/eos/cell_sms.c @@ -13,7 +13,7 @@ #define CTRL_Z 0x1a -static const char *TAG = "EOS SMS"; +static const char *TAG = "EOS CELL SMS"; static char _pdu_in[2048]; static char _pdu_out[2048]; @@ -266,7 +266,8 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b } buf_len = _rv; - eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } while (1); eos_modem_give(); @@ -345,9 +346,13 @@ static void sms_received_handler(char *urc, regmatch_t m[]) { } buf_len = _rv; - eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } void eos_cell_sms_init(void) { - at_urc_insert("^\\+CMTI: .*,([0-9]+)$", sms_received_handler, REG_EXTENDED); + int rv; + + rv = at_urc_insert("^\\+CMTI: .*,([0-9]+)$", sms_received_handler, REG_EXTENDED); + assert(rv == EOS_OK); } diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c index 375025f..fb77b67 100644 --- a/fw/esp32/components/eos/cell_ussd.c +++ b/fw/esp32/components/eos/cell_ussd.c @@ -9,7 +9,7 @@ #include "at_cmd.h" #include "cell.h" -static const char *TAG = "EOS USSD"; +static const char *TAG = "EOS CELL USSD"; extern char *at_cmd_buf; @@ -64,7 +64,8 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) { len = 2; if (m[2].rm_so == -1) { - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); return; } @@ -101,9 +102,13 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) { return; } - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } void eos_cell_ussd_init(void) { - at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED); + int rv; + + rv = at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED); + assert(rv == EOS_OK); } diff --git a/fw/esp32/components/eos/cell_voice.c b/fw/esp32/components/eos/cell_voice.c index 2a7bb18..273b402 100644 --- a/fw/esp32/components/eos/cell_voice.c +++ b/fw/esp32/components/eos/cell_voice.c @@ -13,6 +13,8 @@ #include "at_cmd.h" #include "cell.h" +static const char *TAG = "EOS CELL VOICE"; + extern char *at_cmd_buf; void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { @@ -93,35 +95,41 @@ static void ring_handler(char *urc, regmatch_t m[]) { memcpy(buf + 1, ring_buf + match[1].rm_so, num_len); len += num_len; } - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void busy_handler(char *urc, regmatch_t m[]) { unsigned char *buf; uint16_t len; + int rv; eos_cell_pcm_stop(); buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BUSY; len = 1; - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void miss_handler(char *urc, regmatch_t m[]) { unsigned char *buf; uint16_t len; + int rv; eos_cell_pcm_stop(); buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_MISS; len = 1; - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void call_begin_handler(char *urc, regmatch_t m[]) { unsigned char *buf; + int rv; vTaskDelay(100 / portTICK_PERIOD_MS); at_cmd("AT+CECH=0x0000\r"); @@ -142,12 +150,14 @@ static void call_begin_handler(char *urc, regmatch_t m[]) { buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; - eos_net_send(EOS_NET_MTYPE_CELL, buf, 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void call_end_handler(char *urc, regmatch_t m[]) { unsigned char *buf; int duration = 0; + int rv; eos_cell_pcm_stop(); @@ -158,14 +168,29 @@ static void call_end_handler(char *urc, regmatch_t m[]) { buf[2] = duration >> 16; buf[3] = duration >> 8; buf[4] = duration; - eos_net_send(EOS_NET_MTYPE_CELL, buf, 5); + rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 5); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } void eos_cell_voice_init(void) { - at_urc_insert("^RING", ring_handler, REG_EXTENDED); - at_urc_insert("^BUSY", busy_handler, REG_EXTENDED); - at_urc_insert("^NO CARRIER", miss_handler, REG_EXTENDED); - at_urc_insert("^MISSED.CALL: [^ ]+ (\\+?[0-9]+)$", miss_handler, REG_EXTENDED); - at_urc_insert("^VOICE CALL: BEGIN", call_begin_handler, REG_EXTENDED); - at_urc_insert("^VOICE CALL: END: ([0-9]{6}$)$", call_end_handler, REG_EXTENDED); -}
\ No newline at end of file + int rv; + + rv = at_urc_insert("^RING", ring_handler, REG_EXTENDED); + assert(rv == EOS_OK); + + rv = at_urc_insert("^BUSY", busy_handler, REG_EXTENDED); + assert(rv == EOS_OK); + + rv = at_urc_insert("^NO CARRIER", miss_handler, REG_EXTENDED); + assert(rv == EOS_OK); + + rv = at_urc_insert("^MISSED.CALL: [^ ]+ (\\+?[0-9]+)$", miss_handler, REG_EXTENDED); + assert(rv == EOS_OK); + + rv = at_urc_insert("^VOICE CALL: BEGIN", call_begin_handler, REG_EXTENDED); + assert(rv == EOS_OK); + + rv = at_urc_insert("^VOICE CALL: END: ([0-9]{6}$)$", call_end_handler, REG_EXTENDED); + assert(rv == EOS_OK); + +} diff --git a/fw/esp32/components/eos/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..b6dba99 100644 --- a/fw/esp32/components/eos/include/app.h +++ b/fw/esp32/components/eos/include/app.h @@ -1,5 +1,7 @@ #include <stdint.h> +#include "net.h" + /* common */ #define EOS_APP_MTU 1500 #define EOS_APP_SIZE_BUF EOS_APP_MTU @@ -7,17 +9,18 @@ #define EOS_APP_MTYPE_TUN 1 #define EOS_APP_MAX_MTYPE 8 -#define EOS_APP_MTYPE_FLAG_MASK 0xc0 - /* esp32 specific */ #define EOS_APP_SIZE_BUFQ 4 #define EOS_APP_SIZE_SNDQ 4 -typedef void (*eos_app_fptr_t) (unsigned char, unsigned char *, uint16_t); - void eos_app_init(void); +void eos_app_run(void); unsigned char *eos_app_alloc(void); void eos_app_free(unsigned char *buf); -int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t len); -void eos_app_set_handler(unsigned char mtype, eos_app_fptr_t handler); + +int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); + +void eos_app_sleep_req(void); +void eos_app_wake(void); +void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler); diff --git a/fw/esp32/components/eos/include/cell.h b/fw/esp32/components/eos/include/cell.h index cb9f49c..c1e7545 100644 --- a/fw/esp32/components/eos/include/cell.h +++ b/fw/esp32/components/eos/include/cell.h @@ -27,7 +27,6 @@ #define EOS_CELL_MTYPE_VOICE_END 7 #define EOS_CELL_MTYPE_VOICE_MISS 8 #define EOS_CELL_MTYPE_VOICE_BUSY 9 -#define EOS_CELL_MTYPE_VOICE_ERR 10 #define EOS_CELL_MTYPE_SMS_MSG 1 #define EOS_CELL_MTYPE_SMS_LIST 2 @@ -76,24 +75,26 @@ #define EOS_CELL_UART_SIZE_BUF 1024 void eos_cell_init(void); +void eos_cell_run(void); void eos_modem_init(void); +void eos_modem_run(void); int eos_modem_atinit(void); +void eos_modem_reset(void); void eos_modem_flush(void); size_t eos_modem_write(void *data, size_t size); size_t eos_modem_read(void *data, size_t size, uint32_t timeout); int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout); -int eos_modem_resp(char *ok_str, char *err_str, uint32_t timeout); int eos_modem_present(void); +int eos_modem_initialized(void); uint8_t eos_modem_get_mode(void); size_t eos_modem_get_status(unsigned char *buffer); int eos_modem_set_mode(uint8_t mode); int eos_modem_take(uint32_t timeout); void eos_modem_give(void); -void eos_modem_sleep(void); -void eos_modem_deep_sleep(void); -void eos_modem_wake(uint8_t source, uint8_t mode); -int eos_modem_reset(void); + +void eos_modem_sleep_req(void); +void eos_modem_wake(void); void eos_ppp_get_apn(char *apn); void eos_ppp_set_apn(char *apn); @@ -105,8 +106,7 @@ int eos_ppp_connect(void); void eos_ppp_disconnect(void); void eos_cell_pcm_init(void); -ssize_t eos_cell_pcm_read(unsigned char *data, size_t size); -int eos_cell_pcm_push(unsigned char *data, size_t size); +void eos_cell_pcm_push(unsigned char *data, size_t size); void eos_cell_pcm_start(void); void eos_cell_pcm_stop(void); diff --git a/fw/esp32/components/eos/include/eos.h b/fw/esp32/components/eos/include/eos.h index bc9dc51..e772637 100644 --- a/fw/esp32/components/eos/include/eos.h +++ b/fw/esp32/components/eos/include/eos.h @@ -11,21 +11,21 @@ #define EOS_ERR_NOMEM -100 -#define EOS_TASK_PRIORITY_NET_XCHG 1 -#define EOS_TASK_PRIORITY_APP_XCHG 1 -#define EOS_TASK_PRIORITY_UDP_RCVR 1 +#define EOS_TASK_PRIORITY_NET 1 +#define EOS_TASK_PRIORITY_APP 1 +#define EOS_TASK_PRIORITY_SOCK 1 #define EOS_TASK_PRIORITY_UART 1 #define EOS_TASK_PRIORITY_MODEM 1 -#define EOS_TASK_PRIORITY_I2S 1 +#define EOS_TASK_PRIORITY_PCM 1 #define EOS_TASK_PRIORITY_CELL 1 #define EOS_TASK_PRIORITY_PWR 1 -#define EOS_TASK_SSIZE_NET_XCHG 8192 -#define EOS_TASK_SSIZE_APP_XCHG 8192 -#define EOS_TASK_SSIZE_UDP_RCVR 4096 +#define EOS_TASK_SSIZE_NET 8192 +#define EOS_TASK_SSIZE_APP 8192 +#define EOS_TASK_SSIZE_SOCK 4096 #define EOS_TASK_SSIZE_UART 4096 #define EOS_TASK_SSIZE_MODEM 4096 -#define EOS_TASK_SSIZE_I2S 4096 +#define EOS_TASK_SSIZE_PCM 4096 #define EOS_TASK_SSIZE_CELL 4096 #define EOS_TASK_SSIZE_PWR 4096 diff --git a/fw/esp32/components/eos/include/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..b5ae9ac 100644 --- a/fw/esp32/components/eos/include/msgq.h +++ b/fw/esp32/components/eos/include/msgq.h @@ -14,9 +14,9 @@ typedef struct EOSMsgQ { } EOSMsgQ; void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); +uint8_t eos_msgq_len(EOSMsgQ *msgq); int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len); void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len); -uint8_t eos_msgq_len(EOSMsgQ *msgq); typedef struct EOSBufQ { uint8_t idx_r; @@ -26,6 +26,6 @@ typedef struct EOSBufQ { } EOSBufQ; void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size); +uint8_t eos_bufq_len(EOSBufQ *bufq); int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer); unsigned char *eos_bufq_pop(EOSBufQ *bufq); -uint8_t eos_bufq_len(EOSBufQ *bufq); diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h index 3e9e625..b500e82 100644 --- a/fw/esp32/components/eos/include/net.h +++ b/fw/esp32/components/eos/include/net.h @@ -5,32 +5,36 @@ #define EOS_NET_SIZE_BUF EOS_NET_MTU #define EOS_NET_MTYPE_SOCK 1 -#define EOS_NET_MTYPE_RNG 3 -#define EOS_NET_MTYPE_POWER 4 +#define EOS_NET_MTYPE_WIFI 2 +#define EOS_NET_MTYPE_CELL 3 +#define EOS_NET_MTYPE_APP 4 +#define EOS_NET_MTYPE_RNG 5 -#define EOS_NET_MTYPE_WIFI 5 -#define EOS_NET_MTYPE_CELL 6 -#define EOS_NET_MTYPE_SIP 7 -#define EOS_NET_MTYPE_APP 8 +#define EOS_NET_MAX_MTYPE 5 -#define EOS_NET_MAX_MTYPE 8 +#define EOS_NET_MTYPE_SLEEP 0x10 /* does not have net handler */ #define EOS_NET_MTYPE_FLAG_ONEW 0x40 #define EOS_NET_MTYPE_FLAG_REPL 0x80 -#define EOS_NET_MTYPE_FLAG_MASK 0xc0 +#define EOS_NET_MTYPE_MASK 0x3F /* 0x0F if mtype is handled by evtq */ /* esp32 specific */ #define EOS_NET_SIZE_BUFQ 4 #define EOS_NET_SIZE_SNDQ 4 -typedef void (*eos_net_fptr_t) (unsigned char, unsigned char *, uint16_t); +typedef void (*eos_net_handler_t) (unsigned char, unsigned char *, uint16_t); +void eos_net_xchg_task(void *param); void eos_net_init(void); +void eos_net_run(void); unsigned char *eos_net_alloc(void); void eos_net_free(unsigned char *buf); -int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len); -void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len); -void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler); -void eos_net_sleep(void); -void eos_net_wake(uint8_t source, uint8_t mode); + +int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); +void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); + +void eos_net_sleep_req(void); +void eos_net_wake(void); + +void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler); diff --git a/fw/esp32/components/eos/include/net_priv.h b/fw/esp32/components/eos/include/net_priv.h new file mode 100644 index 0000000..fa1de61 --- /dev/null +++ b/fw/esp32/components/eos/include/net_priv.h @@ -0,0 +1,33 @@ +#define NET_DEV_NET EOS_PWR_DEV_NET +#define NET_DEV_APP EOS_PWR_DEV_APP + +typedef struct NETConfig { + int sleep; + int sleep_req; + int present; + int gpio_mosi; + int gpio_miso; + int gpio_sclk; + int gpio_cs; + int gpio_rts; + int gpio_cts; + uint32_t dev; + spi_host_device_t spi_host; + spi_bus_config_t *spi_bus_cfg; + spi_slave_interface_config_t *spi_iface_cfg; + spi_slave_transaction_t *spi_tr_cfg; + TaskHandle_t xchg_task_handle; + SemaphoreHandle_t mutex; + SemaphoreHandle_t bufq_mutex; + SemaphoreHandle_t bufq_semaph; + EOSBufQ *buf_q; + EOSMsgQ *send_q; + eos_net_handler_t msg_handler; +} NETConfig; + +void _eos_net_init_gpio(NETConfig *config); +unsigned char *_eos_net_alloc(NETConfig *config); +void _eos_net_free(NETConfig *config, unsigned char *buf); +int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len); +void _eos_net_sleep_req(NETConfig *config); +void _eos_net_wake(NETConfig *config); diff --git a/fw/esp32/components/eos/include/power.h b/fw/esp32/components/eos/include/power.h index 2215907..2590b80 100644 --- a/fw/esp32/components/eos/include/power.h +++ b/fw/esp32/components/eos/include/power.h @@ -1,22 +1,25 @@ #include <stdint.h> -#define EOS_PWR_MTYPE_BUTTON 1 +#define EOS_PWR_GPIO_NET 8 +#define EOS_PWR_GPIO_APP 10 +#define EOS_PWR_GPIO_MODEM 16 -#define EOS_PWR_WAKE_RST 0 -#define EOS_PWR_WAKE_BTN 1 -#define EOS_PWR_WAKE_UART 2 -#define EOS_PWR_WAKE_NET 3 -#define EOS_PWR_WAKE_NETQ 4 -#define EOS_PWR_WAKE_UNDEF 5 +#define EOS_PWR_DEV_NONE 0 +#define EOS_PWR_DEV_NET ((uint32_t)1 << EOS_PWR_GPIO_NET) +#define EOS_PWR_DEV_APP ((uint32_t)1 << EOS_PWR_GPIO_APP) +#define EOS_PWR_DEV_MODEM ((uint32_t)1 << EOS_PWR_GPIO_MODEM) +#define EOS_PWR_DEV_ALL (EOS_PWR_DEV_NET | EOS_PWR_DEV_APP | EOS_PWR_DEV_MODEM) -#define EOS_PWR_SMODE_LIGHT 1 -#define EOS_PWR_SMODE_DEEP 2 +#define EOS_PWR_SMODE_TICKLESS 1 +#define EOS_PWR_SMODE_LIGHT 2 +#define EOS_PWR_SMODE_DEEP 3 void eos_power_init(void); +void eos_power_run(void); +void eos_power_sys_sleep(uint8_t mode); +void eos_power_sys_wake(uint8_t mode) ; +uint32_t eos_power_wakeup_source(void); -void eos_power_wait4init(void); -void eos_power_wait4wake(void); -uint8_t eos_power_wakeup_cause(void); -void eos_power_sleep(void); -void eos_power_wake(uint8_t source); -void eos_power_net_ready(void);
\ No newline at end of file +void eos_power_sleep_req(uint8_t mode, uint32_t dev); +void eos_power_sleep_rdy(uint32_t dev); +void eos_power_wake(uint32_t dev); diff --git a/fw/esp32/components/eos/include/sock.h b/fw/esp32/components/eos/include/sock.h index 7e937cb..f2cf0c4 100644 --- a/fw/esp32/components/eos/include/sock.h +++ b/fw/esp32/components/eos/include/sock.h @@ -15,4 +15,6 @@ typedef struct EOSNetAddr { uint16_t port; } EOSNetAddr; -void eos_sock_init(void);
\ No newline at end of file +void eos_sock_init(void); +void eos_sock_run(void); +void eos_sock_reopen(void);
\ No newline at end of file diff --git a/fw/esp32/components/eos/include/wifi.h b/fw/esp32/components/eos/include/wifi.h index c1819e7..d080e25 100644 --- a/fw/esp32/components/eos/include/wifi.h +++ b/fw/esp32/components/eos/include/wifi.h @@ -13,6 +13,7 @@ #define EOS_WIFI_MAX_SCAN_RECORDS 20 void eos_wifi_init(void); +void eos_wifi_run(void); int eos_wifi_scan(void); int eos_wifi_auth(char *ssid, char *pass); @@ -21,4 +22,4 @@ int eos_wifi_disconnect(void); ssize_t eos_wifi_get_status(unsigned char *buffer); void eos_wifi_send_status(void); -void eos_wifi_send_scan(void);
\ No newline at end of file +void eos_wifi_send_scan(void); diff --git a/fw/esp32/components/eos/msgq.c b/fw/esp32/components/eos/msgq.c index c200f7c..57fb669 100644 --- a/fw/esp32/components/eos/msgq.c +++ b/fw/esp32/components/eos/msgq.c @@ -12,6 +12,10 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->array = array; } +uint8_t eos_msgq_len(EOSMsgQ *msgq) { + return (uint8_t)(msgq->idx_w - msgq->idx_r); +} + int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) { if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL; @@ -37,10 +41,6 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui } } -uint8_t eos_msgq_len(EOSMsgQ *msgq) { - return (uint8_t)(msgq->idx_w - msgq->idx_r); -} - void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) { bufq->idx_r = 0; bufq->idx_w = 0; @@ -48,6 +48,10 @@ void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) { bufq->array = array; } +uint8_t eos_bufq_len(EOSBufQ *bufq) { + return (uint8_t)(bufq->idx_w - bufq->idx_r); +} + int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer) { if ((uint8_t)(bufq->idx_w - bufq->idx_r) == bufq->size) return EOS_ERR_FULL; @@ -60,7 +64,3 @@ unsigned char *eos_bufq_pop(EOSBufQ *bufq) { return bufq->array[IDX_MASK(bufq->idx_r++, bufq->size)]; } - -uint8_t eos_bufq_len(EOSBufQ *bufq) { - return (uint8_t)(bufq->idx_w - bufq->idx_r); -} diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c index 56ec940..0ba2a2d 100644 --- a/fw/esp32/components/eos/net.c +++ b/fw/esp32/components/eos/net.c @@ -16,20 +16,21 @@ #include "eos.h" #include "msgq.h" #include "power.h" +#include "app.h" #include "net.h" +#include "net_priv.h" -#define SPI_GPIO_RTS 22 -#define SPI_GPIO_CTS 21 -#define SPI_GPIO_MOSI 23 -#define SPI_GPIO_MISO 19 -#define SPI_GPIO_SCLK 18 -#define SPI_GPIO_CS 5 +#define SPI_GPIO_RTS 35 +#define SPI_GPIO_CTS 3 +#define SPI_GPIO_MOSI 40 +#define SPI_GPIO_MISO 39 +#define SPI_GPIO_SCLK 38 +#define SPI_GPIO_CS 8 #define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 4) #define SPI_SIZE_HDR 3 -static volatile int net_sleep = 0; -static volatile int net_wake = 0; +#define SPI_HOST SPI3_HOST static EOSBufQ net_buf_q; static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; @@ -37,262 +38,440 @@ static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; static EOSMsgQ net_send_q; static EOSMsgItem net_sndq_array[EOS_NET_SIZE_SNDQ]; -static SemaphoreHandle_t mutex; -static SemaphoreHandle_t semaph; -static TaskHandle_t net_xchg_task_handle; +static NETConfig net_config; +static eos_net_handler_t net_handler[EOS_NET_MAX_MTYPE]; + +static spi_bus_config_t net_spi_bus_cfg; +static spi_slave_interface_config_t net_spi_iface_cfg; +static spi_slave_transaction_t net_spi_tr_cfg; + static const char *TAG = "EOS NET"; -static eos_net_fptr_t net_handler[EOS_NET_MAX_MTYPE]; +static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { + ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, buf_len); +} + +static void net_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { + uint8_t idx; -static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { - ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len); + idx = mtype & EOS_NET_MTYPE_MASK; + if (idx && (idx <= EOS_NET_MAX_MTYPE) && (buf_len <= EOS_NET_MTU)) { + net_handler[idx - 1](mtype, buffer, buf_len); + } else { + bad_handler(mtype, buffer, buf_len); + } } -// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. +/* Called after a transaction is queued and ready for pickup by master */ static void _post_setup_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 1); + NETConfig *config = trans->user; + + gpio_set_level(config->gpio_cts, 0); } -// Called after transaction is sent/received. We use this to set the handshake line low. +/* Called after transaction is sent/received */ static void _post_trans_cb(spi_slave_transaction_t *trans) { - gpio_set_level(SPI_GPIO_CTS, 0); + NETConfig *config = trans->user; + + gpio_set_level(config->gpio_cts, 1); +} + +static void net_goto_sleep(NETConfig *config) { + esp_err_t ret; + uint8_t msgq_len; + + + xSemaphoreTake(config->mutex, portMAX_DELAY); + msgq_len = eos_msgq_len(config->send_q); + if (msgq_len) { + gpio_set_level(config->gpio_rts, 0); + } else { + gpio_set_level(config->gpio_rts, 1); + } + xSemaphoreGive(config->mutex); + + ret = spi_slave_free(config->spi_host); + assert(ret == ESP_OK); + + /* for deep sleep */ + gpio_hold_en(config->gpio_cts); + + eos_power_sleep_rdy(config->dev); + vTaskSuspend(NULL); + + gpio_hold_dis(config->gpio_cts); + + ret = spi_slave_initialize(config->spi_host, config->spi_bus_cfg, config->spi_iface_cfg, SPI_DMA_CH_AUTO); + assert(ret == ESP_OK); + + xSemaphoreTake(config->mutex, portMAX_DELAY); + config->sleep = 0; + msgq_len = eos_msgq_len(config->send_q); + if (msgq_len) { + gpio_set_level(config->gpio_rts, 0); + } else { + gpio_set_level(config->gpio_rts, 1); + } + xSemaphoreGive(config->mutex); } -static void net_xchg_task(void *pvParameters) { - int wake = 0; - int skip_msg = 0; +void eos_net_xchg_task(void *param) { + NETConfig *config = param; + int present, skip_msg = 0, sleep_msg = 0; unsigned char mtype = 0; unsigned char mtype_flags = 0; unsigned char *buffer; - uint16_t len; unsigned char *buf_send = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); unsigned char *buf_recv = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); + uint16_t buf_len; + size_t trans_len; + spi_bus_config_t *spi_bus_cfg = config->spi_bus_cfg; + spi_slave_interface_config_t *spi_iface_cfg = config->spi_iface_cfg; + spi_slave_transaction_t *spi_tr_cfg = config->spi_tr_cfg; esp_err_t ret; - static spi_slave_transaction_t spi_tr; - - //Configuration for the SPI bus - static spi_bus_config_t spi_bus_cfg = { - .mosi_io_num = SPI_GPIO_MOSI, - .miso_io_num = SPI_GPIO_MISO, - .sclk_io_num = SPI_GPIO_SCLK - }; - - //Configuration for the SPI slave interface - static spi_slave_interface_config_t spi_slave_cfg = { - .mode = 0, - .spics_io_num = SPI_GPIO_CS, - .queue_size = 2, - .flags = 0, - .post_setup_cb = _post_setup_cb, - .post_trans_cb = _post_trans_cb - }; - - //Initialize SPI slave interface - ret = spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 2); - assert(ret == ESP_OK); - - memset(&spi_tr, 0, sizeof(spi_tr)); - spi_tr.tx_buffer = buf_send; - spi_tr.rx_buffer = buf_recv; - spi_tr.length = SPI_SIZE_BUF * 8; - - if (eos_power_wakeup_cause() != EOS_PWR_WAKE_RST) { - wake = 1; - skip_msg = 1; + assert(buf_send != NULL); + assert(buf_recv != NULL); + + /* Configuration for the SPI bus */ + spi_bus_cfg->mosi_io_num = config->gpio_mosi; + spi_bus_cfg->miso_io_num = config->gpio_miso; + spi_bus_cfg->sclk_io_num = config->gpio_sclk; + + /* Configuration for the SPI slave interface */ + spi_iface_cfg->mode = 0; + spi_iface_cfg->spics_io_num = config->gpio_cs; + spi_iface_cfg->queue_size = 2; + spi_iface_cfg->flags = 0; + spi_iface_cfg->post_setup_cb = _post_setup_cb; + spi_iface_cfg->post_trans_cb = _post_trans_cb; + + spi_tr_cfg->tx_buffer = buf_send; + spi_tr_cfg->rx_buffer = buf_recv; + spi_tr_cfg->length = SPI_SIZE_BUF * 8; + spi_tr_cfg->user = config; + + xSemaphoreTake(config->mutex, portMAX_DELAY); + present = config->present; + xSemaphoreGive(config->mutex); + if (!present) { + vTaskSuspend(NULL); } - eos_power_wait4init(); + /* Initialize SPI slave interface */ + ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO); + assert(ret == ESP_OK); + while (1) { if (!skip_msg) { - xSemaphoreTake(mutex, portMAX_DELAY); + xSemaphoreTake(config->mutex, portMAX_DELAY); - eos_msgq_pop(&net_send_q, &mtype, &buffer, &len); + eos_msgq_pop(config->send_q, &mtype, &buffer, &buf_len); if (mtype) { buf_send[0] = mtype; - buf_send[1] = len >> 8; - buf_send[2] = len & 0xFF; + buf_send[1] = buf_len >> 8; + buf_send[2] = buf_len & 0xFF; if (buffer) { - memcpy(buf_send + SPI_SIZE_HDR, buffer, len); - eos_bufq_push(&net_buf_q, buffer); - xSemaphoreGive(semaph); + memcpy(buf_send + SPI_SIZE_HDR, buffer, buf_len); + xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); + eos_bufq_push(config->buf_q, buffer); + xSemaphoreGive(config->bufq_mutex); + xSemaphoreGive(config->bufq_semaph); } + } else if (!sleep_msg && config->sleep_req) { + buf_send[0] = EOS_NET_MTYPE_SLEEP; + buf_send[1] = 0; + buf_send[2] = 0; + sleep_msg = 1; + config->sleep_req = 0; + if (config->dev == NET_DEV_NET) config->sleep = 1; } else { - gpio_set_level(SPI_GPIO_RTS, 0); + gpio_set_level(config->gpio_rts, 1); buf_send[0] = 0; buf_send[1] = 0; buf_send[2] = 0; } - xSemaphoreGive(mutex); + xSemaphoreGive(config->mutex); } skip_msg = 0; buf_recv[0] = 0; buf_recv[1] = 0; buf_recv[2] = 0; - spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY); - // ESP_LOGI(TAG, "RECV:%d", buf_recv[0]); + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); + assert(ret == ESP_OK); + + trans_len = spi_tr_cfg->trans_len / 8; + + ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", buf_recv[0], config->dev, trans_len); + + if (sleep_msg && (config->dev == NET_DEV_NET)) { + net_goto_sleep(config); + sleep_msg = 0; + continue; + } + + if (trans_len < 1) { + ESP_LOGE(TAG, "RECV LEN:%d", trans_len); + continue; + } - if (wake) { - eos_power_net_ready(); - wake = 0; + /* SPI reset */ + if ((trans_len == 1) && (buf_recv[0] == 0)) { + if (buf_send[0]) skip_msg = 1; + continue; } - if ((spi_tr.trans_len / 8) < SPI_SIZE_HDR) continue; - if (buf_recv[0] == 0x00) continue; + mtype = buf_recv[0] & EOS_NET_MTYPE_MASK; + mtype_flags = buf_recv[0] & ~EOS_NET_MTYPE_MASK; + if (buf_send[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) { + skip_msg = 1; + } - if (buf_recv[0] == 0xFF) { // Sleep req - if (buf_send[0] == 0) { - spi_slave_free(VSPI_HOST); - eos_power_sleep(); + if (buf_send[0] && (trans_len < buf_len + SPI_SIZE_HDR) && !skip_msg) { + spi_tr_cfg->tx_buffer = buf_send + trans_len; + spi_tr_cfg->rx_buffer = buf_recv + trans_len; + spi_tr_cfg->length = (SPI_SIZE_BUF - trans_len) * 8; + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); + assert(ret == ESP_OK); + trans_len += spi_tr_cfg->trans_len / 8; + spi_tr_cfg->tx_buffer = buf_send; + spi_tr_cfg->rx_buffer = buf_recv; + spi_tr_cfg->length = SPI_SIZE_BUF * 8; + } - xSemaphoreTake(mutex, portMAX_DELAY); - net_sleep = 1; - if (eos_msgq_len(&net_send_q)) net_wake = 1; - xSemaphoreGive(mutex); + if (mtype == 0) continue; - if (net_wake) eos_power_wake(EOS_PWR_WAKE_NETQ); - vTaskSuspend(NULL); + if (mtype == EOS_NET_MTYPE_SLEEP) { + uint8_t mode; - xSemaphoreTake(mutex, portMAX_DELAY); - net_sleep = 0; - net_wake = 0; - xSemaphoreGive(mutex); + mode = EOS_PWR_SMODE_LIGHT; - spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); - wake = 1; - skip_msg = 1; + switch (config->dev) { + case NET_DEV_NET: { + eos_power_sleep_req(mode, EOS_PWR_DEV_ALL); + break; + } + case NET_DEV_APP: { + uint8_t msgq_len; + + xSemaphoreTake(config->mutex, portMAX_DELAY); + msgq_len = eos_msgq_len(config->send_q); + if (msgq_len == 0) { + config->sleep = 1; + config->sleep_req = 0; + } + xSemaphoreGive(config->mutex); + if (msgq_len == 0) { + net_goto_sleep(config); + sleep_msg = 0; + } + break; + } } continue; } - mtype = buf_recv[0] & ~EOS_NET_MTYPE_FLAG_MASK; - mtype_flags = buf_recv[0] & EOS_NET_MTYPE_FLAG_MASK; - len = (uint16_t)buf_recv[1] << 8; - len |= (uint16_t)buf_recv[2] & 0xFF; - buffer = buf_recv + SPI_SIZE_HDR; - if ((mtype <= EOS_NET_MAX_MTYPE) && (len <= EOS_NET_MTU)) { - net_handler[mtype - 1](buf_recv[0], buffer, len); - } else { - bad_handler(buf_recv[0], buffer, len); - } - if ((mtype_flags & EOS_NET_MTYPE_FLAG_ONEW) && buf_send[0]) { - skip_msg = 1; + if (trans_len < SPI_SIZE_HDR) { + ESP_LOGE(TAG, "RECV LEN:%d", trans_len); + continue; } + buf_len = (uint16_t)buf_recv[1] << 8; + buf_len |= (uint16_t)buf_recv[2] & 0xFF; + buffer = buf_recv + SPI_SIZE_HDR; + config->msg_handler(buf_recv[0], buffer, buf_len); + if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) { - spi_tr.tx_buffer = buf_recv; - spi_tr.rx_buffer = NULL; - spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY); - spi_tr.tx_buffer = buf_send; - spi_tr.rx_buffer = buf_recv; + spi_tr_cfg->tx_buffer = buf_recv; + spi_tr_cfg->rx_buffer = NULL; + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); + assert(ret == ESP_OK); + spi_tr_cfg->tx_buffer = buf_send; + spi_tr_cfg->rx_buffer = buf_recv; } } + vTaskDelete(NULL); } -void eos_net_init(void) { - int i; - - // Configuration for the handshake lines +void _eos_net_init_gpio(NETConfig *config) { + /* Configuration for the handshake lines */ gpio_config_t io_conf = {}; + gpio_set_level(config->gpio_rts, 1); + gpio_set_level(config->gpio_cts, 1); io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_CTS); + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pin_bit_mask = BIT64(config->gpio_rts) | BIT64(config->gpio_cts); gpio_config(&io_conf); - gpio_set_level(SPI_GPIO_CTS, 0); +} - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_RTS); - gpio_config(&io_conf); - gpio_set_level(SPI_GPIO_RTS, 0); +void eos_net_init(void) { + SemaphoreHandle_t mutex; + SemaphoreHandle_t bufq_mutex; + SemaphoreHandle_t bufq_semaph; + int i; eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_SNDQ); eos_bufq_init(&net_buf_q, net_bufq_array, EOS_NET_SIZE_BUFQ); for (i=0; i<EOS_NET_SIZE_BUFQ; i++) { - eos_bufq_push(&net_buf_q, malloc(EOS_NET_SIZE_BUF)); + unsigned char *buffer; + + buffer = malloc(EOS_NET_SIZE_BUF); + assert(buffer != NULL); + eos_bufq_push(&net_buf_q, buffer); } for (i=0; i<EOS_NET_MAX_MTYPE; i++) { net_handler[i] = bad_handler; } - semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ); mutex = xSemaphoreCreateBinary(); + assert(mutex != NULL); + bufq_mutex = xSemaphoreCreateBinary(); + assert(bufq_mutex != NULL); + bufq_semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ); + assert(bufq_semaph != NULL); + xSemaphoreGive(mutex); - xTaskCreate(&net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET_XCHG, NULL, EOS_TASK_PRIORITY_NET_XCHG, &net_xchg_task_handle); + xSemaphoreGive(bufq_mutex); + + net_config.sleep = 0; + net_config.sleep_req = 0; + net_config.present = 1; + net_config.dev = NET_DEV_NET; + net_config.gpio_mosi = SPI_GPIO_MOSI; + net_config.gpio_miso = SPI_GPIO_MISO; + net_config.gpio_sclk = SPI_GPIO_SCLK; + net_config.gpio_cs = SPI_GPIO_CS; + net_config.gpio_rts = SPI_GPIO_RTS; + net_config.gpio_cts = SPI_GPIO_CTS; + net_config.spi_host = SPI_HOST; + net_config.spi_bus_cfg = &net_spi_bus_cfg; + net_config.spi_iface_cfg = &net_spi_iface_cfg; + net_config.spi_tr_cfg = &net_spi_tr_cfg; + net_config.mutex = mutex; + net_config.bufq_mutex = bufq_mutex; + net_config.bufq_semaph = bufq_semaph; + net_config.buf_q = &net_buf_q; + net_config.send_q = &net_send_q; + net_config.msg_handler = net_msg_handler; + + _eos_net_init_gpio(&net_config); + + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + gpio_hold_dis(net_config.gpio_cts); + } + ESP_LOGI(TAG, "INIT"); } -unsigned char *eos_net_alloc(void) { +void eos_net_run(void) { + BaseType_t rv; + + rv = xTaskCreate(&eos_net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET, &net_config, EOS_TASK_PRIORITY_NET, &net_config.xchg_task_handle); + assert(rv == pdPASS); + + ESP_LOGI(TAG, "RUN"); +} + +unsigned char *_eos_net_alloc(NETConfig *config) { unsigned char *ret; - xSemaphoreTake(semaph, portMAX_DELAY); - xSemaphoreTake(mutex, portMAX_DELAY); - ret = eos_bufq_pop(&net_buf_q); - xSemaphoreGive(mutex); + xSemaphoreTake(config->bufq_semaph, portMAX_DELAY); + xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); + ret = eos_bufq_pop(config->buf_q); + xSemaphoreGive(config->bufq_mutex); return ret; } +void _eos_net_free(NETConfig *config, unsigned char *buf) { + xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); + eos_bufq_push(config->buf_q, buf); + xSemaphoreGive(config->bufq_semaph); + xSemaphoreGive(config->bufq_mutex); +} + +unsigned char *eos_net_alloc(void) { + return _eos_net_alloc(&net_config); +} + void eos_net_free(unsigned char *buf) { - xSemaphoreTake(mutex, portMAX_DELAY); - eos_bufq_push(&net_buf_q, buf); - xSemaphoreGive(semaph); - xSemaphoreGive(mutex); + _eos_net_free(&net_config, buf); } -int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len) { +int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { int rv = EOS_OK; int sleep; - xSemaphoreTake(mutex, portMAX_DELAY); - sleep = net_sleep && !net_wake; - gpio_set_level(SPI_GPIO_RTS, 1); - rv = eos_msgq_push(&net_send_q, mtype, buffer, len); - xSemaphoreGive(mutex); - - if (rv) eos_net_free(buffer); + xSemaphoreTake(config->mutex, portMAX_DELAY); + sleep = config->sleep; + rv = eos_msgq_push(config->send_q, mtype, buffer, buf_len); + if (!rv && !sleep) gpio_set_level(config->gpio_rts, 0); + xSemaphoreGive(config->mutex); - if (sleep) eos_power_wake(EOS_PWR_WAKE_NETQ); + if (!rv && sleep) eos_power_wake(config->dev); + if (rv) _eos_net_free(config, buffer); return rv; } -void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len) { +int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { + return _eos_net_send(&net_config, mtype, buffer, buf_len); +} + +void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { buffer -= SPI_SIZE_HDR; buffer[0] = mtype; - buffer[1] = len >> 8; - buffer[2] = len & 0xFF; + buffer[1] = buf_len >> 8; + buffer[2] = buf_len & 0xFF; } -void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler) { - if (handler == NULL) handler = bad_handler; - if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler; -} +void _eos_net_sleep_req(NETConfig *config) { + int sleep, present; + + xSemaphoreTake(config->mutex, portMAX_DELAY); + sleep = config->sleep; + present = config->present; + if (!sleep && present) { + config->sleep_req = 1; + gpio_set_level(config->gpio_rts, 0); + } + xSemaphoreGive(config->mutex); -void eos_net_sleep(void) { - gpio_set_level(SPI_GPIO_CTS, 1); - vTaskDelay(200 / portTICK_PERIOD_MS); - gpio_set_level(SPI_GPIO_CTS, 0); + if (!present) eos_power_sleep_rdy(config->dev); } -void eos_net_wake(uint8_t source, uint8_t mode) { - int sleep; +void _eos_net_wake(NETConfig *config) { + int sleep, present; + + xSemaphoreTake(config->mutex, portMAX_DELAY); + present = config->present; + xSemaphoreGive(config->mutex); - if (mode == EOS_PWR_SMODE_DEEP) return; + if (!present) return; do { - vTaskResume(net_xchg_task_handle); + vTaskResume(config->xchg_task_handle); vTaskDelay(10 / portTICK_PERIOD_MS); - - xSemaphoreTake(mutex, portMAX_DELAY); - sleep = net_sleep; - xSemaphoreGive(mutex); + xSemaphoreTake(config->mutex, portMAX_DELAY); + sleep = config->sleep; + xSemaphoreGive(config->mutex); } while (sleep); } + +void eos_net_sleep_req(void) { + _eos_net_sleep_req(&net_config); +} + +void eos_net_wake(void) { + _eos_net_wake(&net_config); +} + +void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler) { + if (handler == NULL) handler = bad_handler; + if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler; +} diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c index b98c0ec..27c44a5 100644 --- a/fw/esp32/components/eos/power.c +++ b/fw/esp32/components/eos/power.c @@ -4,37 +4,30 @@ #include <freertos/task.h> #include <freertos/queue.h> #include <driver/gpio.h> +#include <driver/rtc_io.h> +#include <driver/uart.h> + +#include <esp_system.h> #include <esp_sleep.h> -#include <esp_timer.h> #include <esp_pm.h> #include <esp_log.h> -#include <esp32/rom/rtc.h> #include "eos.h" #include "net.h" +#include "app.h" #include "cell.h" #include "power.h" -#define POWER_GPIO_BTN 0 -#define POWER_GPIO_NET 5 -#define POWER_GPIO_UART 35 - -#define POWER_ETYPE_BTN 1 -#define POWER_ETYPE_SLEEP1 2 -#define POWER_ETYPE_SLEEP2 3 -#define POWER_ETYPE_WAKE 4 -#define POWER_ETYPE_NETRDY 5 +#define PWR_ETYPE_SLEEP_REQ 1 +#define PWR_ETYPE_SLEEP_RDY 2 +#define PWR_ETYPE_WAKE 3 typedef struct { uint8_t type; - union { - uint8_t source; - uint8_t level; - }; + uint8_t mode; + uint32_t dev; } power_event_t; -static esp_timer_handle_t timer; - static esp_pm_lock_handle_t power_lock_cpu_freq; static esp_pm_lock_handle_t power_lock_apb_freq; static esp_pm_lock_handle_t power_lock_no_sleep; @@ -43,232 +36,119 @@ static const char *TAG = "EOS POWER"; static QueueHandle_t power_queue; -static volatile int init_done = 0; -static volatile int wake_done = 0; - -static void IRAM_ATTR btn_handler(void *arg) { - power_event_t evt; - - evt.type = POWER_ETYPE_BTN; - evt.level = gpio_get_level(POWER_GPIO_BTN); - xQueueSendFromISR(power_queue, &evt, NULL); -} - -static void IRAM_ATTR btn_wake_handler(void *arg) { - power_event_t evt; - - gpio_intr_disable(POWER_GPIO_BTN); - - evt.type = POWER_ETYPE_WAKE; - evt.source = EOS_PWR_WAKE_BTN; - xQueueSendFromISR(power_queue, &evt, NULL); - -} - static void IRAM_ATTR net_wake_handler(void *arg) { power_event_t evt; - gpio_intr_disable(POWER_GPIO_NET); - - evt.type = POWER_ETYPE_WAKE; - evt.source = EOS_PWR_WAKE_NET; + evt.type = PWR_ETYPE_WAKE; + evt.dev = EOS_PWR_DEV_NET; xQueueSendFromISR(power_queue, &evt, NULL); } -static void IRAM_ATTR uart_wake_handler(void *arg) { +static void IRAM_ATTR app_wake_handler(void *arg) { power_event_t evt; - gpio_intr_disable(POWER_GPIO_UART); - - evt.type = POWER_ETYPE_WAKE; - evt.source = EOS_PWR_WAKE_UART; + evt.type = PWR_ETYPE_WAKE; + evt.dev = EOS_PWR_DEV_APP; xQueueSendFromISR(power_queue, &evt, NULL); } -static void timer_handler(void *arg) { +static void IRAM_ATTR modem_wake_handler(void *arg) { power_event_t evt; - evt.type = POWER_ETYPE_SLEEP2; + evt.type = PWR_ETYPE_WAKE; + evt.dev = EOS_PWR_DEV_MODEM; xQueueSendFromISR(power_queue, &evt, NULL); } -static void power_sleep_stage1(int modem_wake_en) { - gpio_config_t io_conf = {}; - - eos_modem_sleep(); - eos_net_sleep(); - - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - - gpio_isr_handler_add(POWER_GPIO_BTN, btn_wake_handler, NULL); - gpio_isr_handler_add(POWER_GPIO_NET, net_wake_handler, NULL); - if (modem_wake_en) { - gpio_isr_handler_add(POWER_GPIO_UART, uart_wake_handler, NULL); - } - - esp_sleep_enable_gpio_wakeup(); - gpio_wakeup_enable(POWER_GPIO_BTN, GPIO_INTR_LOW_LEVEL); - gpio_wakeup_enable(POWER_GPIO_NET, GPIO_INTR_LOW_LEVEL); - if (modem_wake_en) { - gpio_wakeup_enable(POWER_GPIO_UART, GPIO_INTR_LOW_LEVEL); - } - - esp_timer_start_once(timer, 10 * 1000000); - - esp_pm_lock_release(power_lock_cpu_freq); - esp_pm_lock_release(power_lock_apb_freq); - esp_pm_lock_release(power_lock_no_sleep); -} - -static void power_sleep_stage2(int modem_wake_en, uint8_t mode) { - switch (mode) { - case EOS_PWR_SMODE_LIGHT: { - ESP_LOGI(TAG, "LIGHT SLEEP"); - - esp_light_sleep_start(); - break; - } - - case EOS_PWR_SMODE_DEEP: { - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); - - gpio_deep_sleep_hold_en(); - esp_sleep_enable_ext0_wakeup(POWER_GPIO_BTN, 0); - if (modem_wake_en) { - esp_sleep_enable_ext1_wakeup((uint64_t)1 << POWER_GPIO_UART, ESP_EXT1_WAKEUP_ALL_LOW); - } - - ESP_LOGI(TAG, "DEEP SLEEP"); - - eos_modem_deep_sleep(); - esp_deep_sleep_start(); - break; - } - } -} - -static void power_wake_stage1(uint8_t source, uint8_t mode) { - if (mode == EOS_PWR_SMODE_LIGHT) { - gpio_config_t io_conf = {}; - - esp_pm_lock_acquire(power_lock_cpu_freq); - esp_pm_lock_acquire(power_lock_apb_freq); - esp_pm_lock_acquire(power_lock_no_sleep); - - gpio_wakeup_disable(POWER_GPIO_BTN); - gpio_wakeup_disable(POWER_GPIO_NET); - gpio_wakeup_disable(POWER_GPIO_UART); - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); - - gpio_isr_handler_remove(POWER_GPIO_NET); - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_DISABLE; - io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - } - - gpio_intr_disable(POWER_GPIO_BTN); - if ((source != EOS_PWR_WAKE_BTN) && (source != EOS_PWR_WAKE_NET)) { - gpio_set_level(POWER_GPIO_BTN, 0); - gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_OUTPUT); - vTaskDelay(200 / portTICK_PERIOD_MS); - gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_INPUT); - } - - eos_net_wake(source, mode); -} - -static void power_wake_stage2(uint8_t source, uint8_t mode) { - eos_modem_wake(source, mode); - - gpio_set_intr_type(POWER_GPIO_BTN, GPIO_INTR_ANYEDGE); - gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); - - ESP_LOGI(TAG, "WAKE"); - wake_done = 1; -} - static void power_event_task(void *pvParameters) { power_event_t evt; - uint8_t source; - uint8_t wakeup_cause; uint8_t mode; - int sleep1, sleep2; - int modem_wake_en; + uint32_t sleep_req, sleep_rdy; + int sys_sleep; mode = 0; - source = 0; - wakeup_cause = eos_power_wakeup_cause(); - if (wakeup_cause != EOS_PWR_WAKE_RST) { - mode = EOS_PWR_SMODE_DEEP; - sleep1 = 1; - } else { - sleep1 = 0; - } - sleep2 = 0; - modem_wake_en = 0; - + sys_sleep = 0; + sleep_req = 0; + sleep_rdy = 0; while (1) { if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) { switch (evt.type) { - case POWER_ETYPE_SLEEP1: { - if (!sleep1) { - modem_wake_en = eos_modem_present(); - mode = EOS_PWR_SMODE_LIGHT; - power_sleep_stage1(modem_wake_en); - sleep1 = 1; - sleep2 = 1; + case PWR_ETYPE_SLEEP_REQ: { + if (evt.mode) mode = evt.mode; + if ((evt.dev & EOS_PWR_DEV_NET) && !(sleep_req & EOS_PWR_DEV_NET)) { + eos_net_sleep_req(); } - break; - } - - case POWER_ETYPE_SLEEP2: { - if (sleep2) { - mode = EOS_PWR_SMODE_DEEP; - power_sleep_stage2(modem_wake_en, mode); - sleep2 = 0; + if ((evt.dev & EOS_PWR_DEV_APP) && !(sleep_req & EOS_PWR_DEV_APP)) { + eos_app_sleep_req(); } - break; - } - - case POWER_ETYPE_WAKE: { - if (sleep1) { - source = evt.source; - power_wake_stage1(source, mode); - if (sleep2) { - esp_timer_stop(timer); - sleep2 = 0; - } + if ((evt.dev & EOS_PWR_DEV_MODEM) && !(sleep_req & EOS_PWR_DEV_MODEM)) { + eos_modem_sleep_req(); + } + sleep_req |= evt.dev; + if (sleep_rdy == EOS_PWR_DEV_ALL) { + eos_power_sleep_rdy(0); } break; } - case POWER_ETYPE_NETRDY: { - power_wake_stage2(source, mode); - sleep1 = 0; - source = 0; + case PWR_ETYPE_SLEEP_RDY: { + gpio_config_t io_conf = { + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_NEGEDGE, + .pull_up_en = 1, + .pull_down_en = 0, + }; + + if (evt.dev & EOS_PWR_DEV_NET) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_NET); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_NET, net_wake_handler, NULL); + } + if (evt.dev & EOS_PWR_DEV_APP) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_APP); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_APP, app_wake_handler, NULL); + } + if (evt.dev & EOS_PWR_DEV_MODEM) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_MODEM); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_MODEM, modem_wake_handler, NULL); + } + sleep_rdy |= evt.dev; + if (!sys_sleep && mode && (sleep_rdy == EOS_PWR_DEV_ALL)) { + sys_sleep = 1; + eos_power_sys_sleep(mode); + } break; } - case POWER_ETYPE_BTN: { - unsigned char *buf; - - buf = eos_net_alloc(); - buf[0] = EOS_PWR_MTYPE_BUTTON; - buf[1] = evt.level; - eos_net_send(EOS_NET_MTYPE_POWER, buf, 2); + case PWR_ETYPE_WAKE: { + ESP_LOGI(TAG, "WAKE:0x%.8lX", evt.dev); + if (sys_sleep) { + eos_power_sys_wake(mode); + sys_sleep = 0; + mode = 0; + } + if ((evt.dev & EOS_PWR_DEV_NET) && (sleep_rdy & EOS_PWR_DEV_NET)) { + gpio_isr_handler_remove(EOS_PWR_GPIO_NET); + gpio_reset_pin(EOS_PWR_GPIO_NET); + eos_net_wake(); + } + if ((evt.dev & EOS_PWR_DEV_APP) && (sleep_rdy & EOS_PWR_DEV_APP)) { + gpio_isr_handler_remove(EOS_PWR_GPIO_APP); + gpio_reset_pin(EOS_PWR_GPIO_APP); + eos_app_wake(); + } + if ((evt.dev & EOS_PWR_DEV_MODEM) && (sleep_rdy & EOS_PWR_DEV_MODEM)) { + gpio_isr_handler_remove(EOS_PWR_GPIO_MODEM); + gpio_reset_pin(EOS_PWR_GPIO_MODEM); + eos_modem_wake(); + } + sleep_req &= ~evt.dev; + sleep_rdy &= ~evt.dev; + ESP_LOGI(TAG, "WAKE DONE:0x%.8lX", evt.dev); break; } - - default: - break; } } } @@ -276,35 +156,9 @@ static void power_event_task(void *pvParameters) { } void eos_power_init(void) { - esp_err_t ret; - gpio_config_t io_conf = {}; - esp_timer_create_args_t timer_args = {}; - esp_pm_config_esp32_t pwr_conf; - uint8_t wakeup_cause; - - io_conf.intr_type = GPIO_INTR_ANYEDGE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_BTN); - io_conf.pull_up_en = 1; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); - - timer_args.callback = timer_handler, - timer_args.arg = NULL; - timer_args.name = "sleep"; - - ret = esp_timer_create(&timer_args, &timer); - assert(ret == ESP_OK); - /* - ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - assert(ret == ESP_OK); - ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_ON); - assert(ret == ESP_OK); - ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON); - assert(ret == ESP_OK); - */ + esp_err_t ret; + esp_pm_config_t pwr_conf; ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, NULL, &power_lock_cpu_freq); assert(ret == ESP_OK); @@ -326,70 +180,118 @@ void eos_power_init(void) { ret = esp_pm_configure(&pwr_conf); assert(ret == ESP_OK); + */ - power_queue = xQueueCreate(4, sizeof(power_event_t)); - xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL); - - wakeup_cause = eos_power_wakeup_cause(); - if (wakeup_cause != EOS_PWR_WAKE_RST) { - eos_power_wake(wakeup_cause); + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + rtc_gpio_deinit(EOS_PWR_GPIO_NET); + rtc_gpio_deinit(EOS_PWR_GPIO_APP); + rtc_gpio_deinit(EOS_PWR_GPIO_MODEM); + eos_power_sys_wake(EOS_PWR_SMODE_DEEP); } - init_done = 1; + power_queue = xQueueCreate(4, sizeof(power_event_t)); + assert(power_queue != NULL); + ESP_LOGI(TAG, "INIT"); } -void eos_power_wait4init(void) { - while (!init_done); -} +void eos_power_run(void) { + BaseType_t rv; -void eos_power_wait4wake(void) { - if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) return; - while (!wake_done); -} + rv = xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL); + assert(rv == pdPASS); -uint8_t eos_power_wakeup_cause(void) { - esp_reset_reason_t reset_cause = esp_reset_reason(); - esp_sleep_wakeup_cause_t wakeup_cause = esp_sleep_get_wakeup_cause(); + ESP_LOGI(TAG, "RUN"); +} - if (reset_cause == ESP_RST_DEEPSLEEP) { - switch (wakeup_cause) { - case ESP_SLEEP_WAKEUP_EXT0: - return EOS_PWR_WAKE_BTN; +void eos_power_sys_sleep(uint8_t mode) { + switch (mode) { + case EOS_PWR_SMODE_TICKLESS: { + esp_pm_lock_release(power_lock_cpu_freq); + esp_pm_lock_release(power_lock_apb_freq); + esp_pm_lock_release(power_lock_no_sleep); + break; + } - case ESP_SLEEP_WAKEUP_EXT1: - return EOS_PWR_WAKE_UART; + case EOS_PWR_SMODE_LIGHT: + case EOS_PWR_SMODE_DEEP: { + esp_err_t ret; + + /* in case of missing modem */ + rtc_gpio_pullup_en(EOS_PWR_GPIO_MODEM); + esp_sleep_enable_ext1_wakeup_io(EOS_PWR_DEV_ALL, ESP_EXT1_WAKEUP_ANY_LOW); + if (mode == EOS_PWR_SMODE_DEEP) { + gpio_deep_sleep_hold_en(); + esp_deep_sleep_start(); + } else { + ESP_LOGI(TAG, "LIGHT SLEEP"); + uart_wait_tx_idle_polling(UART_NUM_0); + ret = esp_light_sleep_start(); + ESP_LOGI(TAG, "LIGHT WAKE: %d", ret); + eos_power_wake(eos_power_wakeup_source()); + } + break; + } + } +} - default: - return EOS_PWR_WAKE_UNDEF; +void eos_power_sys_wake(uint8_t mode) { + switch (mode) { + case EOS_PWR_SMODE_TICKLESS: { + esp_pm_lock_acquire(power_lock_cpu_freq); + esp_pm_lock_acquire(power_lock_apb_freq); + esp_pm_lock_acquire(power_lock_no_sleep); + break; + } + case EOS_PWR_SMODE_LIGHT: + case EOS_PWR_SMODE_DEEP: { + rtc_gpio_pullup_dis(EOS_PWR_GPIO_MODEM); + esp_sleep_disable_ext1_wakeup_io(0); + if (mode == EOS_PWR_SMODE_DEEP) { + gpio_deep_sleep_hold_dis(); + } + break; } + } +} + +uint32_t eos_power_wakeup_source(void) { + esp_sleep_wakeup_cause_t wakeup_cause; + uint32_t dev; + + dev = EOS_PWR_DEV_NONE; + wakeup_cause = esp_sleep_get_wakeup_cause(); + if (wakeup_cause == ESP_SLEEP_WAKEUP_EXT1) { + dev = esp_sleep_get_ext1_wakeup_status(); + return dev; } else { - return EOS_PWR_WAKE_RST; + ESP_LOGE(TAG, "BAD WAKEUP CAUSE"); } + return dev; } -void eos_power_sleep(void) { +void eos_power_sleep_req(uint8_t mode, uint32_t dev) { power_event_t evt; - evt.type = POWER_ETYPE_SLEEP1; - evt.source = 0; + evt.type = PWR_ETYPE_SLEEP_REQ; + evt.mode = mode; + evt.dev = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } -void eos_power_wake(uint8_t source) { +void eos_power_sleep_rdy(uint32_t dev) { power_event_t evt; - evt.type = POWER_ETYPE_WAKE; - evt.source = source; - + evt.type = PWR_ETYPE_SLEEP_RDY; + evt.dev = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } -void eos_power_net_ready(void) { +void eos_power_wake(uint32_t dev) { power_event_t evt; - evt.type = POWER_ETYPE_NETRDY; - evt.source = 0; - + ESP_LOGI(TAG, "WAKE SENT"); + evt.type = PWR_ETYPE_WAKE; + evt.dev = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } diff --git a/fw/esp32/components/eos/rng.c b/fw/esp32/components/eos/rng.c index 3927df1..675a79c 100644 --- a/fw/esp32/components/eos/rng.c +++ b/fw/esp32/components/eos/rng.c @@ -1,4 +1,4 @@ -#include <esp_system.h> +#include <esp_random.h> #include <esp_log.h> #include <esp_err.h> @@ -26,6 +26,7 @@ rng_handler_fin: void eos_rng_init(void) { eos_net_set_handler(EOS_NET_MTYPE_RNG, rng_handler); + ESP_LOGI(TAG, "INIT"); } diff --git a/fw/esp32/components/eos/sock.c b/fw/esp32/components/eos/sock.c index 08d95d5..b6ed3e9 100644 --- a/fw/esp32/components/eos/sock.c +++ b/fw/esp32/components/eos/sock.c @@ -1,6 +1,7 @@ #include <stdlib.h> #include <stdint.h> #include <string.h> +#include <sys/select.h> #include <freertos/FreeRTOS.h> #include <freertos/semphr.h> @@ -9,6 +10,9 @@ #include <esp_system.h> #include <esp_log.h> #include <esp_err.h> +#include <esp_vfs.h> +#include <esp_vfs_dev.h> +#include <esp_vfs_eventfd.h> #include <lwip/sockets.h> #include <lwip/err.h> @@ -23,8 +27,14 @@ static const char *TAG = "EOS SOCK"; static SemaphoreHandle_t mutex; +static int cmd_fd, rep_fd; static int _socks[EOS_SOCK_MAX_SOCK]; +#define CMD_OPEN 1 +#define CMD_CLOSE 2 +#define CMD_SEND 3 +#define CMD_REOPEN 4 + static int t_open_dgram(void) { struct sockaddr_in _myaddr; int sock; @@ -74,83 +84,246 @@ static ssize_t t_recvfrom(int sock, void *msg, size_t msg_size, EOSNetAddr *addr return recvlen; } +static void populate_fds(fd_set *fds, int *max_fd) { + int i; + + *max_fd = cmd_fd; + + FD_ZERO(fds); + FD_SET(cmd_fd, fds); + for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { + if (_socks[i]) { + FD_SET(_socks[i], fds); + if (_socks[i] > *max_fd) { + *max_fd = _socks[i]; + } + } + } +} + static void udp_rcvr_task(void *pvParameters) { - uint8_t sock_i = (uint8_t)pvParameters; - int sock = _socks[sock_i-1]; - - do { - EOSNetAddr addr; - unsigned char *buf, *_buf; - ssize_t rv; - - buf = eos_net_alloc(); - rv = t_recvfrom(sock, buf + EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF - EOS_SOCK_SIZE_UDP_HDR, &addr); - if (rv < 0) { - eos_net_free(buf); - ESP_LOGE(TAG, "UDP RECV ERR:%d", rv); - break; + EOSNetAddr addr; + unsigned char *buffer; + uint16_t buf_len; + fd_set all_fds, read_fds; + uint8_t sock_i; + uint8_t cmd[8]; + ssize_t _rv; + int sock, max_fd, i; + int rv; + + assert(sizeof(buffer) == 4); + + populate_fds(&all_fds, &max_fd); + while (1) { + memcpy(&read_fds, &all_fds, sizeof(fd_set)); + rv = select(max_fd + 1, &read_fds, NULL, NULL, NULL); + if (rv <= 0) { + ESP_LOGE(TAG, "SELECT ERR:%d", rv); + continue; } - _buf = buf; - _buf[0] = EOS_SOCK_MTYPE_PKT; - _buf[1] = sock_i; - _buf += 2; - memcpy(_buf, addr.host, sizeof(addr.host)); - _buf += sizeof(addr.host); - _buf[0] = addr.port >> 8; - _buf[1] = addr.port; - _buf += sizeof(addr.port); - eos_net_send(EOS_NET_MTYPE_SOCK, buf, rv + EOS_SOCK_SIZE_UDP_HDR); - } while (1); - xSemaphoreTake(mutex, portMAX_DELAY); - _socks[sock_i-1] = 0; - xSemaphoreGive(mutex); + for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { + sock = _socks[i]; + if (sock && FD_ISSET(sock, &read_fds)) { + unsigned char *_buf; + + buffer = eos_net_alloc(); + _rv = t_recvfrom(sock, buffer + EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF - EOS_SOCK_SIZE_UDP_HDR, &addr); + if (_rv < 0) { + eos_net_free(buffer); + ESP_LOGE(TAG, "RECV ERR:%d", _rv); + } + _buf = buffer; + _buf[0] = EOS_SOCK_MTYPE_PKT; + _buf[1] = i + 1; + _buf += 2; + memcpy(_buf, addr.host, sizeof(addr.host)); + _buf += sizeof(addr.host); + _buf[0] = addr.port >> 8; + _buf[1] = addr.port; + _buf += sizeof(addr.port); + rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, _rv + EOS_SOCK_SIZE_UDP_HDR); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); + } + } + if (FD_ISSET(cmd_fd, &read_fds)) { + rv = read(cmd_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + switch (cmd[0]) { + case CMD_OPEN: { + sock = t_open_dgram(); + sock_i = 0; + if (sock > 0) { + for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { + if (_socks[i] == 0) { + sock_i = i + 1; + _socks[i] = sock; + break; + } + } + if (sock_i) { + populate_fds(&all_fds, &max_fd); + } + } + memset(cmd, 0, sizeof(cmd)); + cmd[1] = sock_i; + + rv = write(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + break; + } + + case CMD_CLOSE: { + sock_i = cmd[1] - 1; + sock = _socks[sock_i]; + if (sock) { + t_close(sock); + _socks[sock_i] = 0; + populate_fds(&all_fds, &max_fd); + } + + rv = write(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + break; + } + + case CMD_SEND: { + sock_i = cmd[1] - 1; + buf_len = (uint16_t)cmd[2] << 8; + buf_len |= (uint16_t)cmd[3]; + memcpy(&buffer, cmd + 4, sizeof(buffer)); + + sock = _socks[sock_i]; + memcpy(addr.host, buffer, sizeof(addr.host)); + buffer += sizeof(addr.host); + buf_len -= sizeof(addr.host); + addr.port = (uint16_t)buffer[0] << 8; + addr.port |= (uint16_t)buffer[1]; + buffer += sizeof(addr.port); + buf_len -= sizeof(addr.port); + _rv = t_sendto(sock, buffer, buf_len, &addr); + + memset(cmd, 0, sizeof(cmd)); + + rv = write(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + break; + } + + case CMD_REOPEN: { + buffer = NULL; + buf_len = 0; + + for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { + sock = _socks[i]; + if (sock) { + t_close(sock); + _socks[i] = -1; + } + } + for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { + sock = _socks[i]; + if (sock) { + sock = t_open_dgram(); + if (sock > 0) { + _socks[i] = sock; + } else { + _socks[i] = 0; + if (buffer) { + buffer[buf_len] = i + 1; + buf_len++; + } else { + buffer = eos_net_alloc(); + buffer[0] = EOS_SOCK_MTYPE_CLOSE; + buffer[1] = i + 1; + buf_len = 2; + } + } + } + } + if (buffer) { + rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); + } + + rv = write(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + break; + } + + default: + ESP_LOGE(TAG, "BAD CMD:%d", cmd[0]); + break; + } + + } + } + vTaskDelete(NULL); } static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { unsigned char mtype; uint8_t sock_i; - int sock, i; + uint8_t cmd[8]; + int rv; if (buf_len < 1) return; + memset(cmd, 0, sizeof(cmd)); + mtype = buffer[0]; switch (mtype) { case EOS_SOCK_MTYPE_PKT: { - EOSNetAddr addr; + unsigned char *_buf = buffer; if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return; - sock_i = buffer[1]-1; - if (sock_i >= EOS_SOCK_MAX_SOCK) return; - - sock = _socks[sock_i]; - buffer += 2; - memcpy(addr.host, buffer, sizeof(addr.host)); - buffer += sizeof(addr.host); - addr.port = (uint16_t)buffer[0] << 8; - addr.port |= (uint16_t)buffer[1]; - buffer += sizeof(addr.port); - t_sendto(sock, buffer, buf_len - EOS_SOCK_SIZE_UDP_HDR, &addr); + sock_i = buffer[1]; + if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return; + + _buf += 2; + cmd[0] = CMD_SEND; + cmd[1] = sock_i; + cmd[2] = buf_len >> 8; + cmd[3] = buf_len; + memcpy(cmd + 4, &_buf, sizeof(_buf)); + + xSemaphoreTake(mutex, portMAX_DELAY); + + rv = write(cmd_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + rv = read(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + xSemaphoreGive(mutex); + + assert(cmd[0] == CMD_SEND); break; } case EOS_SOCK_MTYPE_OPEN_DGRAM: { - sock = t_open_dgram(); - sock_i = 0; - if (sock > 0) { - xSemaphoreTake(mutex, portMAX_DELAY); - for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { - if (_socks[i] == 0) { - sock_i = i+1; - _socks[i] = sock; - break; - } - } - xSemaphoreGive(mutex); - } - if (sock_i) xTaskCreate(&udp_rcvr_task, "udp_rcvr", EOS_TASK_SSIZE_UDP_RCVR, (void *)sock_i, EOS_TASK_PRIORITY_UDP_RCVR, NULL); + cmd[0] = CMD_OPEN; + + xSemaphoreTake(mutex, portMAX_DELAY); + + rv = write(cmd_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + rv = read(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + xSemaphoreGive(mutex); + + assert(cmd[0] == CMD_OPEN); + sock_i = cmd[1]; buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM; buffer[1] = sock_i; eos_net_reply(EOS_NET_MTYPE_SOCK, buffer, 2); @@ -160,19 +333,72 @@ static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b case EOS_SOCK_MTYPE_CLOSE: { if (buf_len < 2) return; - sock_i = buffer[1]-1; - if (sock_i >= EOS_SOCK_MAX_SOCK) return; + sock_i = buffer[1]; + if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return; + + cmd[0] = CMD_CLOSE; + cmd[1] = sock_i; + + xSemaphoreTake(mutex, portMAX_DELAY); - sock = _socks[sock_i]; - t_close(sock); + rv = write(cmd_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + rv = read(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + xSemaphoreGive(mutex); + + assert(cmd[0] == CMD_CLOSE); break; } } } void eos_sock_init(void) { + esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT(); + esp_err_t ret; + + ret = esp_vfs_eventfd_register(&config); + assert(ret == ESP_OK); + + cmd_fd = eventfd(0, 0); + assert(cmd_fd > 0); + + rep_fd = eventfd(0, 0); + assert(rep_fd > 0); + mutex = xSemaphoreCreateBinary(); + assert(mutex != NULL); xSemaphoreGive(mutex); + eos_net_set_handler(EOS_NET_MTYPE_SOCK, sock_handler); + ESP_LOGI(TAG, "INIT"); } + +void eos_sock_run(void) { + BaseType_t rv; + + rv = xTaskCreate(&udp_rcvr_task, "udp_rcvr", EOS_TASK_SSIZE_SOCK, NULL, EOS_TASK_PRIORITY_SOCK, NULL); + assert(rv == pdPASS); + + ESP_LOGI(TAG, "RUN"); +} + +void eos_sock_reopen(void) { + uint8_t cmd[8]; + int rv; + + cmd[0] = CMD_REOPEN; + xSemaphoreTake(mutex, portMAX_DELAY); + + rv = write(cmd_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + rv = read(rep_fd, cmd, sizeof(cmd)); + assert(rv == sizeof(cmd)); + + xSemaphoreGive(mutex); + assert(cmd[0] == CMD_REOPEN); +} diff --git a/fw/esp32/components/eos/tun.c b/fw/esp32/components/eos/tun.c index a7181ee..f27fcfe 100644 --- a/fw/esp32/components/eos/tun.c +++ b/fw/esp32/components/eos/tun.c @@ -6,13 +6,14 @@ #include <lwip/tcpip.h> #include <lwip/etharp.h> +#include "net.h" #include "app.h" #include "tun.h" static ip4_addr_t ipaddr, netmask, gw; static struct netif netif_tun; -static err_t ESP_IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) { +static err_t IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) { unsigned char *buf; struct pbuf *q; @@ -27,7 +28,7 @@ static err_t ESP_IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const return ERR_OK; } -static void ESP_IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) { +static void IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) { struct netif *netif = &netif_tun; struct pbuf *p; int rv; @@ -55,11 +56,15 @@ static err_t tun_init(struct netif *netif) { } void eos_tun_init(void) { + struct netif *rv; + IP4_ADDR(&gw, 0,0,0,0); IP4_ADDR(&ipaddr, 192,168,10,2); IP4_ADDR(&netmask, 255,255,255,0); - netif_add(&netif_tun, &ipaddr, &netmask, &gw, NULL, tun_init, tcpip_input); + rv = netif_add(&netif_tun, &ipaddr, &netmask, &gw, NULL, tun_init, tcpip_input); + assert(rv != NULL); + netif_set_up(&netif_tun); eos_app_set_handler(EOS_APP_MTYPE_TUN, tun_input); -}
\ No newline at end of file +} diff --git a/fw/esp32/components/eos/wifi.c b/fw/esp32/components/eos/wifi.c index 2be169f..77f9143 100755 --- a/fw/esp32/components/eos/wifi.c +++ b/fw/esp32/components/eos/wifi.c @@ -10,7 +10,6 @@ #include <esp_log.h> #include <esp_err.h> #include <esp_wifi.h> -#include <nvs_flash.h> #include "eos.h" #include "net.h" @@ -53,8 +52,6 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e ESP_LOGI(TAG, "Event disconnected - reason: %d", sta_disconnected->reason); if (sta_disconnected->reason == WIFI_REASON_ASSOC_LEAVE) { - stop = 0; - reconnect_cnt = 0; eos_wifi_send_status(); break; } @@ -113,25 +110,25 @@ static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b mtype = buffer[0]; switch (mtype) { case EOS_WIFI_MTYPE_STATUS: { - int reply; - ssize_t rv; + unsigned char *_buffer; + ssize_t _rv; + int reply, rv; reply = _mtype & EOS_NET_MTYPE_FLAG_REPL; if (reply) { - rv = eos_wifi_get_status(buffer + 1); - if (rv < 0) break; + _rv = eos_wifi_get_status(buffer + 1); + if (_rv < 0) break; - eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, rv + 1); + eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, _rv + 1); } else { - unsigned char *buf; - - buf = eos_net_alloc(); - buf[0] = EOS_WIFI_MTYPE_STATUS; - rv = eos_wifi_get_status(buf + 1); - if (rv < 0) break; + _buffer = eos_net_alloc(); + _buffer[0] = EOS_WIFI_MTYPE_STATUS; + _rv = eos_wifi_get_status(_buffer + 1); + if (_rv < 0) break; - eos_net_send(EOS_NET_MTYPE_WIFI, buf, rv + 1); + rv = eos_net_send(EOS_NET_MTYPE_WIFI, _buffer, _rv + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } break; } @@ -202,20 +199,14 @@ static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b } void eos_wifi_init(void) { - esp_err_t ret; wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t ret; wifi_netif = esp_netif_create_default_wifi_sta(); ret = esp_wifi_init(&wifi_config); assert(ret == ESP_OK); - ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL); - assert(ret == ESP_OK); - - ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL); - assert(ret == ESP_OK); - ret = esp_wifi_set_storage(WIFI_STORAGE_RAM); assert(ret == ESP_OK); @@ -226,9 +217,22 @@ void eos_wifi_init(void) { assert(ret == ESP_OK); eos_net_set_handler(EOS_NET_MTYPE_WIFI, wifi_handler); + ESP_LOGI(TAG, "INIT"); } +void eos_wifi_run(void) { + esp_err_t ret; + + ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL); + assert(ret == ESP_OK); + + ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL); + assert(ret == ESP_OK); + + ESP_LOGI(TAG, "RUN"); +} + ssize_t eos_wifi_get_status(unsigned char *buffer) { unsigned char *p; wifi_ap_record_t ap_info; @@ -293,26 +297,28 @@ ssize_t eos_wifi_get_status(unsigned char *buffer) { void eos_wifi_send_status(void) { unsigned char *rbuf; - ssize_t rv; + ssize_t _rv; + int rv; rbuf = eos_net_alloc(); rbuf[0] = EOS_WIFI_MTYPE_STATUS; - rv = eos_wifi_get_status(rbuf + 1); - if (rv < 0) { + _rv = eos_wifi_get_status(rbuf + 1); + if (_rv < 0) { eos_net_free(rbuf); return; } - eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, rv + 1); + rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, _rv + 1); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } void eos_wifi_send_scan(void) { static wifi_ap_record_t scan_r[EOS_WIFI_MAX_SCAN_RECORDS]; static uint16_t scan_n; - unsigned char *rbuf, *p; - int i; size_t len; esp_err_t ret; + unsigned char *rbuf, *p; + int i, rv; scan_n = EOS_WIFI_MAX_SCAN_RECORDS; memset(scan_r, 0, sizeof(scan_r)); @@ -336,5 +342,7 @@ void eos_wifi_send_scan(void) { strcpy((char *)p, (char *)scan_r[i].ssid); p += len + 1; } - eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf); + + rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf); + if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } diff --git a/fw/esp32/main/component.mk b/fw/esp32/main/component.mk deleted file mode 100644 index 61f8990..0000000 --- a/fw/esp32/main/component.mk +++ /dev/null @@ -1,8 +0,0 @@ -# -# Main component makefile. -# -# This Makefile can be left empty. By default, it will take the sources in the -# src/ directory, compile them and link them into lib(subdirectory_name).a -# in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# 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..7e4f5ec --- /dev/null +++ b/fw/fe310/eos/dev/aon.c @@ -0,0 +1,42 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "eos.h" +#include "soc/aon.h" + +#include "aon.h" + +#define AON_EVE_REG 0 +#define AON_EVE_MASK 0x03 + +#define AON_NET_REG 0 +#define AON_NET_MASK 0x04 + +void eos_aon_save4eve(uint8_t power_state) { + uint32_t reg; + + power_state &= AON_EVE_MASK; + reg = eos_aon_get_reg(AON_EVE_REG); + reg &= ~AON_EVE_MASK; + reg |= power_state; + + eos_aon_set_reg(AON_EVE_REG, reg); +} + +uint8_t eos_aon_load4eve(void) { + return (eos_aon_get_reg(AON_EVE_REG) & AON_EVE_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); +}
\ 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..4551cc0 --- /dev/null +++ b/fw/fe310/eos/dev/aon.h @@ -0,0 +1,7 @@ +#include <stdint.h> + +void eos_aon_save4eve(uint8_t power_state); +uint8_t eos_aon_load4eve(void); + +void eos_aon_save4net(int absent); +int eos_aon_load4net(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..ce2cf05 100644 --- a/fw/fe310/eos/dev/app.c +++ b/fw/fe310/eos/dev/app.c @@ -2,23 +2,18 @@ #include <stdint.h> #include "eos.h" +#include "log.h" #include "hpamp.h" #include "app.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - void eos_app_hp_change(int hp_det) { if (hp_det) { int rv; 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; } } 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..b6459b4 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; @@ -37,6 +33,7 @@ int eos_ctp_init(void) { } 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; @@ -56,6 +53,7 @@ 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; @@ -73,6 +71,7 @@ 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; @@ -94,10 +93,10 @@ int eos_ctp_give(void) { rv = eos_egpio_intr_disable(); if (rv) return rv; - rv = eve_select(); + rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0); if (rv) return rv; - rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0); + rv = eve_select(); if (rv) return rv; eve_touch_set_engine(EVE_TOUCH_ENGINE_GOODIX); @@ -138,7 +137,6 @@ int eos_ctp_take(void) { 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 +148,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 +161,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 +185,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/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..cfcd0f3 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,47 +174,47 @@ 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) { + int rv; + type &= ~EOS_EVT_MASK; switch (type) { - case EGPIO_ETYPE_INT: { - int rv; - - rv = handle_egpio_evt(0); - if (rv < 0) goto handle_evt_fin; + 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; } } @@ -205,16 +222,12 @@ handle_evt_eve_fin: 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 +237,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 = fxl6408_reg_read(1, FXL6408_REG_ID_CTRL, &data); + + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, 0xff); + if (rv) return rv; + 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 +341,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 +374,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 +407,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 +460,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 +478,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 +520,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 +533,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 +555,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 +569,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 +584,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 +594,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 +614,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 +623,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..25a3558 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,15 +61,12 @@ 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_pwr_set_state(eos_aon_load4eve()); eve_activate(); gpio_reg = eve_gpio_read(); eve_cmd_set_offset(); - if (gpio_reg & EVE_GPIO_DISP) { + if (gpio_reg & (1 << EVE_GPIO_DISP)) { eve_pwr_set_state(EVE_PSTATE_ACTIVE); } eve_deactivate(); @@ -92,9 +86,19 @@ 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 (eos_aon_load4eve() == EVE_PSTATE_ACTIVE) return EOS_OK; + + /* DISP pin is off */ + if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR_BUSY; + } rv = eve_select(); if (rv) return rv; @@ -111,10 +115,12 @@ int eos_eve_run(void) { 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_brightness(0); eve_clk_stop(); eve_intr_disable(); eve_touch_stop(); @@ -125,16 +131,46 @@ int eos_eve_sleep(void) { return EOS_OK; } +int eos_eve_wake(void) { + int disp, rv; + + if (eve_pwr_state() == EVE_PSTATE_ACTIVE) return EOS_ERR; + + rv = eve_select(); + if (rv) return rv; + + eve_activate(); + disp = eve_gpio_get(EVE_GPIO_DISP); + if (disp) { + eve_pwr_set_state(EVE_PSTATE_ACTIVE); + } + eve_deactivate(); + + if (eve_pwr_state() != EVE_PSTATE_ACTIVE) { + rv = EOS_ERR_BUSY; + goto eve_wake_fin; + } + + eve_touch_intr_enable(); + eve_touch_start(); + eve_intr_enable(); + eve_clk_start(); +eve_wake_fin: + eve_deselect(); + + return rv; +} + +void eos_eve_save2aon(void) { + eos_aon_save4eve(eve_pwr_state()); +} + 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 +191,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..564e8c1 100644 --- a/fw/fe310/eos/dev/eve.h +++ b/fw/fe310/eos/dev/eve.h @@ -1,22 +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); int eos_eve_sleep(void); int eos_eve_wake(void); +void eos_eve_save2aon(void); void eve_calibrate(void); int eve_select(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..3863f5d --- /dev/null +++ b/fw/fe310/eos/dev/eve_priv.h @@ -0,0 +1,10 @@ +#define EVE_GPIO_DIR 0x800f +#define EVE_GPIO_DEFAULT 0x8002 /* DISP on, 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 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..01d86e9 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" @@ -38,6 +37,10 @@ static int lcd_disable(void) { return rv; } +static int lcd_enabled(void) { + return eos_egpio_get_val(EGPIO_PIN_LCD_EN); +} + static int lcd_select(void) { int rv; @@ -52,6 +55,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 +64,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); @@ -118,6 +123,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 +132,8 @@ int eos_lcd_sleep(void) { int eos_lcd_wake(void) { int rv; + if (lcd_enabled()) return EOS_ERR; + rv = lcd_init(); return rv; } diff --git a/fw/fe310/eos/dev/net.c b/fw/fe310/eos/dev/net.c index d340e29..c1fd9b5 100644 --- a/fw/fe310/eos/dev/net.c +++ b/fw/fe310/eos/dev/net.c @@ -3,13 +3,13 @@ #include "encoding.h" #include "platform.h" +#include "board.h" #include "eos.h" +#include "log.h" #include "msgq.h" #include "event.h" -#include "board.h" - #include "soc/interrupt.h" #include "soc/timer.h" #include "soc/pwr.h" @@ -17,17 +17,27 @@ #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_STATE_FLAG_RUN 0x0001 +#define NET_STATE_FLAG_INIT 0x0002 +#define NET_STATE_FLAG_XCHG 0x0004 +#define NET_STATE_FLAG_ONEW 0x0010 +#define NET_STATE_FLAG_SYNC 0x0020 +#define NET_STATE_FLAG_RTS 0x0040 +#define NET_STATE_FLAG_CTS 0x0080 +#define NET_STATE_FLAG_SLEEP 0x0100 +#define NET_STATE_FLAG_SLEEP_REQ 0x0200 +#define NET_STATE_FLAG_ABSENT 0x0400 + +#define NET_FLAG_MORE 0x01 +#define NET_FLAG_SYNC 0x02 +#define NET_FLAG_REPL 0x04 #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) @@ -39,7 +49,7 @@ static unsigned char net_bufq_buffer[EOS_NET_SIZE_BUFQ][EOS_NET_SIZE_BUF] __attr static EOSMsgQ net_send_q; static EOSMsgItem net_sndq_array[EOS_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; @@ -49,40 +59,35 @@ 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,18 +96,6 @@ 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; net_state_flags |= (NET_STATE_FLAG_INIT | NET_STATE_FLAG_XCHG); @@ -127,7 +120,7 @@ static int net_xchg_next(unsigned char *_buffer) { unsigned char type; unsigned char *buffer = NULL; uint16_t len; - int ret = _buffer ? 1 : 0; + int do_release = _buffer ? 1 : 0; eos_msgq_pop(&net_send_q, &type, &buffer, &len); if (type) { @@ -135,14 +128,14 @@ static int net_xchg_next(unsigned char *_buffer) { } else if (net_state_flags & NET_STATE_FLAG_RTS) { if (_buffer) { buffer = _buffer; - ret = 0; + do_release = 0; } else { buffer = eos_bufq_pop(&net_buf_q); } if (buffer) net_xchg_start(0, buffer, 0); } - return ret; + return do_release; } static void net_handle_xchg(void) { @@ -162,7 +155,7 @@ static void net_handle_xchg(void) { r3 = 0; } - net_state_type = (r1 & 0xFF); + net_state_type = (r1 & EOS_NET_MTYPE_MASK); net_state_len_rx = (r2 & 0xFF) << 8; net_state_len_rx |= (r3 & 0xFF); len = MAX(net_state_len_tx, net_state_len_rx); @@ -191,8 +184,18 @@ static void net_handle_xchg(void) { 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 { + int rv; + + rv = eos_evtq_push_isr(EOS_EVT_NET | (net_state_type & ~EOS_EVT_MASK), net_state_buf, 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 { @@ -204,8 +207,9 @@ static void net_handle_xchg(void) { } 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,23 +219,24 @@ 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; + unsigned char idx = (type & ~EOS_EVT_MASK); - if (idx < EOS_NET_MAX_MTYPE) { - net_handler[idx](type, buffer, len); + if (idx && (idx <= EOS_NET_MAX_MTYPE)) { + net_handler[idx - 1](type, buffer, len); } else { eos_net_bad_handler(type, buffer, len); } @@ -263,29 +268,35 @@ 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, unsigned char *buffer, 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) { + rv = net_acquire(net_wrapper_acq & flag); + if (rv) { eos_evtq_get_handler(type)(type, buffer, 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, buffer, 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, unsigned char *buffer, 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, buffer, len, _idx); } else { eos_evtq_get_handler(type)(type, buffer, len); } @@ -294,6 +305,14 @@ static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t 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); + } +} + static void net_wait4xchg(void) { while (net_state_flags & NET_STATE_FLAG_XCHG) { asm volatile ("wfi"); @@ -310,12 +329,47 @@ static void net_wait4cts(void) { } } +static void net_wake(void) { + while (net_state_flags & NET_STATE_FLAG_SLEEP) { + net_xchg_reset(); + eos_sleep(10); + set_csr(mstatus, MSTATUS_MIE); + clear_csr(mstatus, MSTATUS_MIE); + } +} + +static int net_select(int *dsel) { + *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; + + if (!(net_state_flags & NET_STATE_FLAG_RUN)) { + int rv; + + 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 */ + net_wake(); + + return EOS_OK; +} + +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,7 +385,7 @@ 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); @@ -343,47 +397,69 @@ int eos_net_init(uint8_t wakeup_cause) { 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; + + rv = EOS_OK; net_start(); + wakeup_cause = eos_pwr_wakeup_cause(); + 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 (wakeup_cause == EOS_PWR_WAKE_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(); + if (!rv) { + GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << NET_PIN_CTS); + } else { + net_state_flags |= NET_STATE_FLAG_ABSENT; + EOS_LOG(EOS_LOG_ERR, "NET DEVICE ABSENT\n"); + } + } else { + if (eos_aon_load4net()) { + /* device previously declared as absent */ + net_state_flags |= NET_STATE_FLAG_ABSENT; + } else if (!(net_state_flags & NET_STATE_FLAG_CTS)) { + /* will assume that remote device is sleeping */ + 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; + net_resume(); } - net_resume(); set_csr(mstatus, MSTATUS_MIE); - return EOS_OK; + return rv; } void eos_net_start(void) { @@ -402,47 +478,51 @@ 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; + return EOS_OK; +} - 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); +int eos_net_sleep_rdy(void) { + int rv; - 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"); - } + clear_csr(mstatus, MSTATUS_MIE); + rv = !!(net_state_flags & NET_STATE_FLAG_SLEEP); + set_csr(mstatus, MSTATUS_MIE); - if (!rv) { - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); - net_state_flags &= ~NET_STATE_FLAG_RUN; - } + return rv; +} +void eos_net_wake(void) { + clear_csr(mstatus, MSTATUS_MIE); + net_state_flags &= ~NET_STATE_FLAG_SLEEP_REQ; set_csr(mstatus, MSTATUS_MIE); +} - return rv; +void eos_net_save2aon(void) { + int absent; + + clear_csr(mstatus, MSTATUS_MIE); + absent = !!(net_state_flags & NET_STATE_FLAG_ABSENT); + set_csr(mstatus, MSTATUS_MIE); + eos_aon_save4net(absent); } void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) { @@ -459,7 +539,7 @@ void eos_net_acquire_for_evt(unsigned char type, char 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; @@ -481,12 +561,12 @@ void eos_net_release(void) { } unsigned char *eos_net_alloc(void) { - unsigned char *ret = NULL; + unsigned char *rv = NULL; - while (ret == NULL) { + while (rv == NULL) { clear_csr(mstatus, MSTATUS_MIE); if (net_state_next_buf) { - ret = net_state_next_buf; + rv = net_state_next_buf; net_state_next_buf = NULL; } else { asm volatile ("wfi"); @@ -494,7 +574,7 @@ unsigned char *eos_net_alloc(void) { set_csr(mstatus, MSTATUS_MIE); } - return ret; + return rv; } void eos_net_free(unsigned char *buffer, unsigned char more) { @@ -516,81 +596,72 @@ void eos_net_free(unsigned char *buffer, unsigned char more) { static int net_xchg(unsigned char *type, unsigned char *buffer, 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 & NET_FLAG_MORE) _type |= EOS_NET_MTYPE_FLAG_ONEW; + if (flags & NET_FLAG_REPL) _type |= EOS_NET_MTYPE_FLAG_REPL; + if (flags & NET_FLAG_SYNC) sync = 1; clear_csr(mstatus, MSTATUS_MIE); - if ((flags & EOS_NET_FLAG_ONEW) && !(net_state_flags & NET_STATE_FLAG_RUN)) _sync = 1; - - if (_sync && !(net_state_flags & NET_STATE_FLAG_RUN)) { - int _rv; - + rv = net_select(&dsel); + if (rv) { set_csr(mstatus, MSTATUS_MIE); - spi_dev = eos_spi_dev(); - _rv = eos_spi_deselect(); - if (_rv) return _rv; - clear_csr(mstatus, MSTATUS_MIE); + return rv; } - 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, 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; - *type = (net_state_type & ~EOS_NET_MTYPE_FLAG_MASK); - *len = net_state_len_rx; + if (flags & NET_FLAG_REPL) { + net_wait4cts(); + net_xchg_start(0, buffer, 0); } + net_wait4xchg(); + net_state_flags &= ~NET_STATE_FLAG_SYNC; + *type = net_state_type & EOS_NET_MTYPE_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); } else { rv = eos_msgq_push(&net_send_q, _type, buffer, _len); - if (rv) eos_bufq_push(&net_buf_q, buffer); } } set_csr(mstatus, MSTATUS_MIE); - if (spi_dev != EOS_SPI_DEV_NET) eos_spi_select(spi_dev); + if (sync && !(flags & NET_FLAG_SYNC)) eos_net_free(buffer, !!(flags & NET_FLAG_MORE)); + 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, unsigned char *buffer, uint16_t len) { - return net_xchg(&type, buffer, &len, (EOS_NET_FLAG_ONEW | EOS_NET_FLAG_SYNC)); -} - -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 more) { int rv; - rv = net_xchg(&type, buffer, &len, more ? EOS_NET_FLAG_ONEW : 0); + rv = net_xchg(&type, buffer, &len, more ? NET_FLAG_MORE : 0); if (rv) eos_net_free(buffer, more); return rv; } +int eos_net_send_sync(unsigned char type, unsigned char *buffer, uint16_t len) { + return net_xchg(&type, buffer, &len, NET_FLAG_SYNC); +} + +int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) { + return net_xchg(type, buffer, len, (NET_FLAG_SYNC | 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); + return eos_net_send(type, buffer, len, more); } else { - return eos_net_send(type, buffer, len); + return eos_net_send_sync(type, buffer, len); } } diff --git a/fw/fe310/eos/dev/net.h b/fw/fe310/eos/dev/net.h index 2482a32..12b4d14 100644 --- a/fw/fe310/eos/dev/net.h +++ b/fw/fe310/eos/dev/net.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" /* common */ @@ -6,32 +7,30 @@ #define EOS_NET_SIZE_BUF EOS_NET_MTU #define EOS_NET_MTYPE_SOCK 1 -#define EOS_NET_MTYPE_RNG 3 -#define EOS_NET_MTYPE_POWER 4 +#define EOS_NET_MTYPE_WIFI 2 +#define EOS_NET_MTYPE_CELL 3 +#define EOS_NET_MTYPE_APP 4 +#define EOS_NET_MTYPE_RNG 5 -#define EOS_NET_MTYPE_WIFI 5 -#define EOS_NET_MTYPE_CELL 6 -#define EOS_NET_MTYPE_SIP 7 -#define EOS_NET_MTYPE_APP 8 +#define EOS_NET_MAX_MTYPE 5 -#define EOS_NET_MAX_MTYPE 8 +#define EOS_NET_MTYPE_SLEEP 0x10 /* does not have net handler */ #define EOS_NET_MTYPE_FLAG_ONEW 0x40 #define EOS_NET_MTYPE_FLAG_REPL 0x80 -#define EOS_NET_MTYPE_FLAG_MASK 0xc0 +#define EOS_NET_MTYPE_MASK 0x3F /* 0x0F if mtype is handled by evtq */ /* fe310 specific */ #define EOS_NET_SIZE_BUFQ 2 -#define EOS_NET_FLAG_ONEW 0x1 -#define EOS_NET_FLAG_SYNC 0x2 -#define EOS_NET_FLAG_REPL 0x4 - -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_save2aon(void); void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len); void eos_net_set_handler(unsigned char type, eos_evt_handler_t handler); @@ -41,7 +40,7 @@ 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_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more); +int eos_net_send_sync(unsigned char type, unsigned char *buffer, uint16_t len); 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); diff --git a/fw/fe310/eos/dev/pwr.c b/fw/fe310/eos/dev/pwr.c new file mode 100644 index 0000000..06a76d8 --- /dev/null +++ b/fw/fe310/eos/dev/pwr.c @@ -0,0 +1,49 @@ +#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_eve_save2aon(); + eos_net_save2aon(); + 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..319816d 100644 --- a/fw/fe310/eos/dev/spi.c +++ b/fw/fe310/eos/dev/spi.c @@ -5,6 +5,7 @@ #include "platform.h" #include "eos.h" +#include "log.h" #include "msgq.h" #include "event.h" @@ -13,33 +14,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 +52,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 +61,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 +77,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 +89,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 +111,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..0320aa6 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, diff --git a/fw/fe310/eos/eos.c b/fw/fe310/eos/eos.c index 6df8700..73ab29c 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,94 @@ 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); } -void eos_run_once(void) { - eos_gt911_cfg_print(); - eos_gt911_configure(); - eos_gt911_cfg_print(); +#include "dev/drv/gt911.h" +#include "eve/eve.h" - eos_eve_calibrate(); +void eos_run_once(void) { + gt911_cfg_print(); + gt911_configure(); + gt911_cfg_print(); + + eve_select(); + eve_brightness(0x40); + eve_calibrate(); + eve_brightness(0); + 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..e5c5f80 100644 --- a/fw/fe310/eos/eve/eve.c +++ b/fw/fe310/eos/eve/eve.c @@ -12,86 +12,86 @@ static uint16_t cmd_offset; static char dl_burst; static uint32_t dl_addr; -static uint8_t power_state; +static uint8_t power_state = EVE_PSTATE_ACTIVE; 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 +102,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 +119,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 +140,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 +148,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 +254,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 +368,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 +384,22 @@ int eve_init(void) { #endif /* nothing is being displayed yet... the pixel clock is still 0x00 */ + power_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,8 +408,27 @@ void eve_intr_disable(void) { } void eve_activate(void) { + if (power_state == EVE_PSTATE_ACTIVE) return; + eve_command(EVE_ACTIVE, 0); - eve_sleep(40); + if (power_state == EVE_PSTATE_SLEEP) { + eve_sleep(20); + } +} + +void eve_deactivate(void) { + switch (power_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) { @@ -423,9 +442,6 @@ void eve_pwr_standby(void) { void eve_pwr_sleep(void) { if (power_state != EVE_PSTATE_ACTIVE) return; - eve_clk_stop(); - eve_intr_disable(); - eve_command(EVE_SLEEP, 0); power_state = EVE_PSTATE_SLEEP; @@ -434,14 +450,17 @@ void eve_pwr_sleep(void) { void eve_pwr_wake(void) { eve_activate(); - if (power_state == EVE_PSTATE_SLEEP) { - eve_intr_enable(); - eve_clk_start(); - } - power_state = EVE_PSTATE_ACTIVE; } +void eve_pwr_set_state(uint8_t state) { + power_state = state; +} + +uint8_t eve_pwr_state(void) { + return power_state; +} + int eve_gpio_get(int gpio) { uint16_t reg = eve_read16(REG_GPIOX); @@ -456,17 +475,33 @@ 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); } @@ -490,5 +525,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..02388bb 100644 --- a/fw/fe310/eos/eve/eve.h +++ b/fw/fe310/eos/eve/eve.h @@ -6,17 +6,16 @@ #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_GPIO_DISP 15 #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 +52,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,14 +65,20 @@ 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); +void eve_pwr_set_state(uint8_t state); + +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); 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..6f34b81 100644 --- a/fw/fe310/eos/eve/eve_platform.h +++ b/fw/fe310/eos/eve/eve_platform.h @@ -1,38 +1,56 @@ #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" -#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 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..7c5b39f 100644 --- a/fw/fe310/eos/eve/eve_touch_engine.c +++ b/fw/fe310/eos/eve/eve_touch_engine.c @@ -26,36 +26,66 @@ 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_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..8eb7333 100644 --- a/fw/fe310/eos/eve/eve_touch_engine.h +++ b/fw/fe310/eos/eve/eve_touch_engine.h @@ -1,9 +1,20 @@ #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_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..c0e2bfe 100644 --- a/fw/fe310/eos/eve/widget/selectw.c +++ b/fw/fe310/eos/eve/widget/selectw.c @@ -14,19 +14,26 @@ #define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) -static int selectw_verify(utf8_t *option, uint16_t option_size) { +static int selectw_verify(utf8_t *option, uint16_t option_size, EVEFont *font, size_t *_o_len) { size_t o_len; uint16_t o_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; + rv = eve_font_verify(font, option + o_curr, option_size - o_curr, NULL, &o_len); + if (rv) { + if (_o_len) *_o_len = o_curr; + return rv; + } o_curr += o_len + 1; + if (o_len == 0) { + if (_o_len) *_o_len = o_curr; + return EVE_OK; + } } + if (_o_len) *_o_len = o_curr; return EVE_OK; } @@ -57,28 +64,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 +103,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 +111,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) { @@ -172,6 +183,10 @@ uint8_t eve_selectw_draw(EVEWidget *_widget, uint8_t tag0) { 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 +207,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; } @@ -226,8 +243,8 @@ int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option) { int o_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; i = 0; @@ -252,10 +269,11 @@ 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 rv, i; - rv = selectw_verify(option, option_size); - if (rv) return rv; if (option_size > widget->option_size) return EVE_ERR_FULL; + rv = selectw_verify(option, option_size, widget->font, NULL); + if (rv) return rv; + memcpy(widget->option, option, option_size); memset(widget->option + option_size, 0, widget->option_size - option_size); @@ -264,3 +282,23 @@ int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t opt return EVE_OK; } + +void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size) { + size_t good_l, bad_l; + int rv; + + do { + rv = selectw_verify(option, option_size, widget->font, &good_l); + if (rv == EVE_OK) return; + + option += good_l; + option_size -= good_l; + + bad_l = strnlen(option, option_size); + if (bad_l != option_size) { + bad_l++; + } + memmove(option, option + bad_l, option_size - bad_l); + memset(option + option_size - bad_l, 0, bad_l); + } while (bad_l != option_size); +} diff --git a/fw/fe310/eos/eve/widget/selectw.h b/fw/fe310/eos/eve/widget/selectw.h index aa49866..185d787 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); @@ -31,3 +31,4 @@ 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); +void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size); 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..b21e5ea 100644 --- a/fw/fe310/eos/event.c +++ b/fw/fe310/eos/event.c @@ -1,69 +1,110 @@ #include <stdlib.h> #include <stdint.h> #include <unistd.h> -#include <stdio.h> #include "encoding.h" #include "platform.h" #include "eos.h" +#include "log.h" #include "msgq.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, unsigned char *buffer, 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, buffer, len); } else { eos_evtq_bad_handler(type, buffer, 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_len(void) { + int rv; + + clear_csr(mstatus, MSTATUS_MIE); + rv = eos_msgq_len(&_eos_event_q); + set_csr(mstatus, MSTATUS_MIE); + + return rv; +} + int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len) { + int rv; + + clear_csr(mstatus, MSTATUS_MIE); + rv = eos_msgq_push(&_eos_event_q, type, buffer, len); + set_csr(mstatus, MSTATUS_MIE); + + return rv; +} + +int eos_evtq_push_widx(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx) { + int rv; + clear_csr(mstatus, MSTATUS_MIE); - int ret = eos_msgq_push(&_eos_event_q, type, buffer, len); + rv = eos_msgq_push_widx(&_eos_event_q, type, buffer, len, idx); 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_widx_isr(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx) { + return eos_msgq_push_widx(&_eos_event_q, type, buffer, len, idx); +} + void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len) { clear_csr(mstatus, MSTATUS_MIE); eos_msgq_pop(&_eos_event_q, type, buffer, len); set_csr(mstatus, MSTATUS_MIE); } +void eos_evtq_pop_widx(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) { + clear_csr(mstatus, MSTATUS_MIE); + eos_msgq_pop_widx(&_eos_event_q, type, buffer, len, idx); + set_csr(mstatus, MSTATUS_MIE); +} + void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len) { eos_msgq_pop(&_eos_event_q, type, buffer, len); } +void eos_evtq_pop_widx_isr(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) { + eos_msgq_pop_widx(&_eos_event_q, type, buffer, len, idx); +} + int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len) { int rv = 0; clear_csr(mstatus, MSTATUS_MIE); rv = eos_msgq_find(&_eos_event_q, type, NULL, 0, buffer, len); set_csr(mstatus, MSTATUS_MIE); + + return rv; } int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { @@ -72,23 +113,30 @@ int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, clear_csr(mstatus, MSTATUS_MIE); rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len); set_csr(mstatus, MSTATUS_MIE); + + return rv; } -void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { +int 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) { + if (rv && (rv != EOS_ERR_NOTFOUND)) { + set_csr(mstatus, MSTATUS_MIE); + return rv; + } + if (rv) { unsigned char _type; unsigned char *_buffer; uint16_t _len; + uint8_t idx; - eos_msgq_pop(&_eos_event_q, &_type, &_buffer, &_len); + eos_msgq_pop_widx(&_eos_event_q, &_type, &_buffer, &_len, &idx); if (_type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](_type, _buffer, _len); + evt_handler_global(_type, _buffer, _len, idx); } else { asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); @@ -109,12 +157,13 @@ void eos_evtq_flush_isr(void) { unsigned char type; unsigned char *buffer; uint16_t len; + uint8_t idx; do { - eos_msgq_pop(&_eos_event_q, &type, &buffer, &len); + eos_msgq_pop_widx(&_eos_event_q, &type, &buffer, &len, &idx); if (type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](type, buffer, len); + evt_handler_global(type, buffer, len, idx); clear_csr(mstatus, MSTATUS_MIE); } } while (type); @@ -125,6 +174,7 @@ void eos_evtq_loop(void) { while(foo) { eos_evtq_exec(); + if (evt_loop_f) evt_loop_f(); } } @@ -132,33 +182,46 @@ void eos_evtq_exec(void) { unsigned char type; unsigned char *buffer; 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, &buffer, &len, &idx); if (type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](type, buffer, len); + evt_handler_global(type, buffer, 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); + 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..bdc1af1 100644 --- a/fw/fe310/eos/event.h +++ b/fw/fe310/eos/event.h @@ -3,20 +3,35 @@ #include "evt_def.h" typedef void (*eos_evt_handler_t) (unsigned char, unsigned char *, uint16_t); +typedef void (*eos_evt_handler_global_t) (unsigned char, unsigned char *, uint16_t, uint8_t); + +typedef void (*eos_evt_loopf_t) (void); + +int eos_evtq_init(void); +int eos_evtq_len(void); -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_widx(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx); int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len); +int eos_evtq_push_widx_isr(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx); + void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len); +void eos_evtq_pop_widx(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) ; void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len); +void eos_evtq_pop_widx_isr(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx); + 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); +int 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_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..2af3b14 100644 --- a/fw/fe310/eos/msgq.c +++ b/fw/fe310/eos/msgq.c @@ -17,7 +17,15 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->array = array; } +uint8_t eos_msgq_len(EOSMsgQ *msgq) { + return (uint8_t)(msgq->idx_w - msgq->idx_r); +} + int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) { + return eos_msgq_push_widx(msgq, type, buffer, len, NULL); +} + +int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, 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); @@ -25,10 +33,15 @@ int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint msgq->array[idx].buffer = buffer; msgq->array[idx].len = len; 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) { + eos_msgq_pop_widx(msgq, type, buffer, len, NULL); +} + +void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *_idx) { if (msgq->idx_r == msgq->idx_w) { *type = 0; *buffer = NULL; @@ -39,6 +52,7 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui *buffer = msgq->array[idx].buffer; *len = msgq->array[idx].len; msgq->idx_r++; + if (_idx) *_idx = idx; } } @@ -52,7 +66,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = NULL; *len = 0; } - return 0; + return EOS_ERR_NOTFOUND; } idx = IDX_MASK(msgq->idx_r, msgq->size); @@ -65,7 +79,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = _buffer; *len = _len; } - return 1; + return EOS_OK; } } for (i = msgq->idx_r + 1; IDX_LT(i, msgq->idx_w); i++) { @@ -82,7 +96,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = _buffer; *len = _len; } - return 1; + return EOS_OK; } } } @@ -90,11 +104,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = NULL; *len = 0; } - return 0; -} - -uint8_t eos_msgq_len(EOSMsgQ *msgq) { - return (uint8_t)(msgq->idx_w - msgq->idx_r); + return EOS_ERR_NOTFOUND; } void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) { @@ -104,6 +114,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 +130,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..0634144 100644 --- a/fw/fe310/eos/msgq.h +++ b/fw/fe310/eos/msgq.h @@ -14,10 +14,12 @@ typedef struct EOSMsgQ { } EOSMsgQ; void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); +uint8_t eos_msgq_len(EOSMsgQ *msgq); int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len); +int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *_idx); void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len); +void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *_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 eos_msgq_len(EOSMsgQ *msgq); typedef struct EOSBufQ { uint8_t idx_r; @@ -27,6 +29,6 @@ typedef struct EOSBufQ { } EOSBufQ; void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size); +uint8_t eos_bufq_len(EOSBufQ *bufq); int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer); unsigned char *eos_bufq_pop(EOSBufQ *bufq); -uint8_t eos_bufq_len(EOSBufQ *bufq); diff --git a/fw/fe310/eos/net/Makefile b/fw/fe310/eos/net/Makefile index fc65454..0646956 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 sock.o cell.o lib = ../../libeos-net.a diff --git a/fw/fe310/eos/net/cell.c b/fw/fe310/eos/net/cell.c index 96216ba..c0c77af 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, unsigned char *buffer, uint16_t buf_len) { unsigned char mtype; unsigned char idx; - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); + if ((buffer == NULL) || (buf_len < 1)) { + eos_net_bad_handler(type, buffer, buf_len); return; } mtype = 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, buffer, buf_len); } else { - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, buffer, buf_len); } } @@ -52,32 +52,32 @@ 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) { buffer -= offset; - return eos_net_send_async(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, 1); + return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, !sync, 1); } -int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected) { - if (len < 2) return EOS_ERR_SIZE; +int eos_cell_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t *connected) { + if (buf_len < 2) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET; buffer++; - len--; + buf_len--; *status = buffer[0]; buffer++; - len--; + buf_len--; if (*status == EOS_CELL_STATUS_PPP) { - if (len < 1) return EOS_ERR_SIZE; + if (buf_len < 1) return EOS_ERR_SIZE; if (connected) *connected = buffer[0]; buffer++; - len--; + buf_len--; } return EOS_OK; } int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv; @@ -88,10 +88,10 @@ int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) } type = EOS_NET_MTYPE_CELL; - len = 1; + buf_len = 1; buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto cell_status_fin; if (type != EOS_NET_MTYPE_CELL) { @@ -99,7 +99,7 @@ int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) goto cell_status_fin; } - rv = eos_cell_status_parse(buffer, len, status, connected); + rv = eos_cell_status_parse(buffer, buf_len, status, connected); cell_status_fin: if (do_release) eos_net_free(buffer, 1); @@ -132,7 +132,7 @@ int eos_cell_uart_give(unsigned char *buffer, int sync) { return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } -unsigned char *eos_cell_uart_data_buffer(uint16_t *offset) { +unsigned char *eos_cell_uart_data_alloc(uint16_t *offset) { unsigned char *buffer; buffer = eos_net_alloc(); @@ -185,7 +185,7 @@ int eos_cell_voice_hangup(unsigned char *buffer, int sync) { return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } -unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) { +unsigned char *eos_cell_voice_pcm_alloc(uint16_t *offset) { unsigned char *buffer; buffer = eos_net_alloc(); @@ -197,7 +197,7 @@ 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 async; size_t addr_len, txt_len; - uint16_t len; + uint16_t buf_len; addr_len = strlen(addr); txt_len = strlen(txt); @@ -221,48 +221,48 @@ 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; - len = 5; - memcpy(buffer + len, addr, addr_len); - len += addr_len; - memcpy(buffer + len, txt, txt_len); - len += txt_len; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, len, async, 1); + buf_len = 5; + memcpy(buffer + buf_len, addr, addr_len); + buf_len += addr_len; + memcpy(buffer + buf_len, txt, txt_len); + buf_len += txt_len; + return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, buf_len, async, 1); } -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 buf_len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) { uint16_t _addr_len; - if (len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE; + if (buf_len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG)) return EOS_ERR_NET; buffer += 3 + EOS_CELL_SMS_SIZE_TS; - len -= 3 + EOS_CELL_SMS_SIZE_TS; + buf_len -= 3 + EOS_CELL_SMS_SIZE_TS; _addr_len = *buffer; if (_addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE; - if ((_addr_len == 0) || (len < (_addr_len + 1))) return EOS_ERR_SIZE; + if ((_addr_len == 0) || (buf_len < (_addr_len + 1))) return EOS_ERR_SIZE; if (addr && addr_len) { *addr = buffer + 1; *addr_len = _addr_len; } buffer += _addr_len + 1; - len -= _addr_len + 1; + buf_len -= _addr_len + 1; - if (len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; + if (buf_len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; if (txt && txt_len) { *txt = buffer; - *txt_len = len; + *txt_len = buf_len; } 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(unsigned char *buffer, uint16_t buf_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(buffer, buf_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; @@ -276,7 +276,7 @@ int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv; @@ -287,24 +287,24 @@ int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned } type = EOS_NET_MTYPE_CELL; - len = 1; + buf_len = 1; buffer[0] = EOS_CELL_MTYPE_PDP | atype; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto cell_pdp_get_fin; - if ((type != EOS_NET_MTYPE_CELL) || (len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) { + if ((type != EOS_NET_MTYPE_CELL) || (buf_len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) { rv = EOS_ERR_NET; goto cell_pdp_get_fin; } - len--; - if ((len > EOS_CELL_PDP_SIZE_ARG) || (len > arg_size - 1)) { + buf_len--; + if ((buf_len > EOS_CELL_PDP_SIZE_ARG) || (buf_len > arg_size - 1)) { rv = EOS_ERR_SIZE; goto cell_pdp_get_fin; } - memcpy(buffer + 1, arg, len); - arg[len] = '\0'; + memcpy(buffer + 1, arg, buf_len); + arg[buf_len] = '\0'; cell_pdp_get_fin: if (do_release) eos_net_free(buffer, 1); diff --git a/fw/fe310/eos/net/cell.h b/fw/fe310/eos/net/cell.h index ac334e9..3264022 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 @@ -73,20 +73,20 @@ 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_parse(unsigned char *buffer, uint16_t buf_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); +unsigned char *eos_cell_uart_data_alloc(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); +unsigned char *eos_cell_voice_pcm_alloc(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_sms_parse(unsigned char *buffer, uint16_t buf_len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len); +int eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_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); 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/sock.c b/fw/fe310/eos/net/sock.c index c9934e8..c55b8e8 100644 --- a/fw/fe310/eos/net/sock.c +++ b/fw/fe310/eos/net/sock.c @@ -10,26 +10,40 @@ 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, unsigned char *buffer, uint16_t buf_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 ((buffer == NULL) || (buf_len < 2)) { + eos_net_bad_handler(type, buffer, buf_len); return; } switch(buffer[0]) { - case EOS_SOCK_MTYPE_PKT: - evt_handler[sock - 1](type, buffer, len); + case EOS_SOCK_MTYPE_PKT: { + sock = buffer[1]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { + eos_net_bad_handler(type, buffer, buf_len); + return; + } + evt_handler[sock - 1](type, buffer, buf_len); + break; + } + + case EOS_SOCK_MTYPE_CLOSE: { + for (i=1; i<buf_len; i++) { + sock = buffer[i]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { + eos_net_bad_handler(type, buffer, buf_len); + return; + } + evt_handler[sock - 1](type, buffer, buf_len); + } break; + } + default: - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, buffer, buf_len); break; } } @@ -54,7 +68,7 @@ eos_evt_handler_t eos_sock_get_handler(unsigned char sock) { int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv, sock; @@ -65,23 +79,23 @@ int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer) { } type = EOS_NET_MTYPE_SOCK; - len = 1; + buf_len = 1; buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto sock_open_udp_fin; if (type != EOS_NET_MTYPE_SOCK) { rv = EOS_ERR_NET; goto sock_open_udp_fin; } - if (len < 2) { + if (buf_len < 2) { rv = EOS_ERR_SIZE; goto sock_open_udp_fin; } sock = buffer[1]; - if (sock == 0) { + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) { rv = EOS_ERR_NET; goto sock_open_udp_fin; } @@ -108,7 +122,29 @@ void eos_sock_close(unsigned char sock, unsigned char *buffer) { 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) { +int eos_sock_pkt_alloc(unsigned char **buffer, unsigned char *pkt, size_t pkt_len) { + *buffer = NULL; + + if (pkt && (pkt_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_SIZE_BUF)) return EOS_ERR_SIZE; + + *buffer = eos_net_alloc(); + *buffer += EOS_SOCK_SIZE_UDP_HDR; + if (pkt) memcpy(*buffer, pkt, pkt_len); + + return EOS_OK; +} + +unsigned char *eos_sock_buf2pkt(unsigned char *buf, uint16_t buf_len) { + if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return NULL; + + return buf + EOS_SOCK_SIZE_UDP_HDR; +} + +unsigned char *eos_sock_pkt2buf(unsigned char *pkt) { + return pkt - EOS_SOCK_SIZE_UDP_HDR; +} + +static void sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer) { buffer[0] = EOS_SOCK_MTYPE_PKT; buffer[1] = sock; buffer += 2; @@ -117,46 +153,47 @@ 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 eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len, unsigned char more) { int rv; - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; + buffer -= EOS_SOCK_SIZE_UDP_HDR; + sock_sendto(sock, addr, buffer); - return eos_net_send(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR); + rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR, more); + return rv; } -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_sendto_sync(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len) { int rv; - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; + buffer -= EOS_SOCK_SIZE_UDP_HDR; + sock_sendto(sock, addr, buffer); - return eos_net_send_async(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR, more); + rv = eos_net_send_sync(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR); + return rv; } -int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr) { - if (len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; +int eos_sock_recvfrom(unsigned char *buffer, uint16_t buf_len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size) { + if (buf_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 < buf_len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; + memcpy(pkt, buffer, buf_len - EOS_SOCK_SIZE_UDP_HDR); } return EOS_OK; diff --git a/fw/fe310/eos/net/sock.h b/fw/fe310/eos/net/sock.h index e2f8637..8dbb111 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; @@ -23,6 +26,10 @@ 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_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); +int eos_sock_pkt_alloc(unsigned char **buffer, unsigned char *pkt, size_t pkt_len); +unsigned char *eos_sock_buf2pkt(unsigned char *buf, uint16_t buf_len); +unsigned char *eos_sock_pkt2buf(unsigned char *pkt); + +int eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len, unsigned char more); +int eos_sock_sendto_sync(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len); +int eos_sock_recvfrom(unsigned char *buffer, uint16_t buf_len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size); diff --git a/fw/fe310/eos/net/wifi.c b/fw/fe310/eos/net/wifi.c index ebbb9ca..1391121 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, unsigned char *buffer, uint16_t buf_len) { unsigned char mtype; - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); + if ((buffer == NULL) || (buf_len < 1)) { + eos_net_bad_handler(type, buffer, buf_len); return; } mtype = buffer[0]; if ((mtype < EOS_WIFI_MAX_MTYPE) && evt_handler[mtype]) { - evt_handler[mtype](mtype, buffer, len); + evt_handler[mtype](mtype, buffer, buf_len); } else { - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, buffer, buf_len); } } @@ -44,28 +44,28 @@ 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) { - if (len < 2) return EOS_ERR_SIZE; +int eos_wifi_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size) { + if (buf_len < 2) return EOS_ERR_SIZE; if (buffer[0] != EOS_WIFI_MTYPE_STATUS) return EOS_ERR_NET; buffer++; - len--; + buf_len--; *status = buffer[0]; buffer++; - len--; + buf_len--; switch (*status) { case EOS_WIFI_STATUS_GOT_IP: - if (len < sizeof(uint32_t)) return EOS_ERR_SIZE; + if (buf_len < sizeof(uint32_t)) return EOS_ERR_SIZE; if (ip_addr) memcpy(ip_addr, buffer, sizeof(uint32_t)); buffer += sizeof(uint32_t); - len -= sizeof(uint32_t); + buf_len -= sizeof(uint32_t); case EOS_WIFI_STATUS_CONNECTED: if (ssid) { - if ((len == 0) || (len > EOS_WIFI_SIZE_SSID) || (len > ssid_size - 1)) return EOS_ERR_SIZE; - memcpy(ssid, buffer, len); - ssid[len] = '\0'; + if ((buf_len == 0) || (buf_len > EOS_WIFI_SIZE_SSID) || (buf_len > ssid_size - 1)) return EOS_ERR_SIZE; + memcpy(ssid, buffer, buf_len); + ssid[buf_len] = '\0'; } break; } @@ -74,7 +74,7 @@ int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv; @@ -85,17 +85,17 @@ int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssi } type = EOS_NET_MTYPE_WIFI; - len = 1; + buf_len = 1; buffer[0] = EOS_WIFI_MTYPE_STATUS; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto wifi_status_fin; 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); + rv = eos_wifi_status_parse(buffer, buf_len, status, ip_addr, ssid, ssid_size); wifi_status_fin: if (do_release) eos_net_free(buffer, 1); diff --git a/fw/fe310/eos/net/wifi.h b/fw/fe310/eos/net/wifi.h index 93d2fc4..800723e 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,10 @@ 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_parse(unsigned char *buffer, uint16_t buf_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_disconnect(unsigned char *buffer, int sync); 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..8bd5600 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" @@ -32,80 +34,63 @@ static eos_i2s_handler_t i2s_mic_handler = NULL; static eos_i2s_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) { @@ -135,7 +120,9 @@ static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l } 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,12 +277,8 @@ 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; -} - -void eos_i2s_set_mode(unsigned char mode) { - _eos_i2s_drvr[I2S_MODE] = mode; +int eos_i2s_set_lsgain(int gain) { + return eos_egpio_set_val(EGPIO_PIN_LSGAIN_SEL, gain); } void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) { @@ -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) { @@ -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..e2155a4 100644 --- a/fw/fe310/eos/soc/i2s.h +++ b/fw/fe310/eos/soc/i2s.h @@ -2,39 +2,41 @@ #include "i2s_def.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_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_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..64a057b 100644 --- a/fw/fe310/eos/soc/spi.c +++ b/fw/fe310/eos/soc/spi.c @@ -3,13 +3,16 @@ #include "encoding.h" #include "platform.h" +#include "board.h" #include "eos.h" +#include "log.h" #include "msgq.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,15 +24,12 @@ #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; @@ -40,6 +40,7 @@ static eos_evt_handler_t evt_handler[EOS_SPI_MAX_EVT]; 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); } else { @@ -47,7 +48,7 @@ static void spi_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l } } -int eos_spi_init(uint8_t wakeup_cause) { +int eos_spi_init(void) { int i; for (i=0; i<EOS_SPI_MAX_EVT; i++) { @@ -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); } @@ -126,7 +127,7 @@ void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags) { } static void spi_wait4xchg(void) { - uint8_t done = 0; + int done = 0; while (!done) { clear_csr(mstatus, MSTATUS_MIE); @@ -134,23 +135,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(unsigned char *buffer, uint16_t len, uint8_t flags) { + if (!spi_evt) return EOS_ERR; + + spi_wait4xchg(); - spi_in_xchg = 1; _eos_spi_xchg_init(buffer, len, flags); - eos_spi_cs_set(); + 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 +177,18 @@ 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) { + int rv; + + rv = eos_evtq_push_isr(EOS_EVT_SPI | spi_evt, spi_state_buf, 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 +196,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 +388,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..20999b5 100644 --- a/fw/fe310/eos/soc/spi.h +++ b/fw/fe310/eos/soc/spi.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_SPI_FLAG_TX 0x01 @@ -10,9 +11,9 @@ #define EOS_SPI_MAX_EVT 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); @@ -20,11 +21,12 @@ 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); +int eos_spi_xchg(unsigned char *buffer, 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..0573e84 100644 --- a/fw/fe310/eos/soc/timer.c +++ b/fw/fe310/eos/soc/timer.c @@ -48,7 +48,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; @@ -75,18 +75,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 +121,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..f5c7b4e 100644 --- a/fw/fe310/eos/soc/timer.h +++ b/fw/fe310/eos/soc/timer.h @@ -12,14 +12,14 @@ typedef void (*eos_timer_handler_t) (unsigned char); -int eos_timer_init(uint8_t wakeup_cause); +int eos_timer_init(void); void eos_timer_set_handler(unsigned char evt, eos_timer_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..44c9a52 100644 --- a/fw/fe310/eos/soc/uart.c +++ b/fw/fe310/eos/soc/uart.c @@ -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; } diff --git a/fw/fe310/eos/soc/uart.h b/fw/fe310/eos/soc/uart.h index 41329fb..474942d 100644 --- a/fw/fe310/eos/soc/uart.h +++ b/fw/fe310/eos/soc/uart.h @@ -9,7 +9,8 @@ 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); 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); diff --git a/hw/library/usb.dcm b/hw/library/haptic.dcm index 5f3ed79..5f3ed79 100644 --- a/hw/library/usb.dcm +++ b/hw/library/haptic.dcm diff --git a/hw/library/haptic.lib b/hw/library/haptic.lib new file mode 100644 index 0000000..2e59a48 --- /dev/null +++ b/hw/library/haptic.lib @@ -0,0 +1,26 @@ +EESchema-LIBRARY Version 2.4 +#encoding utf-8 +# +# DRV2605LDGS +# +DEF DRV2605LDGS U 0 40 Y Y 1 F N +F0 "U" 0 300 60 H V C CNN +F1 "DRV2605LDGS" 0 -400 60 H V C CNN +F2 "" 0 0 60 H I C CNN +F3 "" 0 0 60 H I C CNN +DRAW +S -350 250 350 -350 0 1 0 N +X REG 1 550 -200 200 L 50 50 1 1 O +X VDD 10 550 200 200 L 50 50 1 1 W +X SCL 2 -550 200 200 R 50 50 1 1 I +X SDA 3 -550 100 200 R 50 50 1 1 B +X IN/TRIG 4 -550 0 200 R 50 50 1 1 I +X EN 5 -550 -100 200 R 50 50 1 1 I +X VDD/NC 6 550 100 200 L 50 50 1 1 W +X OUT+ 7 550 0 200 L 50 50 1 1 O +X GND 8 550 -300 200 L 50 50 1 1 W +X OUT- 9 550 -100 200 L 50 50 1 1 O +ENDDRAW +ENDDEF +# +#End Library diff --git a/hw/library/usb.lib b/hw/library/usb.lib deleted file mode 100644 index 2fc61d0..0000000 --- a/hw/library/usb.lib +++ /dev/null @@ -1,44 +0,0 @@ -EESchema-LIBRARY Version 2.4 -#encoding utf-8 -# -# USB3_B_Micro -# -DEF USB3_B_Micro J 0 40 Y Y 1 F N -F0 "J" -350 700 60 H V C CNN -F1 "USB3_B_Micro" 100 700 60 H V C CNN -F2 "" 0 100 60 H I C CNN -F3 "" 0 100 60 H I C CNN -DRAW -C -100 145 25 1 1 10 F -C 0 -130 50 1 1 0 F -S -400 650 400 -600 1 1 10 f -S -110 -600 -90 -560 1 1 0 N -S -10 -600 10 -560 1 1 0 N -S 75 170 125 220 1 1 10 F -S 400 -490 360 -510 1 1 0 N -S 400 -390 360 -410 1 1 0 N -S 400 -190 360 -210 1 1 0 N -S 400 -90 360 -110 1 1 0 N -S 400 110 360 90 1 1 0 N -S 400 210 360 190 1 1 0 N -S 400 310 360 290 1 1 0 N -S 400 510 360 490 1 1 0 N -P 2 1 1 20 0 -130 0 270 N -P 3 1 1 20 0 -30 -100 70 -100 120 N -P 3 1 1 20 0 20 100 120 100 170 N -P 4 1 1 10 -50 270 0 370 50 270 -50 270 F -X VBUS 1 500 500 100 L 50 50 1 1 P -X SSRX+ 10 500 -500 100 L 50 50 1 1 I -X SHIELD 11 -200 -700 100 U 50 50 1 1 P -X D- 2 500 300 100 L 50 50 1 1 B -X D+ 3 500 200 100 L 50 50 1 1 B -X ID 4 500 100 100 L 50 50 1 1 O -X GND 5 0 -700 100 U 50 50 1 1 P -X SSTX- 6 500 -100 100 L 50 50 1 1 O -X SSTX+ 7 500 -200 100 L 50 50 1 1 O -X DRAIN 8 -100 -700 100 U 50 50 1 1 P -X SSRX- 9 500 -400 100 L 50 50 1 1 I -ENDDRAW -ENDDEF -# -#End Library diff --git a/util/prog.c b/util/prog.c index 0227682..e4360e0 100644 --- a/util/prog.c +++ b/util/prog.c @@ -48,11 +48,8 @@ int main(int argc, char *argv[]) { ftdi_set_eeprom_value(ftdi, SELF_POWERED, 1); ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_0, CBUSX_PWREN); ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_1, CBUSX_IOMODE); - /* next rev hw - ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_3, CBUSX_VBUS_SENSE); - */ ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_2, CBUSX_TRISTATE); - ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_3, CBUSX_TRISTATE); + ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_3, CBUSX_VBUS_SENSE); ret = ftdi_eeprom_build(ftdi); if (ret < 0) goto ftdi_fin; diff --git a/util/switch.c b/util/switch.c index 2fc0eb6..9f60fd3 100644 --- a/util/switch.c +++ b/util/switch.c @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) { case DEV_ESP32: { printf("Switch to esp32\n"); - ret = ftdi_set_bitmode(ftdi, 0x00, BITMODE_CBUS); + ret = ftdi_set_bitmode(ftdi, 0x22, BITMODE_CBUS); break; } } diff --git a/yocto/README b/yocto/README index ef99121..6c92a6e 100644 --- a/yocto/README +++ b/yocto/README @@ -7,6 +7,8 @@ https://developer.toradex.com/linux-bsp/os-development/build-yocto/build-a-refer https://developer.toradex.com/linux-bsp/os-development/build-u-boot-and-linux-kernel-from-source-code/build-u-boot/ https://developer.toradex.com/linux-bsp/os-development/build-u-boot-and-linux-kernel-from-source-code/build-linux-kernel-from-source-code/ https://developer.toradex.com/linux-bsp/os-development/build-u-boot-and-linux-kernel-from-source-code/build-device-tree-overlays-from-source-code/ +https://developer.toradex.com/linux-bsp/os-development/build-yocto/custom-meta-layers-recipes-and-images-in-yocto-project-hello-world-examples/ +https://developer.toradex.com/linux-bsp/os-development/build-yocto/device-tree-overlays-linux - install dependencies: # dependencies for yocto: @@ -18,7 +20,7 @@ apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev biso apt-get install u-boot-tools # dependencies for kernel: - apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev bison flex +apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev bison flex apt-get install u-boot-tools locale-gen en_US.UTF-8 @@ -43,12 +45,9 @@ curl https://commondatastorage.googleapis.com/git-repo-downloads/repo > bin/repo chmod 755 bin/repo - install the ARM GCC toolchain: -mkdir arm -cd arm wget https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz tar xvf arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz ln -s arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu gcc-linaro-aarch64 -cd .. - install device tree compiler tool: git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git -b v1.7.2 @@ -76,11 +75,12 @@ yocto image - clone meta-information mkdir oe-core cd oe-core -# branch: repo init -u git://git.toradex.com/toradex-manifest.git -b scarthgap-7.x.y -m tdxref/default.xml +# branch: +repo init -u git://git.toradex.com/toradex-manifest.git -b scarthgap-7.x.y -m tdxref/default.xml # specific tag: -repo init -u git://git.toradex.com/toradex-manifest.git -b refs/tags/7.1.0 -m tdxref/default.xml +# repo init -u git://git.toradex.com/toradex-manifest.git -b refs/tags/7.1.0 -m tdxref/default.xml repo sync -# repeat sync until successful +# repeat repo sync until successful - setup environment: . export @@ -90,17 +90,59 @@ vi conf/local.conf ... # set MACHINE: MACHINE ?= "verdin-imx8mp" -# append: +... +# set debian packages +PACKAGE_CLASSES ?= "package_deb" +... +# append ACCEPT_FSL_EULA = "1" -TOOLCHAIN_TARGET_TASK:append = " kernel-devsrc" + +- append mikrophone layer: +vi conf/bblayers.conf +# append to BBLAYERS variable: ... + ${TOPDIR}/../layers/meta-mikrophone \ +" -- build: -bitbake -k tdx-reference-minimal-image -c populate_sdk +# copy yocto/meta-mikrophone to ../layers/ dir from mikroPhone repo + +- build image: +bitbake -k mikrophone-image +bitbake -k mikrophone-image -c populate_sdk + +- install sdk: +deploy/sdk/tdx-xwayland-glibc-x86_64-mikroPhone-Image-armv8a-verdin-imx8mp-toolchain-7.x.y.sh +# install into: /build/tdx-xwayland/7.x.y - machine.conf in: layers/meta-toradex-nxp/conf/machine/verdin-imx8mp.conf -- distro.conf in: layers/meta-toradex-distro/conf/distro/*.conf -- demo images in: layers/meta-toradex-demos/recipes-images/images/*.bb + layers/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc +- mikrophone distro.conf in: layers/meta-mikrophone/conf/distro/mikrophone.conf +- mikrophone images in: layers/meta-mikrophone/recipes-images/images/mikrophone-image.bb + +- deployable tarballs in: build/deploy/images/verdin-imx8mp/ +- deployable sdk in: build/deploy/sdk/ + +- toradex distro.conf in: layers/meta-toradex-distro/conf/distro/*.conf +- toradex demo images in: layers/meta-toradex-demos/recipes-images/images/*.bb + + +upgrade yocto image +------------------- + +- upgrade yocto: +. /build/tools/start.sh +cd /build/oe-core +repo sync + +- build image: +. export +bitbake -k mikrophone-image +bitbake -k mikrophone-image -c populate_sdk + +- to launch TEZI installer: insert sdcard, reboot linux then stop u-boot auto boot and type: +setenv fdtfile imx8mp-verdin-wifi-dev.dtb +boot + u-boot ------ @@ -177,3 +219,46 @@ overlay cd overlays STAGING_KERNEL_DIR=../linux-toradex make mikroPhone-panel_overlay.dtbo cd .. + + +esp32d +------ + +- setup environment: +. /build/tdx-xwayland/7.x.y/environment-setup-armv8a-tdx-linux + +- build: +# copy yocto/esp32d from mikroPhone repo +cd esp32d +make +cd .. + + +debian repository +----------------- + +- install aptly and configure aptly: +apt-get install aptly gnupg1 gpgv1 +aptly # creates config file +vi ~/.aptly.conf +... + "gpgProvider": "internal", +... + "FileSystemPublishEndpoints": { + "mikrophone": { + "rootDir": "/build/repo", + "linkMethod": "copy", + "verifyMethod": "md5" + } + }, +... + +- generate gpg signing key: +gpg1 --gen-key +gpg1 --export --armor # signing key for apt-key add + +- create and publish repository: +aptly repo create -distribution=koshuta -component=main mikrophone +aptly repo add mikrophone /build/oe-core/build/deploy/deb +aptly publish repo mikrophone filesystem:mikrophone: +aptly publish update koshuta filesystem:mikrophone: diff --git a/yocto/esp32d/Makefile b/yocto/esp32d/Makefile new file mode 100644 index 0000000..677d09d --- /dev/null +++ b/yocto/esp32d/Makefile @@ -0,0 +1,15 @@ +#CFLAGS = +LDFLAGS = -pthread -lgpiod +TARGET = esp32d +obj = msgq.o spi.o tun.o + +all: $(TARGET) + +%.o: %.c %.h + $(CC) $(CFLAGS) -c $< + +$(TARGET): $(obj) + $(CC) $(obj) $(LDFLAGS) -o $@ + +clean: + rm -f $(TARGET) *.o diff --git a/yocto/esp32d/msgq.c b/yocto/esp32d/msgq.c new file mode 100644 index 0000000..3039f13 --- /dev/null +++ b/yocto/esp32d/msgq.c @@ -0,0 +1,43 @@ +#include <stdlib.h> +#include <pthread.h> + +#include "msgq.h" + +#define IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) + +int msgq_init(MSGQueue *msgq, unsigned char **array, uint16_t size) { + int rv; + + msgq->idx_r = 0; + msgq->idx_w = 0; + msgq->size = size; + msgq->array = array; + rv = pthread_mutex_init(&msgq->mutex, NULL); + if (rv) { + return MSGQ_ERR; + } + + rv = pthread_cond_init(&msgq->cond, NULL); + if (rv) { + pthread_mutex_destroy(&msgq->mutex); + return MSGQ_ERR; + } + return MSGQ_OK; +} + +int msgq_push(MSGQueue *msgq, unsigned char *buffer) { + if ((uint16_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return MSGQ_ERR_FULL; + + msgq->array[IDX_MASK(msgq->idx_w++, msgq->size)] = buffer; + return MSGQ_OK; +} + +unsigned char *msgq_pop(MSGQueue *msgq) { + if (msgq->idx_r == msgq->idx_w) return NULL; + + return msgq->array[IDX_MASK(msgq->idx_r++, msgq->size)]; +} + +uint16_t msgq_len(MSGQueue *msgq) { + return (uint16_t)(msgq->idx_w - msgq->idx_r); +} diff --git a/yocto/esp32d/msgq.h b/yocto/esp32d/msgq.h new file mode 100644 index 0000000..32b20d0 --- /dev/null +++ b/yocto/esp32d/msgq.h @@ -0,0 +1,22 @@ +#include <stdint.h> + +#define MSGQ_OK 0 +#define MSGQ_ERR -1 + +#define MSGQ_ERR_SIZE -10 +#define MSGQ_ERR_FULL -11 +#define MSGQ_ERR_EMPTY -12 + +typedef struct MSGQueue { + uint16_t idx_r; + uint16_t idx_w; + uint16_t size; + unsigned char **array; + pthread_mutex_t mutex; + pthread_cond_t cond; +} MSGQueue; + +int msgq_init(MSGQueue *msgq, unsigned char **array, uint16_t size); +int msgq_push(MSGQueue *msgq, unsigned char *buffer); +unsigned char *msgq_pop(MSGQueue *msgq); +uint16_t msgq_len(MSGQueue *msgq); diff --git a/yocto/esp32d/spi.c b/yocto/esp32d/spi.c new file mode 100644 index 0000000..db46a63 --- /dev/null +++ b/yocto/esp32d/spi.c @@ -0,0 +1,411 @@ +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <assert.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/ioctl.h> + +#include <linux/spi/spidev.h> + +#include <gpiod.h> +#include <pthread.h> + +#include "msgq.h" +#include "tun.h" +#include "spi.h" + +static pthread_t worker_thd; +static pthread_t rtscts_thd; +static pthread_t msg_handler_thd; +static pthread_t tun_handler_thd; +static pthread_mutex_t mutex; +static pthread_cond_t cond; + +static MSGQueue spi_bufq; +static unsigned char *spi_bufq_array[SPI_SIZE_BUFQ]; + +static MSGQueue spi_msgq_in; +static unsigned char *spi_msgq_in_array[SPI_SIZE_MSGQ_IN]; + +static MSGQueue spi_msgq_out; +static unsigned char *spi_msgq_out_array[SPI_SIZE_MSGQ_OUT]; + +static uint32_t spi_speed = SPI_SPEED; +static int spi_fd; +static volatile int spi_cts; + +struct gpiod_line_request *request = NULL; + +static void _spi_wait4cts(void) { + pthread_mutex_lock(&mutex); + while (!spi_cts) { + pthread_cond_wait(&cond, &mutex); + } + spi_cts = 0; + pthread_mutex_unlock(&mutex); +} + +static int _spi_xchg(unsigned char *buffer) { + int rv; + uint16_t len_tx; + uint16_t len_rx; + struct spi_ioc_transfer tr; + + memset(&tr, 0, sizeof(tr)); + tr.tx_buf = (unsigned long)buffer; + tr.rx_buf = (unsigned long)buffer; + tr.speed_hz = spi_speed; + + len_tx = (uint16_t)buffer[1] << 8; + len_tx |= (uint16_t)buffer[2] & 0xFF; + if (len_tx > SPI_MTU) return SPI_ERR; + + if (buffer[0]) { + len_tx += SPI_SIZE_HDR; + // esp32 dma workaraund + if (len_tx < 8) { + len_tx = 8; + } else if (len_tx % 4 != 0) { + len_tx = (len_tx / 4 + 1) * 4; + } + + tr.len = len_tx; + } else { + /* nothing to send, reset esp32 spi transaction */ + tr.len = 1; + + _spi_wait4cts(); + rv = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); + if (rv < 0) return SPI_ERR_MSG; + + /* receive SPI_SIZE_RECEIVE bytes in first transaction (estimate) */ + len_tx = SPI_SIZE_RECEIVE + SPI_SIZE_HDR; + tr.len = len_tx; + buffer[1] = 0; + buffer[2] = 0; + } + + _spi_wait4cts(); + rv = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); + if (rv < 0) return SPI_ERR_MSG; + + len_rx = (uint16_t)buffer[1] << 8; + len_rx |= (uint16_t)buffer[2] & 0xFF; + if (len_rx > SPI_MTU) return SPI_ERR; + + len_rx += SPI_SIZE_HDR; + if (len_rx > len_tx) { + tr.tx_buf = (unsigned long)NULL; + tr.rx_buf = (unsigned long)(buffer + len_tx); + + len_tx = len_rx - len_tx; + // esp32 dma workaraund + if (len_tx < 8) { + len_tx = 8; + } else if (len_tx % 4 != 0) { + len_tx = (len_tx / 4 + 1) * 4; + } + + tr.len = len_tx; + + _spi_wait4cts(); + rv = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); + if (rv < 0) return SPI_ERR_MSG; + } + + return SPI_OK; +} + +static void *worker(void *arg) { + MSGQueue *bufq = &spi_bufq; + MSGQueue *msgq_in = &spi_msgq_in; + MSGQueue *msgq_out = &spi_msgq_out; + int rv; + unsigned char *buffer; + + while (1) { + pthread_mutex_lock(&msgq_out->mutex); + buffer = msgq_pop(msgq_out); + if ((buffer == NULL) && (gpiod_line_request_get_value(request, SPI_GPIO_RTS) == GPIOD_LINE_VALUE_INACTIVE)) { + pthread_mutex_lock(&bufq->mutex); + buffer = msgq_pop(bufq); + pthread_mutex_unlock(&bufq->mutex); + } + if (buffer == NULL) { + pthread_cond_wait(&msgq_out->cond, &msgq_out->mutex); + buffer = msgq_pop(msgq_out); + } + pthread_mutex_unlock(&msgq_out->mutex); + if (buffer) { + rv = _spi_xchg(buffer); + if (rv || (buffer[0] == 0)) { + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + pthread_mutex_lock(&bufq->mutex); + msgq_push(bufq, buffer); + pthread_mutex_unlock(&bufq->mutex); + } else { + pthread_mutex_lock(&msgq_in->mutex); + rv = msgq_push(msgq_in, buffer); + if (rv == MSGQ_OK) pthread_cond_signal(&msgq_in->cond); + pthread_mutex_unlock(&msgq_in->mutex); + + if (rv) { + pthread_mutex_lock(&bufq->mutex); + msgq_push(bufq, buffer); + pthread_mutex_unlock(&bufq->mutex); + } + } + } + } + + return NULL; +} + +static void *rtscts_handler(void *arg) { + MSGQueue *msgq_out = &spi_msgq_out; + struct gpiod_edge_event_buffer *event_buffer; + struct gpiod_edge_event *event; + int rv; + + event_buffer = gpiod_edge_event_buffer_new(1); + + while (1) { + rv = gpiod_line_request_read_edge_events(request, event_buffer, 1); + if (rv != 1) continue; + + event = gpiod_edge_event_buffer_get_event(event_buffer, 0); + switch (gpiod_edge_event_get_line_offset(event)) { + case SPI_GPIO_RTS: { + pthread_mutex_lock(&msgq_out->mutex); + pthread_cond_signal(&msgq_out->cond); + pthread_mutex_unlock(&msgq_out->mutex); + break; + } + + case SPI_GPIO_CTS: { + pthread_mutex_lock(&mutex); + spi_cts = 1; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + break; + } + } + } + + gpiod_edge_event_buffer_free(event_buffer); + return NULL; +} + +static void *msg_handler(void *arg) { + MSGQueue *bufq = &spi_bufq; + MSGQueue *msgq_in = &spi_msgq_in; + unsigned char *buffer; + unsigned char mtype; + uint16_t len; + int rv; + + while (1) { + pthread_mutex_lock(&msgq_in->mutex); + buffer = msgq_pop(msgq_in); + if (buffer == NULL) { + pthread_cond_wait(&msgq_in->cond, &msgq_in->mutex); + buffer = msgq_pop(msgq_in); + } + pthread_mutex_unlock(&msgq_in->mutex); + if (buffer) { + mtype = buffer[0]; + len = (uint16_t)buffer[1] << 8; + len |= (uint16_t)buffer[2] & 0xFF; + + switch (mtype) { + case SPI_MTYPE_TUN: + tun_write(buffer + SPI_SIZE_HDR, len); + break; + } + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + pthread_mutex_lock(&bufq->mutex); + msgq_push(bufq, buffer); + pthread_mutex_unlock(&bufq->mutex); + } + } + + return NULL; +} + +static void *tun_handler(void *arg) { + unsigned char *buffer; + ssize_t len; + + while (1) { + buffer = spi_alloc(); + if (buffer == NULL) continue; + + len = tun_read(buffer + SPI_SIZE_HDR, SPI_SIZE_BUF - SPI_SIZE_HDR); + if (len < 0) { + perror("tun read"); + continue; + } + spi_xchg(SPI_MTYPE_TUN, buffer, len); + } + + return NULL; +} + +unsigned char *spi_alloc(void) { + MSGQueue *bufq = &spi_bufq; + unsigned char *buffer; + + pthread_mutex_lock(&bufq->mutex); + buffer = msgq_pop(bufq); + pthread_mutex_unlock(&bufq->mutex); + + return buffer; +} + +void spi_free(unsigned char *buffer) { + MSGQueue *bufq = &spi_bufq; + + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + pthread_mutex_lock(&bufq->mutex); + msgq_push(bufq, buffer); + pthread_mutex_unlock(&bufq->mutex); +} + +int spi_xchg(unsigned char mtype, unsigned char *buffer, uint16_t len) { + MSGQueue *bufq = &spi_bufq; + MSGQueue *msgq_out = &spi_msgq_out; + int rv; + + buffer[0] = mtype; + buffer[1] = len >> 8; + buffer[2] = len & 0xFF; + + pthread_mutex_lock(&msgq_out->mutex); + rv = msgq_push(msgq_out, buffer); + if (rv == MSGQ_OK) pthread_cond_signal(&msgq_out->cond); + pthread_mutex_unlock(&msgq_out->mutex); + + if (rv) { + pthread_mutex_lock(&bufq->mutex); + msgq_push(bufq, buffer); + pthread_mutex_unlock(&bufq->mutex); + } + + return rv; +} + +int gpio_init(void) { + struct gpiod_chip *chip = NULL; + struct gpiod_line_settings *line_settings = NULL; + struct gpiod_line_config *line_cfg = NULL; + struct gpiod_request_config *req_cfg = NULL; + int rv; + + unsigned int line_offsets[2] = { SPI_GPIO_RTS, SPI_GPIO_CTS }; + + chip = gpiod_chip_open(SPI_GPIO_DEV); + if (chip == NULL) goto gpio_init_fin; + + line_settings = gpiod_line_settings_new(); + if (line_settings == NULL) goto gpio_init_fin; + + gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_INPUT); + gpiod_line_settings_set_edge_detection(line_settings, GPIOD_LINE_EDGE_FALLING); + gpiod_line_settings_set_bias(line_settings, GPIOD_LINE_BIAS_PULL_UP); + + line_cfg = gpiod_line_config_new(); + if (line_cfg == NULL) goto gpio_init_fin; + + rv = gpiod_line_config_add_line_settings(line_cfg, line_offsets, 2, line_settings); + if (rv) goto gpio_init_fin; + + req_cfg = gpiod_request_config_new(); + if (req_cfg == NULL) goto gpio_init_fin; + + gpiod_request_config_set_consumer(req_cfg, "rts-cts"); + + request = gpiod_chip_request_lines(chip, req_cfg, line_cfg); + +gpio_init_fin: + rv = (request ? SPI_OK : (chip ? SPI_ERR : SPI_ERR_OPEN)); + + if (req_cfg) gpiod_request_config_free(req_cfg); + if (line_cfg) gpiod_line_config_free(line_cfg); + if (line_settings) gpiod_line_settings_free(line_settings); + if (chip) gpiod_chip_close(chip); + + return rv; +} + +int spi_init(void) { + unsigned char *buffer; + int rv, i; + + spi_fd = open(SPI_DEV, O_RDWR); + if (spi_fd < 0) return SPI_ERR_OPEN; + + rv = ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed); + if (rv == -1) return SPI_ERR; + + rv = msgq_init(&spi_bufq, spi_bufq_array, SPI_SIZE_BUFQ); + assert(rv == MSGQ_OK); + + rv = msgq_init(&spi_msgq_in, spi_msgq_in_array, SPI_SIZE_MSGQ_IN); + assert(rv == MSGQ_OK); + + rv = msgq_init(&spi_msgq_out, spi_msgq_out_array, SPI_SIZE_MSGQ_OUT); + assert(rv == MSGQ_OK); + + for (i=0; i<SPI_SIZE_BUFQ; i++) { + buffer = malloc(SPI_SIZE_BUF); + assert(buffer); + msgq_push(&spi_bufq, buffer); + } + + rv = pthread_mutex_init(&mutex, NULL); + assert(rv == 0); + + rv = pthread_cond_init(&cond, NULL); + assert(rv == 0); + + /* assret initial contitions */ + pthread_mutex_lock(&mutex); + spi_cts = (gpiod_line_request_get_value(request, SPI_GPIO_CTS) == GPIOD_LINE_VALUE_INACTIVE); + pthread_mutex_unlock(&mutex); + + rv = pthread_create(&worker_thd, NULL, worker, NULL); + assert(rv == 0); + + rv = pthread_create(&rtscts_thd, NULL, rtscts_handler, NULL); + assert(rv == 0); + + rv = pthread_create(&msg_handler_thd, NULL, msg_handler, NULL); + assert(rv == 0); + + rv = pthread_create(&tun_handler_thd, NULL, tun_handler, NULL); + assert(rv == 0); + + return SPI_OK; +} + +int main(int argc, char *argv[]) { + int rv; + + rv = tun_init(SPI_TUN_NAME); + if (rv) printf("TUN INIT ERR\n"); + + rv = gpio_init(); + if (rv) printf("GPIO INIT ERR\n"); + + rv = spi_init(); + if (rv) printf("SPI INIT ERR\n"); + + while (1); +} diff --git a/yocto/esp32d/spi.h b/yocto/esp32d/spi.h new file mode 100644 index 0000000..4d9ff86 --- /dev/null +++ b/yocto/esp32d/spi.h @@ -0,0 +1,31 @@ +#include <stdint.h> + +#define SPI_DEV "/dev/spidev0" +#define SPI_SPEED 10000000 + +#define SPI_TUN_NAME "tun0" + +#define SPI_GPIO_DEV "/dev/gpiochip3" +#define SPI_GPIO_CTS 28 +#define SPI_GPIO_RTS 25 + +#define SPI_MTU 1500 +#define SPI_SIZE_HDR 3 +#define SPI_SIZE_BUF (SPI_MTU + SPI_SIZE_HDR) +#define SPI_SIZE_RECEIVE 16 /* guestimate on number of bytes for transaction initiated by falling RTS */ + +#define SPI_SIZE_BUFQ 64 +#define SPI_SIZE_MSGQ_IN 32 +#define SPI_SIZE_MSGQ_OUT 32 + +#define SPI_MTYPE_TUN 1 + +#define SPI_OK 0 +#define SPI_ERR -1 +#define SPI_ERR_OPEN -10 +#define SPI_ERR_MSG -11 + +unsigned char *spi_alloc(void); +void spi_free(unsigned char *buffer); +int spi_xchg(unsigned char mtype, unsigned char *buffer, uint16_t len); +int spi_init(void);
\ No newline at end of file diff --git a/yocto/esp32d/tun.c b/yocto/esp32d/tun.c new file mode 100644 index 0000000..75043a3 --- /dev/null +++ b/yocto/esp32d/tun.c @@ -0,0 +1,84 @@ +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/ioctl.h> + +#include <linux/if.h> +#include <linux/if_tun.h> + +#include <pthread.h> + +#include "spi.h" +#include "tun.h" + +static pthread_t read_thd; + +static int tun_fd; +static char tun_name[IFNAMSIZ]; + +static int tun_alloc(char *dev, int flags) { + struct ifreq ifr; + int fd, err; + char *clonedev = "/dev/net/tun"; + + /* Arguments taken by the function: + * + * char *dev: the name of an interface (or '\0'). MUST have enough + * space to hold the interface name if '\0' is passed + * int flags: interface flags (eg, IFF_TUN etc.) + */ + + fd = open(clonedev, O_RDWR); + if (fd < 0) { + return fd; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */ + + if (*dev) { + /* if a device name was specified, put it in the structure; otherwise, + * the kernel will try to allocate the "next" device of the + * specified type */ + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + } + + /* try to create the device */ + err = ioctl(fd, TUNSETIFF, (void *) &ifr); + if (err < 0) { + close(fd); + return err; + } + + /* if the operation was successful, write back the name of the + * interface to the variable "dev", so the caller can know + * it. Note that the caller MUST reserve space in *dev (see calling + * code below) */ + strcpy(dev, ifr.ifr_name); + + /* this is the special file descriptor that the caller will use to talk + * with the virtual interface */ + return fd; +} + +ssize_t tun_read(unsigned char *buffer, size_t buf_size) { + return read(tun_fd, buffer, buf_size); +} + +ssize_t tun_write(unsigned char *buffer, size_t buf_len) { + return write(tun_fd, buffer, buf_len); +} + +int tun_init(char *name) { + int rv; + + if (strlen(name) >= sizeof(tun_name) - 1) return -1; + strcpy(tun_name, name); + + tun_fd = tun_alloc(tun_name, IFF_TUN | IFF_NO_PI); + if (tun_fd < 0) return -1; + + return 0; +} diff --git a/yocto/esp32d/tun.h b/yocto/esp32d/tun.h new file mode 100644 index 0000000..793a4c9 --- /dev/null +++ b/yocto/esp32d/tun.h @@ -0,0 +1,5 @@ +#include <sys/types.h> + +ssize_t tun_read(unsigned char *buffer, size_t buf_size); +ssize_t tun_write(unsigned char *buffer, size_t buf_len); +int tun_init(char *name);
\ No newline at end of file diff --git a/yocto/meta-mikrophone/conf/distro/mikrophone.conf b/yocto/meta-mikrophone/conf/distro/mikrophone.conf new file mode 100644 index 0000000..efeba6e --- /dev/null +++ b/yocto/meta-mikrophone/conf/distro/mikrophone.conf @@ -0,0 +1,20 @@ +# Toradex Distro for Wayland with XWayland. +# Using the downstream kernel flavour. + +require conf/distro/include/tdx-base.inc + +DISTRO = "mikrophone" +DISTRO_NAME = "mikroPhone distribution" +DISTRO_FLAVOUR = "" + +IMX_DEFAULT_BSP = "nxp" + +# we use graphics, so set opengl +DISTRO_FEATURES:append = " opengl" + +DISTRO_FEATURES:append = " wayland x11" + +# lxqt requires this +DISTRO_FEATURES:append = " polkit" +TASK_BASIC_SSHDAEMON = "openssh-sshd openssh-sftp openssh-sftp-server" +IMAGE_FEATURES:append = " ssh-server-openssh" diff --git a/yocto/meta-mikrophone/conf/layer.conf b/yocto/meta-mikrophone/conf/layer.conf new file mode 100644 index 0000000..8abd100 --- /dev/null +++ b/yocto/meta-mikrophone/conf/layer.conf @@ -0,0 +1,13 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "meta-mikrophone" +BBFILE_PATTERN_meta-mikrophone = "^${LAYERDIR}/" +BBFILE_PRIORITY_meta-mikrophone = "6" + +LAYERDEPENDS_meta-mikrophone = "core" +LAYERSERIES_COMPAT_meta-mikrophone = "scarthgap" diff --git a/yocto/meta-mikrophone/conf/machine/._verdin-imx8mp-mikrophone.conf b/yocto/meta-mikrophone/conf/machine/._verdin-imx8mp-mikrophone.conf Binary files differnew file mode 100644 index 0000000..fe7655c --- /dev/null +++ b/yocto/meta-mikrophone/conf/machine/._verdin-imx8mp-mikrophone.conf diff --git a/yocto/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc b/yocto/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc new file mode 100644 index 0000000..b64f4f1 --- /dev/null +++ b/yocto/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc @@ -0,0 +1,14 @@ +# needed in recent builds for wifi and bt +MACHINE_FIRMWARE:append = " firmware-nxp-wifi-nxp8997-sdio" + +# our device tree +KERNEL_DEVICETREE:append = " \ + ${KERNEL_DTB_PREFIX}imx8mp-verdin-wifi-mikrophone.dtb \ + ${KERNEL_DTB_PREFIX}imx8mp-verdin-nonwifi-mikrophone.dtb \ +" +# DTB for u-boot only +UBOOT_DTB_NAME = "imx8mp-verdin-wifi-mikrophone.dtb" + +# for SDK only +TOOLCHAIN_TARGET_TASK:append = " kernel-devsrc" +TOOLCHAIN_TARGET_TASK:remove = "target-sdk-provides-dummy" diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-mikrophone.dtsi b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-mikrophone.dtsi new file mode 100644 index 0000000..6ce6362 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-mikrophone.dtsi @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2025 Uros Majstorovic + */ + +/* Verdin SPI_1 */ +&ecspi1 { + status = "okay"; +}; + +&eqos { + status = "disable"; +}; + +&fec { + status = "disable"; +}; + +&flexcan1 { + status = "disable"; +}; + +&flexcan2 { + status = "disable"; +}; + +/* Verdin QSPI_1 */ +&flexspi { + status = "disable"; +}; + +/* Verdin I2C_2_DSI */ +&i2c2 { + status = "disabled"; +}; + +&i2c3 { + status = "disabled"; +}; + +/* Verdin I2C_1 */ +&i2c4 { + status = "okay"; +}; + +/* Verdin PCIE_1 */ +&pcie { + status = "okay"; +}; + +&pcie_phy { + status = "okay"; +}; + +/* Verdin PWM_1 */ +&pwm1 { + status = "okay"; +}; + +/* Verdin PWM_2 */ +&pwm2 { + status = "disabled"; +}; + +/* Verdin PWM_3_DSI */ +&pwm3 { + status = "disabled"; +}; + +®_usdhc2_vmmc { + vin-supply = <®_3p3v>; +}; + +/* Verdin UART_1 */ +&uart1 { + status = "disabled"; +}; + +/* Verdin UART_2 */ +&uart2 { + status = "disabled"; +}; + +/* Verdin UART_3, used as the Linux Console */ +&uart3 { + status = "okay"; +}; + +/* Verdin USB_1 */ +&usb3_0 { + status = "okay"; +}; + +&usb3_phy0 { + status = "okay"; +}; + +/* Verdin USB_2 */ +&usb3_1 { + fsl,permanently-attached; + status = "okay"; +}; + +&usb3_phy1 { + status = "okay"; +}; + +/* Verdin SDCard */ +&usdhc2 { + status = "okay"; +}; diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-nonwifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-nonwifi-mikrophone.dts new file mode 100644 index 0000000..e8ba274 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-nonwifi-mikrophone.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2025 Uros Majstorovic + */ + +/dts-v1/; + +#include "imx8mp-verdin.dtsi" +#include "imx8mp-verdin-nonwifi.dtsi" +#include "imx8mp-verdin-mikrophone.dtsi" + +/ { + model = "Toradex Verdin iMX8M Plus on mikroPhone"; + compatible = "toradex,verdin-imx8mp-nonwifi-mikrophone", + "toradex,verdin-imx8mp-nonwifi", + "toradex,verdin-imx8mp", + "fsl,imx8mp"; +}; diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-wifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-wifi-mikrophone.dts new file mode 100644 index 0000000..3b04ab5 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-wifi-mikrophone.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2025 Uros Majstorovic + */ + +/dts-v1/; + +#include "imx8mp-verdin.dtsi" +#include "imx8mp-verdin-wifi.dtsi" +#include "imx8mp-verdin-mikrophone.dtsi" + +/ { + model = "Toradex Verdin iMX8M Plus WB on mikroPhone"; + compatible = "toradex,verdin-imx8mp-wifi-mikrophone", + "toradex,verdin-imx8mp-wifi", + "toradex,verdin-imx8mp", + "fsl,imx8mp"; +}; diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex_%.bbappend b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex_%.bbappend new file mode 100644 index 0000000..0a6f719 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex_%.bbappend @@ -0,0 +1,19 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/u-boot-toradex:" + +SRC_URI += "\ + file://imx8mp-verdin-mikrophone.dtsi \ + file://imx8mp-verdin-wifi-mikrophone.dts \ + file://imx8mp-verdin-nonwifi-mikrophone.dts \ + " + +DTS_SRCDIR = "dts/upstream/src/arm64/freescale" + +do_configure:append() { + cp ${WORKDIR}/imx8mp-verdin-mikrophone.dtsi ${S}/${DTS_SRCDIR} + cp ${WORKDIR}/imx8mp-verdin-wifi-mikrophone.dts ${S}/${DTS_SRCDIR} + cp ${WORKDIR}/imx8mp-verdin-nonwifi-mikrophone.dts ${S}/${DTS_SRCDIR} + # Remove exisiting fdtfile, if there is one + sed -i '/"fdtfile=.*\\0" \\/d' ${S}/include/configs/verdin-imx8mp.h + # Add new fdtfile + sed -i 's/\("fdt_board=.*\\0" \\\)/\0\n\t"fdtfile=imx8mp-verdin-wifi-mikrophone.dtb\\0" \\/' ${S}/include/configs/verdin-imx8mp.h +}
\ No newline at end of file diff --git a/yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb b/yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb new file mode 100644 index 0000000..4a88221 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb @@ -0,0 +1,74 @@ +inherit core-image + +SUMMARY = "mikroPhone image" +DESCRIPTION = "mikroPhone image" + +LICENSE = "MIT" + +#Prefix to the resulting deployable tarball name +export IMAGE_BASENAME = "mikroPhone-Image" +MACHINE_NAME ?= "${MACHINE}" +IMAGE_NAME = "${MACHINE_NAME}_${IMAGE_BASENAME}" + +IMAGE_FEATURES += " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'weston', '', d)} \ +" + +# Copy Licenses to image /usr/share/common-license +COPY_LIC_MANIFEST ?= "1" +COPY_LIC_DIRS ?= "1" + +add_rootfs_version () { + printf "${DISTRO_NAME} ${DISTRO_VERSION} (${DISTRO_CODENAME}) \\\n \\\l\n" > ${IMAGE_ROOTFS}/etc/issue + printf "${DISTRO_NAME} ${DISTRO_VERSION} (${DISTRO_CODENAME}) %%h\n" > ${IMAGE_ROOTFS}/etc/issue.net + printf "${IMAGE_NAME}\n\n" >> ${IMAGE_ROOTFS}/etc/issue + printf "${IMAGE_NAME}\n\n" >> ${IMAGE_ROOTFS}/etc/issue.net +} + +add_home_root_symlink () { + ln -sf ${ROOT_HOME} ${IMAGE_ROOTFS}/home/root +} + +# add the rootfs version to the welcome banner +ROOTFS_POSTPROCESS_COMMAND += " add_rootfs_version; add_home_root_symlink;" + +IMAGE_LINGUAS = "en-us" +#IMAGE_LINGUAS = "de-de fr-fr en-gb en-us pt-br es-es kn-in ml-in ta-in" + +CONMANPKGS ?= "connman connman-plugin-loopback connman-plugin-ethernet connman-plugin-wifi connman-client" + +IMAGE_INSTALL += " \ + packagegroup-boot \ + packagegroup-basic \ + packagegroup-base-tdx-cli \ + packagegroup-machine-tdx-cli \ + packagegroup-wifi-tdx-cli \ + packagegroup-wifi-fw-tdx-cli \ + udev-extraconf \ + ${CONMANPKGS} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', \ + 'timestamp-service systemd-analyze', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 wayland', \ + 'weston-xwayland xterm', '', d)} \ + ${@bb.utils.contains('MACHINE_FEATURES', 'tpm2', \ + 'packagegroup-tpm2-tdx-cli', '', d)} \ + \ + packagegroup-tdx-cli \ + packagegroup-tdx-graphical \ + packagegroup-fsl-isp \ + \ + bash \ + coreutils \ + less \ + makedevs \ + mime-support \ + net-tools \ + util-linux \ + v4l-utils \ + \ + gpicview \ + media-files \ + \ + gnupg \ + weston weston-init wayland-terminal-launch \ +" diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays/mikroPhone-panel_overlay.dts b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays/mikroPhone-panel_overlay.dts new file mode 100644 index 0000000..bee2682 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays/mikroPhone-panel_overlay.dts @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2025 Uros Majstorovic + */ + +// adapted from: https://git.toradex.com/cgit/device-tree-overlays.git/tree/overlays/verdin-imx8mp_panel-cap-touch-10inch-lvds_overlay.dts?h=toradex_6.6-2.2.x-imx +// Verdin iMX8M Plus single-channel LVDS + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pwm/pwm.h> +#include "freescale/imx8mp-pinfunc.h" + +/ { + compatible = "toradex,verdin-imx8mp"; +}; + +&{/} { + backlight_lvds_native: backlight-lvds-native { + compatible = "pwm-backlight"; + pinctrl-names = "default"; + brightness-levels = <0 45 63 88 119 158 203 255>; + default-brightness-level = <4>; + /* Verdin PWM_1 (SODIMM 15) */ + pwms = <&pwm1 0 6666667>; + }; + + panel-lvds-native { + compatible = "panel-lvds"; + backlight = <&backlight_lvds_native>; + data-mapping = "vesa-24"; + height-mm = <110>; + width-mm = <62>; + + panel-timing { + clock-frequency = <36000000>; + hactive = <480>; + hfront-porch = <23 60 71>; + hsync-len = <15 40 47>; + hback-porch = <23 60 71>; + + vactive = <854>; + vfront-porch = <5 7 10>; + vsync-len = <6 9 12>; + vback-porch = <5 7 10>; + + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <1>; /* positive edge */ + }; + + port { + panel_lvds_native_in: endpoint { + remote-endpoint = <&lvds_out>; + }; + }; + }; +}; + +/* Verdin I2C_1 */ +&i2c4 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + gt911@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + pinctrl-names = "default"; + pinctrl-0 = <&gpio1>; + /* Verdin GPIO_3 (SODIMM 210) */ + interrupt-parent = <&gpio1>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; + /* Verdin GPIO_4 (SODIMM 212) */ + reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +}; + +&lcdif2 { + status = "okay"; +}; + +&ldb { + status = "okay"; + + lvds-channel@0 { + #address-cells = <1>; + #size-cells = <0>; + fsl,data-mapping = "spwg"; + fsl,data-width = <24>; + status = "okay"; + + port@1 { + reg = <1>; + + lvds_out: endpoint { + remote-endpoint = <&panel_lvds_native_in>; + }; + }; + }; +}; + +&ldb_phy { + status = "okay"; +}; diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays_git.bbappend b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays_git.bbappend new file mode 100644 index 0000000..cae7974 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays_git.bbappend @@ -0,0 +1,15 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/device-tree-overlays:" + +MIKROPHONE_OVERLAYS_BINARY = "verdin-imx8mp_hdmi_overlay.dtbo mikroPhone-panel_overlay.dtbo" + +SRC_URI += " \ + file://mikroPhone-panel_overlay.dts \ +" + +TEZI_EXTERNAL_KERNEL_DEVICETREE = "${MIKROPHONE_OVERLAYS_BINARY}" + +TEZI_EXTERNAL_KERNEL_DEVICETREE_BOOT = "${MIKROPHONE_OVERLAYS_BINARY}" + +do_collect_overlays:prepend() { + cp ${WORKDIR}/mikroPhone-panel_overlay.dts ${S} +}
\ No newline at end of file diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex%.bbappend b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex%.bbappend new file mode 100644 index 0000000..a706b06 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex%.bbappend @@ -0,0 +1,20 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/linux-toradex:" + +# Prevent the use of in-tree defconfig +# unset KBUILD_DEFCONFIG + +SRC_URI += "\ + file://imx8mp-verdin-mikrophone.dtsi \ + file://imx8mp-verdin-wifi-mikrophone.dts \ + file://imx8mp-verdin-nonwifi-mikrophone.dts \ + file://kernel_lvds_freq.patch \ + " + +# For arm64 bit freescale/NXP devices +DTS_SRCDIR = "arch/arm64/boot/dts/freescale" + +do_configure:append() { + cp ${WORKDIR}/imx8mp-verdin-mikrophone.dtsi ${S}/${DTS_SRCDIR} + cp ${WORKDIR}/imx8mp-verdin-wifi-mikrophone.dts ${S}/${DTS_SRCDIR} + cp ${WORKDIR}/imx8mp-verdin-nonwifi-mikrophone.dts ${S}/${DTS_SRCDIR} +}
\ No newline at end of file diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-mikrophone.dtsi b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-mikrophone.dtsi new file mode 100644 index 0000000..7c23309 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-mikrophone.dtsi @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2025 Uros Majstorovic + */ + +/* Verdin HDMI_1 Audio */ +&aud2htx { + status = "okay"; +}; + +/* Verdin SPI_1 */ +&ecspi1 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + spidev@0 { + /* Use compatible "rohm,dh2228fv" to bind spidev driver */ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <50000000>; + }; +}; + +&eqos { + status = "disabled"; +}; + +&fec { + status = "disabled"; +}; + +&flexcan1 { + status = "disabled"; +}; + +&flexcan2 { + status = "disabled"; +}; + +/* Verdin QSPI_1 */ +&flexspi { + status = "disabled"; +}; + +&gpio4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; +}; + +/* Verdin I2C_2_DSI */ +&i2c2 { + status = "disabled"; +}; + +/* CAM I2C, disabled for now */ +&i2c3 { + status = "disabled"; +}; + +/* Verdin I2C_1 */ +&i2c4 { + status = "okay"; +}; + +/* Verdin PCIE_1 */ +&pcie { + status = "okay"; +}; + +&pcie_phy { + status = "okay"; +}; + +/* Verdin PWM_1 */ +&pwm1 { + status = "okay"; +}; + +/* Verdin PWM_2 */ +&pwm2 { + status = "disabled"; +}; + +/* Verdin PWM_3_DSI */ +&pwm3 { + status = "disabled"; +}; + +®_usdhc2_vmmc { + vin-supply = <®_3p3v>; +}; + +/* Verdin HDMI_1 Audio */ +&sound_hdmi { + status = "okay"; +}; + +/* Verdin UART_1 */ +&uart1 { + status = "disabled"; +}; + +/* Verdin UART_2 */ +&uart2 { + status = "disabled"; +}; + +/* Verdin UART_3, used as the Linux Console */ +&uart3 { + status = "okay"; +}; + +/* Verdin USB_1 */ +&usb3_0 { + status = "okay"; +}; + +&usb3_phy0 { + status = "okay"; +}; + +/* Verdin USB_2 */ +&usb3_1 { + // fsl,permanently-attached; + status = "okay"; +}; + +&usb3_phy1 { + status = "okay"; +}; + +/* Verdin SDCard */ +&usdhc2 { + status = "okay"; +}; + +/* Video and graphics */ +&vpu_g1 { + status = "okay"; +}; + +&vpu_g2 { + status = "okay"; +}; + +&vpu_vc8000e { + status = "okay"; +}; + +&vpu_v4l2 { + status = "okay"; +}; + +&gpu_2d { + status = "okay"; +}; + +&gpu_3d { + status = "okay"; +}; + +&ml_vipsi { + status = "okay"; +}; + +&mix_gpu_ml { + status = "okay"; +}; diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-nonwifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-nonwifi-mikrophone.dts new file mode 100644 index 0000000..91c08a7 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-nonwifi-mikrophone.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2025 Uros Majstorovic + */ + +/dts-v1/; + +#include "imx8mp-verdin.dtsi" +#include "imx8mp-verdin-nonwifi.dtsi" +#include "imx8mp-verdin-mikrophone.dtsi" + +/ { + model = "Toradex Verdin iMX8M Plus on mikroPhone"; + compatible = "toradex,verdin-imx8mp-nonwifi-mikrophone", + "toradex,verdin-imx8mp-wifi", + "toradex,verdin-imx8mp", + "fsl,imx8mp"; +}; diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-wifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-wifi-mikrophone.dts new file mode 100644 index 0000000..35792e1 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-wifi-mikrophone.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2025 Uros Majstorovic + */ + +/dts-v1/; + +#include "imx8mp-verdin.dtsi" +#include "imx8mp-verdin-wifi.dtsi" +#include "imx8mp-verdin-mikrophone.dtsi" + +/ { + model = "Toradex Verdin iMX8M Plus WB on mikroPhone"; + compatible = "toradex,verdin-imx8mp-wifi-mikrophone", + "toradex,verdin-imx8mp-wifi", + "toradex,verdin-imx8mp", + "fsl,imx8mp"; +}; diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/kernel_lvds_freq.patch b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/kernel_lvds_freq.patch new file mode 100644 index 0000000..9955bc4 --- /dev/null +++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/kernel_lvds_freq.patch @@ -0,0 +1,62 @@ +diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +index 55adf1bf45d9..c875474e6c45 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +@@ -752,7 +752,7 @@ clk: clock-controller@30380000 { + <800000000>, + <393216000>, + <361267200>, +- <1039500000>; ++ <252000000>; + }; + + src: reset-controller@30390000 { +diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c +index 6c17786ecb9f..8c9840f08c0e 100644 +--- a/drivers/clk/imx/clk-pll14xx.c ++++ b/drivers/clk/imx/clk-pll14xx.c +@@ -75,6 +75,7 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { + PLL_1443X_RATE(49152000U, 393, 3, 6, 0x374c), + PLL_1443X_RATE(45158400U, 241, 2, 6, 0xd845), + PLL_1443X_RATE(40960000U, 109, 1, 6, 0x3a07), ++ PLL_1443X_RATE(252000000U, 84, 2, 2, 0), + }; + + struct imx_pll14xx_clk imx_1443x_pll = { +diff --git a/drivers/gpu/drm/imx/imx8mp-ldb.c b/drivers/gpu/drm/imx/imx8mp-ldb.c +index e3f5c5e6e842..55dbafa863cf 100644 +--- a/drivers/gpu/drm/imx/imx8mp-ldb.c ++++ b/drivers/gpu/drm/imx/imx8mp-ldb.c +@@ -186,15 +186,6 @@ imx8mp_ldb_encoder_atomic_check(struct drm_encoder *encoder, + return -EINVAL; + } + +- /* +- * Due to limited video PLL frequency points on i.MX8mp, +- * we do mode fixup here in case any mode is unsupported. +- */ +- if (ldb->dual) +- mode->clock = mode->clock > 100000 ? 148500 : 74250; +- else +- mode->clock = 74250; +- + return 0; + } + +@@ -212,16 +203,6 @@ imx8mp_ldb_encoder_mode_valid(struct drm_encoder *encoder, + if (ldb_ch->panel) + return MODE_OK; + +- /* +- * Due to limited video PLL frequency points on i.MX8mp, +- * we do mode valid check here. +- */ +- if (ldb->dual && mode->clock != 74250 && mode->clock != 148500) +- return MODE_NOCLOCK; +- +- if (!ldb->dual && mode->clock != 74250) +- return MODE_NOCLOCK; +- + return MODE_OK; + } + diff --git a/yocto/overlays/mikroPhone-panel_overlay.dts b/yocto/overlays/mikroPhone-panel_overlay.dts index 0bc14b3..bee2682 100644 --- a/yocto/overlays/mikroPhone-panel_overlay.dts +++ b/yocto/overlays/mikroPhone-panel_overlay.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT /* - * Copyright 2023 Toradex + * Copyright 2025 Uros Majstorovic */ // adapted from: https://git.toradex.com/cgit/device-tree-overlays.git/tree/overlays/verdin-imx8mp_panel-cap-touch-10inch-lvds_overlay.dts?h=toradex_6.6-2.2.x-imx @@ -32,8 +32,8 @@ compatible = "panel-lvds"; backlight = <&backlight_lvds_native>; data-mapping = "vesa-24"; - height-mm = <136>; - width-mm = <217>; + height-mm = <110>; + width-mm = <62>; panel-timing { clock-frequency = <36000000>; @@ -61,16 +61,8 @@ }; }; -&gpu_2d { - status = "okay"; -}; - -&gpu_3d { - status = "okay"; -}; - /* Verdin I2C_1 */ -&i2c1 { +&i2c4 { #address-cells = <1>; #size-cells = <0>; status = "okay"; @@ -116,16 +108,3 @@ &ldb_phy { status = "okay"; }; - -&mix_gpu_ml { - status = "okay"; -}; - -&ml_vipsi { - status = "okay"; -}; - -/* Verdin PWM_2 */ -&pwm1 { - status = "okay"; -}; |