summaryrefslogtreecommitdiff
path: root/code/fe310/eos/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'code/fe310/eos/net.c')
-rw-r--r--code/fe310/eos/net.c220
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) {