diff options
author | Uros Majstorovic <majstor@majstor.org> | 2018-03-14 18:31:22 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2018-03-14 18:31:22 +0100 |
commit | 4b655364d426f8429b063d9746c754beca6f7d1f (patch) | |
tree | 73afa86876733d81cf0fc331643cb0a6cd036e5e | |
parent | 7e209672e005b911166f27b691acfc6c988e93fb (diff) |
fixed concerning new asm trap entry
-rw-r--r-- | code/fe310/eos/Makefile | 12 | ||||
-rw-r--r-- | code/fe310/eos/ecp.c | 22 | ||||
-rw-r--r-- | code/fe310/eos/eos.h | 1 | ||||
-rw-r--r-- | code/fe310/eos/event.c | 82 | ||||
-rw-r--r-- | code/fe310/eos/event.h | 16 | ||||
-rw-r--r-- | code/fe310/eos/interrupt.c | 33 | ||||
-rw-r--r-- | code/fe310/eos/interrupt.h | 6 | ||||
-rw-r--r-- | code/fe310/eos/net.c | 240 | ||||
-rw-r--r-- | code/fe310/eos/net.h | 4 | ||||
-rw-r--r-- | code/fe310/eos/spi.h | 22 | ||||
-rw-r--r-- | code/fe310/eos/timer.c | 21 |
11 files changed, 269 insertions, 190 deletions
diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile index 573bca7..43313fd 100644 --- a/code/fe310/eos/Makefile +++ b/code/fe310/eos/Makefile @@ -1,11 +1,11 @@ -FE310_HOME=/opt/my/freedom-e-sdk +FE310_HOME = /opt/my/freedom-e-sdk -CC=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc -AR=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-ar +CC = $(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc +AR = $(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-ar -CFLAGS=-O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../.. - -obj = msgq.o event.o interrupt.o timer.o net.o eos.o ecp.o +CFLAGS = -O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../.. + +obj = eos.o msgq.o event.o interrupt.o timer.o net.o ecp.o %.o: %.c %.h diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c index b50e0d7..9301555 100644 --- a/code/fe310/eos/ecp.c +++ b/code/fe310/eos/ecp.c @@ -12,20 +12,11 @@ static ECPSocket *_sock = NULL; -static unsigned char net_buf_reserved = 0; static void timer_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { - int ok = eos_net_acquire(net_buf_reserved); - if (ok) { - ecp_cts_t next = ecp_timer_exe(_sock); - if (next) { - uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; - eos_timer_set(tick, 1); - } - eos_net_release(1); - net_buf_reserved = 0; - } else { - net_buf_reserved = 1; - eos_evtq_push(EOS_EVT_TIMER, NULL, 0); + ecp_cts_t next = ecp_timer_exe(_sock); + if (next) { + uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; + eos_timer_set(tick, 1); } } @@ -60,9 +51,8 @@ int ecp_init(ECPContext *ctx) { rv = ecp_ctx_create_vconn(ctx); if (rv) return rv; - eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler); - eos_evtq_set_handler(EOS_EVT_MASK_NET | EOS_NET_CMD_PKT, packet_handler); - + eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler, EOS_EVT_FLAG_WRAP); + eos_net_set_handler(EOS_NET_CMD_PKT, packet_handler, 0); return ECP_OK; } diff --git a/code/fe310/eos/eos.h b/code/fe310/eos/eos.h index 938030e..8ca73e5 100644 --- a/code/fe310/eos/eos.h +++ b/code/fe310/eos/eos.h @@ -1,5 +1,6 @@ #define EOS_OK 0 #define EOS_ERR_Q_FULL -10 +#define EOS_ERR_Q_EMPTY -11 void eos_init(void); void eos_start(void); diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c index 25f1fa1..a1cf591 100644 --- a/code/fe310/eos/event.c +++ b/code/fe310/eos/event.c @@ -1,56 +1,65 @@ +#include <stdint.h> #include <stdio.h> +#include <unistd.h> #include "encoding.h" #include "platform.h" -#include "eos.h" -#include "msgq.h" #include "net.h" -#include "timer.h" +#include "msgq.h" #include "event.h" -static EOSMsgQ event_q; +EOSMsgQ _eos_event_q; static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q]; -static eos_evt_fptr_t evt_net_handler[EOS_NET_MAX_CMD]; -static eos_evt_fptr_t evt_timer_handler = NULL; -static eos_evt_fptr_t evt_ui_handler = NULL; - -static void bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { - printf("bad handler: %d\n", cmd); -} +static eos_evt_fptr_t evt_handler[EOS_EVT_MAX_EVT]; +static uint16_t evt_handler_wrapper_acq = 0; +static uint16_t evt_handler_wrapper_en = 0; void eos_evtq_init(void) { int i; - for (i=0; i<EOS_NET_MAX_CMD; i++) { - evt_net_handler[i] = bad_handler; + for (i=0; i<EOS_EVT_MAX_EVT; i++) { + evt_handler[i] = eos_evtq_bad_handler; } - evt_timer_handler = bad_handler; - evt_ui_handler = bad_handler; - eos_msgq_init(&event_q, event_q_array, EOS_EVT_SIZE_Q); + eos_msgq_init(&_eos_event_q, event_q_array, EOS_EVT_SIZE_Q); } int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len) { - return eos_msgq_push(&event_q, cmd, buffer, len); + return eos_msgq_push(&_eos_event_q, cmd, buffer, len); } void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len) { - eos_msgq_pop(&event_q, cmd, buffer, len); + eos_msgq_pop(&_eos_event_q, cmd, buffer, len); +} + +void eos_evtq_bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { + write(1, "error\n", 6); +} + +void eos_evtq_handler_wrapper(unsigned char cmd, unsigned char *buffer, uint16_t len, uint16_t *flags_acq, uint16_t flag, eos_evt_fptr_t f) { + int ok = eos_net_acquire(*flags_acq & flag); + if (ok) { + f(cmd, buffer, len); + eos_net_release(1); + *flags_acq &= ~flag; + } else { + *flags_acq |= flag; + eos_evtq_push(cmd, buffer, len); + } } void eos_evtq_handle(unsigned char cmd, unsigned char *buffer, uint16_t len) { - if (cmd & EOS_EVT_MASK_NET) { - cmd &= ~EOS_EVT_MASK_NET; - if (cmd < EOS_NET_MAX_CMD) { - evt_net_handler[cmd](cmd, buffer, len); + if (((cmd & EOS_EVT_MASK) >> 4) > EOS_EVT_MAX_EVT) { + eos_evtq_bad_handler(cmd, buffer, len); + } else { + unsigned char idx = ((cmd & EOS_EVT_MASK) >> 4) - 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 { - bad_handler(cmd, buffer, len); + evt_handler[idx](cmd, buffer, len); } - } else if (cmd == EOS_EVT_TIMER) { - evt_timer_handler(cmd, buffer, len); - } else if (cmd == EOS_EVT_UI) { - evt_ui_handler(cmd, buffer, len); } } @@ -58,7 +67,7 @@ void eos_evtq_loop(void) { unsigned char cmd; unsigned char *buffer; uint16_t len; - volatile int foo = 1; + int foo = 1; while(foo) { clear_csr(mstatus, MSTATUS_MIE); @@ -68,18 +77,17 @@ void eos_evtq_loop(void) { eos_evtq_handle(cmd, buffer, len); clear_csr(mstatus, MSTATUS_MIE); } else { - // asm volatile ("wfi"); + asm volatile ("wfi"); } set_csr(mstatus, MSTATUS_MIE); } } -void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler) { - if (cmd & EOS_EVT_MASK_NET) { - evt_net_handler[cmd & ~EOS_EVT_MASK_NET] = handler; - } else if (cmd == EOS_EVT_TIMER) { - evt_timer_handler = handler; - } else if (cmd == EOS_EVT_UI) { - evt_ui_handler = handler; +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags) { + if (flags & EOS_EVT_FLAG_WRAP) { + uint16_t flag = (uint16_t)1 << (((cmd & EOS_EVT_MASK) >> 4) - 1); + evt_handler_wrapper_en |= flag; } -}
\ No newline at end of file + evt_handler[((cmd & EOS_EVT_MASK) >> 4) - 1] = handler; +} + diff --git a/code/fe310/eos/event.h b/code/fe310/eos/event.h index 21079b4..ce71c0b 100644 --- a/code/fe310/eos/event.h +++ b/code/fe310/eos/event.h @@ -1,9 +1,15 @@ #include <stdint.h> -#define EOS_EVT_MASK_NET 0x80 -#define EOS_EVT_TIMER 0x01 -#define EOS_EVT_UI 0x02 +#define EOS_EVT_FLAG_WRAP 0x1 +#define EOS_EVT_NET 0x10 +#define EOS_EVT_TIMER 0x20 +#define EOS_EVT_AUDIO 0x30 +#define EOS_EVT_UI 0x40 + +#define EOS_EVT_MASK 0xF0 + +#define EOS_EVT_MAX_EVT 4 #define EOS_EVT_SIZE_Q 4 typedef void (*eos_evt_fptr_t) (unsigned char, unsigned char *, uint16_t); @@ -11,6 +17,8 @@ typedef void (*eos_evt_fptr_t) (unsigned char, unsigned char *, uint16_t); void eos_evtq_init(void); int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len); void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len); +void eos_evtq_bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_evtq_handler_wrapper(unsigned char cmd, unsigned char *buffer, uint16_t len, uint16_t *flags_acq, uint16_t flag, eos_evt_fptr_t f); void eos_evtq_handle(unsigned char cmd, unsigned char *buffer, uint16_t len); void eos_evtq_loop(void); -void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler);
\ No newline at end of file +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags); diff --git a/code/fe310/eos/interrupt.c b/code/fe310/eos/interrupt.c index def1a24..77ab6d5 100644 --- a/code/fe310/eos/interrupt.c +++ b/code/fe310/eos/interrupt.c @@ -1,6 +1,4 @@ -#include <stdio.h> #include <stdlib.h> -#include <string.h> #include <stdint.h> #include <unistd.h> @@ -15,15 +13,16 @@ static plic_instance_t plic; static eos_intr_fptr_t ext_interrupt_handler[PLIC_NUM_INTERRUPTS]; -void handle_m_ext_interrupt(void) { - plic_source int_num = PLIC_claim_interrupt(&plic); - if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num])) { +uintptr_t eos_intr_handle(uintptr_t int_num) { + // plic_source int_num = PLIC_claim_interrupt(&plic); + if ((int_num >=1) && (int_num < PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num])) { ext_interrupt_handler[int_num](); } else { - printf("handle_m_ext_interrupt error\n\n"); - exit(1 + (uintptr_t) int_num); + write(1, "error\n", 6); + exit(int_num); } - PLIC_complete_interrupt(&plic, int_num); + // PLIC_complete_interrupt(&plic, int_num); + return int_num; } void eos_intr_init(void) { @@ -46,8 +45,24 @@ void eos_intr_init(void) { set_csr(mstatus, MSTATUS_MIE); } -void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) { +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) { ext_interrupt_handler[int_num] = handler; + PLIC_set_priority(&plic, int_num, priority); PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_set_priority(uint8_t int_num, uint8_t priority) { PLIC_set_priority(&plic, int_num, priority); } + +void eos_intr_enable(uint8_t int_num) { + PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_disable(uint8_t int_num) { + PLIC_disable_interrupt(&plic, int_num); +} + +void eos_intr_mask(uint8_t priority) { + PLIC_set_threshold(&plic, priority); +} diff --git a/code/fe310/eos/interrupt.h b/code/fe310/eos/interrupt.h index 7ef81b8..3ccfb21 100644 --- a/code/fe310/eos/interrupt.h +++ b/code/fe310/eos/interrupt.h @@ -5,4 +5,8 @@ typedef void (*eos_intr_fptr_t) (void); void eos_intr_init(void); -void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler); +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler); +void eos_intr_set_priority(uint8_t int_num, uint8_t priority); +void eos_intr_enable(uint8_t int_num); +void eos_intr_disable(uint8_t int_num); +void eos_intr_mask(uint8_t priority);
\ No newline at end of file diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c index 080da72..4588485 100644 --- a/code/fe310/eos/net.c +++ b/code/fe310/eos/net.c @@ -10,7 +10,6 @@ #include "eos.h" #include "msgq.h" -#include "event.h" #include "interrupt.h" #include "net.h" #include "spi.h" @@ -19,18 +18,18 @@ #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) #define SPI_BUFQ_IDX_MASK(IDX) ((IDX) & (SPI_SIZE_BUFQ - 1)) -static volatile uint8_t spi_res = 0; -static volatile uint8_t spi_res_next = 0; -static volatile unsigned char *spi_res_buf = NULL; - static EOSMsgQ spi_sndq; 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; static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF]; static int spi_bufq_push(unsigned char *buffer) { spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_w++)] = buffer; + return EOS_OK; } static unsigned char *spi_bufq_pop(void) { @@ -38,45 +37,43 @@ static unsigned char *spi_bufq_pop(void) { return spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_r++)]; } -static volatile uint8_t spi_rdy = 0; -static volatile uint8_t spi_cts = 0; -static volatile uint8_t spi_rts = 0; -static SPIBuffer spi_buffer; +static SPIState spi_state; static void spi_reset(void) { int i; - volatile uint32_t r; - spi_cts = 0; + spi_state.flags &= ~SPI_FLAG_CTS; + spi_state.flags |= SPI_FLAG_RST; // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); SPI1_REG(SPI_REG_TXFIFO) = 0; - while ((r = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; + SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(0); + SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; } static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) { - volatile uint32_t r1, r2; - - spi_cts = 0; - spi_buffer.buffer = buffer; - spi_buffer.len_rx = 0; - spi_buffer.idx_tx = 0; - spi_buffer.idx_rx = 0; - - if (spi_res_buf == NULL) { + 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_res_next = 1; - } else if (spi_res) { + 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; } + 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; + // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; @@ -86,30 +83,8 @@ static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) { while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); SPI1_REG(SPI_REG_TXFIFO) = len & 0xFF; - while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - while ((r2 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - - if (cmd & EOS_NET_CMD_FLAG_ONEW) { - r1 = 0; - r2 = 0; - } - - spi_buffer.cmd = ((r1 & 0xFF) >> 3); - spi_buffer.len_rx = ((r1 & 0x07) << 8); - - spi_buffer.len_rx |= (r2 & 0xFF); - spi_buffer.len = MAX(len, spi_buffer.len_rx); - - // Work around esp32 bug - if (spi_buffer.len < 6) { - spi_buffer.len = 6; - } else if ((spi_buffer.len + 2) % 4 != 0) { - spi_buffer.len = ((spi_buffer.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_IE) = SPI_IP_TXWM | SPI_IP_RXWM; + SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(1); + SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; } static int spi_xchg_next(unsigned char *_buffer) { @@ -120,7 +95,7 @@ static int spi_xchg_next(unsigned char *_buffer) { eos_msgq_pop(&spi_sndq, &cmd, &buffer, &len); if (cmd) { spi_xchg(cmd, buffer, len); - } else if (spi_rts) { + } else if (spi_state.flags & SPI_FLAG_RTS) { if (_buffer == NULL) _buffer = spi_bufq_pop(); if (_buffer) { spi_xchg(0, _buffer, 0); @@ -131,47 +106,82 @@ static int spi_xchg_next(unsigned char *_buffer) { } static void spi_xchg_handler(void) { + volatile uint32_t r1, r2; int i; + if (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; + + return; + } else if (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) { + 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); + + // 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; + } + + 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_IE) = SPI_IP_TXWM | SPI_IP_RXWM; + spi_state.flags &= ~SPI_FLAG_INIT; + } + if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) { - uint16_t sz_chunk = MIN(spi_buffer.len - spi_buffer.idx_tx, SPI_SIZE_CHUNK); + uint16_t sz_chunk = MIN(spi_state.len - 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_buffer.buffer[spi_buffer.idx_tx+i]; + SPI1_REG(SPI_REG_TXFIFO) = spi_state.buf[spi_state.idx_tx+i]; } - spi_buffer.idx_tx += i; + spi_state.idx_tx += i; } - for (i=0; i<spi_buffer.idx_tx - spi_buffer.idx_rx; i++) { + for (i=0; i<spi_state.idx_tx - spi_state.idx_rx; i++) { volatile uint32_t x = SPI1_REG(SPI_REG_RXFIFO); if (x & SPI_RXFIFO_EMPTY) break; - spi_buffer.buffer[spi_buffer.idx_rx+i] = x & 0xFF; + spi_state.buf[spi_state.idx_rx+i] = x & 0xFF; } - spi_buffer.idx_rx += i; + spi_state.idx_rx += i; - if (spi_buffer.idx_rx == spi_buffer.len) { + if (spi_state.idx_rx == spi_state.len) { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; SPI1_REG(SPI_REG_IE) = 0x0; - if (spi_buffer.cmd) { - int r = eos_evtq_push(spi_buffer.cmd | EOS_EVT_MASK_NET, spi_buffer.buffer, spi_buffer.len_rx); - if (r) spi_bufq_push(spi_buffer.buffer); - } else if ((spi_res || spi_res_next) && (spi_res_buf == NULL)) { - spi_res_buf = spi_buffer.buffer; - spi_res_next = 0; + if (spi_state.cmd) { + int r = eos_evtq_push(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; } else { - spi_bufq_push(spi_buffer.buffer); + spi_bufq_push(spi_state.buf); } - } else if (spi_buffer.idx_tx == spi_buffer.len) { - SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_buffer.len - spi_buffer.idx_rx - 1, SPI_SIZE_CHUNK - 1)); + } 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)); 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_cts = 1; + spi_state.flags |= SPI_FLAG_CTS; - if (spi_rdy) { + if (spi_state.flags & SPI_FLAG_RDY) { spi_xchg_next(NULL); } else { uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2); @@ -183,16 +193,31 @@ static void spi_rts_hanler(void) { uint32_t rts_offset = (0x1 << SPI_GPIO_RTS_OFFSET); if (GPIO_REG(GPIO_RISE_IP) & rts_offset) { GPIO_REG(GPIO_RISE_IP) = rts_offset; - spi_rts = 1; - if (spi_rdy && spi_cts) spi_reset(); + 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) { GPIO_REG(GPIO_FALL_IP) = rts_offset; - spi_rts = 0; + spi_state.flags &= ~SPI_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); + } 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); + } } } + void eos_net_init(void) { int i; @@ -201,23 +226,30 @@ void eos_net_init(void) { 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); GPIO_REG(GPIO_IOF_SEL) &= ~SPI_IOF_MASK; GPIO_REG(GPIO_IOF_EN) |= SPI_IOF_MASK; - eos_intr_set_handler(INT_SPI1_BASE, 5, spi_xchg_handler); + 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_handler(INT_GPIO_BASE + SPI_GPIO_CTS_OFFSET, 5, spi_cts_hanler); - + eos_intr_set(INT_GPIO_BASE + SPI_GPIO_CTS_OFFSET, 5, 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_handler(INT_GPIO_BASE + SPI_GPIO_RTS_OFFSET, 5, spi_rts_hanler); + eos_intr_set(INT_GPIO_BASE + SPI_GPIO_RTS_OFFSET, 5, spi_rts_hanler); + + for (i=0; i<EOS_NET_MAX_CMD; i++) { + evt_handler[i] = eos_evtq_bad_handler; + } + eos_evtq_set_handler(EOS_EVT_NET, net_handler, 0); } void eos_net_start(uint32_t sckdiv) { @@ -240,8 +272,8 @@ void eos_net_start(uint32_t sckdiv) { // SPI1_REG(SPI_REG_CSDEF) = 0xFFFF; clear_csr(mstatus, MSTATUS_MIE); - spi_rdy = 1; - if (spi_cts) spi_xchg_next(NULL); + spi_state.flags |= SPI_FLAG_RDY; + if (spi_state.flags & SPI_FLAG_CTS) spi_xchg_next(NULL); set_csr(mstatus, MSTATUS_MIE); } @@ -249,8 +281,8 @@ void eos_net_stop(void) { volatile uint8_t done = 0; clear_csr(mstatus, MSTATUS_MIE); - spi_rdy = 0; - if (spi_cts) { + spi_state.flags &= ~SPI_FLAG_RDY; + if (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; @@ -259,19 +291,27 @@ void eos_net_stop(void) { while (!done) { clear_csr(mstatus, MSTATUS_MIE); - done = spi_cts; + done = spi_state.flags & SPI_FLAG_CTS; if (!done) asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); } } +void eos_net_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags) { + if (flags & EOS_EVT_FLAG_WRAP) { + uint16_t flag = (uint16_t)1 << ((cmd & ~EOS_EVT_MASK) - 1); + evt_handler_wrapper_en |= 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_res++; - if (spi_res_buf == NULL) { - spi_res_buf = buffer; + spi_state.next_cnt++; + if (spi_state.next_buf == NULL) { + spi_state.next_buf = buffer; } else { rv = spi_bufq_push(buffer); } @@ -286,7 +326,7 @@ int eos_net_acquire(unsigned char reserved) { if (reserved) { while (!ret) { clear_csr(mstatus, MSTATUS_MIE); - if (spi_res_buf) { + if (spi_state.next_buf) { ret = 1; } else { asm volatile ("wfi"); @@ -295,9 +335,9 @@ int eos_net_acquire(unsigned char reserved) { } } else { clear_csr(mstatus, MSTATUS_MIE); - spi_res++; - spi_res_buf = spi_bufq_pop(); - ret = (spi_res_buf != NULL); + spi_state.next_cnt++; + spi_state.next_buf = spi_bufq_pop(); + ret = (spi_state.next_buf != NULL); set_csr(mstatus, MSTATUS_MIE); } return ret; @@ -307,10 +347,10 @@ int eos_net_release(unsigned char reserved) { int rv = EOS_OK; clear_csr(mstatus, MSTATUS_MIE); - if (reserved) spi_res--; - if (!spi_res && spi_res_buf) { - rv = spi_bufq_push((unsigned char *)spi_res_buf); - if (!rv) spi_res_buf = NULL; + 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; } set_csr(mstatus, MSTATUS_MIE); @@ -318,31 +358,31 @@ int eos_net_release(unsigned char reserved) { } unsigned char *eos_net_alloc(void) { - volatile unsigned char *ret = NULL; + unsigned char *ret = NULL; while (ret == NULL) { clear_csr(mstatus, MSTATUS_MIE); - if (spi_res_buf) { - ret = spi_res_buf; - spi_res_buf = NULL; + if (spi_state.next_buf) { + ret = spi_state.next_buf; + spi_state.next_buf = NULL; } else { asm volatile ("wfi"); } set_csr(mstatus, MSTATUS_MIE); } - return (unsigned char *)ret; + return ret; } -int eos_net_free(unsigned char *buffer, unsigned char reserve_next) { +int eos_net_free(unsigned char *buffer, unsigned char reserve) { int rv = EOS_OK; uint8_t do_release = 1; clear_csr(mstatus, MSTATUS_MIE); - if ((spi_res || reserve_next) && (spi_res_buf == NULL)) { - spi_res_buf = buffer; + if ((reserve || spi_state.next_cnt) && (spi_state.next_buf == NULL)) { + spi_state.next_buf = buffer; } else { - if (spi_rdy && spi_cts) do_release = spi_xchg_next(buffer); + if ((spi_state.flags & SPI_FLAG_RDY) && (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); @@ -354,7 +394,7 @@ int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len) { int rv = EOS_OK; clear_csr(mstatus, MSTATUS_MIE); - if (spi_rdy && spi_cts) { + if ((spi_state.flags & SPI_FLAG_RDY) && (spi_state.flags & SPI_FLAG_CTS)) { spi_xchg(cmd, buffer, len); } else { rv = eos_msgq_push(&spi_sndq, cmd, buffer, len); diff --git a/code/fe310/eos/net.h b/code/fe310/eos/net.h index 0091c3c..106a204 100644 --- a/code/fe310/eos/net.h +++ b/code/fe310/eos/net.h @@ -1,4 +1,5 @@ #include <stdint.h> +#include "event.h" #define EOS_NET_CMD_FLAG_ONEW 0x10 @@ -7,11 +8,12 @@ #define EOS_NET_CMD_SCAN 3 #define EOS_NET_CMD_PKT 4 -#define EOS_NET_MAX_CMD 8 +#define EOS_NET_MAX_CMD 4 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); diff --git a/code/fe310/eos/spi.h b/code/fe310/eos/spi.h index 7e281b8..55ff846 100644 --- a/code/fe310/eos/spi.h +++ b/code/fe310/eos/spi.h @@ -10,19 +10,31 @@ #define SPI_SIZE_BUF 1500 #define SPI_SIZE_CHUNK 4 -#define SPI_SIZE_BUFQ 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)) -typedef struct SPIBuffer { - unsigned char cmd; - unsigned char *buffer; + +#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; -} SPIBuffer; + unsigned char cmd; + unsigned char *buf; + uint8_t next_cnt; + unsigned char *next_buf; +} SPIState; typedef struct SPIBufQ { uint8_t idx_r; diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c index 0a07ed9..9e2ae9d 100644 --- a/code/fe310/eos/timer.c +++ b/code/fe310/eos/timer.c @@ -13,7 +13,7 @@ static eos_timer_fptr_t timer_ext_handler = NULL; volatile uint64_t timer_next = 0; volatile uint64_t timer_next_evt = 0; -void handle_m_time_interrupt(void) { +void eos_timer_handle(void) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); uint64_t now = *mtime; @@ -44,10 +44,9 @@ void eos_timer_set(uint32_t tick, unsigned char is_evt) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - clear_csr(mstatus, MSTATUS_MIE); + clear_csr(mie, MIP_MTIP); uint64_t now = *mtime; - uint64_t then = *mtimecmp; uint64_t next = now + tick; if (is_evt) { if ((timer_next_evt == 0) || (next < timer_next_evt)) timer_next_evt = next; @@ -56,16 +55,15 @@ void eos_timer_set(uint32_t tick, unsigned char is_evt) { if ((timer_next == 0) || (next < timer_next)) timer_next = next; next = timer_next_evt ? MIN(timer_next, timer_next_evt) : timer_next; } - if ((then == 0) || (next < then)) *mtimecmp = next; - if (then == 0) set_csr(mie, MIP_MTIP); + if ((*mtimecmp == 0) || (next < *mtimecmp)) *mtimecmp = next; - set_csr(mstatus, MSTATUS_MIE); + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } void eos_timer_clear(unsigned char is_evt) { volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - clear_csr(mstatus, MSTATUS_MIE); + clear_csr(mie, MIP_MTIP); if (is_evt) { timer_next_evt = 0; @@ -74,13 +72,14 @@ void eos_timer_clear(unsigned char is_evt) { timer_next = 0; *mtimecmp = timer_next_evt; } - if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); - set_csr(mstatus, MSTATUS_MIE); + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } void eos_timer_set_handler(eos_timer_fptr_t handler) { - clear_csr(mstatus, MSTATUS_MIE); + volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + + clear_csr(mie, MIP_MTIP); timer_ext_handler = handler; - set_csr(mstatus, MSTATUS_MIE); + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } |