diff options
author | Uros Majstorovic <majstor@majstor.org> | 2018-03-21 05:56:42 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2018-03-21 05:56:42 +0100 |
commit | 6c7ac8ffd4f21a159438959cb365c7caa279e149 (patch) | |
tree | 2ae80f85367be49e42cb2ccbb50d43aab56d96c7 | |
parent | 048197ad519fd3bc1d05a15a7d4fb0a87270c635 (diff) |
fixed net driver; added asm version of spi handlers
-rw-r--r-- | code/ecp/fe310/transport.c | 24 | ||||
-rw-r--r-- | code/fe310/eos/ecp.c | 2 | ||||
-rw-r--r-- | code/fe310/eos/event.c | 2 | ||||
-rw-r--r-- | code/fe310/eos/i2s.c | 2 | ||||
-rw-r--r-- | code/fe310/eos/i2s_def.h | 2 | ||||
-rw-r--r-- | code/fe310/eos/msgq_def.h | 4 | ||||
-rw-r--r-- | code/fe310/eos/net.c | 265 | ||||
-rw-r--r-- | code/fe310/eos/net.h | 12 | ||||
-rw-r--r-- | code/fe310/eos/spi.h | 31 | ||||
-rw-r--r-- | code/fe310/eos/trap_entry.S | 550 |
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: |