summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code/ecp/fe310/transport.c24
-rw-r--r--code/fe310/eos/ecp.c2
-rw-r--r--code/fe310/eos/event.c2
-rw-r--r--code/fe310/eos/i2s.c2
-rw-r--r--code/fe310/eos/i2s_def.h2
-rw-r--r--code/fe310/eos/msgq_def.h4
-rw-r--r--code/fe310/eos/net.c265
-rw-r--r--code/fe310/eos/net.h12
-rw-r--r--code/fe310/eos/spi.h31
-rw-r--r--code/fe310/eos/trap_entry.S550
10 files changed, 667 insertions, 227 deletions
diff --git a/code/ecp/fe310/transport.c b/code/ecp/fe310/transport.c
index 3686e66..f728792 100644
--- a/code/ecp/fe310/transport.c
+++ b/code/ecp/fe310/transport.c
@@ -4,6 +4,8 @@
#include <eos/eos.h>
#include <eos/net.h>
+static unsigned char _flags = 0;
+
int ecp_tr_addr_eq(ECPNetAddr *addr1, ECPNetAddr *addr2) {
if (addr1->port != addr2->port) return 0;
if (memcmp(addr1->host, addr2->host, sizeof(addr1->host)) != 0) return 0;
@@ -29,11 +31,15 @@ ssize_t ecp_tr_send(int *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *a
unsigned char cmd = EOS_NET_CMD_PKT;
int rv;
+ flags |= _flags;
if (flags & ECP_SEND_FLAG_MORE) {
cmd |= EOS_NET_CMD_FLAG_ONEW;
}
if (flags & ECP_SEND_FLAG_REPLY) {
- if (packet && packet->buffer) buf = packet->buffer-addr_len;
+ if (packet && packet->buffer) {
+ buf = packet->buffer-addr_len;
+ packet->buffer = NULL;
+ }
} else {
buf = eos_net_alloc();
memcpy(buf+addr_len, packet->buffer, msg_size);
@@ -52,18 +58,18 @@ ssize_t ecp_tr_recv(int *sock, ECPBuffer *packet, ECPNetAddr *addr, int timeout)
void ecp_tr_buf_free(ECP2Buffer *b, unsigned char flags) {
size_t addr_len = ECP_IPv4_ADDR_SIZE + sizeof(uint16_t);
- if (b && b->packet && b->packet->buffer) eos_net_free(b->packet->buffer-addr_len, flags & ECP_SEND_FLAG_MORE);
+ if (b && b->packet && b->packet->buffer) {
+ eos_net_free(b->packet->buffer-addr_len, flags & ECP_SEND_FLAG_MORE);
+ b->packet->buffer = NULL;
+ }
}
void ecp_tr_buf_flag_set(ECP2Buffer *b, unsigned char flags) {
- size_t addr_len = ECP_IPv4_ADDR_SIZE + sizeof(uint16_t);
- if (flags & ECP_SEND_FLAG_MORE) {
- if (b && b->packet && b->packet->buffer) eos_net_reserve(b->packet->buffer-addr_len);
- }
+ _flags |= flags;
+ if (flags & ECP_SEND_FLAG_MORE) ecp_tr_buf_free(b, flags);
}
void ecp_tr_buf_flag_clear(ECP2Buffer *b, unsigned char flags) {
- if (flags & ECP_SEND_FLAG_MORE) {
- eos_net_release(1);
- }
+ _flags &= ~flags;
+ if (flags & ECP_SEND_FLAG_MORE) eos_net_release();
}
diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c
index 61f834a..06a3fc3 100644
--- a/code/fe310/eos/ecp.c
+++ b/code/fe310/eos/ecp.c
@@ -50,7 +50,7 @@ static void packet_handler(unsigned char cmd, unsigned char *buffer, uint16_t le
}
#endif
if (bufs.packet->buffer) eos_net_free(buffer, 0);
- eos_net_release(0);
+ eos_net_release();
}
int ecp_init(ECPContext *ctx) {
diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c
index 127e45a..f7ee4ef 100644
--- a/code/fe310/eos/event.c
+++ b/code/fe310/eos/event.c
@@ -46,7 +46,7 @@ void eos_evtq_handler_wrapper(unsigned char cmd, unsigned char *buffer, uint16_t
int ok = eos_net_acquire(*flags_acq & flag);
if (ok) {
f(cmd, buffer, len);
- eos_net_release(1);
+ eos_net_release();
*flags_acq &= ~flag;
} else {
*flags_acq |= flag;
diff --git a/code/fe310/eos/i2s.c b/code/fe310/eos/i2s.c
index b771495..8a4465c 100644
--- a/code/fe310/eos/i2s.c
+++ b/code/fe310/eos/i2s.c
@@ -119,7 +119,7 @@ void eos_i2s_init(void) {
I2S_PWM_REG_WS(PWM_COUNT) = 0;
I2S_PWM_REG_WS(PWM_CMP0) = (_eos_i2s_ck_period + 1) * 64 - 1;
I2S_PWM_REG_WS(PWM_CMP1) = (_eos_i2s_ck_period + 1) * 32;
- I2S_PWM_REG_WS(PWM_CMP2) = (_eos_i2s_ck_period + 1) * 62;
+ I2S_PWM_REG_WS(PWM_CMP2) = (_eos_i2s_ck_period + 1) * 64 - 512;
eos_intr_set(I2S_IRQ_SD_ID, 0, NULL);
eos_intr_set(I2S_IRQ_CK_ID, 0, NULL);
diff --git a/code/fe310/eos/i2s_def.h b/code/fe310/eos/i2s_def.h
index 99aabbe..0f3207e 100644
--- a/code/fe310/eos/i2s_def.h
+++ b/code/fe310/eos/i2s_def.h
@@ -24,7 +24,7 @@
#define I2S_SMPL_BITS_S 5
#define I2S_PWM_SCALE_CK 2
-#define I2S_ABUF_SIZE_CHUNK 64
+#define I2S_ABUF_SIZE_CHUNK 16
/* asm */
#define I2S_ABUF_OFF_IDXR 0
diff --git a/code/fe310/eos/msgq_def.h b/code/fe310/eos/msgq_def.h
index 683de9b..733fc39 100644
--- a/code/fe310/eos/msgq_def.h
+++ b/code/fe310/eos/msgq_def.h
@@ -4,3 +4,7 @@
#define MSGQ_OFF_SIZE 2
#define MSGQ_OFF_ARRAY 4
#define MSGQ_ITEM_SIZE 12
+
+#define MSGQ_ITEM_OFF_CMD 0
+#define MSGQ_ITEM_OFF_BUF 4
+#define MSGQ_ITEM_OFF_SIZE 8
diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c
index 58bd5fd..c0b5252 100644
--- a/code/fe310/eos/net.c
+++ b/code/fe310/eos/net.c
@@ -10,6 +10,7 @@
#include "eos.h"
#include "msgq.h"
#include "interrupt.h"
+
#include "net.h"
#include "spi.h"
@@ -17,34 +18,41 @@
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
#define SPI_BUFQ_IDX_MASK(IDX) ((IDX) & (SPI_SIZE_BUFQ - 1))
-static EOSMsgQ spi_sndq;
+EOSMsgQ _eos_spi_send_q;
static EOSMsgItem spi_sndq_array[SPI_SIZE_BUFQ];
-static eos_evt_fptr_t evt_handler[EOS_NET_MAX_CMD];
-static uint16_t evt_handler_wrapper_acq = 0;
-static uint16_t evt_handler_wrapper_en = 0;
-static SPIBufQ spi_bufq;
+SPIBufQ _eos_spi_buf_q;
static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF];
extern EOSMsgQ _eos_event_q;
+uint8_t _eos_spi_state_flags = 0;
+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_cmd = 0;
+unsigned char *_eos_spi_state_buf = NULL;
+uint8_t _eos_spi_state_next_cnt = 0;
+unsigned char *_eos_spi_state_next_buf = NULL;
+
+static eos_evt_fptr_t evt_handler[EOS_NET_MAX_CMD];
+static uint16_t evt_handler_wrapper_en = 0;
+
static int spi_bufq_push(unsigned char *buffer) {
- spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_w++)] = buffer;
+ _eos_spi_buf_q.array[SPI_BUFQ_IDX_MASK(_eos_spi_buf_q.idx_w++)] = buffer;
return EOS_OK;
}
static unsigned char *spi_bufq_pop(void) {
- if (spi_bufq.idx_r == spi_bufq.idx_w) return NULL;
- return spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_r++)];
+ if (_eos_spi_buf_q.idx_r == _eos_spi_buf_q.idx_w) return NULL;
+ return _eos_spi_buf_q.array[SPI_BUFQ_IDX_MASK(_eos_spi_buf_q.idx_r++)];
}
-static SPIState spi_state;
-
-static void spi_reset(void) {
- int i;
-
- spi_state.flags &= ~SPI_FLAG_CTS;
- spi_state.flags |= SPI_FLAG_RST;
+static void spi_xchg_reset(void) {
+ _eos_spi_state_flags &= ~SPI_FLAG_CTS;
+ _eos_spi_state_flags |= SPI_FLAG_RST;
// before starting a transaction, set SPI peripheral to desired mode
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
@@ -55,25 +63,19 @@ static void spi_reset(void) {
SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;
}
-static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) {
- spi_state.flags &= ~SPI_FLAG_CTS;
- spi_state.flags |= SPI_FLAG_INIT;
- if (spi_state.next_buf == NULL) {
- if (cmd & EOS_NET_CMD_FLAG_ONEW) {
- spi_state.flags |= SPI_FLAG_ONEW;
- } else if (spi_state.next_cnt) {
- cmd |= EOS_NET_CMD_FLAG_ONEW;
- }
- } else if (cmd & EOS_NET_CMD_FLAG_ONEW) {
- cmd &= ~EOS_NET_CMD_FLAG_ONEW;
- }
+static void spi_xchg_start(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ _eos_spi_state_flags &= ~SPI_FLAG_CTS;
+ _eos_spi_state_flags |= SPI_FLAG_INIT;
- spi_state.cmd = cmd;
- spi_state.buf = buffer;
- spi_state.len_tx = len;
- spi_state.len_rx = 0;
- spi_state.idx_tx = 0;
- spi_state.idx_rx = 0;
+ if (_eos_spi_state_next_cnt && (_eos_spi_state_next_buf == NULL)) cmd |= EOS_NET_CMD_FLAG_ONEW;
+ if (cmd & EOS_NET_CMD_FLAG_ONEW) _eos_spi_state_flags |= SPI_FLAG_ONEW;
+
+ _eos_spi_state_cmd = cmd;
+ _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;
@@ -93,13 +95,13 @@ static int spi_xchg_next(unsigned char *_buffer) {
unsigned char *buffer = NULL;
uint16_t len;
- eos_msgq_pop(&spi_sndq, &cmd, &buffer, &len);
+ eos_msgq_pop(&_eos_spi_send_q, &cmd, &buffer, &len);
if (cmd) {
- spi_xchg(cmd, buffer, len);
- } else if (spi_state.flags & SPI_FLAG_RTS) {
+ spi_xchg_start(cmd, buffer, len);
+ } else if (_eos_spi_state_flags & SPI_FLAG_RTS) {
if (_buffer == NULL) _buffer = spi_bufq_pop();
if (_buffer) {
- spi_xchg(0, _buffer, 0);
+ spi_xchg_start(0, _buffer, 0);
return 0;
}
}
@@ -110,79 +112,81 @@ static void spi_xchg_handler(void) {
volatile uint32_t r1, r2;
int i;
- if (spi_state.flags & SPI_FLAG_RST) {
+ if (_eos_spi_state_flags & SPI_FLAG_RST) {
while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
SPI1_REG(SPI_REG_IE) = 0x0;
- spi_state.flags &= ~SPI_FLAG_RST;
+ _eos_spi_state_flags &= ~SPI_FLAG_RST;
return;
- } else if (spi_state.flags & SPI_FLAG_INIT) {
+ } else if (_eos_spi_state_flags & SPI_FLAG_INIT) {
while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
while ((r2 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
- if (spi_state.cmd & EOS_NET_CMD_FLAG_ONEW) {
+ if (_eos_spi_state_cmd & EOS_NET_CMD_FLAG_ONEW) {
r1 = 0;
r2 = 0;
}
- spi_state.cmd = ((r1 & 0xFF) >> 3);
- spi_state.len_rx = ((r1 & 0x07) << 8);
- spi_state.len_rx |= (r2 & 0xFF);
- spi_state.len = MAX(spi_state.len_tx, spi_state.len_rx);
+ _eos_spi_state_cmd = ((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);
// Work around esp32 bug
- if (spi_state.len < 6) {
- spi_state.len = 6;
- } else if ((spi_state.len + 2) % 4 != 0) {
- spi_state.len = ((spi_state.len + 2)/4 + 1) * 4 - 2;
+ 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;
}
- SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_CHUNK/2);
- SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(SPI_SIZE_CHUNK - 1);
+ SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_TXWM);
+ SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(SPI_SIZE_RXWM);
SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM | SPI_IP_RXWM;
- spi_state.flags &= ~SPI_FLAG_INIT;
+ _eos_spi_state_flags &= ~SPI_FLAG_INIT;
+ return;
}
if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) {
- uint16_t sz_chunk = MIN(spi_state.len - spi_state.idx_tx, SPI_SIZE_CHUNK);
+ uint16_t sz_chunk = MIN(_eos_spi_state_len - _eos_spi_state_idx_tx, SPI_SIZE_CHUNK);
for (i=0; i<sz_chunk; i++) {
- if (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL) break;
- SPI1_REG(SPI_REG_TXFIFO) = spi_state.buf[spi_state.idx_tx+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];
}
- spi_state.idx_tx += i;
+ _eos_spi_state_idx_tx += i;
}
- for (i=0; i<spi_state.idx_tx - spi_state.idx_rx; 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;
- spi_state.buf[spi_state.idx_rx+i] = x & 0xFF;
+ _eos_spi_state_buf[_eos_spi_state_idx_rx+i] = x & 0xFF;
}
- spi_state.idx_rx += i;
+ _eos_spi_state_idx_rx += i;
- if (spi_state.idx_rx == spi_state.len) {
+ 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 (spi_state.cmd) {
- int r = eos_msgq_push(&_eos_event_q, EOS_EVT_NET | spi_state.cmd, spi_state.buf, spi_state.len_rx);
- if (r) spi_bufq_push(spi_state.buf);
- } else if ((spi_state.next_cnt || (spi_state.flags & SPI_FLAG_ONEW)) && (spi_state.next_buf == NULL)) {
- spi_state.next_buf = spi_state.buf;
- spi_state.flags &= ~SPI_FLAG_ONEW;
+ if (_eos_spi_state_cmd) {
+ int r = eos_msgq_push(&_eos_event_q, EOS_EVT_NET | _eos_spi_state_cmd, _eos_spi_state_buf, _eos_spi_state_len_rx);
+ if (r) spi_bufq_push(_eos_spi_state_buf);
+ } else if (((_eos_spi_state_flags & SPI_FLAG_ONEW) || _eos_spi_state_next_cnt) && (_eos_spi_state_next_buf == NULL)) {
+ _eos_spi_state_next_buf = _eos_spi_state_buf;
+ _eos_spi_state_flags &= ~SPI_FLAG_ONEW;
} else {
- spi_bufq_push(spi_state.buf);
+ spi_bufq_push(_eos_spi_state_buf);
}
- } else if (spi_state.idx_tx == spi_state.len) {
- SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_state.len - spi_state.idx_rx - 1, SPI_SIZE_CHUNK - 1));
+ } 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_RXWM));
SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;
}
}
static void spi_cts_hanler(void) {
- GPIO_REG(GPIO_RISE_IP) = (0x1 << SPI_GPIO_CTS_OFFSET);
- spi_state.flags |= SPI_FLAG_CTS;
+ GPIO_REG(GPIO_RISE_IP) = (0x1 << SPI_PIN_CTS);
+ _eos_spi_state_flags |= SPI_FLAG_CTS;
- if (spi_state.flags & SPI_FLAG_RDY) {
+ if (_eos_spi_state_flags & SPI_FLAG_RDY) {
spi_xchg_next(NULL);
} else {
uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2);
@@ -191,16 +195,14 @@ static void spi_cts_hanler(void) {
}
static void spi_rts_hanler(void) {
- uint32_t rts_offset = (0x1 << SPI_GPIO_RTS_OFFSET);
+ uint32_t rts_offset = (0x1 << SPI_PIN_RTS);
if (GPIO_REG(GPIO_RISE_IP) & rts_offset) {
GPIO_REG(GPIO_RISE_IP) = rts_offset;
- spi_state.flags |= SPI_FLAG_RTS;
- if ((spi_state.flags & SPI_FLAG_RDY) && (spi_state.flags & SPI_FLAG_CTS)) spi_reset();
- }
-
- if (GPIO_REG(GPIO_FALL_IP) & rts_offset) {
+ _eos_spi_state_flags |= SPI_FLAG_RTS;
+ if ((_eos_spi_state_flags & SPI_FLAG_RDY) && (_eos_spi_state_flags & SPI_FLAG_CTS)) spi_xchg_reset();
+ } else if (GPIO_REG(GPIO_FALL_IP) & rts_offset) {
GPIO_REG(GPIO_FALL_IP) = rts_offset;
- spi_state.flags &= ~SPI_FLAG_RTS;
+ _eos_spi_state_flags &= ~SPI_FLAG_RTS;
}
}
@@ -209,12 +211,17 @@ static void net_handler(unsigned char cmd, unsigned char *buffer, uint16_t len)
eos_evtq_bad_handler(cmd, buffer, len);
} else {
unsigned char idx = (cmd & ~EOS_EVT_MASK) - 1;
- uint16_t flag = (uint16_t)1 << idx;
- if (flag & evt_handler_wrapper_en) {
- eos_evtq_handler_wrapper(cmd, buffer, len, &evt_handler_wrapper_acq, flag, evt_handler[idx]);
- } else {
- evt_handler[idx](cmd, buffer, len);
+ uint16_t wrap = ((uint16_t)1 << idx) & evt_handler_wrapper_en;
+
+ if (wrap) {
+ eos_net_free(buffer, 1);
+ buffer = NULL;
+ len = 0;
}
+
+ evt_handler[idx](cmd, buffer, len);
+
+ if (wrap) eos_net_release();
}
}
@@ -222,30 +229,29 @@ static void net_handler(unsigned char cmd, unsigned char *buffer, uint16_t len)
void eos_net_init(void) {
int i;
- spi_bufq.idx_r = 0;
- spi_bufq.idx_w = 0;
+ _eos_spi_buf_q.idx_r = 0;
+ _eos_spi_buf_q.idx_w = 0;
for (i=0; i<SPI_SIZE_BUFQ; i++) {
spi_bufq_push(spi_bufq_array[i]);
}
- memset(&spi_state, 0, sizeof(spi_state));
- eos_msgq_init(&spi_sndq, spi_sndq_array, SPI_SIZE_BUFQ);
+ eos_msgq_init(&_eos_spi_send_q, spi_sndq_array, SPI_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, spi_xchg_handler);
- GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_GPIO_CTS_OFFSET);
- GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_GPIO_CTS_OFFSET);
- GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_GPIO_CTS_OFFSET);
- GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_GPIO_CTS_OFFSET);
- eos_intr_set(INT_GPIO_BASE + SPI_GPIO_CTS_OFFSET, 5, spi_cts_hanler);
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_PIN_CTS);
+ GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_PIN_CTS);
+ GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_PIN_CTS);
+ GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_PIN_CTS);
+ eos_intr_set(INT_GPIO_BASE + SPI_PIN_CTS, 4, spi_cts_hanler);
- GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_GPIO_RTS_OFFSET);
- GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_GPIO_RTS_OFFSET);
- GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_GPIO_RTS_OFFSET);
- GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_GPIO_RTS_OFFSET);
- GPIO_REG(GPIO_FALL_IE) |= (0x1 << SPI_GPIO_RTS_OFFSET);
- eos_intr_set(INT_GPIO_BASE + SPI_GPIO_RTS_OFFSET, 5, spi_rts_hanler);
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_PIN_RTS);
+ GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_PIN_RTS);
+ GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_PIN_RTS);
+ GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_PIN_RTS);
+ GPIO_REG(GPIO_FALL_IE) |= (0x1 << SPI_PIN_RTS);
+ eos_intr_set(INT_GPIO_BASE + SPI_PIN_RTS, 4, spi_rts_hanler);
for (i=0; i<EOS_NET_MAX_CMD; i++) {
evt_handler[i] = eos_evtq_bad_handler;
@@ -273,8 +279,8 @@ void eos_net_start(uint32_t sckdiv) {
// SPI1_REG(SPI_REG_CSDEF) = 0xFFFF;
clear_csr(mstatus, MSTATUS_MIE);
- spi_state.flags |= SPI_FLAG_RDY;
- if (spi_state.flags & SPI_FLAG_CTS) spi_xchg_next(NULL);
+ _eos_spi_state_flags |= SPI_FLAG_RDY;
+ if (_eos_spi_state_flags & SPI_FLAG_CTS) spi_xchg_next(NULL);
set_csr(mstatus, MSTATUS_MIE);
}
@@ -282,8 +288,8 @@ void eos_net_stop(void) {
volatile uint8_t done = 0;
clear_csr(mstatus, MSTATUS_MIE);
- spi_state.flags &= ~SPI_FLAG_RDY;
- if (spi_state.flags & SPI_FLAG_CTS) {
+ _eos_spi_state_flags &= ~SPI_FLAG_RDY;
+ if (_eos_spi_state_flags & SPI_FLAG_CTS) {
uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2);
GPIO_REG(GPIO_IOF_EN) &= ~iof_mask;
done = 1;
@@ -292,7 +298,7 @@ void eos_net_stop(void) {
while (!done) {
clear_csr(mstatus, MSTATUS_MIE);
- done = spi_state.flags & SPI_FLAG_CTS;
+ done = _eos_spi_state_flags & SPI_FLAG_CTS;
if (!done) asm volatile ("wfi");
set_csr(mstatus, MSTATUS_MIE);
}
@@ -306,29 +312,15 @@ void eos_net_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flag
evt_handler[(cmd & ~EOS_EVT_MASK) - 1] = handler;
}
-int eos_net_reserve(unsigned char *buffer) {
- int rv = EOS_OK;
-
- clear_csr(mstatus, MSTATUS_MIE);
- spi_state.next_cnt++;
- if (spi_state.next_buf == NULL) {
- spi_state.next_buf = buffer;
- } else {
- rv = spi_bufq_push(buffer);
- }
- set_csr(mstatus, MSTATUS_MIE);
-
- return rv;
-}
-
int eos_net_acquire(unsigned char reserved) {
int ret = 0;
if (reserved) {
while (!ret) {
clear_csr(mstatus, MSTATUS_MIE);
- if (spi_state.next_buf) {
+ if (_eos_spi_state_next_buf) {
ret = 1;
+ _eos_spi_state_next_cnt--;
} else {
asm volatile ("wfi");
}
@@ -336,22 +328,21 @@ int eos_net_acquire(unsigned char reserved) {
}
} else {
clear_csr(mstatus, MSTATUS_MIE);
- spi_state.next_cnt++;
- spi_state.next_buf = spi_bufq_pop();
- ret = (spi_state.next_buf != NULL);
+ if (_eos_spi_state_next_buf == NULL) _eos_spi_state_next_buf = spi_bufq_pop();
+ ret = (_eos_spi_state_next_buf != NULL);
+ if (!ret) _eos_spi_state_next_cnt++;
set_csr(mstatus, MSTATUS_MIE);
}
return ret;
}
-int eos_net_release(unsigned char reserved) {
+int eos_net_release(void) {
int rv = EOS_OK;
clear_csr(mstatus, MSTATUS_MIE);
- if (reserved) spi_state.next_cnt--;
- if (!spi_state.next_cnt && spi_state.next_buf) {
- rv = spi_bufq_push((unsigned char *)spi_state.next_buf);
- if (!rv) spi_state.next_buf = NULL;
+ if (!_eos_spi_state_next_cnt && _eos_spi_state_next_buf) {
+ rv = spi_bufq_push(_eos_spi_state_next_buf);
+ if (!rv) _eos_spi_state_next_buf = NULL;
}
set_csr(mstatus, MSTATUS_MIE);
@@ -363,9 +354,9 @@ unsigned char *eos_net_alloc(void) {
while (ret == NULL) {
clear_csr(mstatus, MSTATUS_MIE);
- if (spi_state.next_buf) {
- ret = spi_state.next_buf;
- spi_state.next_buf = NULL;
+ if (_eos_spi_state_next_buf) {
+ ret = _eos_spi_state_next_buf;
+ _eos_spi_state_next_buf = NULL;
} else {
asm volatile ("wfi");
}
@@ -380,10 +371,10 @@ int eos_net_free(unsigned char *buffer, unsigned char reserve) {
uint8_t do_release = 1;
clear_csr(mstatus, MSTATUS_MIE);
- if ((reserve || spi_state.next_cnt) && (spi_state.next_buf == NULL)) {
- spi_state.next_buf = buffer;
+ if ((reserve || _eos_spi_state_next_cnt) && (_eos_spi_state_next_buf == NULL)) {
+ _eos_spi_state_next_buf = buffer;
} else {
- if ((spi_state.flags & SPI_FLAG_RDY) && (spi_state.flags & SPI_FLAG_CTS)) do_release = spi_xchg_next(buffer);
+ if ((_eos_spi_state_flags & SPI_FLAG_RDY) && (_eos_spi_state_flags & SPI_FLAG_CTS)) do_release = spi_xchg_next(buffer);
if (do_release) rv = spi_bufq_push(buffer);
}
set_csr(mstatus, MSTATUS_MIE);
@@ -395,10 +386,10 @@ int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len) {
int rv = EOS_OK;
clear_csr(mstatus, MSTATUS_MIE);
- if ((spi_state.flags & SPI_FLAG_RDY) && (spi_state.flags & SPI_FLAG_CTS)) {
- spi_xchg(cmd, buffer, len);
+ if ((_eos_spi_state_flags & SPI_FLAG_RDY) && (_eos_spi_state_flags & SPI_FLAG_CTS)) {
+ spi_xchg_start(cmd, buffer, len);
} else {
- rv = eos_msgq_push(&spi_sndq, cmd, buffer, len);
+ rv = eos_msgq_push(&_eos_spi_send_q, cmd, buffer, len);
}
set_csr(mstatus, MSTATUS_MIE);
diff --git a/code/fe310/eos/net.h b/code/fe310/eos/net.h
index 106a204..8c15efa 100644
--- a/code/fe310/eos/net.h
+++ b/code/fe310/eos/net.h
@@ -1,22 +1,14 @@
#include <stdint.h>
#include "event.h"
-#define EOS_NET_CMD_FLAG_ONEW 0x10
-
-#define EOS_NET_CMD_CONNECT 1
-#define EOS_NET_CMD_DISCONNECT 2
-#define EOS_NET_CMD_SCAN 3
-#define EOS_NET_CMD_PKT 4
-
-#define EOS_NET_MAX_CMD 4
+#include "net_def.h"
void eos_net_init(void);
void eos_net_start(uint32_t sckdiv);
void eos_net_stop(void);
void eos_net_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags);
-int eos_net_reserve(unsigned char *buffer);
int eos_net_acquire(unsigned char reserved);
-int eos_net_release(unsigned char reserved);
+int eos_net_release(void);
unsigned char *eos_net_alloc(void);
int eos_net_free(unsigned char *buffer, unsigned char reserve_next);
int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len);
diff --git a/code/fe310/eos/spi.h b/code/fe310/eos/spi.h
index 55ff846..7cad270 100644
--- a/code/fe310/eos/spi.h
+++ b/code/fe310/eos/spi.h
@@ -3,39 +3,10 @@
#include "encoding.h"
#include "platform.h"
-#define SPI_MODE0 0x00
-#define SPI_MODE1 0x01
-#define SPI_MODE2 0x02
-#define SPI_MODE3 0x03
+#include "spi_def.h"
-#define SPI_SIZE_BUF 1500
-#define SPI_SIZE_CHUNK 4
-#define SPI_SIZE_BUFQ 2
-#define SPI_GPIO_RTS_OFFSET PIN_8_OFFSET
-#define SPI_GPIO_CTS_OFFSET PIN_7_OFFSET
#define SPI_IOF_MASK (((uint32_t)1 << IOF_SPI1_SCK) | ((uint32_t)1 << IOF_SPI1_MOSI) | ((uint32_t)1 << IOF_SPI1_MISO))
-
-#define SPI_FLAG_RDY 0x01
-#define SPI_FLAG_RST 0x02
-#define SPI_FLAG_RTS 0x04
-#define SPI_FLAG_CTS 0x08
-#define SPI_FLAG_INIT 0x10
-#define SPI_FLAG_ONEW 0x20
-
-typedef struct SPIState {
- uint8_t flags;
- uint16_t len;
- uint16_t len_tx;
- uint16_t len_rx;
- uint16_t idx_tx;
- uint16_t idx_rx;
- unsigned char cmd;
- unsigned char *buf;
- uint8_t next_cnt;
- unsigned char *next_buf;
-} SPIState;
-
typedef struct SPIBufQ {
uint8_t idx_r;
uint8_t idx_w;
diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S
index fef7d27..bf02c84 100644
--- a/code/fe310/eos/trap_entry.S
+++ b/code/fe310/eos/trap_entry.S
@@ -12,21 +12,10 @@
#define PWM0_CTRL_ADDR 0x10015000
#define PWM1_CTRL_ADDR 0x10025000
#define PWM2_CTRL_ADDR 0x10035000
-
-#define PWM_CFG 0x00
-#define PWM_COUNT 0x08
-#define PWM_CMP0 0x20
-#define PWM_CMP1 0x24
-#define PWM_CMP2 0x28
-#define PWM_CMP3 0x2C
-
-#define PWM_CFG_CMP0IP 0x10000000
-#define PWM_CFG_CMP1IP 0x20000000
-#define PWM_CFG_CMP2IP 0x40000000
-#define PWM_CFG_CMP3IP 0x80000000
+#include "sifive/devices/pwm.h"
#define GPIO_CTRL_ADDR 0x10012000
-#define GPIO_INPUT_VAL 0x00
+#include "sifive/devices/gpio.h"
#define INT_PWM0_BASE 40
#define INT_PWM1_BASE 44
@@ -45,7 +34,6 @@
.global eos_trap_entry
eos_trap_entry:
addi sp, sp, -4*REGBYTES
-
STORE x8, 0*REGBYTES(sp)
STORE x9, 1*REGBYTES(sp)
STORE x18, 2*REGBYTES(sp)
@@ -66,13 +54,37 @@ eos_trap_entry:
beq x9, x18, handler_ci
j handler
+evtq_push:
+ la x9, _eos_event_q
+ lbu x18, MSGQ_OFF_IDXR(x9)
+ lbu x19, MSGQ_OFF_IDXW(x9)
+ lbu x8, MSGQ_OFF_SIZE(x9)
+
+ sub x18, x19, x18
+ beq x18, x8, 1f
+
+ addi x8, x8, -1
+ and x8, x8, x19
+ li x18, MSGQ_ITEM_SIZE
+ mul x8, x8, x18
+ lw x18, MSGQ_OFF_ARRAY(x9)
+ add x8, x8, x18
+
+ addi x19, x19, 1
+ sb x19, MSGQ_OFF_IDXW(x9)
+ jalr x0, x20
+
+1:
+ mv x8, x0
+ jalr x0, x20
+
handler_sd:
# exit if too early
li x18, I2S_PWM_CTRL_ADDR_CK
lw x8, PWM_COUNT(x18)
lw x9, PWM_CMP2(x18)
srli x9, x9, I2S_PWM_SCALE_CK
- blt x8, x9, handler_sd_exit_
+ bltu x8, x9, handler_sd_exit_
# read mic value -> x8
li x18, GPIO_CTRL_ADDR
@@ -93,6 +105,7 @@ handler_sd:
li x18, PLIC_PRIORITY
sw x0, 4*I2S_IRQ_SD_ID(x18)
+ # store x20
addi sp, sp, -1*REGBYTES
STORE x20, 0*REGBYTES(sp)
@@ -214,7 +227,7 @@ handler_sd:
la x9, _eos_i2s_mic_buf
lhu x18, I2S_ABUF_OFF_IDXR(x9)
sub x18, x19, x18
- blt x18, x20, handler_sd_exit
+ bltu x18, x20, handler_sd_exit
la x9, _eos_i2s_mic_rd
lw x18, 0(x9)
@@ -222,26 +235,10 @@ handler_sd:
sw x0, 0(x9)
# push to event queue
- la x9, _eos_event_q
- lbu x18, MSGQ_OFF_IDXR(x9)
- lbu x19, MSGQ_OFF_IDXW(x9)
- lbu x20, MSGQ_OFF_SIZE(x9)
-
- sub x18, x19, x18
- beq x18, x20, handler_sd_exit
-
- addi x20, x20, -1
- and x20, x20, x19
- li x18, MSGQ_ITEM_SIZE
- mul x20, x20, x18
- lw x18, MSGQ_OFF_ARRAY(x9)
- add x20, x20, x18
+ jal x20, evtq_push
+ beqz x8, handler_sd_exit
li x18, (EOS_EVT_AUDIO | I2S_EVT_MIC)
- sb x18, 0(x20)
-
- addi x19, x19, 1
- sb x19, MSGQ_OFF_IDXW(x9)
- j handler_sd_exit
+ sb x18, MSGQ_ITEM_OFF_CMD(x8)
handler_sd_exit:
LOAD x20, 0*REGBYTES(sp)
@@ -289,7 +286,7 @@ handler_ci:
li x18, I2S_PWM_CTRL_ADDR_WS
lw x8, PWM_COUNT(x18)
lw x9, PWM_CMP2(x18)
- blt x8, x9, handler_ci_exit
+ bltu x8, x9, handler_ci_exit
# disable ci/enable ck irq
li x18, PLIC_PRIORITY
@@ -302,6 +299,74 @@ handler_ci:
li x19, I2S_IRQ_MASK
sw x19, 0(x18)
+ # pop from spk buf -> x8
+ la x9, _eos_i2s_spk_buf
+ lhu x18, I2S_ABUF_OFF_IDXR(x9)
+ lhu x19, I2S_ABUF_OFF_IDXW(x9)
+ beq x18, x19, handler_ci_exit
+ lhu x19, I2S_ABUF_OFF_SIZE(x9)
+
+ addi x19, x19, -1
+ and x19, x19, x18
+ lw x8, I2S_ABUF_OFF_ARRAY(x9)
+ add x19, x19, x8
+ lbu x8, 0(x19)
+
+ addi x18, x18, 1
+ sh x18, I2S_ABUF_OFF_IDXR(x9)
+
+#define UART0_CTRL_ADDR 0x10013000
+#define UART_REG_TXFIFO 0x00
+ # li x18, UART0_CTRL_ADDR
+ # sw x8, UART_REG_TXFIFO(x18)
+
+ # aLaw decode -> x8
+ xori x8, x8, 0x55
+ andi x9, x8, 0x80
+ beqz x9, 0f
+ li x9, 1
+ slli x9, x9, 7
+ not x9, x9
+ and x9, x8, x9
+ li x9, -1
+0:
+ andi x18, x8, 0xf0
+ srli x18, x18, 4
+ addi x18, x18, 4
+
+ li x19, 4
+ beq x18, x19, 1f
+
+ andi x8, x8, 0x0f
+ addi x19, x18, -4
+ sll x8, x8, x19
+
+ li x19, 1
+ sll x19, x19, x18
+ or x8, x8, x19
+
+ li x19, 1
+ addi x18, x18, -5
+ sll x19, x19, x18
+ or x8, x8, x19
+ j 2f
+1:
+ slli x8, x8, 1
+ ori x8, x8, 1
+2:
+ beqz x9, 3f
+ mul x8, x8, x9
+3:
+ # END
+ # li x18, UART0_CTRL_ADDR
+ # mv x9, x8
+ # srai x9, x9, 8
+ # andi x9, x9, 0xff
+ # sw x9, UART_REG_TXFIFO(x18)
+ # mv x9, x8
+ # andi x9, x9, 0xff
+ # sw x9, UART_REG_TXFIFO(x18)
+
handler_ci_exit:
# complete
li x18, I2S_IRQ_CI_ID
@@ -311,6 +376,417 @@ handler_ci_exit:
# exit
j trap_exit_data
+#define SPI1_CTRL_ADDR 0x10024000
+#define IOF_SPI1_SS2 9
+
+#include "sifive/devices/spi.h"
+#include "net_def.h"
+#include "spi_def.h"
+
+spi_xchg_start:
+ ori x21, x21, SPI_FLAG_INIT
+ andi x21, x21, ~SPI_FLAG_CTS
+ la x22, _eos_spi_state_next_cnt
+ lbu x23, 0(x22)
+ beqz x23, 1f
+ la x22, _eos_spi_state_next_buf
+ lw x23, 0(x22)
+ bnez x23, 1f
+ ori x9, x9, EOS_NET_CMD_FLAG_ONEW
+
+1:
+ andi x22, x9, EOS_NET_CMD_FLAG_ONEW
+ beqz x22, 2f
+ ori x21, x21, SPI_FLAG_ONEW
+2:
+ sw x21, 0(x20)
+
+ la x20, _eos_spi_state_cmd
+ sb x9, 0(x20)
+ la x20, _eos_spi_state_buf
+ sw x18, 0(x20)
+ la x20, _eos_spi_state_len_tx
+ sw x19, 0(x20)
+ la x20, _eos_spi_state_len_rx
+ sw x0, 0(x20)
+ la x20, _eos_spi_state_idx_tx
+ sw x0, 0(x20)
+ la x20, _eos_spi_state_idx_rx
+ sw x0, 0(x20)
+
+ li x20, SPI1_CTRL_ADDR
+ li x21, SPI_CSMODE_HOLD
+ sw x21, SPI_REG_CSMODE(x20)
+
+ slli x21, x9, 3
+ srli x22, x19, 8
+ or x21, x21, x22
+ andi x21, x21, 0xff
+ sw x21, SPI_REG_TXFIFO(x20)
+
+ andi x21, x19, 0xff
+ sw x21, SPI_REG_TXFIFO(x20)
+
+ li x21, 1
+ sw x21, SPI_REG_RXCTRL(x20)
+ li x21, SPI_IP_RXWM
+ sw x21, SPI_REG_IE(x20)
+ jalr x0, x8
+
+handler_spi_xchg:
+ addi sp, sp, -4*REGBYTES
+ STORE x20, 0*REGBYTES(sp)
+ STORE x21, 1*REGBYTES(sp)
+ STORE x22, 2*REGBYTES(sp)
+ STORE x23, 3*REGBYTES(sp)
+
+ li x19, SPI1_CTRL_ADDR
+ la x18, _eos_spi_state_flags
+ lbu x20, 0(x18)
+ andi x8, x20, SPI_FLAG_RST
+ beqz x8, 1f
+
+ andi x20, x20, ~SPI_FLAG_RST
+ sb x20, 0(x18)
+ lw x0, SPI_REG_RXFIFO(x19)
+ li x8, SPI_CSMODE_AUTO
+ sw x8, SPI_REG_CSMODE(x19)
+ sw x0, SPI_REG_IE(x19)
+ j handler_spi_xchg_exit
+
+1:
+ andi x8, x20, SPI_FLAG_INIT
+ beqz x8, 6f
+
+ andi x20, x20, ~SPI_FLAG_INIT
+ sb x20, 0(x18)
+ li x8, SPI_SIZE_TXWM
+ sw x8, SPI_REG_TXCTRL(x19)
+ li x8, SPI_SIZE_RXWM
+ sw x8, SPI_REG_RXCTRL(x19)
+ li x8, (SPI_IP_TXWM | SPI_IP_RXWM)
+ sw x8, SPI_REG_IE(x19)
+ lw x8, SPI_REG_RXFIFO(x19)
+ lw x9, SPI_REG_RXFIFO(x19)
+ andi x8, x8, 0xff
+ andi x9, x9, 0xff
+ la x18, _eos_spi_state_cmd
+ lbu x23, 0(x18)
+ andi x23, x23, EOS_NET_CMD_FLAG_ONEW
+ beqz x23, 2f
+ mv x8, x0
+ mv x9, x0
+
+2:
+ srli x23, x8, 3
+ sb x23, 0(x18)
+ andi x22, x8, 0x07
+ slli x22, x22, 8
+ or x22, x22, x9
+ la x18, _eos_spi_state_len_rx
+ sw x22, 0(x18)
+ la x18, _eos_spi_state_len_tx
+ lw x21, 0(x18)
+ bgeu x21, x22, 3f
+ mv x21, x22
+3:
+ li x8, 6
+ bgeu x21, x8, 4f
+ mv x21, x8
+ j 5f
+
+4:
+ addi x8, x21, 2
+ li x9, 4
+ remu x18, x8, x9
+ beqz x18, 5f
+ divu x21, x8, x9
+ addi x21, x21, 1
+ mul x21, x21, x9
+ addi x21, x21, -2
+
+5:
+ la x18, _eos_spi_state_len
+ sw x21, 0(x18)
+ j handler_spi_xchg_exit
+
+6:
+ la x18, _eos_spi_state_len
+ lw x20, 0(x18)
+ la x18, _eos_spi_state_idx_tx
+ lw x21, 0(x18)
+ la x18, _eos_spi_state_idx_rx
+ lw x22, 0(x18)
+ la x18, _eos_spi_state_buf
+ lw x23, 0(x18)
+
+ lw x8, SPI_REG_IP(x19)
+ andi x8, x8, SPI_IP_TXWM
+ beqz x8, 9f
+
+ sub x9, x20, x21
+ li x8, SPI_SIZE_CHUNK
+ bltu x8, x9, 7f
+ mv x8, x9
+7:
+ addi x8, x8, -1
+ add x9, x23, x21
+
+8:
+ bltz x8, 9f
+ lw x18, SPI_REG_TXFIFO(x19)
+ bltz x18, 9f
+ lbu x18, 0(x9)
+ sw x18, SPI_REG_TXFIFO(x19)
+ addi x8, x8, -1
+ addi x9, x9, 1
+ addi x21, x21, 1
+ j 8b
+
+9:
+ # lw x8, SPI_REG_IP(x19)
+ # andi x8, x8, SPI_IP_RXWM
+ # beqz x8, 11f
+
+ sub x8, x21, x22
+ addi x8, x8, -1
+ add x9, x23, x22
+
+10:
+ bltz x8, 11f
+ lw x18, SPI_REG_RXFIFO(x19)
+ bltz x18, 11f
+ sb x18, 0(x9)
+ addi x8, x8, -1
+ addi x9, x9, 1
+ addi x22, x22, 1
+ j 10b
+
+11:
+ la x18, _eos_spi_state_idx_tx
+ sw x21, 0(x18)
+ la x18, _eos_spi_state_idx_rx
+ sw x22, 0(x18)
+
+ bne x22, x20, 15f
+ li x8, SPI_CSMODE_AUTO
+ sw x8, SPI_REG_CSMODE(x19)
+ sw x0, SPI_REG_IE(x19)
+ la x18, _eos_spi_state_cmd
+ lbu x21, 0(x18)
+ beqz x21, 12f
+
+ # push to event queue
+ jal x20, evtq_push
+ beqz x8, 14f
+ ori x21, x21, EOS_EVT_NET
+ sb x21, MSGQ_ITEM_OFF_CMD(x8)
+ sw x23, MSGQ_ITEM_OFF_BUF(x8)
+ la x18, _eos_spi_state_len_rx
+ lw x22, 0(x18)
+ sh x22, MSGQ_ITEM_OFF_SIZE(x8)
+ j handler_spi_xchg_exit
+
+12:
+ la x18, _eos_spi_state_flags
+ lbu x8, 0(x18)
+ andi x19, x8, SPI_FLAG_ONEW
+ bnez x19, 13f
+ la x19, _eos_spi_state_next_cnt
+ lbu x9, 0(x19)
+ beqz x9, 14f
+13:
+ bnez x23, 14f
+ la x19, _eos_spi_state_next_buf
+ sw x23, 0(x19)
+ andi x8, x8, ~SPI_FLAG_ONEW
+ sb x8, 0(x18)
+
+ j handler_spi_xchg_exit
+
+14:
+ # push spi bufq
+ la x19, _eos_spi_buf_q
+ lbu x8, SPI_BUFQ_OFF_IDXW(x19)
+
+ andi x9, x8, SPI_SIZE_BUFQ - 1
+ slli x9, x9, 2
+ add x9, x19, x9
+ sw x23, SPI_BUFQ_OFF_ARRAY(x9)
+
+ addi x8, x8, 1
+ sb x8, SPI_BUFQ_OFF_IDXW(x19)
+
+ j handler_spi_xchg_exit
+
+15:
+ bne x21, x20, handler_spi_xchg_exit
+ sub x8, x20, x22
+ addi x8, x8, -1
+ li x9, SPI_SIZE_RXWM
+ bltu x8, x9, 16f
+ mv x8, x9
+16:
+ sw x8, SPI_REG_RXCTRL(x19)
+ li x9, SPI_IP_RXWM
+ sw x9, SPI_REG_IE(x19)
+
+handler_spi_xchg_exit:
+ LOAD x20, 0*REGBYTES(sp)
+ LOAD x21, 1*REGBYTES(sp)
+ LOAD x22, 2*REGBYTES(sp)
+ LOAD x23, 3*REGBYTES(sp)
+ addi sp, sp, 4*REGBYTES
+
+ # XXX should complete!
+ # li x18, I2S_IRQ_SD_ID
+ # li x19, PLIC_CLAIM
+ # sw x18, 0(x19)
+
+ # exit
+ j trap_exit_data
+
+handler_spi_cts:
+ addi sp, sp, -4*REGBYTES
+ STORE x20, 0*REGBYTES(sp)
+ STORE x21, 1*REGBYTES(sp)
+ STORE x22, 2*REGBYTES(sp)
+ STORE x23, 3*REGBYTES(sp)
+
+ li x8, 1
+ slli x8, x8, SPI_PIN_CTS
+ li x19, GPIO_CTRL_ADDR
+ sw x8, GPIO_RISE_IP(x19)
+
+ la x20, _eos_spi_state_flags
+ lw x21, 0(x20)
+ ori x21, x21, SPI_FLAG_CTS
+ sw x21, 0(x20)
+ andi x9, x21, SPI_FLAG_RDY
+ beqz x9, 2f
+
+ # pop from send q
+ la x9, _eos_spi_send_q
+ lbu x18, MSGQ_OFF_IDXR(x9)
+ lbu x19, MSGQ_OFF_IDXW(x9)
+ beq x18, x19, 1f
+ lbu x8, MSGQ_OFF_SIZE(x9)
+
+ addi x8, x8, -1
+ and x8, x8, x18
+ li x19, MSGQ_ITEM_SIZE
+ mul x8, x8, x19
+ lw x19, MSGQ_OFF_ARRAY(x9)
+ add x8, x19, x8
+ addi x18, x18, 1
+ sb x18, MSGQ_OFF_IDXR(x9)
+
+ lbu x9, MSGQ_ITEM_OFF_CMD(x8)
+ lw x18, MSGQ_ITEM_OFF_BUF(x8)
+ lhu x19, MSGQ_ITEM_OFF_SIZE(x8)
+ beqz x9, 1f
+ beqz x18, 1f
+ beqz x19, 1f
+ jal x8, spi_xchg_start
+
+ j handler_spi_cts_exit
+
+1:
+ la x9, _eos_spi_buf_q
+ lbu x18, SPI_BUFQ_OFF_IDXR(x9)
+ lbu x19, SPI_BUFQ_OFF_IDXW(x9)
+ beq x18, x19, handler_spi_cts_exit
+
+ andi x8, x18, SPI_SIZE_BUFQ - 1
+ slli x8, x8, 2
+ add x8, x9, x8
+ addi x18, x18, 1
+ sb x18, SPI_BUFQ_OFF_IDXW(x9)
+ mv x9, x0
+ lw x18, SPI_BUFQ_OFF_ARRAY(x8)
+ mv x19, x0
+ beqz x18, handler_spi_cts_exit
+ jal x8, spi_xchg_start
+
+ j handler_spi_cts_exit
+
+2:
+ lw x8, GPIO_IOF_EN(x19)
+ li x9, 1
+ slli x9, x9, IOF_SPI1_SS2
+ not x9, x9
+ and x8, x8, x9
+ sw x8, GPIO_IOF_EN(x19)
+
+handler_spi_cts_exit:
+ LOAD x20, 0*REGBYTES(sp)
+ LOAD x21, 1*REGBYTES(sp)
+ LOAD x22, 2*REGBYTES(sp)
+ LOAD x23, 3*REGBYTES(sp)
+ addi sp, sp, 4*REGBYTES
+
+ # XXX should complete!
+ # li x18, I2S_IRQ_SD_ID
+ # li x19, PLIC_CLAIM
+ # sw x18, 0(x19)
+
+ # exit
+ j trap_exit_data
+
+handler_spi_rts:
+ li x8, 1
+ slli x8, x8, SPI_PIN_RTS
+ li x18, GPIO_CTRL_ADDR
+ la x19, _eos_spi_state_flags
+
+ lw x9, GPIO_RISE_IP(x18)
+ and x9, x9, x8
+ beqz x9, 1f
+
+ sw x8, GPIO_RISE_IP(x18)
+ lbu x8, 0(x19)
+ ori x8, x8, SPI_FLAG_RTS
+ sb x8, 0(x19)
+
+ andi x9, x8, SPI_FLAG_RDY
+ beqz x9, handler_spi_rts_exit
+ andi x9, x8, SPI_FLAG_CTS
+ beqz x9, handler_spi_rts_exit
+
+ andi x8, x8, ~SPI_FLAG_CTS
+ ori x8, x8, SPI_FLAG_RST
+ sb x8, 0(x19)
+
+ li x19, SPI1_CTRL_ADDR
+ li x8, SPI_CSMODE_HOLD
+ sw x8, SPI_REG_CSMODE(x19)
+ sw x0, SPI_REG_TXFIFO(x19)
+ sw x0, SPI_REG_RXCTRL(x19)
+ li x8, SPI_IP_RXWM
+ sw x8, SPI_REG_IE(x19)
+
+ j handler_spi_rts_exit
+
+1:
+ lw x9, GPIO_FALL_IP(x18)
+ and x9, x9, x8
+ beqz x9, handler_spi_rts_exit
+
+ sw x8, GPIO_FALL_IP(x18)
+ lbu x8, 0(x18)
+ andi x8, x8, ~SPI_FLAG_RTS
+ sb x8, 0(x19)
+
+handler_spi_rts_exit:
+ # XXX should complete!
+ # li x18, I2S_IRQ_SD_ID
+ # li x19, PLIC_CLAIM
+ # sw x18, 0(x19)
+
+ # exit
+ j trap_exit_data
+
+
trap_exit_data:
# Remain in M-mode after mret
li x18, MSTATUS_MPP
@@ -320,8 +796,8 @@ trap_exit_data:
LOAD x9, 1*REGBYTES(sp)
LOAD x18, 2*REGBYTES(sp)
LOAD x19, 3*REGBYTES(sp)
-
addi sp, sp, 4*REGBYTES
+
mret
handler: