From 42d5c7be2c6bea5c03f55f43ad34b4bc28d50bcc Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Thu, 20 May 2021 19:12:47 +0200 Subject: net protocol added req/rep messages --- fw/esp32/components/eos/include/net.h | 4 +- fw/esp32/components/eos/net.c | 44 +++++-- fw/fe310/eos/Makefile | 6 +- fw/fe310/eos/eos.c | 2 +- fw/fe310/eos/event.c | 19 ++- fw/fe310/eos/event.h | 3 +- fw/fe310/eos/msgq.c | 36 ++++-- fw/fe310/eos/msgq.h | 2 +- fw/fe310/eos/net.c | 223 ++++++++++++++++++++-------------- fw/fe310/eos/net.h | 8 +- fw/fe310/eos/spi_dev.c | 2 +- 11 files changed, 221 insertions(+), 128 deletions(-) diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h index f71d07d..f6b3700 100644 --- a/fw/esp32/components/eos/include/net.h +++ b/fw/esp32/components/eos/include/net.h @@ -13,7 +13,9 @@ #define EOS_NET_MAX_MTYPE 8 -#define EOS_NET_MTYPE_FLAG_ONEW 0x80 +#define EOS_NET_MTYPE_FLAG_ONEW 0x40 +#define EOS_NET_MTYPE_FLAG_REPW 0x80 +#define EOS_NET_MTYPE_FLAG_MASK 0xc0 /* esp32 specific */ #define EOS_NET_SIZE_BUFQ 4 diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c index 59b0c4e..e48d714 100644 --- a/fw/esp32/components/eos/net.c +++ b/fw/esp32/components/eos/net.c @@ -57,9 +57,11 @@ static void _post_trans_cb(spi_slave_transaction_t *trans) { } static void net_xchg_task(void *pvParameters) { - int repeat = 0; int wake = 0; + int reply = 0; + int skip_next_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); @@ -95,12 +97,12 @@ static void net_xchg_task(void *pvParameters) { if (eos_power_wakeup_cause()) { wake = 1; - repeat = 1; + skip_next_msg = 1; } eos_power_wait4init(); while (1) { - if (!repeat) { + if (!skip_next_msg) { xSemaphoreTake(mutex, portMAX_DELAY); eos_msgq_pop(&net_send_q, &mtype, &buffer, &len); @@ -122,13 +124,25 @@ static void net_xchg_task(void *pvParameters) { xSemaphoreGive(mutex); } - repeat = 0; + skip_next_msg = 0; - buf_recv[0] = 0; - buf_recv[1] = 0; - buf_recv[2] = 0; + if (reply) { + spi_tr.tx_buffer = buf_recv; + spi_tr.rx_buffer = NULL; + } else { + 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]); + if (reply) { + reply = 0; + spi_tr.tx_buffer = buf_send; + spi_tr.rx_buffer = buf_recv; + if (buf_send[0]) skip_next_msg = 1; + continue; + } if (wake) { eos_power_net_ready(); @@ -157,23 +171,27 @@ static void net_xchg_task(void *pvParameters) { spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); wake = 1; - repeat = 1; + skip_next_msg = 1; } continue; } - mtype = buf_recv[0]; + 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 + 3; - if (mtype & EOS_NET_MTYPE_FLAG_ONEW) { - mtype &= ~EOS_NET_MTYPE_FLAG_ONEW; - if (buf_send[0]) repeat = 1; - } if ((mtype <= EOS_NET_MAX_MTYPE) && (len <= EOS_NET_SIZE_BUF)) { mtype_handler[mtype-1](mtype, buffer, len); } else { bad_handler(mtype, buffer, len); } + if ((mtype_flags & EOS_NET_MTYPE_FLAG_ONEW) && buf_send[0]) { + skip_next_msg = 1; + } + if (mtype_flags & EOS_NET_MTYPE_FLAG_REPW) { + skip_next_msg = 1; + reply = 1; + } } vTaskDelete(NULL); } diff --git a/fw/fe310/eos/Makefile b/fw/fe310/eos/Makefile index 66ac136..abdcbac 100644 --- a/fw/fe310/eos/Makefile +++ b/fw/fe310/eos/Makefile @@ -1,8 +1,10 @@ include ../common.mk -CFLAGS += -I. -I../bsp/include -I../bsp/drivers +CRYPTO_DIR = ../../../crypto -obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o power.o i2s.o i2c.o uart.o spi.o spi_dev.o sdcard.o net.o wifi.o cell.o sock.o unicode.o +CFLAGS += -I. -I../bsp/include -I../bsp/drivers -I$(CRYPTO_DIR) + +obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o power.o i2s.o i2c.o uart.o spi.o spi_dev.o sdcard.o sdc_crypto.o cam.o net.o wifi.o cell.o sock.o unicode.o %.o: %.c %.h diff --git a/fw/fe310/eos/eos.c b/fw/fe310/eos/eos.c index a96f391..e2ad3d1 100644 --- a/fw/fe310/eos/eos.c +++ b/fw/fe310/eos/eos.c @@ -42,7 +42,7 @@ void eos_init(void) { eos_sock_init(); eos_bq25895_init(); - eos_net_wake(wakeup_cause); + eos_net_start(wakeup_cause); eve_init(wakeup_cause == EOS_PWR_WAKE_RST, touch_calibrate, touch_matrix, EVE_GPIO_DIR); if (touch_calibrate) { diff --git a/fw/fe310/eos/event.c b/fw/fe310/eos/event.c index 6953dca..e0a185f 100644 --- a/fw/fe310/eos/event.c +++ b/fw/fe310/eos/event.c @@ -55,12 +55,28 @@ void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len eos_msgq_pop(&_eos_event_q, type, buffer, len); } +int eos_evtq_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); +} + +int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { + int rv = 0; + + clear_csr(mstatus, MSTATUS_MIE); + rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len); + set_csr(mstatus, MSTATUS_MIE); +} + void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { int rv = 0; while(!rv) { clear_csr(mstatus, MSTATUS_MIE); - rv = eos_msgq_get(&_eos_event_q, type, selector, sel_len, buffer, len); + rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len); if (!rv) { unsigned char _type; unsigned char *_buffer; @@ -127,6 +143,7 @@ void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t le 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; } diff --git a/fw/fe310/eos/event.h b/fw/fe310/eos/event.h index ba906bb..c9edd03 100644 --- a/fw/fe310/eos/event.h +++ b/fw/fe310/eos/event.h @@ -9,6 +9,8 @@ int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len); int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len); void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len); void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len); +int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len); +int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); void eos_evtq_flush(void); void eos_evtq_flush_isr(void); @@ -17,4 +19,3 @@ void eos_evtq_loop(void); 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); - diff --git a/fw/fe310/eos/msgq.c b/fw/fe310/eos/msgq.c index e76090c..a483a58 100644 --- a/fw/fe310/eos/msgq.c +++ b/fw/fe310/eos/msgq.c @@ -42,40 +42,54 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui } } -int eos_msgq_get(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { +int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { uint8_t i, j, idx; + unsigned char *_buffer; + uint16_t _len; if (msgq->idx_r == msgq->idx_w) { - *buffer = NULL; - *len = 0; + if (buffer && len) { + *buffer = NULL; + *len = 0; + } return 0; } idx = IDX_MASK(msgq->idx_r, msgq->size); if (type == msgq->array[idx].type) { - *buffer = msgq->array[idx].buffer; - *len = msgq->array[idx].len; - if ((selector == NULL) || (sel_len == 0) || ((sel_len <= *len) && (memcmp(selector, *buffer, sel_len) == 0))) { + _buffer = msgq->array[idx].buffer; + _len = msgq->array[idx].len; + if ((selector == NULL) || (sel_len == 0) || ((sel_len <= _len) && (memcmp(selector, _buffer, sel_len) == 0))) { msgq->idx_r++; + if (buffer && len) { + *buffer = _buffer; + *len = _len; + } return 1; } } for (i = msgq->idx_r + 1; IDX_LT(i, msgq->idx_w); i++) { idx = IDX_MASK(i, msgq->size); if (type== msgq->array[idx].type) { - *buffer = msgq->array[idx].buffer; - *len = msgq->array[idx].len; - if ((selector == NULL) || (sel_len == 0) || ((sel_len <= *len) && (memcmp(selector, *buffer, sel_len) == 0))) { + _buffer = msgq->array[idx].buffer; + _len = msgq->array[idx].len; + if ((selector == NULL) || (sel_len == 0) || ((sel_len <= _len) && (memcmp(selector, _buffer, sel_len) == 0))) { for (j = i + 1; IDX_LT(j, msgq->idx_w); j++) { msgq->array[IDX_MASK(j - 1, msgq->size)] = msgq->array[IDX_MASK(j, msgq->size)]; } msgq->idx_w--; + if (buffer && len) { + *buffer = _buffer; + *len = _len; + } return 1; } } } - *buffer = NULL; - *len = 0; + if (buffer && len) { + *buffer = NULL; + *len = 0; + } return 0; } diff --git a/fw/fe310/eos/msgq.h b/fw/fe310/eos/msgq.h index 9f2ca81..7e3b5e5 100644 --- a/fw/fe310/eos/msgq.h +++ b/fw/fe310/eos/msgq.h @@ -16,7 +16,7 @@ typedef struct EOSMsgQ { void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len); void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len); -int eos_msgq_get(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); +int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); uint8_t eos_msgq_len(EOSMsgQ *msgq); typedef struct EOSBufQ { diff --git a/fw/fe310/eos/net.c b/fw/fe310/eos/net.c index 5edb013..197c2b1 100644 --- a/fw/fe310/eos/net.c +++ b/fw/fe310/eos/net.c @@ -20,12 +20,12 @@ #include "net.h" #define NET_STATE_FLAG_RUN 0x01 -#define NET_STATE_FLAG_RST 0x02 -#define NET_STATE_FLAG_RTS 0x04 -#define NET_STATE_FLAG_CTS 0x08 -#define NET_STATE_FLAG_INIT 0x10 -#define NET_STATE_FLAG_ONEW 0x20 -#define NET_STATE_FLAG_XCHG 0x40 +#define NET_STATE_FLAG_INIT 0x02 +#define NET_STATE_FLAG_XCHG 0x04 +#define NET_STATE_FLAG_ONEW 0x10 +#define NET_STATE_FLAG_REPW 0x20 +#define NET_STATE_FLAG_RTS 0x40 +#define NET_STATE_FLAG_CTS 0x80 #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) @@ -54,12 +54,11 @@ static int net_xchg_sleep(void) { int i; int rv = EOS_OK; 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) = 0xFF; while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); if (x & 0xFF) rv = EOS_ERR_BUSY; @@ -77,6 +76,7 @@ static int net_xchg_sleep(void) { static void net_xchg_wake(void) { int i; volatile uint32_t x = 0; + net_state_flags &= ~NET_STATE_FLAG_CTS; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; @@ -90,13 +90,15 @@ static void net_xchg_wake(void) { } static void net_xchg_reset(void) { + volatile uint32_t x = 0; net_state_flags &= ~NET_STATE_FLAG_CTS; - net_state_flags |= (NET_STATE_FLAG_RST | NET_STATE_FLAG_XCHG); SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; + SPI1_REG(SPI_REG_TXFIFO) = 0; - SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(0); - SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; + 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) { @@ -105,6 +107,7 @@ static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t l if (net_state_next_cnt && (net_state_next_buf == NULL)) type |= EOS_NET_MTYPE_FLAG_ONEW; if (type & EOS_NET_MTYPE_FLAG_ONEW) net_state_flags |= NET_STATE_FLAG_ONEW; + if (type & EOS_NET_MTYPE_FLAG_REPW) net_state_flags |= NET_STATE_FLAG_REPW; net_state_type = type; net_state_len_tx = len; @@ -123,40 +126,36 @@ static int net_xchg_next(unsigned char *_buffer) { unsigned char type; unsigned char *buffer = NULL; uint16_t len; + int ret = _buffer ? 1 : 0; eos_msgq_pop(&net_send_q, &type, &buffer, &len); if (type) { net_xchg_start(type, buffer, len); } else if (net_state_flags & NET_STATE_FLAG_RTS) { - if (_buffer == NULL) _buffer = eos_bufq_pop(&net_buf_q); if (_buffer) { - net_xchg_start(0, _buffer, 0); - return 0; + buffer = _buffer; + ret = 0; + } else { + buffer = eos_bufq_pop(&net_buf_q); } + if (buffer) net_xchg_start(0, buffer, 0); } - return 1; + + return ret; } static void net_handle_xchg(void) { volatile uint32_t r1, r2, r3; uint32_t len; - if (net_state_flags & NET_STATE_FLAG_RST) { - net_state_flags &= ~(NET_STATE_FLAG_RST | NET_STATE_FLAG_XCHG); - - r1 = SPI1_REG(SPI_REG_RXFIFO); - SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; - SPI1_REG(SPI_REG_IE) = 0x0; - - return; - } else if (net_state_flags & NET_STATE_FLAG_INIT) { + if (net_state_flags & NET_STATE_FLAG_INIT) { net_state_flags &= ~NET_STATE_FLAG_INIT; r1 = SPI1_REG(SPI_REG_RXFIFO); r2 = SPI1_REG(SPI_REG_RXFIFO); r3 = SPI1_REG(SPI_REG_RXFIFO); - if (net_state_flags & NET_STATE_FLAG_ONEW) { + if (net_state_flags & (NET_STATE_FLAG_ONEW | NET_STATE_FLAG_REPW)) { r1 = 0; r2 = 0; r3 = 0; @@ -189,14 +188,18 @@ static void net_handle_xchg(void) { eos_spi_handle_xchg(); if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_AUTO) { // exchange done - if (net_state_type) { - int r = eos_evtq_push_isr(EOS_EVT_NET | net_state_type, net_state_buf, net_state_len_rx); - if (r) 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; - net_state_flags &= ~NET_STATE_FLAG_ONEW; + if (net_state_flags & NET_STATE_FLAG_REPW) { + net_state_flags &= ~NET_STATE_FLAG_REPW; } else { - eos_bufq_push(&net_buf_q, net_state_buf); + if (net_state_type) { + int r = eos_evtq_push_isr(EOS_EVT_NET | net_state_type, net_state_buf, net_state_len_rx); + if (r) 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; + net_state_flags &= ~NET_STATE_FLAG_ONEW; + } else { + eos_bufq_push(&net_buf_q, net_state_buf); + } } net_state_flags &= ~NET_STATE_FLAG_XCHG; } @@ -216,7 +219,9 @@ static void net_handle_rts(void) { if (GPIO_REG(GPIO_RISE_IP) & rts_offset) { GPIO_REG(GPIO_RISE_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(); + 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; net_state_flags &= ~NET_STATE_FLAG_RTS; @@ -272,10 +277,12 @@ static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint1 } static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = ((type & EOS_EVT_MASK) >> 4) - 1; - uint16_t flag = (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1); + unsigned char idx = (type & EOS_EVT_MASK) >> 4; - if (idx < EOS_EVT_MAX_EVT) { + if (idx && (idx <= EOS_EVT_MAX_EVT)) { + 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); } else { @@ -286,6 +293,17 @@ static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len) } } +static void net_pause(void) { + net_state_flags &= ~NET_STATE_FLAG_RUN; +} + +static void net_resume(void) { + net_state_flags |= NET_STATE_FLAG_RUN; + if (net_state_flags & NET_STATE_FLAG_CTS) { + net_xchg_next(NULL); + } +} + void eos_net_init(void) { int i; @@ -317,18 +335,33 @@ void eos_net_init(void) { 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); } -void eos_net_start(void) { +void eos_net_start(uint8_t wakeup_cause) { eos_intr_set_handler(INT_SPI1_BASE, net_handle_xchg); SPI1_REG(SPI_REG_SCKDIV) = eos_spi_div(EOS_SPI_DEV_NET); SPI1_REG(SPI_REG_CSID) = eos_spi_csid(EOS_SPI_DEV_NET); clear_csr(mstatus, MSTATUS_MIE); - net_state_flags |= NET_STATE_FLAG_RUN; - if (net_state_flags & NET_STATE_FLAG_CTS) { - net_xchg_next(NULL); + if (wakeup_cause) { + 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"); + } + GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); + } + net_xchg_reset(); } + net_resume(); set_csr(mstatus, MSTATUS_MIE); } @@ -395,39 +428,6 @@ int eos_net_sleep(uint32_t timeout) { return rv; } -int eos_net_wake(uint8_t source) { - int rv = EOS_OK; - - clear_csr(mstatus, MSTATUS_MIE); - if (net_state_flags & NET_STATE_FLAG_RUN) rv = EOS_ERR; - set_csr(mstatus, MSTATUS_MIE); - - if (rv) return rv; - - eos_intr_set_handler(INT_SPI1_BASE, net_handle_xchg); - SPI1_REG(SPI_REG_SCKDIV) = eos_spi_div(EOS_SPI_DEV_NET); - SPI1_REG(SPI_REG_CSID) = eos_spi_csid(EOS_SPI_DEV_NET); - - clear_csr(mstatus, MSTATUS_MIE); - net_state_flags |= NET_STATE_FLAG_RUN; - if (source) { - if (source != 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"); - } - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); - } - net_xchg_reset(); - if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS)) net_state_flags |= NET_STATE_FLAG_RTS; - } - set_csr(mstatus, MSTATUS_MIE); - - return rv; -} - void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) { eos_evtq_bad_handler(type, buffer, len); if (buffer) eos_net_free(buffer, 0); @@ -439,10 +439,11 @@ void eos_net_set_handler(unsigned char mtype, eos_evt_handler_t handler) { } void eos_net_acquire_for_evt(unsigned char type, char acq) { - unsigned char idx = ((type & EOS_EVT_MASK) >> 4) - 1; - uint16_t flag = type & ~EOS_EVT_MASK ? (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1) : 0xFFFF; + 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 < EOS_EVT_MAX_EVT) { + if (idx && (idx <= EOS_EVT_MAX_EVT)) { + idx--; net_flags_acq[idx] &= ~flag; if (acq) net_flags_acq[idx] |= flag; } @@ -486,45 +487,81 @@ void eos_net_free(unsigned char *buffer, unsigned char more) { if ((more || net_state_next_cnt) && (net_state_next_buf == NULL)) { net_state_next_buf = buffer; } else { - if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) do_release = net_xchg_next(buffer); - if (do_release) eos_bufq_push(&net_buf_q, buffer); + if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) { + do_release = net_xchg_next(buffer); + } + if (do_release) { + eos_bufq_push(&net_buf_q, buffer); + } } set_csr(mstatus, MSTATUS_MIE); } -int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more) { +static int net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) { int rv = EOS_OK; - - if (more) type |= EOS_NET_MTYPE_FLAG_ONEW; + int _sync = 0; + unsigned char _type = *type; + uint16_t _len = *len; + uint8_t spi_dev = EOS_SPI_DEV_NET; clear_csr(mstatus, MSTATUS_MIE); - if ((type & EOS_NET_MTYPE_FLAG_ONEW) && !(net_state_flags & NET_STATE_FLAG_RUN)) { - uint8_t spi_dev; + if ((_type & EOS_NET_MTYPE_FLAG_REPW) || ((_type & EOS_NET_MTYPE_FLAG_ONEW) && !(net_state_flags & NET_STATE_FLAG_RUN))) _sync = 1; + + if (!(net_state_flags & NET_STATE_FLAG_RUN) && _sync) { + int _rv; set_csr(mstatus, MSTATUS_MIE); spi_dev = eos_spi_dev(); - rv = eos_spi_deselect(); - if (rv) return rv; - + _rv = eos_spi_deselect(); + if (_rv) return _rv; clear_csr(mstatus, MSTATUS_MIE); + } + + if (_sync) { + net_pause(); while (!(net_state_flags & NET_STATE_FLAG_CTS)) { asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); clear_csr(mstatus, MSTATUS_MIE); } - net_xchg_start(type, buffer, len); - set_csr(mstatus, MSTATUS_MIE); - - eos_spi_select(spi_dev); + net_xchg_start(_type, buffer, _len); + if (_type & EOS_NET_MTYPE_FLAG_REPW) { + while (!(net_state_flags & NET_STATE_FLAG_CTS)) { + asm volatile ("wfi"); + set_csr(mstatus, MSTATUS_MIE); + clear_csr(mstatus, MSTATUS_MIE); + } + net_xchg_start(0, buffer, 0); + while (net_state_flags & NET_STATE_FLAG_XCHG) { + asm volatile ("wfi"); + set_csr(mstatus, MSTATUS_MIE); + clear_csr(mstatus, MSTATUS_MIE); + } + *type = net_state_type; + *len = net_state_len_rx; + } + net_resume(); } else { if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) { - net_xchg_start(type, buffer, len); + net_xchg_start(_type, buffer, _len); } else { - rv = eos_msgq_push(&net_send_q, type, buffer, len); + rv = eos_msgq_push(&net_send_q, _type, buffer, _len); if (rv) eos_bufq_push(&net_buf_q, buffer); } - set_csr(mstatus, MSTATUS_MIE); } + set_csr(mstatus, MSTATUS_MIE); + if (spi_dev != EOS_SPI_DEV_NET) eos_spi_select(spi_dev); + return rv; } + +int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more) { + if (more) type |= EOS_NET_MTYPE_FLAG_ONEW; + return net_xchg(&type, buffer, &len); +} + +int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) { + *type |= EOS_NET_MTYPE_FLAG_REPW; + return net_xchg(type, buffer, len); +} diff --git a/fw/fe310/eos/net.h b/fw/fe310/eos/net.h index 1aaea1f..ecefbec 100644 --- a/fw/fe310/eos/net.h +++ b/fw/fe310/eos/net.h @@ -14,16 +14,17 @@ #define EOS_NET_MAX_MTYPE 8 -#define EOS_NET_MTYPE_FLAG_ONEW 0x80 +#define EOS_NET_MTYPE_FLAG_ONEW 0x40 +#define EOS_NET_MTYPE_FLAG_REPW 0x80 +#define EOS_NET_MTYPE_FLAG_MASK 0xc0 /* fe310 specific */ #define EOS_NET_SIZE_BUFQ 2 void eos_net_init(void); -void eos_net_start(void); +void eos_net_start(uint8_t wakeup_cause); void eos_net_stop(void); int eos_net_sleep(uint32_t timeout); -int eos_net_wake(uint8_t source); 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); @@ -34,3 +35,4 @@ 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_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len); diff --git a/fw/fe310/eos/spi_dev.c b/fw/fe310/eos/spi_dev.c index 4713826..0448f76 100644 --- a/fw/fe310/eos/spi_dev.c +++ b/fw/fe310/eos/spi_dev.c @@ -59,7 +59,7 @@ int eos_spi_deselect(void) { eos_spi_stop(); spi_dev = EOS_SPI_DEV_NET; - eos_net_start(); + eos_net_start(0); return EOS_OK; } -- cgit v1.2.3