]> www.fi.muni.cz Git - tinyboard.git/blob - projects/step-up/pattern.c
pattern.c: ADC-timed blinking patterns
[tinyboard.git] / projects / step-up / pattern.c
1 #include <avr/io.h>
2 #include <stdlib.h> // for NULL
3
4 #include "lights.h"
5
6 #define N_LEDS 1
7 static unsigned char led_counters[N_LEDS];
8 static pattern_t *led_patterns[N_LEDS];
9
10 static pattern_t pattern_num[] = {
11         { 0, 0x5 },
12         { 1, 0x1 }, /* 10 */
13         { 0, 0x5 },
14         { 1, 0x1 }, /*  9 */
15         { 0, 0x5 },
16         { 1, 0x1 }, /*  8 */
17         { 0, 0x5 },
18         { 1, 0x1 }, /*  7 */
19         { 0, 0x5 },
20         { 1, 0x1 }, /*  6 */
21         { 0, 0x5 },
22         { 1, 0x1 }, /*  5 */
23         { 0, 0x5 },
24         { 1, 0x1 }, /*  4 */
25         { 0, 0x5 },
26         { 1, 0x1 }, /*  3 */
27         { 0, 0x5 },
28         { 1, 0x1 }, /*  2 */
29         { 0, 0x5 },
30         { 1, 0x1 }, /*  1 */
31         { 0, 0xF },
32         PATTERN_END
33 };
34
35 static pattern_t pattern_invnum[] = {
36         { 1, 0x5 },
37         { 0, 0x1 }, /* 10 */
38         { 1, 0x5 },
39         { 0, 0x1 }, /*  9 */
40         { 1, 0x5 },
41         { 0, 0x1 }, /*  8 */
42         { 1, 0x5 },
43         { 0, 0x1 }, /*  7 */
44         { 1, 0x5 },
45         { 0, 0x1 }, /*  6 */
46         { 1, 0x5 },
47         { 0, 0x1 }, /*  5 */
48         { 1, 0x5 },
49         { 0, 0x1 }, /*  4 */
50         { 1, 0x5 },
51         { 0, 0x1 }, /*  3 */
52         { 1, 0x5 },
53         { 0, 0x1 }, /*  2 */
54         { 1, 0x5 },
55         { 0, 0x1 }, /*  1 */
56         { 1, 0xF },
57         PATTERN_END
58 };
59
60 pattern_t off_pattern[] = {
61         { 0, 0x1 },
62         PATTERN_END
63 };
64
65 pattern_t on1_pattern[] = {
66         { 1, 1 },
67         { 0, 2 },
68         { 1, 1 },
69         { 0, 8 },
70         { 1, 1 },
71         { 0, 8 },
72         PATTERN_END
73 };
74
75 static void led_set_mode(unsigned char n, unsigned char mode)
76 {
77         if (n == 0) {
78                 pwmled_on_off(mode);
79         }
80 }
81
82 void led_set_pattern(unsigned char n, pattern_t *pattern)
83 {
84         if (!pattern)
85                 pattern = off_pattern;
86
87         led_patterns[n] = pattern;
88
89         led_counters[n] = pattern->duration;
90         led_set_mode(n, pattern->mode);
91 }
92
93 void init_pattern()
94 {
95         unsigned char i;
96
97         for (i = 0; i < N_LEDS; i++)
98                 led_set_pattern(i, NULL);
99 }
100
101 pattern_t *number_pattern(unsigned char num, unsigned char inv)
102 {
103         if (num >= 10)
104                 num = 10;
105
106         if (inv) {
107                 return pattern_invnum
108                         + sizeof(pattern_invnum)/sizeof(pattern_t)
109                         - 2 - 2*num;
110         } else {
111                 return pattern_num
112                         + sizeof(pattern_num)/sizeof(pattern_t)
113                         - 2 - 2*num;
114         }
115 }
116
117 static pattern_t *pattern_select(unsigned char n)
118 {
119         static unsigned char count;
120         static unsigned char mode;
121         switch(n) {
122         case 0:
123                 if (++count > 2) {
124                         count = 0;
125                         if (mode == 0) {
126                                 mode = 3;
127                         } else {
128                                 mode = 0;
129                         }
130
131                         pwmled_set_target(mode);
132                 }
133                 return number_pattern(mode ? 2 : 3, 0);
134         default: return NULL;
135         }
136 }
137
138 void pattern_reload()
139 {
140         unsigned char i;
141
142         for (i = 0; i < N_LEDS; i++)
143                 led_set_pattern(i, pattern_select(i));
144 }
145
146 static void inline pattern_finished(unsigned char n)
147 {
148         unsigned char i;
149
150         led_patterns[n] = NULL;
151
152         if (n == 0) {
153                 led_set_pattern(0, pattern_select(0));
154         }
155 #if 0
156         } else if (n == 3) {
157                 if (!led_patterns[4])
158                         led_set_pattern(4, pattern_select(4));
159         } else if (n == 4) {
160                 if (!led_patterns[3])
161                         led_set_pattern(3, pattern_select(3));
162         } else {
163                 led_set_pattern(n, pattern_select(n));
164         }
165 #endif
166 }
167
168 void patterns_next_tick()
169 {
170         unsigned char i;
171
172         for (i = 0; i < N_LEDS; i++) {
173                 if (!led_patterns[i]) {
174                         pattern_finished(i);
175                         continue;
176                 }
177
178                 if (--led_counters[i] == 0) {
179                         pattern_t *p = led_patterns[i];
180                         p++;
181                         if (p->duration == 0) { // END
182                                 /* Keep the last state, wait for others */
183                                 pattern_finished(i);
184                                 continue;
185                         }
186                         led_set_pattern(i, p);
187                 }
188
189         }
190 }
191