Include mcu.h.
[dmxpainter.git] / src / sched.c
1 #include "sched.h"
2
3 #include "mcu.h"
4
5 #include <string.h>
6
7 #include <avr/interrupt.h>
8 #include <avr/sleep.h>
9
10 /////////////////////////////////////////
11
12 #define SCHED_QUEUE_LENGTH UINT8_C(10)
13
14 void *  g_sched_ring[SCHED_QUEUE_LENGTH];
15 uint8_t g_sched_head;
16 uint8_t g_sched_tail;
17
18 /////////////////////////////////////////
19
20 void sched_init()
21 {
22   set_sleep_mode(SLEEP_MODE_IDLE);
23   
24   memset(g_sched_ring, (int)NULL, sizeof(g_sched_ring));
25   g_sched_head = 0;
26   g_sched_tail = 0;
27 }
28
29 /////////////////////////////////////////
30
31 void sched_put(sched_func_t func)
32 {
33   if (func == NULL) return;
34   g_sched_ring[g_sched_tail] = func;
35   g_sched_tail = (g_sched_tail + 1) % SCHED_QUEUE_LENGTH;
36 }
37
38 uint8_t sched_get(sched_func_t * func)
39 {
40   *func = g_sched_ring[g_sched_head];
41   if (*func == NULL) return 0;
42
43   g_sched_ring[g_sched_head] = NULL;
44   g_sched_head = (g_sched_head + 1) % SCHED_QUEUE_LENGTH;
45   return 1;
46 }
47
48 /////////////////////////////////////////
49 //TODO: enqueue in front
50 void sched_loop()
51 {
52   sched_func_t first;
53   uint8_t      running;
54   sched_func_t func;
55   sched_res_t  resched;\r
56   
57   while (1) {
58     // Be atomic.
59     cli();
60
61     // Peek at scheduler queue for first call.
62     running = sched_get(&func);
63     first = func;
64     // Need a valid pointer.
65     while (running) {
66       // Got something, enable interrupts, disable sleep mode.
67       sei();
68       sleep_disable();
69
70       // Call the queued function.
71       resched = func();
72
73       // Be atomic again.
74       cli();
75
76       // If the call wasn't successful, reschedule.
77       if (resched != SCHED_OK)
78         sched_put(func);
79       
80       // Get next pointer, exit loop if done.
81       running  = sched_get(&func);\r
82       if (func == first) {\r
83         sched_put(func);\r
84         running = 0;\r
85       }
86     }
87
88     // Wait for next interrupt.
89     sleep_enable();
90     sei();
91     //sleep_cpu();
92   }
93 }
94