diff options
author | Uros Majstorovic <majstor@majstor.org> | 2020-02-19 06:47:43 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2020-02-19 06:47:43 +0100 |
commit | 6666a131ab36b1d96a854da80524d860f9a3884b (patch) | |
tree | 5039423cb8c5592c20f8dd3aec417158ac058484 /code/fe310/eos/net.c | |
parent | 15bddabc5cbe0e751fadcaaa7f7c7c36bca61331 (diff) |
eve long press/double tap/inertial scroll
spi flush bugfix
resolved dependecies: spi -> net; event -> net
renamed various handlers
Diffstat (limited to 'code/fe310/eos/net.c')
-rw-r--r-- | code/fe310/eos/net.c | 220 |
1 files changed, 111 insertions, 109 deletions
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<EOS_NET_MAX_MTYPE; i++) { - evt_handler[i] = eos_evtq_bad_handler; + net_handler[i] = eos_evtq_bad_handler; } - eos_evtq_set_handler(EOS_EVT_NET, net_handler_evt, 0); + eos_evtq_set_handler(0, evt_handler); + eos_evtq_set_handler(EOS_EVT_NET, net_handle_evt); GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_CTS); GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << NET_PIN_CTS); @@ -212,7 +258,7 @@ void eos_net_init(void) { GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << NET_PIN_CTS); GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_CTS); - eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, IRQ_PRIORITY_NET_CTS, net_handler_cts); + eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, IRQ_PRIORITY_NET_CTS, net_handle_cts); GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_RTS); GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << NET_PIN_RTS); @@ -221,13 +267,13 @@ 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_handler_rts); + eos_intr_set(INT_GPIO_BASE + NET_PIN_RTS, IRQ_PRIORITY_NET_RTS, net_handle_rts); } void eos_net_start(void) { - eos_intr_set_handler(INT_SPI1_BASE, net_handler_xchg); - SPI1_REG(SPI_REG_SCKDIV) = SPI_DIV_NET; - SPI1_REG(SPI_REG_CSID) = SPI_CS_IDX_NET; + eos_intr_set_handler(INT_SPI1_BASE, net_handle_xchg); + SPI1_REG(SPI_REG_SCKDIV) = NET_SPI_DIV; + SPI1_REG(SPI_REG_CSID) = NET_SPI_CSID; net_state_flags |= NET_STATE_FLAG_RUN; if (net_state_flags & NET_STATE_FLAG_CTS) { @@ -251,68 +297,24 @@ void eos_net_stop(void) { } } -void _eos_net_handle(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char idx, eos_evt_fptr_t handlers[], uint16_t *flags_buf_free, uint16_t *flags_buf_acq) { - uint16_t buf_free = ((uint16_t)1 << idx) & *flags_buf_free; - uint16_t buf_acq = ((uint16_t)1 << idx) & *flags_buf_acq; - - if (buf_free) { - eos_net_free(buffer, buf_acq); - buffer = NULL; - len = 0; - } - - handlers[idx](type, buffer, len); - - if (buf_free && buf_acq) eos_net_release(); -} - -void _eos_net_set_handler(unsigned char idx, eos_evt_fptr_t handler, eos_evt_fptr_t handlers[], uint8_t flags, uint16_t *flags_buf_free, uint16_t *flags_buf_acq) { - if (flags) { - uint16_t flag = (uint16_t)1 << idx; - *flags_buf_free &= ~flag; - *flags_buf_acq &= ~flag; - if (flags & EOS_NET_FLAG_BFREE) *flags_buf_free |= flag; - if (flags & EOS_NET_FLAG_BACQ) *flags_buf_acq |= flag; - } - handlers[idx] = handler; -} - -void eos_net_set_handler(unsigned char mtype, eos_evt_fptr_t handler, uint8_t flags) { - if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) { - mtype--; - } else { - return; - } - _eos_net_set_handler(mtype, handler, evt_handler, flags, &evt_handler_flags_buf_free, &evt_handler_flags_buf_acq); +void eos_net_set_handler(unsigned char mtype, eos_evt_handler_t handler) { + if (handler == NULL) handler = eos_evtq_bad_handler; + if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler; } -int _eos_net_acquire(unsigned char reserved) { - int ret = 0; +void eos_net_set_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; - 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) { |