From 412a8f99928beff605805807b0f07f6bf8d0a965 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 13 May 2022 12:45:53 +0200 Subject: code rename --- fw/fe310/eos/soc/timer.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 fw/fe310/eos/soc/timer.c (limited to 'fw/fe310/eos/soc/timer.c') diff --git a/fw/fe310/eos/soc/timer.c b/fw/fe310/eos/soc/timer.c new file mode 100644 index 0000000..91861a3 --- /dev/null +++ b/fw/fe310/eos/soc/timer.c @@ -0,0 +1,137 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "msgq.h" +#include "event.h" +#include "timer.h" + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) + +static eos_timer_handler_t timer_handler[EOS_TIMER_MAX_ETYPE + 1]; +static uint64_t timer_next[EOS_TIMER_MAX_ETYPE + 1]; + +static void timer_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char idx = (type & ~EOS_EVT_MASK); + + if (idx && (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); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t now = *mtime; + 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 == 0) { + timer_handler[0](0); + } else { + eos_evtq_push_isr(EOS_EVT_TIMER | i, NULL, 0); + } + } + next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); + } + *mtimecmp = next; + if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); +} + +int eos_timer_init(uint8_t wakeup_cause) { + int i; + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + + 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_handle_evt); + + return EOS_OK; +} + +void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler) { + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + + if (!evt && (*mtimecmp != 0)) clear_csr(mie, MIP_MTIP); + timer_handler[evt] = handler; + if (!evt && (*mtimecmp != 0)) set_csr(mie, MIP_MTIP); +} + +uint32_t eos_timer_get(unsigned char evt) { + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t now; + uint32_t ret; + + if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); + now = *mtime; + if (timer_next[evt]) { + ret = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0; + } else { + ret = EOS_TIMER_NONE; + } + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); + + return ret; +} + +void eos_timer_set(unsigned char evt, uint32_t msec) { + int i; + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t tick = *mtime + msec * (uint64_t)EOS_TIMER_RTC_FREQ / 1000; + uint64_t next = 0; + + if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); + timer_next[evt] = 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]); + } + *mtimecmp = next; + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); +} + +void eos_timer_clear(unsigned char evt) { + int i; + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t next = 0; + + if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); + if (timer_next[evt]) { + 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_time_sleep(uint32_t msec) { + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t mtime0 = *mtime; + + while ((*mtime - mtime0) < (msec * EOS_TIMER_RTC_FREQ / 1000 + 1)); +} + +uint64_t eos_time_get_tick(void) { + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + return *mtime; +} + +uint32_t eos_time_delta_ms(uint32_t tick) { + return ((uint32_t)eos_time_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ; +} -- cgit v1.2.3