summaryrefslogtreecommitdiff
path: root/code/fe310/eos
diff options
context:
space:
mode:
Diffstat (limited to 'code/fe310/eos')
-rw-r--r--code/fe310/eos/Makefile12
-rw-r--r--code/fe310/eos/ecp.c22
-rw-r--r--code/fe310/eos/eos.h1
-rw-r--r--code/fe310/eos/event.c82
-rw-r--r--code/fe310/eos/event.h16
-rw-r--r--code/fe310/eos/interrupt.c33
-rw-r--r--code/fe310/eos/interrupt.h6
-rw-r--r--code/fe310/eos/net.c240
-rw-r--r--code/fe310/eos/net.h4
-rw-r--r--code/fe310/eos/spi.h22
-rw-r--r--code/fe310/eos/timer.c21
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);
}