diff options
author | Uros Majstorovic <majstor@majstor.org> | 2019-10-15 18:11:40 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2019-10-15 18:11:40 +0200 |
commit | edec491d59697a635ddce7a19a870dd3e8d2f3ed (patch) | |
tree | 8b5c00103609eabe9fdc89169c825f544aca41d5 /code/fe310/eos/timer.c | |
parent | 850ce8bb7a447e1d2500d5dac0b0003bb4412c37 (diff) |
event handler flags per evt subtype
timer has evt subtypes
i2s refactor
i2s has spk event
i2s fixed intr handler audio buf push
msgq fixed get message
Diffstat (limited to 'code/fe310/eos/timer.c')
-rw-r--r-- | code/fe310/eos/timer.c | 118 |
1 files changed, 79 insertions, 39 deletions
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); } |