From 6666a131ab36b1d96a854da80524d860f9a3884b Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 19 Feb 2020 06:47:43 +0100 Subject: eve long press/double tap/inertial scroll spi flush bugfix resolved dependecies: spi -> net; event -> net renamed various handlers --- code/fe310/eos/net.c | 220 ++++++++++++++++++++++++++------------------------- 1 file changed, 111 insertions(+), 109 deletions(-) (limited to 'code/fe310/eos/net.c') diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c index 36695bc..afe7997 100644 --- a/code/fe310/eos/net.c +++ b/code/fe310/eos/net.c @@ -30,24 +30,19 @@ static uint8_t net_state_flags = 0; static unsigned char net_state_type = 0; static uint32_t net_state_len_tx = 0; static uint32_t net_state_len_rx = 0; +unsigned char *net_state_buf = NULL; static uint8_t net_state_next_cnt = 0; static unsigned char *net_state_next_buf = NULL; -static eos_evt_fptr_t evt_handler[EOS_NET_MAX_MTYPE]; -static uint16_t evt_handler_flags_buf_free = 0; -static uint16_t evt_handler_flags_buf_acq = 0; - -extern uint32_t _eos_spi_state_len; -extern uint32_t _eos_spi_state_idx_tx; -extern uint32_t _eos_spi_state_idx_rx; -extern unsigned char *_eos_spi_state_buf; +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 void net_xchg_reset(void) { net_state_flags &= ~NET_STATE_FLAG_CTS; net_state_flags |= (NET_STATE_FLAG_RST | NET_STATE_FLAG_XCHG); - // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; SPI1_REG(SPI_REG_TXFIFO) = 0; @@ -66,10 +61,8 @@ static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t l net_state_type = type; net_state_len_tx = len; net_state_len_rx = 0; + net_state_buf = buffer; - _eos_spi_state_buf = buffer; - - // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; SPI1_REG(SPI_REG_TXFIFO) = ((type << 3) | (len >> 8)) & 0xFF; @@ -97,25 +90,12 @@ static int net_xchg_next(unsigned char *_buffer) { return 1; } -void eos_net_xchg_done(void) { - SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; - if (net_state_type) { - int r = eos_evtq_push_isr(EOS_EVT_NET | net_state_type, _eos_spi_state_buf, net_state_len_rx); - if (r) eos_bufq_push(&net_buf_q, _eos_spi_state_buf); - } else if (((net_state_flags & NET_STATE_FLAG_ONEW) || net_state_next_cnt) && (net_state_next_buf == NULL)) { - net_state_next_buf = _eos_spi_state_buf; - net_state_flags &= ~NET_STATE_FLAG_ONEW; - } else { - eos_bufq_push(&net_buf_q, _eos_spi_state_buf); - } - net_state_flags &= ~NET_STATE_FLAG_XCHG; -} - -static void net_handler_xchg(void) { +static void net_handle_xchg(void) { volatile uint32_t r1, r2; + uint32_t len; if (net_state_flags & NET_STATE_FLAG_RST) { - 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; @@ -124,8 +104,6 @@ static void net_handler_xchg(void) { return; } else if (net_state_flags & NET_STATE_FLAG_INIT) { net_state_flags &= ~NET_STATE_FLAG_INIT; - SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM); - SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM; r1 = SPI1_REG(SPI_REG_RXFIFO); r2 = SPI1_REG(SPI_REG_RXFIFO); @@ -138,29 +116,44 @@ static void net_handler_xchg(void) { net_state_type = ((r1 & 0xFF) >> 3); net_state_len_rx = ((r1 & 0x07) << 8); net_state_len_rx |= (r2 & 0xFF); - _eos_spi_state_len = MAX(net_state_len_tx, net_state_len_rx); - _eos_spi_state_idx_tx = 0; - _eos_spi_state_idx_rx = 0; - - // Work around esp32 bug - if (_eos_spi_state_len < 6) { - _eos_spi_state_len = 6; - } else if ((_eos_spi_state_len + 2) % 4 != 0) { - _eos_spi_state_len = ((_eos_spi_state_len + 2)/4 + 1) * 4 - 2; + len = MAX(net_state_len_tx, net_state_len_rx); + + // esp32 bug workaraund + if (len < 6) { + len = 6; + } else if ((len + 2) % 4 != 0) { + len = ((len + 2)/4 + 1) * 4 - 2; } - if (_eos_spi_state_len > EOS_NET_SIZE_BUF) { + if (len > EOS_NET_SIZE_BUF) { + net_state_flags &= ~NET_STATE_FLAG_XCHG; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; SPI1_REG(SPI_REG_IE) = 0x0; + return; } + _eos_spi_xchg_init(net_state_buf, len, 0); + SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM); + SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM; return; } - eos_spi_xchg_handler(); + 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; + } else { + eos_bufq_push(&net_buf_q, net_state_buf); + } + net_state_flags &= ~NET_STATE_FLAG_XCHG; + } } -static void net_handler_cts(void) { +static void net_handle_cts(void) { GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); net_state_flags |= NET_STATE_FLAG_CTS; @@ -169,7 +162,7 @@ static void net_handler_cts(void) { } } -static void net_handler_rts(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; @@ -181,15 +174,67 @@ static void net_handler_rts(void) { } } -static void net_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { +static void net_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { unsigned char idx = (type & ~EOS_EVT_MASK) - 1; - if (idx >= EOS_NET_MAX_MTYPE) { + if (idx < EOS_NET_MAX_MTYPE) { + net_handler[idx](type, buffer, len); + } else { eos_evtq_bad_handler(type, buffer, len); eos_net_free(buffer, 0); - return; } - _eos_net_handle(type, buffer, len, idx, evt_handler, &evt_handler_flags_buf_free, &evt_handler_flags_buf_acq); +} + +static int net_acquire(unsigned char reserved) { + int ret = 0; + + if (reserved) { + while (!ret) { + clear_csr(mstatus, MSTATUS_MIE); + if (net_state_next_buf) { + ret = 1; + net_state_next_cnt--; + } else { + asm volatile ("wfi"); + } + set_csr(mstatus, MSTATUS_MIE); + } + } else { + clear_csr(mstatus, MSTATUS_MIE); + if (net_state_next_buf == NULL) net_state_next_buf = eos_bufq_pop(&net_buf_q); + ret = (net_state_next_buf != NULL); + if (!ret) net_state_next_cnt++; + set_csr(mstatus, MSTATUS_MIE); + } + return ret; +} + +static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char idx, uint16_t flag) { + int ok; + + ok = net_acquire(net_wrapper_acq[idx] & flag); + if (ok) { + eos_evtq_get_handler(type)(type, buffer, len); + net_wrapper_acq[idx] &= ~flag; + } else { + net_wrapper_acq[idx] |= flag; + eos_evtq_push(type, buffer, len); + } +} + +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); + + if (idx < EOS_EVT_MAX_EVT) { + if (flag & net_flags_acq[idx]) { + evt_handler_wrapper(type, buffer, len, idx, flag); + } else { + eos_evtq_get_handler(type)(type, buffer, len); + } + } else { + eos_evtq_bad_handler(type, buffer, len); + } } void eos_net_init(void) { @@ -202,9 +247,10 @@ void eos_net_init(void) { } for (i=0; i> 4) - 1; + uint16_t flag = type & ~EOS_EVT_MASK ? (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1) : 0xFFFF; - if (reserved) { - while (!ret) { - clear_csr(mstatus, MSTATUS_MIE); - if (net_state_next_buf) { - ret = 1; - net_state_next_cnt--; - } else { - asm volatile ("wfi"); - } - set_csr(mstatus, MSTATUS_MIE); - } - } else { - clear_csr(mstatus, MSTATUS_MIE); - if (net_state_next_buf == NULL) net_state_next_buf = eos_bufq_pop(&net_buf_q); - ret = (net_state_next_buf != NULL); - if (!ret) net_state_next_cnt++; - set_csr(mstatus, MSTATUS_MIE); + if (idx < EOS_EVT_MAX_EVT) { + net_flags_acq[idx] &= ~flag; + if (acq) net_flags_acq[idx] |= flag; } - return ret; } void eos_net_acquire(void) { - unsigned char acq = _eos_net_acquire(0); - if (!acq) _eos_net_acquire(1); + unsigned char acq = net_acquire(0); + if (!acq) net_acquire(1); } void eos_net_release(void) { -- cgit v1.2.3