gadget-kspconsole/task.c
Daniele Lacamera b8a7ffcd31 Initial import
2023-11-27 15:16:45 +01:00

142 lines
2.8 KiB
C

/*
* 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);
}
}