123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /*
- * Copyright (C) 2023 Daniele Lacamera <root@danielinux.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "task.h"
- #include <stdint.h>
- #include <stdlib.h>
- #include "system.h"
- static struct screen *focus = NULL;
- static int refresh = 0, redraw = 0;
- static struct task *tasklist;
- static struct screen *screenlist;
- static uint32_t trigger = 0U;
- static volatile uint32_t pending_events = 0;
- static uint8_t current_screen = 0;
- void screen_set_focus(struct screen *s)
- {
- if (s) {
- focus = s;
- if (s->draw)
- s->draw();
- }
- }
- struct screen *screen_get_focus(void)
- {
- return focus;
- }
- void screen_refresh(void)
- {
- refresh = 1;
- }
- void screen_draw(void)
- {
- redraw = 1;
- }
- struct screen *screens(void)
- {
- return screenlist;
- }
- int screen_n_screens(void)
- {
- int n = 0;
- struct screen *s = screenlist;
- while (s) {
- n++;
- s = s->next;
- }
- return n;
- }
- void register_task(struct task *t)
- {
- t->screen = NULL;
- t->next = tasklist;
- tasklist = t;
- if (t->init)
- t->init();
- }
- static int screen_id = 0;
- void register_screen(struct task *t, struct screen *s)
- {
- t->screen = s;
- s->task = t;
- s->next = screenlist;
- s->id = screen_id++;
- screenlist = s;
- if (!focus) {
- focus = screenlist;
- focus->draw();
- }
- }
- void task_add_events(struct task *t, uint32_t ev)
- {
- t->events |= ev;
- }
- void task_del_events(struct task *t, uint32_t ev)
- {
- t->events &= ~ev;
- }
- void trigger_event(uint32_t ev)
- {
- pending_events |= ev;
- }
- void clear_event(uint32_t ev)
- {
- pending_events &= ~ev;
- }
- void main_loop(void) {
- struct task *t = tasklist;
- struct screen *s;
- int prio;
- uint32_t processing_events;
- while(1) {
- WFI();
- if (!pending_events)
- continue;
- for (prio = 0; prio < 32; prio++) {
- processing_events = pending_events&(1 << prio);
- if (processing_events == 0)
- continue;
- t = tasklist;
- while(t) {
- if (processing_events & t->events)
- t->run(processing_events & t->events, NULL);
- t = t->next;
- }
- }
- clear_event(EV_SYSTICK);
- }
- }
|