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 | 
