diff options
author | Uros Majstorovic <majstor@majstor.org> | 2018-03-16 14:15:39 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2018-03-16 14:15:39 +0100 |
commit | b1c3ee27894d33d9fcfca4ea4d0ccfb6d4cfc83e (patch) | |
tree | 16bfe6ba0da03cf94dec735076d2de1eac9fc761 | |
parent | 8755ad4c0b0652f16d3505ed72ed3d8310a35c6f (diff) |
fixed race conditions
-rw-r--r-- | code/fe310/eos/Makefile | 4 | ||||
-rw-r--r-- | code/fe310/eos/event.c | 9 | ||||
-rw-r--r-- | code/fe310/eos/i2s.c | 53 | ||||
-rw-r--r-- | code/fe310/eos/i2s_def.h | 2 | ||||
-rw-r--r-- | code/fe310/eos/interrupt.c | 6 | ||||
-rw-r--r-- | code/fe310/eos/net.c | 4 | ||||
-rw-r--r-- | code/fe310/eos/timer.c | 5 | ||||
-rw-r--r-- | code/fe310/eos/trap_entry.S | 14 |
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) |