summaryrefslogtreecommitdiff
path: root/code/fe310
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2019-10-15 20:20:38 +0200
committerUros Majstorovic <majstor@majstor.org>2019-10-15 20:20:38 +0200
commit86957adfc5e2177010db896581763b4cba07273e (patch)
treec7513c2e5953cb664e9cb5e4d30180dc94b1d758 /code/fe310
parent98b5515f2ada43ca84ab4e8cfbec2c4844eaad6e (diff)
timer bugfix
Diffstat (limited to 'code/fe310')
-rw-r--r--code/fe310/eos/ecp.c5
-rw-r--r--code/fe310/eos/timer.c64
-rw-r--r--code/fe310/eos/timer.h4
3 files changed, 47 insertions, 26 deletions
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);