summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/net.c')
-rw-r--r--fw/fe310/eos/net.c223
1 files changed, 130 insertions, 93 deletions
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);
+}