From ab1006d27417cc831150877ec46fbc13ffeddb53 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 11 Mar 2020 16:28:27 +0100 Subject: timer fix --- code/fe310/eos/timer.c | 49 ++++++++++++++++++++++++++++++------------------- code/fe310/eos/timer.h | 11 ++++++++--- 2 files changed, 38 insertions(+), 22 deletions(-) (limited to 'code/fe310') diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c index 4eb80b4..e07b9a6 100644 --- a/code/fe310/eos/timer.c +++ b/code/fe310/eos/timer.c @@ -62,37 +62,42 @@ void eos_timer_init(void) { void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler) { uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - clear_csr(mie, MIP_MTIP); + if (!evt && (*mtimecmp != 0)) clear_csr(mie, MIP_MTIP); timer_handler[evt] = handler; - if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); + if (!evt && (*mtimecmp != 0)) set_csr(mie, MIP_MTIP); } -uint64_t eos_timer_get(unsigned char evt) { +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 ret = 0; + uint64_t now; + uint32_t ret; - clear_csr(mie, MIP_MTIP); - ret = timer_next[evt]; + 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(uint32_t msec, unsigned char evt, unsigned char b) { +void eos_timer_set(uint32_t msec, unsigned char evt) { 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)RTC_FREQ / 1000; + uint64_t tick = *mtime + msec * (uint64_t)EOS_TIMER_RTC_FREQ / 1000; uint64_t next = 0; - clear_csr(mie, MIP_MTIP); - if (!b || (timer_next[evt] == 0) || (tick < timer_next[evt])) { - 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) 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); } @@ -101,7 +106,7 @@ void eos_timer_clear(unsigned char evt) { uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); uint64_t next = 0; - clear_csr(mie, MIP_MTIP); + 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++) { @@ -112,9 +117,15 @@ void eos_timer_clear(unsigned char evt) { if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } -void eos_timer_sleep(uint32_t msec) { + +void eos_time_sleep(uint32_t msec) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t now_ms = *mtime * 1000 / EOS_TIMER_RTC_FREQ; - uint64_t now_ms = *mtime * 1000 / RTC_FREQ; - while (*mtime * 1000 / RTC_FREQ < now_ms + msec); + while (*mtime * 1000 / EOS_TIMER_RTC_FREQ < now_ms + msec); +} + +uint64_t eos_time_get_tick(void) { + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + return *mtime; } diff --git a/code/fe310/eos/timer.h b/code/fe310/eos/timer.h index edf422d..2ac53f7 100644 --- a/code/fe310/eos/timer.h +++ b/code/fe310/eos/timer.h @@ -6,12 +6,17 @@ #define EOS_TIMER_MAX_ETYPE 4 +#define EOS_TIMER_NONE 0xffffffff +#define EOS_TIMER_RTC_FREQ 32768 + typedef void (*eos_timer_handler_t) (unsigned char); void eos_timer_init(void); void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler); -uint64_t eos_timer_get(unsigned char evt); -void eos_timer_set(uint32_t msec, unsigned char evt, unsigned char b); +uint32_t eos_timer_get(unsigned char evt); +void eos_timer_set(uint32_t msec, unsigned char evt); void eos_timer_clear(unsigned char evt); -void eos_timer_sleep(uint32_t msec); + +void eos_time_sleep(uint32_t msec); +uint64_t eos_time_get_tick(void); -- cgit v1.2.3