summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2018-03-16 14:15:39 +0100
committerUros Majstorovic <majstor@majstor.org>2018-03-16 14:15:39 +0100
commitb1c3ee27894d33d9fcfca4ea4d0ccfb6d4cfc83e (patch)
tree16bfe6ba0da03cf94dec735076d2de1eac9fc761
parent8755ad4c0b0652f16d3505ed72ed3d8310a35c6f (diff)
fixed race conditions
-rw-r--r--code/fe310/eos/Makefile4
-rw-r--r--code/fe310/eos/event.c9
-rw-r--r--code/fe310/eos/i2s.c53
-rw-r--r--code/fe310/eos/i2s_def.h2
-rw-r--r--code/fe310/eos/interrupt.c6
-rw-r--r--code/fe310/eos/net.c4
-rw-r--r--code/fe310/eos/timer.c5
-rw-r--r--code/fe310/eos/trap_entry.S14
8 files changed, 76 insertions, 21 deletions
diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile
index 6f43615..66c7d6a 100644
--- a/code/fe310/eos/Makefile
+++ b/code/fe310/eos/Makefile
@@ -1,9 +1,11 @@
+include ../../ecp/Makefile.platform
+
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
-CFLAGS = -O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -DECP_DEBUG -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../..
+CFLAGS = $(CFLAGS_PL) -I../..
obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o net.o ecp.o
diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c
index a1cf591..127e45a 100644
--- a/code/fe310/eos/event.c
+++ b/code/fe310/eos/event.c
@@ -26,11 +26,16 @@ void eos_evtq_init(void) {
}
int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len) {
- return eos_msgq_push(&_eos_event_q, cmd, buffer, len);
+ clear_csr(mstatus, MSTATUS_MIE);
+ int ret = eos_msgq_push(&_eos_event_q, cmd, buffer, len);
+ set_csr(mstatus, MSTATUS_MIE);
+ return ret;
}
void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len) {
+ clear_csr(mstatus, MSTATUS_MIE);
eos_msgq_pop(&_eos_event_q, cmd, buffer, len);
+ set_csr(mstatus, MSTATUS_MIE);
}
void eos_evtq_bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) {
@@ -71,7 +76,7 @@ void eos_evtq_loop(void) {
while(foo) {
clear_csr(mstatus, MSTATUS_MIE);
- eos_evtq_pop(&cmd, &buffer, &len);
+ eos_msgq_pop(&_eos_event_q, &cmd, &buffer, &len);
if (cmd) {
set_csr(mstatus, MSTATUS_MIE);
eos_evtq_handle(cmd, buffer, len);
diff --git a/code/fe310/eos/i2s.c b/code/fe310/eos/i2s.c
index 98e2ffa..64152dd 100644
--- a/code/fe310/eos/i2s.c
+++ b/code/fe310/eos/i2s.c
@@ -17,10 +17,13 @@
EOSABuf _eos_i2s_mic_buf;
EOSABuf _eos_i2s_spk_buf;
-uint16_t _eos_i2s_mic_wm;
-uint16_t _eos_i2s_spk_wm;
-uint32_t _eos_i2s_ck_period;
+uint32_t _eos_i2s_ck_period = 0;
+uint32_t _eos_i2s_mic_wm = 0;
+uint32_t _eos_i2s_spk_wm = 0;
uint32_t _eos_i2s_mic_volume = 3;
+uint32_t _eos_i2s_spk_volume = 3;
+uint32_t _eos_i2s_mic_rd = 1;
+uint32_t _eos_i2s_spk_wr = 1;
static eos_evt_fptr_t evt_handler[I2S_MAX_HANDLER];
static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) {
@@ -109,7 +112,7 @@ void eos_i2s_init(void) {
I2S_PWM_REG_CK(PWM_COUNT) = 0;
I2S_PWM_REG_CK(PWM_CMP0) = _eos_i2s_ck_period - 1;
I2S_PWM_REG_CK(PWM_CMP1) = I2S_PWM_REG_CK(PWM_CMP0) / 2;
- I2S_PWM_REG_CK(PWM_CMP2) = I2S_PWM_REG_CK(PWM_CMP0) / 4;
+ I2S_PWM_REG_CK(PWM_CMP2) = I2S_PWM_REG_CK(PWM_CMP0) / 2;
I2S_PWM_REG_WS(PWM_CFG) = 0;
I2S_PWM_REG_WS(PWM_COUNT) = 0;
@@ -176,15 +179,28 @@ uint16_t eos_i2s_mic_len(void) {
}
uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) {
- clear_csr(mstatus, MSTATUS_MIE);
- uint16_t ret = _abuf_read(&_eos_i2s_mic_buf, sample, ssize);
- set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ int i;
+ uint16_t _ssize = 0;
+
+ for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ _ssize += _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK);
+ if ((ssize == _ssize) || (_ssize != (i+1)*I2S_ABUF_SIZE_CHUNK)) _eos_i2s_mic_rd = 1;
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ _ssize += _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize);
+ _eos_i2s_mic_rd = 1;
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ return _ssize;
}
int eos_i2s_mic_pop(uint8_t *sample) {
clear_csr(mstatus, MSTATUS_MIE);
int ret = _abuf_pop(&_eos_i2s_mic_buf, sample);
+ _eos_i2s_mic_rd = 1;
set_csr(mstatus, MSTATUS_MIE);
return ret;
}
@@ -197,15 +213,28 @@ uint16_t eos_i2s_spk_len(void) {
}
uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) {
- clear_csr(mstatus, MSTATUS_MIE);
- uint16_t ret = _abuf_write(&_eos_i2s_spk_buf, sample, ssize);
- set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ int i;
+ uint16_t _ssize = 0;
+ for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ _ssize += _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK);
+ if ((ssize == _ssize) || (_ssize != (i+1)*I2S_ABUF_SIZE_CHUNK)) _eos_i2s_spk_wr = 1;
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ _ssize += _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize);
+ _eos_i2s_spk_wr = 1;
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ return _ssize;
+
}
int eos_i2s_spk_push(uint8_t sample) {
clear_csr(mstatus, MSTATUS_MIE);
int ret = _abuf_push(&_eos_i2s_spk_buf, sample);
+ _eos_i2s_spk_wr = 1;
set_csr(mstatus, MSTATUS_MIE);
return ret;
}
diff --git a/code/fe310/eos/i2s_def.h b/code/fe310/eos/i2s_def.h
index 04e9c27..6f831e2 100644
--- a/code/fe310/eos/i2s_def.h
+++ b/code/fe310/eos/i2s_def.h
@@ -21,6 +21,8 @@
#define I2S_SMPL_WIDTH 13
+#define I2S_ABUF_SIZE_CHUNK 64
+
/* asm */
#define I2S_ABUF_OFF_IDXR 0
#define I2S_ABUF_OFF_IDXW 2
diff --git a/code/fe310/eos/interrupt.c b/code/fe310/eos/interrupt.c
index b8c6540..28bd8d1 100644
--- a/code/fe310/eos/interrupt.c
+++ b/code/fe310/eos/interrupt.c
@@ -26,6 +26,12 @@ uintptr_t eos_intr_handle(uintptr_t int_num) {
return int_num;
}
+void handle_m_ext_interrupt(void) {
+ plic_source int_num = PLIC_claim_interrupt(&plic);
+ eos_intr_handle(int_num);
+ PLIC_complete_interrupt(&plic, int_num);
+}
+
void eos_intr_init(void) {
for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){
ext_interrupt_handler[i] = NULL;
diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c
index 3339223..58bd5fd 100644
--- a/code/fe310/eos/net.c
+++ b/code/fe310/eos/net.c
@@ -26,6 +26,8 @@ static uint16_t evt_handler_wrapper_en = 0;
static SPIBufQ spi_bufq;
static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF];
+extern EOSMsgQ _eos_event_q;
+
static int spi_bufq_push(unsigned char *buffer) {
spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_w++)] = buffer;
return EOS_OK;
@@ -162,7 +164,7 @@ static void spi_xchg_handler(void) {
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
SPI1_REG(SPI_REG_IE) = 0x0;
if (spi_state.cmd) {
- int r = eos_evtq_push(EOS_EVT_NET | spi_state.cmd, spi_state.buf, spi_state.len_rx);
+ 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;
diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c
index 915be6f..5e1b381 100644
--- a/code/fe310/eos/timer.c
+++ b/code/fe310/eos/timer.c
@@ -4,6 +4,7 @@
#include "encoding.h"
#include "platform.h"
+#include "msgq.h"
#include "event.h"
#include "timer.h"
@@ -14,6 +15,8 @@ static eos_timer_fptr_t timer_ext_handler = NULL;
volatile uint64_t timer_next = 0;
volatile uint64_t timer_next_evt = 0;
+extern EOSMsgQ _eos_event_q;
+
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);
@@ -28,7 +31,7 @@ void eos_timer_handle(void) {
}
}
if (timer_next_evt && (timer_next_evt <= now)) {
- eos_evtq_push(EOS_EVT_TIMER, NULL, 0);
+ eos_msgq_push(&_eos_event_q, EOS_EVT_TIMER, NULL, 0);
timer_next_evt = 0;
}
*mtimecmp = (timer_next && timer_next_evt) ? MIN(timer_next, timer_next_evt) : (timer_next ? timer_next : timer_next_evt);
diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S
index 1c164d3..7d834f6 100644
--- a/code/fe310/eos/trap_entry.S
+++ b/code/fe310/eos/trap_entry.S
@@ -168,7 +168,7 @@ handler_sd:
xori x8, x8, 0x55
andi x8, x8, 0xff
- # push to mic but
+ # push to mic buf
la x9, _eos_i2s_mic_buf
lhu x18, I2S_ABUF_OFF_IDXR(x9)
lhu x19, I2S_ABUF_OFF_IDXW(x9)
@@ -186,16 +186,22 @@ handler_sd:
addi x19, x19, 1
sh x19, I2S_ABUF_OFF_IDXW(x9)
- # push to event queue
+ # check for push to event queue
la x9, _eos_i2s_mic_wm
- lhu x20, 0(x9)
+ lw x20, 0(x9)
beqz x20, handler_sd_exit
la x9, _eos_i2s_mic_buf
lhu x18, I2S_ABUF_OFF_IDXR(x9)
sub x18, x19, x18
- bne x18, x20, handler_sd_exit
+ blt x18, x20, handler_sd_exit
+
+ la x9, _eos_i2s_mic_rd
+ lw x18, 0(x9)
+ beqz x18, handler_sd_exit
+ 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)