task.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (C) 2023 Daniele Lacamera <root@danielinux.net>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "task.h"
  18. #include <stdint.h>
  19. #include <stdlib.h>
  20. #include "system.h"
  21. static struct screen *focus = NULL;
  22. static int refresh = 0, redraw = 0;
  23. static struct task *tasklist;
  24. static struct screen *screenlist;
  25. static uint32_t trigger = 0U;
  26. static volatile uint32_t pending_events = 0;
  27. static uint8_t current_screen = 0;
  28. void screen_set_focus(struct screen *s)
  29. {
  30. if (s) {
  31. focus = s;
  32. if (s->draw)
  33. s->draw();
  34. }
  35. }
  36. struct screen *screen_get_focus(void)
  37. {
  38. return focus;
  39. }
  40. void screen_refresh(void)
  41. {
  42. refresh = 1;
  43. }
  44. void screen_draw(void)
  45. {
  46. redraw = 1;
  47. }
  48. struct screen *screens(void)
  49. {
  50. return screenlist;
  51. }
  52. int screen_n_screens(void)
  53. {
  54. int n = 0;
  55. struct screen *s = screenlist;
  56. while (s) {
  57. n++;
  58. s = s->next;
  59. }
  60. return n;
  61. }
  62. void register_task(struct task *t)
  63. {
  64. t->screen = NULL;
  65. t->next = tasklist;
  66. tasklist = t;
  67. if (t->init)
  68. t->init();
  69. }
  70. static int screen_id = 0;
  71. void register_screen(struct task *t, struct screen *s)
  72. {
  73. t->screen = s;
  74. s->task = t;
  75. s->next = screenlist;
  76. s->id = screen_id++;
  77. screenlist = s;
  78. if (!focus) {
  79. focus = screenlist;
  80. focus->draw();
  81. }
  82. }
  83. void task_add_events(struct task *t, uint32_t ev)
  84. {
  85. t->events |= ev;
  86. }
  87. void task_del_events(struct task *t, uint32_t ev)
  88. {
  89. t->events &= ~ev;
  90. }
  91. void trigger_event(uint32_t ev)
  92. {
  93. pending_events |= ev;
  94. }
  95. void clear_event(uint32_t ev)
  96. {
  97. pending_events &= ~ev;
  98. }
  99. void main_loop(void) {
  100. struct task *t = tasklist;
  101. struct screen *s;
  102. int prio;
  103. uint32_t processing_events;
  104. while(1) {
  105. WFI();
  106. if (!pending_events)
  107. continue;
  108. for (prio = 0; prio < 32; prio++) {
  109. processing_events = pending_events&(1 << prio);
  110. if (processing_events == 0)
  111. continue;
  112. t = tasklist;
  113. while(t) {
  114. if (processing_events & t->events)
  115. t->run(processing_events & t->events, NULL);
  116. t = t->next;
  117. }
  118. }
  119. clear_event(EV_SYSTICK);
  120. }
  121. }