From 86957adfc5e2177010db896581763b4cba07273e Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Tue, 15 Oct 2019 20:20:38 +0200 Subject: timer bugfix --- code/ecp/fe310/time.c | 5 ++-- code/fe310/eos/ecp.c | 5 ++-- code/fe310/eos/timer.c | 64 ++++++++++++++++++++++++++++++++------------------ code/fe310/eos/timer.h | 4 +++- 4 files changed, 50 insertions(+), 28 deletions(-) diff --git a/code/ecp/fe310/time.c b/code/ecp/fe310/time.c index 69cf14d..455c762 100644 --- a/code/ecp/fe310/time.c +++ b/code/ecp/fe310/time.c @@ -21,6 +21,7 @@ void ecp_tm_sleep_ms(ecp_cts_t msec) { } void ecp_tm_timer_set(ecp_cts_t next) { - uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; - eos_timer_set(tick, EOS_TIMER_ETYPE_ECP); + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t tick = *mtime + next * (uint64_t)RTC_FREQ / 1000; + eos_timer_set(tick, EOS_TIMER_ETYPE_ECP, 1); } diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c index 85539f5..bf51b19 100644 --- a/code/fe310/eos/ecp.c +++ b/code/fe310/eos/ecp.c @@ -16,8 +16,9 @@ static ECPSocket *_sock = NULL; 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, EOS_TIMER_ETYPE_ECP); + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t tick = *mtime + next * (uint64_t)RTC_FREQ / 1000; + eos_timer_set(tick, EOS_TIMER_ETYPE_ECP, 0); } } diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c index 2bbeec8..25b7e7e 100644 --- a/code/fe310/eos/timer.c +++ b/code/fe310/eos/timer.c @@ -54,7 +54,7 @@ void handle_m_time_interrupt(void) { void eos_timer_init(void) { int i; - volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); clear_csr(mie, MIP_MTIP); *mtimecmp = 0; @@ -65,16 +65,30 @@ void eos_timer_init(void) { eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler_evt); } -void eos_timer_set(uint32_t tick, unsigned char evt) { +uint64_t eos_timer_get(unsigned char evt) { + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t ret = 0; + + if (evt && (evt <= EOS_TIMER_MAX_ETYPE)) { + evt--; + } else if (evt == 0) { + evt = EOS_TIMER_MAX_ETYPE; + } else { + return 0; + } + + clear_csr(mie, MIP_MTIP); + ret = timer_next[evt]; + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); + + return ret; +} + +void eos_timer_set(uint64_t tick, unsigned char evt, unsigned char b) { 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 next = 0; - uint64_t now; - clear_csr(mie, MIP_MTIP); - - now = *mtime; if (evt && (evt <= EOS_TIMER_MAX_ETYPE)) { evt--; } else if (evt == 0) { @@ -82,12 +96,15 @@ void eos_timer_set(uint32_t tick, unsigned char evt) { } 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]); - } - *mtimecmp = next; + 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) set_csr(mie, MIP_MTIP); } @@ -96,8 +113,6 @@ 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 (evt && (evt <= EOS_TIMER_MAX_ETYPE)) { evt--; } else if (evt == 0) { @@ -105,20 +120,21 @@ void eos_timer_clear(unsigned char evt) { } else { 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; + 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_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); - if (evt && (evt <= EOS_TIMER_MAX_ETYPE)) { evt--; } else if (evt == 0) { @@ -126,8 +142,10 @@ void eos_timer_set_handler(unsigned char evt, eos_timer_fptr_t handler, uint8_t } else { return; } - timer_handler[evt] = handler; - if (flags) eos_evtq_set_flags(EOS_EVT_TIMER | evt, flags); + clear_csr(mie, MIP_MTIP); + timer_handler[evt] = handler; if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); + + if ((evt != EOS_TIMER_MAX_ETYPE) && flags) eos_evtq_set_flags(EOS_EVT_TIMER | evt + 1, flags); } diff --git a/code/fe310/eos/timer.h b/code/fe310/eos/timer.h index 34512fa..0807d96 100644 --- a/code/fe310/eos/timer.h +++ b/code/fe310/eos/timer.h @@ -8,5 +8,7 @@ typedef void (*eos_timer_fptr_t) (unsigned char); void eos_timer_init(void); -void eos_timer_set(uint32_t tick, unsigned char evt); +uint64_t eos_timer_get(unsigned char evt); +void eos_timer_set(uint64_t tick, unsigned char evt, unsigned char b); +void eos_timer_clear(unsigned char evt); void eos_timer_set_handler(unsigned char evt, eos_timer_fptr_t handler, uint8_t flags); -- cgit v1.2.3