diff options
Diffstat (limited to 'code/fe310')
-rw-r--r-- | code/fe310/eos/ecp.c | 6 | ||||
-rw-r--r-- | code/fe310/eos/event.c | 52 | ||||
-rw-r--r-- | code/fe310/eos/event.h | 3 | ||||
-rw-r--r-- | code/fe310/eos/i2s.c | 61 | ||||
-rw-r--r-- | code/fe310/eos/i2s_def.h | 5 | ||||
-rw-r--r-- | code/fe310/eos/msgq.c | 45 | ||||
-rw-r--r-- | code/fe310/eos/msgq.h | 2 | ||||
-rw-r--r-- | code/fe310/eos/net.c | 42 | ||||
-rw-r--r-- | code/fe310/eos/timer.c | 118 | ||||
-rw-r--r-- | code/fe310/eos/timer.h | 11 | ||||
-rw-r--r-- | code/fe310/eos/trap_entry.S | 84 |
11 files changed, 264 insertions, 165 deletions
diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c index 44d9a47..85539f5 100644 --- a/code/fe310/eos/ecp.c +++ b/code/fe310/eos/ecp.c @@ -13,11 +13,11 @@ static ECPSocket *_sock = NULL; -static void timer_handler(unsigned char type, unsigned char *buffer, uint16_t len) { +static void timer_handler(unsigned char type) { 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_timer_set(tick, EOS_TIMER_ETYPE_ECP); } } @@ -59,8 +59,8 @@ int ecp_init(ECPContext *ctx) { rv = ecp_ctx_create_vconn(ctx); if (rv) return rv; + eos_timer_set_handler(EOS_TIMER_ETYPE_ECP, timer_handler, EOS_EVT_FLAG_NET_BUF_ACQ); /* XXX */ - eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler, EOS_EVT_FLAG_NET_BUF_ACQ); // eos_net_set_handler(EOS_NET_DATA_PKT, packet_handler, 0); return ECP_OK; } diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c index 66b1f4a..9e3fb90 100644 --- a/code/fe310/eos/event.c +++ b/code/fe310/eos/event.c @@ -13,8 +13,8 @@ EOSMsgQ _eos_event_q; static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q]; static eos_evt_fptr_t evt_handler[EOS_EVT_MAX_EVT]; -static uint16_t evt_handler_wrapper_acq = 0; -static uint16_t evt_handler_flags_buf_acq = 0; +static uint16_t evt_handler_wrapper_acq[EOS_EVT_MAX_EVT]; +static uint16_t evt_handler_flags_buf_acq[EOS_EVT_MAX_EVT]; void eos_evtq_init(void) { int i; @@ -42,38 +42,48 @@ void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t le write(1, "error\n", 6); } -static void evtq_handler_wrapper(unsigned char type, 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); +static void evtq_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char idx = ((type & EOS_EVT_MASK) >> 4) - 1; + uint16_t flag = (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1); + int ok; + + ok = eos_net_acquire(evt_handler_wrapper_acq[idx] & flag); if (ok) { - f(type, buffer, len); + evt_handler[idx](type, buffer, len); eos_net_release(); - *flags_acq &= ~flag; + evt_handler_wrapper_acq[idx] &= ~flag; } else { - *flags_acq |= flag; + evt_handler_wrapper_acq[idx] |= flag; eos_evtq_push(type, buffer, len); } } static void evtq_handler(unsigned char type, unsigned char *buffer, uint16_t len) { - if (((type & EOS_EVT_MASK) >> 4) > EOS_EVT_MAX_EVT) { + unsigned char idx = ((type & EOS_EVT_MASK) >> 4) - 1; + uint16_t flag = (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1); + + if (idx >= EOS_EVT_MAX_EVT) { eos_evtq_bad_handler(type, buffer, len); + return; + } + if (flag & evt_handler_flags_buf_acq[idx]) { + evtq_handler_wrapper(type, buffer, len); } else { - unsigned char idx = ((type & EOS_EVT_MASK) >> 4) - 1; - uint16_t flag = (uint16_t)1 << idx; - if (flag & evt_handler_flags_buf_acq) { - evtq_handler_wrapper(type, buffer, len, &evt_handler_wrapper_acq, flag, evt_handler[idx]); - } else { - evt_handler[idx](type, buffer, len); - } + evt_handler[idx](type, buffer, len); } } -void eos_evtq_set_handler(unsigned char type, eos_evt_fptr_t handler, uint8_t flags) { - if (flags) { - uint16_t flag = (uint16_t)1 << (((type & EOS_EVT_MASK) >> 4) - 1); - if (flags & EOS_EVT_FLAG_NET_BUF_ACQ) evt_handler_flags_buf_acq |= flag; - } - evt_handler[((type & EOS_EVT_MASK) >> 4) - 1] = handler; +void eos_evtq_set_handler(unsigned char type, eos_evt_fptr_t handler) { + unsigned char idx = ((type & EOS_EVT_MASK) >> 4) - 1; + + if (idx < EOS_EVT_MAX_EVT) evt_handler[idx] = handler; +} + +void eos_evtq_set_flags(unsigned char type, uint8_t flags) { + unsigned char idx = ((type & EOS_EVT_MASK) >> 4) - 1; + uint16_t flag = type & ~EOS_EVT_MASK ? (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1) : 0xFFFF; + + if ((idx < EOS_EVT_MAX_EVT) && (flags & EOS_EVT_FLAG_NET_BUF_ACQ)) evt_handler_flags_buf_acq[idx] |= flag; } void eos_evtq_loop(void) { diff --git a/code/fe310/eos/event.h b/code/fe310/eos/event.h index 653d5c4..a9a98ef 100644 --- a/code/fe310/eos/event.h +++ b/code/fe310/eos/event.h @@ -8,5 +8,6 @@ void eos_evtq_init(void); int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len); void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len); void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len); -void eos_evtq_set_handler(unsigned char type, eos_evt_fptr_t handler, uint8_t flags); +void eos_evtq_set_handler(unsigned char type, eos_evt_fptr_t handler); +void eos_evtq_set_flags(unsigned char type, uint8_t flags); void eos_evtq_loop(void); diff --git a/code/fe310/eos/i2s.c b/code/fe310/eos/i2s.c index cb25493..d171a45 100644 --- a/code/fe310/eos/i2s.c +++ b/code/fe310/eos/i2s.c @@ -22,9 +22,13 @@ EOSABuf _eos_i2s_spk_buf; uint32_t _eos_i2s_ck_period = 0; uint32_t _eos_i2s_mic_volume = 0; uint32_t _eos_i2s_spk_volume = 0; -static eos_evt_fptr_t evt_handler[I2S_MAX_HANDLER]; -uint32_t _eos_i2s_evt_enable[I2S_MAX_HANDLER]; -uint32_t _eos_i2s_wm[I2S_MAX_HANDLER]; +uint32_t _eos_i2s_mic_wm; +uint32_t _eos_i2s_spk_wm; +uint32_t _eos_i2s_mic_evt_enable; +uint32_t _eos_i2s_spk_evt_enable; + +static eos_evt_fptr_t spk_evt_handler; +static eos_evt_fptr_t mic_evt_handler; static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) { buf->idx_r = 0; @@ -77,14 +81,23 @@ static uint16_t _abuf_len(EOSABuf *buf) { return buf->idx_w - buf->idx_r; } -static void audio_handler(unsigned char type, unsigned char *buffer, uint16_t len) { - type = type & ~EOS_EVT_MASK; - - if (type < I2S_MAX_HANDLER) { - evt_handler[type](type, buffer, len); - _eos_i2s_evt_enable[type] = 1; - } else { - eos_evtq_bad_handler(type, buffer, len); +static void i2s_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + switch(type & ~EOS_EVT_MASK) { + case I2S_ETYPE_MIC: + mic_evt_handler(type, buffer, len); + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_mic_evt_enable = 1; + set_csr(mstatus, MSTATUS_MIE); + break; + case I2S_ETYPE_SPK: + spk_evt_handler(type, buffer, len); + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_spk_evt_enable = 1; + set_csr(mstatus, MSTATUS_MIE); + break; + default: + eos_evtq_bad_handler(type, buffer, len); + break; } } @@ -144,24 +157,22 @@ void eos_i2s_init(uint32_t sample_rate) { I2S_PWM_REG_WS_SPK(PWM_CMP1) = (_eos_i2s_ck_period + 1) * 32; I2S_PWM_REG_WS_SPK(PWM_CMP2) = (_eos_i2s_ck_period + 1) * 33; - _eos_i2s_evt_enable[I2S_EVT_MIC] = 0; - _eos_i2s_evt_enable[I2S_EVT_SPK] = 0; - evt_handler[I2S_EVT_MIC] = NULL; - evt_handler[I2S_EVT_SPK] = NULL; + _eos_i2s_mic_evt_enable = 0; + _eos_i2s_spk_evt_enable = 0; + mic_evt_handler = eos_evtq_bad_handler; + spk_evt_handler = eos_evtq_bad_handler; eos_intr_set(I2S_IRQ_WS_ID, 0, NULL); eos_intr_set(I2S_IRQ_SD_ID, 0, NULL); - for (i=0; i<I2S_MAX_HANDLER; i++) { - evt_handler[i] = eos_evtq_bad_handler; - } - eos_evtq_set_handler(EOS_EVT_AUDIO, audio_handler, EOS_EVT_FLAG_NET_BUF_ACQ); + eos_evtq_set_handler(EOS_EVT_AUDIO, i2s_handler_evt); + eos_evtq_set_flags(EOS_EVT_AUDIO | I2S_ETYPE_MIC, EOS_EVT_FLAG_NET_BUF_ACQ); } extern void _eos_set_pwm(void); void eos_i2s_start(void) { - _eos_i2s_evt_enable[I2S_EVT_MIC] = 1; - _eos_i2s_evt_enable[I2S_EVT_SPK] = 1; + _eos_i2s_mic_evt_enable = 1; + _eos_i2s_spk_evt_enable = 1; eos_intr_set_priority(I2S_IRQ_WS_ID, I2S_IRQ_WS_PRIORITY); @@ -229,13 +240,13 @@ void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) { void eos_i2s_mic_set_handler(eos_evt_fptr_t wm_handler) { clear_csr(mstatus, MSTATUS_MIE); - evt_handler[I2S_EVT_MIC] = wm_handler; + mic_evt_handler = wm_handler; set_csr(mstatus, MSTATUS_MIE); } void eos_i2s_mic_set_wm(uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_wm[I2S_EVT_MIC] = wm; + _eos_i2s_mic_wm = wm; set_csr(mstatus, MSTATUS_MIE); } @@ -281,13 +292,13 @@ void eos_i2s_spk_init(uint8_t *spk_arr, uint16_t spk_arr_size) { void eos_i2s_spk_set_handler(eos_evt_fptr_t wm_handler) { clear_csr(mstatus, MSTATUS_MIE); - evt_handler[I2S_EVT_SPK] = wm_handler; + spk_evt_handler = wm_handler; set_csr(mstatus, MSTATUS_MIE); } void eos_i2s_spk_set_wm(uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_wm[I2S_EVT_SPK] = wm; + _eos_i2s_spk_wm = wm; set_csr(mstatus, MSTATUS_MIE); } diff --git a/code/fe310/eos/i2s_def.h b/code/fe310/eos/i2s_def.h index 06fef72..1f7687a 100644 --- a/code/fe310/eos/i2s_def.h +++ b/code/fe310/eos/i2s_def.h @@ -1,6 +1,5 @@ -#define I2S_EVT_MIC 0x0 -#define I2S_EVT_SPK 0x1 -#define I2S_MAX_HANDLER 2 +#define I2S_ETYPE_MIC 1 +#define I2S_ETYPE_SPK 2 #define I2S_PIN_CK 1 /* PWM 0.1 */ #define I2S_PIN_CK_SW 21 /* PWM 1.2 */ diff --git a/code/fe310/eos/msgq.c b/code/fe310/eos/msgq.c index 867bf94..0c5d8f1 100644 --- a/code/fe310/eos/msgq.c +++ b/code/fe310/eos/msgq.c @@ -1,4 +1,5 @@ #include <stddef.h> +#include <string.h> #include "eos.h" #include "msgq.h" @@ -41,36 +42,38 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui } } -void eos_msgq_get(EOSMsgQ *msgq, unsigned char type, unsigned char **buffer, uint16_t *len) { +void eos_msgq_get(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { + uint8_t i, j, idx; + if (msgq->idx_r == msgq->idx_w) { *buffer = NULL; *len = 0; return; } - - uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size); - unsigned char _type = msgq->array[idx].type; - EOSMsgItem *tmp_item = &msgq->array[idx]; - - *buffer = msgq->array[idx].buffer; - *len = msgq->array[idx].len; - if (_type == type) { - msgq->idx_r++; - return; - } - for (idx = msgq->idx_r + 1; EOS_MSGQ_IDX_LT(idx, msgq->idx_w); idx++) { - *tmp_item = msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)]; - msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].type = _type; - msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].buffer = *buffer; - msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].len = *len; - _type = tmp_item->type; - *buffer = tmp_item->buffer; - *len = tmp_item->len; - if (_type == type) { + + idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size); + if (type == msgq->array[idx].type) { + *buffer = msgq->array[idx].buffer; + *len = msgq->array[idx].len; + if ((selector == NULL) || (sel_len == 0) || ((sel_len <= *len) && (memcmp(selector, *buffer, sel_len) == 0))) { msgq->idx_r++; return; } } + for (i = msgq->idx_r + 1; EOS_MSGQ_IDX_LT(i, msgq->idx_w); i++) { + idx = EOS_MSGQ_IDX_MASK(i, msgq->size); + if (type== msgq->array[idx].type) { + *buffer = msgq->array[idx].buffer; + *len = msgq->array[idx].len; + if ((selector == NULL) || (sel_len == 0) || ((sel_len <= *len) && (memcmp(selector, *buffer, sel_len) == 0))) { + for (j = i + 1; EOS_MSGQ_IDX_LT(j, msgq->idx_w); j++) { + msgq->array[EOS_MSGQ_IDX_MASK(j - 1, msgq->size)] = msgq->array[EOS_MSGQ_IDX_MASK(j, msgq->size)]; + } + msgq->idx_w--; + return; + } + } + } *buffer = NULL; *len = 0; } diff --git a/code/fe310/eos/msgq.h b/code/fe310/eos/msgq.h index 5a61a79..a280357 100644 --- a/code/fe310/eos/msgq.h +++ b/code/fe310/eos/msgq.h @@ -16,4 +16,4 @@ typedef struct EOSMsgQ { void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len); void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len); -void eos_msgq_get(EOSMsgQ *msgq, unsigned char type, unsigned char **buffer, uint16_t *len);
\ No newline at end of file +void eos_msgq_get(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len);
\ No newline at end of file diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c index 0cbe9f6..b8a5056 100644 --- a/code/fe310/eos/net.c +++ b/code/fe310/eos/net.c @@ -217,32 +217,38 @@ static void net_handler_rts(void) { } static void net_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - if ((type & ~EOS_EVT_MASK) > EOS_NET_MAX_MTYPE) { + 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; + + if (idx >= EOS_NET_MAX_MTYPE) { eos_evtq_bad_handler(type, buffer, len); - } else { - 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; - - if (buf_free) { - eos_net_free(buffer, buf_acq); - buffer = NULL; - len = 0; - } + eos_net_free(buffer, 0); + return; + } + if (buf_free) { + eos_net_free(buffer, buf_acq); + buffer = NULL; + len = 0; + } - evt_handler[idx](type, buffer, len); + evt_handler[idx](type, buffer, len); - if (buf_free && buf_acq) eos_net_release(); - } + if (buf_free && buf_acq) eos_net_release(); } -void eos_net_set_handler(unsigned char type, eos_evt_fptr_t handler, uint8_t flags) { +void eos_net_set_handler(unsigned char mtype, eos_evt_fptr_t handler, uint8_t flags) { + if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) { + mtype--; + } else { + return; + } if (flags) { - uint16_t flag = (uint16_t)1 << ((type & ~EOS_EVT_MASK) - 1); + uint16_t flag = (uint16_t)1 << mtype; 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[(type & ~EOS_EVT_MASK) - 1] = handler; + evt_handler[mtype] = handler; } void eos_net_init(void) { @@ -275,7 +281,7 @@ void eos_net_init(void) { 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_evt, 0); + eos_evtq_set_handler(EOS_EVT_NET, net_handler_evt); } void eos_net_start(uint32_t sckdiv) { diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c index b287317..2bbeec8 100644 --- a/code/fe310/eos/timer.c +++ b/code/fe310/eos/timer.c @@ -11,30 +11,40 @@ #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -static eos_timer_fptr_t timer_ext_handler = NULL; -volatile uint64_t timer_next = 0; -volatile uint64_t timer_next_evt = 0; +static eos_timer_fptr_t timer_handler[EOS_TIMER_MAX_ETYPE + 1]; +static uint64_t timer_next[EOS_TIMER_MAX_ETYPE + 1]; extern EOSMsgQ _eos_event_q; +static void timer_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char idx = (type & ~EOS_EVT_MASK) - 1; + + if ((idx < EOS_TIMER_MAX_ETYPE) && timer_handler[idx]) { + timer_handler[idx](type); + } else { + eos_evtq_bad_handler(type, buffer, len); + } +} + void eos_timer_handle(void) { + int i; volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); - volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); uint64_t now = *mtime; - - if (timer_next && (timer_next <= now)) { - uint32_t next = timer_ext_handler(); - if (next) { - timer_next = now + next; - } else { - timer_next = 0; + uint64_t next = 0; + + for (i = 0; i <= EOS_TIMER_MAX_ETYPE; i++) { + if (timer_next[i] && (timer_next[i] <= now)) { + timer_next[i] = 0; + if (i == EOS_TIMER_MAX_ETYPE) { + timer_handler[EOS_TIMER_MAX_ETYPE](0); + } else { + eos_msgq_push(&_eos_event_q, EOS_EVT_TIMER | i + 1, NULL, 0); + } } + next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); } - if (timer_next_evt && (timer_next_evt <= now)) { - 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); + *mtimecmp = next; if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); } @@ -43,51 +53,81 @@ void handle_m_time_interrupt(void) { } void eos_timer_init(void) { + int i; volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - *mtimecmp = 0; + clear_csr(mie, MIP_MTIP); + *mtimecmp = 0; + for (i = 0; i <= EOS_TIMER_MAX_ETYPE; i++) { + timer_next[i] = 0; + timer_handler[i] = NULL; + } + eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler_evt); } -void eos_timer_set(uint32_t tick, unsigned char is_evt) { +void eos_timer_set(uint32_t tick, unsigned char evt) { + int i; volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); - volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t next = 0; + uint64_t now; + clear_csr(mie, MIP_MTIP); - uint64_t now = *mtime; - uint64_t next = now + tick; - if (is_evt) { - if ((timer_next_evt == 0) || (next < timer_next_evt)) timer_next_evt = next; - next = timer_next ? MIN(timer_next, timer_next_evt) : timer_next_evt; - } else if (timer_ext_handler) { - if ((timer_next == 0) || (next < timer_next)) timer_next = next; - next = timer_next_evt ? MIN(timer_next, timer_next_evt) : timer_next; + now = *mtime; + if (evt && (evt <= EOS_TIMER_MAX_ETYPE)) { + evt--; + } else if (evt == 0) { + evt = EOS_TIMER_MAX_ETYPE; + } else { + return; + } + if ((timer_next[evt] == 0) || (now + tick < timer_next[evt])) timer_next[evt] = now + tick; + for (i = 0; i <= EOS_TIMER_MAX_ETYPE; i++) { + next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); } - if ((*mtimecmp == 0) || (next < *mtimecmp)) *mtimecmp = next; + *mtimecmp = next; 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); +void eos_timer_clear(unsigned char evt) { + int i; + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t next = 0; clear_csr(mie, MIP_MTIP); - if (is_evt) { - timer_next_evt = 0; - *mtimecmp = timer_next; + if (evt && (evt <= EOS_TIMER_MAX_ETYPE)) { + evt--; + } else if (evt == 0) { + evt = EOS_TIMER_MAX_ETYPE; } else { - timer_next = 0; - *mtimecmp = timer_next_evt; + return; } + timer_next[evt] = 0; + for (i = 0; i <= EOS_TIMER_MAX_ETYPE; i++) { + next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); + } + *mtimecmp = next; if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } -void eos_timer_set_handler(eos_timer_fptr_t handler) { - volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); +void eos_timer_set_handler(unsigned char evt, eos_timer_fptr_t handler, uint8_t flags) { + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); clear_csr(mie, MIP_MTIP); - timer_ext_handler = handler; + + if (evt && (evt <= EOS_TIMER_MAX_ETYPE)) { + evt--; + } else if (evt == 0) { + evt = EOS_TIMER_MAX_ETYPE; + } else { + return; + } + timer_handler[evt] = handler; + if (flags) eos_evtq_set_flags(EOS_EVT_TIMER | evt, flags); + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } diff --git a/code/fe310/eos/timer.h b/code/fe310/eos/timer.h index 929283b..34512fa 100644 --- a/code/fe310/eos/timer.h +++ b/code/fe310/eos/timer.h @@ -1,7 +1,12 @@ #include <stdint.h> -typedef uint32_t (*eos_timer_fptr_t) (void); +#define EOS_TIMER_ETYPE_ECP 1 +#define EOS_TIMER_ETYPE_USER 2 + +#define EOS_TIMER_MAX_ETYPE 4 + +typedef void (*eos_timer_fptr_t) (unsigned char); void eos_timer_init(void); -void eos_timer_set(uint32_t tick, unsigned char is_evt); -void eos_timer_set_handler(eos_timer_fptr_t handler); +void eos_timer_set(uint32_t tick, unsigned char evt); +void eos_timer_set_handler(unsigned char evt, eos_timer_fptr_t handler, uint8_t flags); diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S index 432e84a..650c45b 100644 --- a/code/fe310/eos/trap_entry.S +++ b/code/fe310/eos/trap_entry.S @@ -75,25 +75,26 @@ evtq_push: la x9, _eos_event_q lbu x18, MSGQ_OFF_IDXR(x9) lbu x19, MSGQ_OFF_IDXW(x9) - lbu x8, MSGQ_OFF_SIZE(x9) - + lbu x20, MSGQ_OFF_SIZE(x9) + sub x18, x19, x18 - beq x18, x8, 0f + andi x18, x18, 0xff + beq x18, x20, 0f - addi x8, x8, -1 - and x8, x8, x19 + addi x20, x20, -1 + and x20, x20, x19 li x18, MSGQ_ITEM_SIZE - mul x8, x8, x18 - lw x18, MSGQ_OFF_ARRAY(x9) - add x8, x8, x18 + mul x20, x20, x18 + lw x21, MSGQ_OFF_ARRAY(x9) + add x21, x21, x20 addi x19, x19, 1 sb x19, MSGQ_OFF_IDXW(x9) - jalr x0, x20 + jalr x0, x22 0: - mv x8, x0 - jalr x0, x20 + mv x20, x0 + jalr x0, x21 i2s_handler_sd: # exit if too early @@ -111,18 +112,41 @@ i2s_handler_sd: la x9, _eos_i2s_spk_buf lhu x18, I2S_ABUF_OFF_IDXR(x9) lhu x19, I2S_ABUF_OFF_IDXW(x9) + lhu x20, I2S_ABUF_OFF_SIZE(x9) + beq x18, x19, i2s_handler_sd_xchg - lhu x19, I2S_ABUF_OFF_SIZE(x9) - addi x19, x19, -1 - and x19, x19, x18 - lw x8, I2S_ABUF_OFF_ARRAY(x9) - add x19, x19, x8 - lbu x8, 0(x19) + addi x20, x20, -1 + and x20, x20, x18 + lw x21, I2S_ABUF_OFF_ARRAY(x9) + add x21, x21, x20 + lbu x8, 0(x21) addi x18, x18, 1 sh x18, I2S_ABUF_OFF_IDXR(x9) + + li x21, 0xffff + sub x18, x19, x18 + and x18, x18, x21 + + # check for push to event queue + la x9, _eos_i2s_spk_wm + lw x20, 0(x9) + beqz x20, i2s_decode + bgtu x18, x20, i2s_decode + + la x9, _eos_i2s_spk_evt_enable + lw x18, 0(x9) + beqz x18, i2s_decode + sw x0, 0(x9) + # push to event queue + jal x22, evtq_push + beqz x21, i2s_decode + li x18, (EOS_EVT_AUDIO | I2S_ETYPE_SPK) + sb x18, MSGQ_ITEM_OFF_TYPE(x21) + +i2s_decode: # aLaw decode -> x8 xori x8, x8, 0x55 andi x9, x8, 0x80 @@ -231,6 +255,7 @@ i2s_handler_sd_xchg: and x9, x9, x20 sw x9, GPIO_OUTPUT_EN(x18) +i2s_encode: # aLaw encode -> x8 li x18, 0x800 li x19, 7 @@ -270,36 +295,35 @@ i2s_handler_sd_xchg: sub x18, x19, x18 and x18, x18, x21 - beq x18, x20, 0f - - addi x19, x19, 1 - sh x19, I2S_ABUF_OFF_IDXW(x9) + beq x18, x20, i2s_handler_sd_exit addi x20, x20, -1 and x20, x20, x19 - lw x19, I2S_ABUF_OFF_ARRAY(x9) - add x20, x19, x20 + lw x21, I2S_ABUF_OFF_ARRAY(x9) + add x20, x21, x20 + + addi x19, x19, 1 + sh x19, I2S_ABUF_OFF_IDXW(x9) sb x8, 0(x20) addi x18, x18, 1 -0: # check for push to event queue - la x9, _eos_i2s_wm + la x9, _eos_i2s_mic_wm lw x20, 0(x9) beqz x20, i2s_handler_sd_exit bltu x18, x20, i2s_handler_sd_exit - la x9, _eos_i2s_evt_enable + la x9, _eos_i2s_mic_evt_enable lw x18, 0(x9) beqz x18, i2s_handler_sd_exit sw x0, 0(x9) # push to event queue - jal x20, evtq_push - beqz x8, i2s_handler_sd_exit - li x18, (EOS_EVT_AUDIO | I2S_EVT_MIC) - sb x18, MSGQ_ITEM_OFF_TYPE(x8) + jal x22, evtq_push + beqz x21, i2s_handler_sd_exit + li x18, (EOS_EVT_AUDIO | I2S_ETYPE_MIC) + sb x18, MSGQ_ITEM_OFF_TYPE(x21) i2s_handler_sd_exit: # complete |