diff options
Diffstat (limited to 'code/fe310/eos/net.c')
-rw-r--r-- | code/fe310/eos/net.c | 238 |
1 files changed, 123 insertions, 115 deletions
diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c index 32b293a..0cbe9f6 100644 --- a/code/fe310/eos/net.c +++ b/code/fe310/eos/net.c @@ -11,49 +11,57 @@ #include "msgq.h" #include "interrupt.h" -#include "net.h" #include "spi.h" +#include "net.h" +#include "net_def.h" #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -#define SPI_BUFQ_IDX_MASK(IDX) ((IDX) & (SPI_SIZE_BUFQ - 1)) +#define NET_BUFQ_IDX_MASK(IDX) ((IDX) & (NET_SIZE_BUFQ - 1)) -EOSMsgQ _eos_spi_send_q; -static EOSMsgItem spi_sndq_array[SPI_SIZE_BUFQ]; +typedef struct EOSNetBufQ { + uint8_t idx_r; + uint8_t idx_w; + unsigned char *array[NET_SIZE_BUFQ]; +} EOSNetBufQ; -SPIBufQ _eos_spi_buf_q; -static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF]; +static EOSMsgQ net_send_q; +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; -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 uint8_t net_state_flags = 0; +static unsigned char net_state_type = 0; +static uint8_t net_state_next_cnt = 0; +static unsigned char *net_state_next_buf = NULL; + +static eos_evt_fptr_t evt_handler[EOS_NET_MAX_MTYPE]; static uint16_t evt_handler_flags_buf_free = 0; static uint16_t evt_handler_flags_buf_acq = 0; -static int spi_bufq_push(unsigned char *buffer) { - _eos_spi_buf_q.array[SPI_BUFQ_IDX_MASK(_eos_spi_buf_q.idx_w++)] = buffer; +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; } -static unsigned char *spi_bufq_pop(void) { - 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 unsigned char *net_bufq_pop(void) { + if (net_buf_q.idx_r == net_buf_q.idx_w) return NULL; + return net_buf_q.array[NET_BUFQ_IDX_MASK(net_buf_q.idx_r++)]; } -static void spi_xchg_reset(void) { - _eos_spi_state_flags &= ~SPI_FLAG_CTS; - _eos_spi_state_flags |= SPI_FLAG_RST; +static void net_xchg_reset(void) { + net_state_flags &= ~NET_FLAG_CTS; + net_state_flags |= NET_FLAG_RST; // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; @@ -64,14 +72,14 @@ static void spi_xchg_reset(void) { SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; } -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; +static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t len) { + net_state_flags &= ~NET_FLAG_CTS; + net_state_flags |= NET_FLAG_INIT; - 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; + 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_FLAG_ONEW; - _eos_spi_state_cmd = cmd; + net_state_type = type; _eos_spi_state_buf = buffer; _eos_spi_state_len_tx = len; _eos_spi_state_len_rx = 0; @@ -81,57 +89,57 @@ static void spi_xchg_start(unsigned char cmd, unsigned char *buffer, uint16_t le // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - SPI1_REG(SPI_REG_TXFIFO) = ((cmd << 3) | (len >> 8)) & 0xFF; + SPI1_REG(SPI_REG_TXFIFO) = ((type << 3) | (len >> 8)) & 0xFF; SPI1_REG(SPI_REG_TXFIFO) = len & 0xFF; SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(1); SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; } -static int spi_xchg_next(unsigned char *_buffer) { - unsigned char cmd; +static int net_xchg_next(unsigned char *_buffer) { + unsigned char type; unsigned char *buffer = NULL; uint16_t len; - eos_msgq_pop(&_eos_spi_send_q, &cmd, &buffer, &len); - if (cmd) { - spi_xchg_start(cmd, buffer, len); - } else if (_eos_spi_state_flags & SPI_FLAG_RTS) { - if (_buffer == NULL) _buffer = spi_bufq_pop(); + 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) { - spi_xchg_start(0, _buffer, 0); + net_xchg_start(0, _buffer, 0); return 0; } } return 1; } -static void spi_handler_xchg(void) { +static void net_handler_xchg(void) { volatile uint32_t r1, r2; int i; - if (_eos_spi_state_flags & SPI_FLAG_RST) { - _eos_spi_state_flags &= ~SPI_FLAG_RST; + if (net_state_flags & NET_FLAG_RST) { + net_state_flags &= ~NET_FLAG_RST; r1 = SPI1_REG(SPI_REG_RXFIFO); SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; SPI1_REG(SPI_REG_IE) = 0x0; return; - } else if (_eos_spi_state_flags & SPI_FLAG_INIT) { - _eos_spi_state_flags &= ~SPI_FLAG_INIT; + } else if (net_state_flags & NET_FLAG_INIT) { + net_state_flags &= ~NET_FLAG_INIT; SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM); SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM; r1 = SPI1_REG(SPI_REG_RXFIFO); r2 = SPI1_REG(SPI_REG_RXFIFO); - if (_eos_spi_state_cmd & EOS_NET_CMD_FLAG_ONEW) { + if (net_state_type & EOS_NET_MTYPE_FLAG_ONEW) { r1 = 0; r2 = 0; } - _eos_spi_state_cmd = ((r1 & 0xFF) >> 3); + 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); @@ -143,7 +151,7 @@ static void spi_handler_xchg(void) { _eos_spi_state_len = ((_eos_spi_state_len + 2)/4 + 1) * 4 - 2; } - if (_eos_spi_state_len > SPI_SIZE_BUF) { + if (_eos_spi_state_len > NET_SIZE_BUF) { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; SPI1_REG(SPI_REG_IE) = 0x0; } @@ -169,14 +177,14 @@ static void spi_handler_xchg(void) { 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 (_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; + 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 { - spi_bufq_push(_eos_spi_state_buf); + net_bufq_push(_eos_spi_state_buf); } } 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)); @@ -184,35 +192,35 @@ static void spi_handler_xchg(void) { } } -static void spi_handler_cts(void) { - GPIO_REG(GPIO_RISE_IP) = (0x1 << SPI_PIN_CTS); - _eos_spi_state_flags |= SPI_FLAG_CTS; +static void net_handler_cts(void) { + GPIO_REG(GPIO_RISE_IP) = (0x1 << NET_PIN_CTS); + net_state_flags |= NET_FLAG_CTS; - if (_eos_spi_state_flags & SPI_FLAG_RDY) { - spi_xchg_next(NULL); + if (net_state_flags & NET_FLAG_RDY) { + net_xchg_next(NULL); } else { - uint32_t iof_mask = ((uint32_t)1 << SPI_PIN_CS); + uint32_t iof_mask = ((uint32_t)1 << NET_PIN_CS); GPIO_REG(GPIO_IOF_EN) &= ~iof_mask; } } -static void spi_handler_rts(void) { - uint32_t rts_offset = (0x1 << SPI_PIN_RTS); +static void net_handler_rts(void) { + uint32_t rts_offset = (0x1 << NET_PIN_RTS); if (GPIO_REG(GPIO_RISE_IP) & rts_offset) { GPIO_REG(GPIO_RISE_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(); + net_state_flags |= NET_FLAG_RTS; + if ((net_state_flags & NET_FLAG_RDY) && (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; - _eos_spi_state_flags &= ~SPI_FLAG_RTS; + net_state_flags &= ~NET_FLAG_RTS; } } -static void net_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { - if ((cmd & ~EOS_EVT_MASK) > EOS_NET_MAX_CMD) { - eos_evtq_bad_handler(cmd, buffer, len); +static void net_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + if ((type & ~EOS_EVT_MASK) > EOS_NET_MAX_MTYPE) { + eos_evtq_bad_handler(type, buffer, len); } else { - unsigned char idx = (cmd & ~EOS_EVT_MASK) - 1; + unsigned char idx = (type & ~EOS_EVT_MASK) - 1; uint16_t buf_free = ((uint16_t)1 << idx) & evt_handler_flags_buf_free; uint16_t buf_acq = ((uint16_t)1 << idx) & evt_handler_flags_buf_acq; @@ -222,56 +230,56 @@ static void net_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) len = 0; } - evt_handler[idx](cmd, buffer, len); + evt_handler[idx](type, buffer, len); if (buf_free && buf_acq) eos_net_release(); } } -void eos_net_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags) { +void eos_net_set_handler(unsigned char type, eos_evt_fptr_t handler, uint8_t flags) { if (flags) { - uint16_t flag = (uint16_t)1 << ((cmd & ~EOS_EVT_MASK) - 1); + uint16_t flag = (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1); if (flags & EOS_NET_FLAG_BUF_FREE) evt_handler_flags_buf_free |= flag; if (flags & EOS_NET_FLAG_BUF_ACQ) evt_handler_flags_buf_acq |= flag; } - evt_handler[(cmd & ~EOS_EVT_MASK) - 1] = handler; + evt_handler[(type & ~EOS_EVT_MASK) - 1] = handler; } void eos_net_init(void) { int i; - _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]); + 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(&_eos_spi_send_q, spi_sndq_array, SPI_SIZE_BUFQ); + 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, spi_handler_xchg); + eos_intr_set(INT_SPI1_BASE, 5, net_handler_xchg); - 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_handler_cts); + 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); + eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, 4, net_handler_cts); - 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_handler_rts); - - for (i=0; i<EOS_NET_MAX_CMD; i++) { + 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); + eos_intr_set(INT_GPIO_BASE + NET_PIN_RTS, 4, net_handler_rts); + + 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, 0); + eos_evtq_set_handler(EOS_EVT_NET, net_handler_evt, 0); } void eos_net_start(uint32_t sckdiv) { - uint32_t iof_mask = ((uint32_t)1 << SPI_PIN_CS); + uint32_t iof_mask = ((uint32_t)1 << NET_PIN_CS); GPIO_REG(GPIO_IOF_SEL) &= ~iof_mask; GPIO_REG(GPIO_IOF_EN) |= iof_mask; @@ -284,14 +292,14 @@ void eos_net_start(uint32_t sckdiv) { SPI_FMT_LEN(8); // enable CS pin for selected channel/pin - SPI1_REG(SPI_REG_CSID) = SPI_IDX_SS; + SPI1_REG(SPI_REG_CSID) = NET_IDX_SS; // There is no way here to change the CS polarity. // SPI1_REG(SPI_REG_CSDEF) = 0xFFFF; clear_csr(mstatus, MSTATUS_MIE); - _eos_spi_state_flags |= SPI_FLAG_RDY; - if (_eos_spi_state_flags & SPI_FLAG_CTS) spi_xchg_next(NULL); + net_state_flags |= NET_FLAG_RDY; + if (net_state_flags & NET_FLAG_CTS) net_xchg_next(NULL); set_csr(mstatus, MSTATUS_MIE); } @@ -299,9 +307,9 @@ void eos_net_stop(void) { volatile uint8_t done = 0; clear_csr(mstatus, MSTATUS_MIE); - _eos_spi_state_flags &= ~SPI_FLAG_RDY; - if (_eos_spi_state_flags & SPI_FLAG_CTS) { - uint32_t iof_mask = ((uint32_t)1 << SPI_PIN_CS); + 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; } @@ -309,7 +317,7 @@ void eos_net_stop(void) { while (!done) { clear_csr(mstatus, MSTATUS_MIE); - done = _eos_spi_state_flags & SPI_FLAG_CTS; + done = net_state_flags & NET_FLAG_CTS; if (!done) asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); } @@ -321,9 +329,9 @@ int eos_net_acquire(unsigned char reserved) { if (reserved) { while (!ret) { clear_csr(mstatus, MSTATUS_MIE); - if (_eos_spi_state_next_buf) { + if (net_state_next_buf) { ret = 1; - _eos_spi_state_next_cnt--; + net_state_next_cnt--; } else { asm volatile ("wfi"); } @@ -331,9 +339,9 @@ int eos_net_acquire(unsigned char reserved) { } } else { clear_csr(mstatus, MSTATUS_MIE); - 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++; + if (net_state_next_buf == NULL) net_state_next_buf = net_bufq_pop(); + ret = (net_state_next_buf != NULL); + if (!ret) net_state_next_cnt++; set_csr(mstatus, MSTATUS_MIE); } return ret; @@ -343,9 +351,9 @@ int eos_net_release(void) { int rv = EOS_OK; clear_csr(mstatus, MSTATUS_MIE); - 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; + if (!net_state_next_cnt && net_state_next_buf) { + rv = net_bufq_push(net_state_next_buf); + if (!rv) net_state_next_buf = NULL; } set_csr(mstatus, MSTATUS_MIE); @@ -357,9 +365,9 @@ unsigned char *eos_net_alloc(void) { while (ret == NULL) { clear_csr(mstatus, MSTATUS_MIE); - if (_eos_spi_state_next_buf) { - ret = _eos_spi_state_next_buf; - _eos_spi_state_next_buf = NULL; + if (net_state_next_buf) { + ret = net_state_next_buf; + net_state_next_buf = NULL; } else { asm volatile ("wfi"); } @@ -374,25 +382,25 @@ int eos_net_free(unsigned char *buffer, unsigned char more) { uint8_t do_release = 1; clear_csr(mstatus, MSTATUS_MIE); - if ((more || _eos_spi_state_next_cnt) && (_eos_spi_state_next_buf == NULL)) { - _eos_spi_state_next_buf = buffer; + if ((more || net_state_next_cnt) && (net_state_next_buf == NULL)) { + net_state_next_buf = buffer; } else { - 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); + if ((net_state_flags & NET_FLAG_RDY) && (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); return rv; } -int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len) { +int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len) { int rv = EOS_OK; clear_csr(mstatus, MSTATUS_MIE); - if ((_eos_spi_state_flags & SPI_FLAG_RDY) && (_eos_spi_state_flags & SPI_FLAG_CTS)) { - spi_xchg_start(cmd, buffer, len); + if ((net_state_flags & NET_FLAG_RDY) && (net_state_flags & NET_FLAG_CTS)) { + net_xchg_start(type, buffer, len); } else { - rv = eos_msgq_push(&_eos_spi_send_q, EOS_EVT_NET | cmd, buffer, len); + rv = eos_msgq_push(&net_send_q, EOS_EVT_NET | type, buffer, len); } set_csr(mstatus, MSTATUS_MIE); |