summaryrefslogtreecommitdiff
path: root/code/fe310/eos/timer.c
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2019-10-15 18:11:40 +0200
committerUros Majstorovic <majstor@majstor.org>2019-10-15 18:11:40 +0200
commitedec491d59697a635ddce7a19a870dd3e8d2f3ed (patch)
tree8b5c00103609eabe9fdc89169c825f544aca41d5 /code/fe310/eos/timer.c
parent850ce8bb7a447e1d2500d5dac0b0003bb4412c37 (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.c118
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);
}