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.c226
1 files changed, 92 insertions, 134 deletions
diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c
index b8a5056..7d1803d 100644
--- a/code/fe310/eos/net.c
+++ b/code/fe310/eos/net.c
@@ -1,8 +1,5 @@
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <stdint.h>
-#include <unistd.h>
#include "encoding.h"
#include "platform.h"
@@ -10,8 +7,11 @@
#include "eos.h"
#include "msgq.h"
#include "interrupt.h"
+#include "event.h"
#include "spi.h"
+#include "spi_def.h"
+
#include "net.h"
#include "net_def.h"
@@ -31,17 +31,11 @@ static EOSMsgItem net_sndq_array[NET_SIZE_BUFQ];
static EOSNetBufQ net_buf_q;
static unsigned char net_bufq_array[NET_SIZE_BUFQ][NET_SIZE_BUF];
-extern EOSMsgQ _eos_event_q;
-
-uint32_t _eos_spi_state_len = 0;
-uint32_t _eos_spi_state_len_tx = 0;
-uint32_t _eos_spi_state_len_rx = 0;
-uint32_t _eos_spi_state_idx_tx = 0;
-uint32_t _eos_spi_state_idx_rx = 0;
-unsigned char *_eos_spi_state_buf = NULL;
-
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;
+
static uint8_t net_state_next_cnt = 0;
static unsigned char *net_state_next_buf = NULL;
@@ -49,6 +43,22 @@ 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 EOSMsgQ _eos_event_q;
+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 void net_bufq_init(void) {
+ int i;
+
+ net_buf_q.idx_r = 0;
+ net_buf_q.idx_w = NET_SIZE_BUFQ;
+ for (i=0; i<NET_SIZE_BUFQ; i++) {
+ net_buf_q.array[i] = net_bufq_array[i];
+ }
+}
+
static int net_bufq_push(unsigned char *buffer) {
net_buf_q.array[NET_BUFQ_IDX_MASK(net_buf_q.idx_w++)] = buffer;
return EOS_OK;
@@ -80,12 +90,11 @@ static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t l
if (type & EOS_NET_MTYPE_FLAG_ONEW) net_state_flags |= NET_FLAG_ONEW;
net_state_type = type;
+ net_state_len_tx = len;
+ net_state_len_rx = 0;
+
_eos_spi_state_buf = buffer;
- _eos_spi_state_len_tx = len;
- _eos_spi_state_len_rx = 0;
- _eos_spi_state_idx_tx = 0;
- _eos_spi_state_idx_rx = 0;
-
+
// before starting a transaction, set SPI peripheral to desired mode
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
@@ -96,28 +105,9 @@ static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t l
SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;
}
-static int net_xchg_next(unsigned char *_buffer) {
- unsigned char type;
- unsigned char *buffer = NULL;
- uint16_t len;
-
- eos_msgq_pop(&net_send_q, &type, &buffer, &len);
- if (type) {
- net_xchg_start(type, buffer, len);
- } else if (net_state_flags & NET_FLAG_RTS) {
- if (_buffer == NULL) _buffer = net_bufq_pop();
- if (_buffer) {
- net_xchg_start(0, _buffer, 0);
- return 0;
- }
- }
- return 1;
-}
-
-static void net_handler_xchg(void) {
+static void net_xchg_handler(void) {
volatile uint32_t r1, r2;
- int i;
-
+
if (net_state_flags & NET_FLAG_RST) {
net_state_flags &= ~NET_FLAG_RST;
@@ -133,16 +123,18 @@ static void net_handler_xchg(void) {
r1 = SPI1_REG(SPI_REG_RXFIFO);
r2 = SPI1_REG(SPI_REG_RXFIFO);
-
+
if (net_state_type & EOS_NET_MTYPE_FLAG_ONEW) {
r1 = 0;
r2 = 0;
}
net_state_type = ((r1 & 0xFF) >> 3);
- _eos_spi_state_len_rx = ((r1 & 0x07) << 8);
- _eos_spi_state_len_rx |= (r2 & 0xFF);
- _eos_spi_state_len = MAX(_eos_spi_state_len_tx, _eos_spi_state_len_rx);
+ 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) {
@@ -159,57 +151,54 @@ static void net_handler_xchg(void) {
return;
}
- uint16_t sz_chunk = MIN(_eos_spi_state_len - _eos_spi_state_idx_tx, SPI_SIZE_CHUNK);
- for (i=0; i<sz_chunk; i++) {
- volatile uint32_t x = SPI1_REG(SPI_REG_TXFIFO);
- if (x & SPI_TXFIFO_FULL) break;
- SPI1_REG(SPI_REG_TXFIFO) = _eos_spi_state_buf[_eos_spi_state_idx_tx+i];
- }
- _eos_spi_state_idx_tx += i;
-
- for (i=0; i<_eos_spi_state_idx_tx - _eos_spi_state_idx_rx; i++) {
- volatile uint32_t x = SPI1_REG(SPI_REG_RXFIFO);
- if (x & SPI_RXFIFO_EMPTY) break;
- _eos_spi_state_buf[_eos_spi_state_idx_rx+i] = x & 0xFF;
- }
- _eos_spi_state_idx_rx += i;
+ eos_spi_xchg_handler();
+}
- if (_eos_spi_state_idx_rx == _eos_spi_state_len) {
- SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
- SPI1_REG(SPI_REG_IE) = 0x0;
- if (net_state_type) {
- int r = eos_msgq_push(&_eos_event_q, EOS_EVT_NET | net_state_type, _eos_spi_state_buf, _eos_spi_state_len_rx);
- if (r) net_bufq_push(_eos_spi_state_buf);
- } else if (((net_state_flags & NET_FLAG_ONEW) || net_state_next_cnt) && (net_state_next_buf == NULL)) {
- net_state_next_buf = _eos_spi_state_buf;
- net_state_flags &= ~NET_FLAG_ONEW;
- } else {
- net_bufq_push(_eos_spi_state_buf);
+static int net_xchg_next(unsigned char *_buffer) {
+ unsigned char type;
+ unsigned char *buffer = NULL;
+ uint16_t len;
+
+ eos_msgq_pop(&net_send_q, &type, &buffer, &len);
+ if (type) {
+ net_xchg_start(type, buffer, len);
+ } else if (net_state_flags & NET_FLAG_RTS) {
+ if (_buffer == NULL) _buffer = net_bufq_pop();
+ if (_buffer) {
+ net_xchg_start(0, _buffer, 0);
+ return 0;
}
- } else if (_eos_spi_state_idx_tx == _eos_spi_state_len) {
- SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(_eos_spi_state_len - _eos_spi_state_idx_rx - 1, SPI_SIZE_WM - 1));
- SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;
+ }
+ return 1;
+}
+
+void eos_net_xchg_done(void) {
+ if (net_state_type) {
+ int r = eos_msgq_push(&_eos_event_q, EOS_EVT_NET | net_state_type, _eos_spi_state_buf, net_state_len_rx);
+ if (r) net_bufq_push(_eos_spi_state_buf);
+ } else if (((net_state_flags & NET_FLAG_ONEW) || net_state_next_cnt) && (net_state_next_buf == NULL)) {
+ net_state_next_buf = _eos_spi_state_buf;
+ net_state_flags &= ~NET_FLAG_ONEW;
+ } else {
+ net_bufq_push(_eos_spi_state_buf);
}
}
static void net_handler_cts(void) {
- GPIO_REG(GPIO_RISE_IP) = (0x1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS);
net_state_flags |= NET_FLAG_CTS;
- if (net_state_flags & NET_FLAG_RDY) {
+ if (net_state_flags & NET_FLAG_RUN) {
net_xchg_next(NULL);
- } else {
- uint32_t iof_mask = ((uint32_t)1 << NET_PIN_CS);
- GPIO_REG(GPIO_IOF_EN) &= ~iof_mask;
}
}
static void net_handler_rts(void) {
- uint32_t rts_offset = (0x1 << NET_PIN_RTS);
+ uint32_t rts_offset = (1 << NET_PIN_RTS);
if (GPIO_REG(GPIO_RISE_IP) & rts_offset) {
GPIO_REG(GPIO_RISE_IP) = rts_offset;
net_state_flags |= NET_FLAG_RTS;
- if ((net_state_flags & NET_FLAG_RDY) && (net_state_flags & NET_FLAG_CTS)) net_xchg_reset();
+ if ((net_state_flags & NET_FLAG_RUN) && (net_state_flags & NET_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_FLAG_RTS;
@@ -253,76 +242,45 @@ void eos_net_set_handler(unsigned char mtype, eos_evt_fptr_t handler, uint8_t fl
void eos_net_init(void) {
int i;
-
- net_buf_q.idx_r = 0;
- net_buf_q.idx_w = 0;
- for (i=0; i<NET_SIZE_BUFQ; i++) {
- net_bufq_push(net_bufq_array[i]);
- }
- eos_msgq_init(&net_send_q, net_sndq_array, NET_SIZE_BUFQ);
- GPIO_REG(GPIO_IOF_SEL) &= ~SPI_IOF_MASK;
- GPIO_REG(GPIO_IOF_EN) |= SPI_IOF_MASK;
- eos_intr_set(INT_SPI1_BASE, 5, net_handler_xchg);
-
- GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << NET_PIN_CTS);
- GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << NET_PIN_CTS);
- GPIO_REG(GPIO_INPUT_EN) |= (0x1 << NET_PIN_CTS);
- GPIO_REG(GPIO_RISE_IE) |= (0x1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_CTS);
eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, 4, net_handler_cts);
-
- GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << NET_PIN_RTS);
- GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << NET_PIN_RTS);
- GPIO_REG(GPIO_INPUT_EN) |= (0x1 << NET_PIN_RTS);
- GPIO_REG(GPIO_RISE_IE) |= (0x1 << NET_PIN_RTS);
- GPIO_REG(GPIO_FALL_IE) |= (0x1 << NET_PIN_RTS);
+
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << NET_PIN_RTS);
+ GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_RTS);
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_RTS);
+ 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, 4, net_handler_rts);
+ net_bufq_init();
+ eos_msgq_init(&net_send_q, net_sndq_array, NET_SIZE_BUFQ);
for (i=0; i<EOS_NET_MAX_MTYPE; i++) {
evt_handler[i] = eos_evtq_bad_handler;
}
eos_evtq_set_handler(EOS_EVT_NET, net_handler_evt);
}
-void eos_net_start(uint32_t sckdiv) {
- uint32_t iof_mask = ((uint32_t)1 << NET_PIN_CS);
-
- GPIO_REG(GPIO_IOF_SEL) &= ~iof_mask;
- GPIO_REG(GPIO_IOF_EN) |= iof_mask;
-
- SPI1_REG(SPI_REG_SCKDIV) = sckdiv;
- SPI1_REG(SPI_REG_SCKMODE) = SPI_MODE0;
- SPI1_REG(SPI_REG_FMT) = SPI_FMT_PROTO(SPI_PROTO_S) |
- SPI_FMT_ENDIAN(SPI_ENDIAN_MSB) |
- SPI_FMT_DIR(SPI_DIR_RX) |
- SPI_FMT_LEN(8);
-
- // enable CS pin for selected channel/pin
- SPI1_REG(SPI_REG_CSID) = NET_IDX_SS;
-
- // There is no way here to change the CS polarity.
- // SPI1_REG(SPI_REG_CSDEF) = 0xFFFF;
-
+void eos_net_start(void) {
+ eos_intr_set_handler(INT_SPI1_BASE, net_xchg_handler);
+ SPI1_REG(SPI_REG_SCKDIV) = SPI_DIV_NET;
+ SPI1_REG(SPI_REG_CSID) = SPI_CS_IDX_NET;
+
clear_csr(mstatus, MSTATUS_MIE);
- net_state_flags |= NET_FLAG_RDY;
+ net_state_flags |= NET_FLAG_RUN;
if (net_state_flags & NET_FLAG_CTS) net_xchg_next(NULL);
set_csr(mstatus, MSTATUS_MIE);
}
void eos_net_stop(void) {
volatile uint8_t done = 0;
-
- clear_csr(mstatus, MSTATUS_MIE);
- net_state_flags &= ~NET_FLAG_RDY;
- if (net_state_flags & NET_FLAG_CTS) {
- uint32_t iof_mask = ((uint32_t)1 << NET_PIN_CS);
- GPIO_REG(GPIO_IOF_EN) &= ~iof_mask;
- done = 1;
- }
- set_csr(mstatus, MSTATUS_MIE);
-
+
while (!done) {
clear_csr(mstatus, MSTATUS_MIE);
+ net_state_flags &= ~NET_FLAG_RUN;
done = net_state_flags & NET_FLAG_CTS;
if (!done) asm volatile ("wfi");
set_csr(mstatus, MSTATUS_MIE);
@@ -331,7 +289,7 @@ void eos_net_stop(void) {
int eos_net_acquire(unsigned char reserved) {
int ret = 0;
-
+
if (reserved) {
while (!ret) {
clear_csr(mstatus, MSTATUS_MIE);
@@ -362,7 +320,7 @@ int eos_net_release(void) {
if (!rv) net_state_next_buf = NULL;
}
set_csr(mstatus, MSTATUS_MIE);
-
+
return rv;
}
@@ -379,7 +337,7 @@ unsigned char *eos_net_alloc(void) {
}
set_csr(mstatus, MSTATUS_MIE);
}
-
+
return ret;
}
@@ -391,7 +349,7 @@ int 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_FLAG_RDY) && (net_state_flags & NET_FLAG_CTS)) do_release = net_xchg_next(buffer);
+ if ((net_state_flags & NET_FLAG_RUN) && (net_state_flags & NET_FLAG_CTS)) do_release = net_xchg_next(buffer);
if (do_release) rv = net_bufq_push(buffer);
}
set_csr(mstatus, MSTATUS_MIE);
@@ -403,10 +361,10 @@ int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len) {
int rv = EOS_OK;
clear_csr(mstatus, MSTATUS_MIE);
- if ((net_state_flags & NET_FLAG_RDY) && (net_state_flags & NET_FLAG_CTS)) {
+ if ((net_state_flags & NET_FLAG_RUN) && (net_state_flags & NET_FLAG_CTS)) {
net_xchg_start(type, buffer, len);
} else {
- rv = eos_msgq_push(&net_send_q, EOS_EVT_NET | type, buffer, len);
+ rv = eos_msgq_push(&net_send_q, type, buffer, len);
}
set_csr(mstatus, MSTATUS_MIE);