]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/pattern.c
56f4781bee1131e2209ce8010de5d0847117a1d5
[bike-lights.git] / firmware / pattern.c
1 #include <avr/io.h>
2
3 #include "lights.h"
4
5 static unsigned char led_counters[N_LEDS];
6 static pattern_t *led_patterns[N_LEDS];
7
8 pattern_t off_pattern[] = {
9         { 0, PATTERN_FOREVER },
10 };
11
12 pattern_t on_pattern[] = {
13         { 1, PATTERN_FOREVER },
14 };
15
16 pattern_t blink_pattern[] = {
17         { 1, 0x4 },
18         { 0, 0x8 },
19         PATTERN_END
20 };
21
22 pattern_t mode1_pattern[] = {
23         { 4, 0x1 },
24         { 0, 0x1 },
25         { 4, 0x1 },
26         { 0, 0x8 },
27         { 1, 0x1 },
28         { 0, 0x1 },
29         { 1, 0x1 },
30         { 0, 0x8 },
31         PATTERN_END
32 };
33
34 pattern_t boot_pattern[] = {
35         { 1, 0x6 },
36         { 0, 0x6 },
37         { 1, 0x3 },
38         { 0, 0x3 },
39         { 1, 0x2 },
40         { 0, 0x2 },
41         { 1, 0x1 },
42         { 0, 0x1 },
43         { 1, 0x1 },
44         { 0, 0x1 },
45         { 1, 0x1 },
46         { 0, 0x1 },
47         { 1, 0x1 },
48         { 0, 0x1 },
49         { 1, 0x10 },
50         { 0, 0x10 },
51         PATTERN_END
52 };
53
54 pattern_t pattern_num[] = {
55         { 0, 0x5 },
56         { 1, 0x1 }, /* 10 */
57         { 0, 0x5 },
58         { 1, 0x1 }, /*  9 */
59         { 0, 0x5 },
60         { 1, 0x1 }, /*  8 */
61         { 0, 0x5 },
62         { 1, 0x1 }, /*  7 */
63         { 0, 0x5 },
64         { 1, 0x1 }, /*  6 */
65         { 0, 0x5 },
66         { 1, 0x1 }, /*  5 */
67         { 0, 0x5 },
68         { 1, 0x1 }, /*  4 */
69         { 0, 0x5 },
70         { 1, 0x1 }, /*  3 */
71         { 0, 0x5 },
72         { 1, 0x1 }, /*  2 */
73         { 0, 0x5 },
74         { 1, 0x1 }, /*  1 */
75         { 0, 0x1E },
76         PATTERN_END
77 };
78
79 static unsigned char test_running;
80
81 static void led_set_mode(unsigned char n, unsigned char mode)
82 {
83         if (n < N_PWMLEDS) {
84                 pwmled_set_mode(n, mode);
85         } else if (n < N_LEDS) {
86                 gpio_set(n - N_PWMLEDS, mode);
87         }
88 }
89
90 void led_set_pattern(unsigned char n, pattern_t *pattern)
91 {
92         if (!pattern)
93                 pattern = off_pattern;
94
95         led_patterns[n] = pattern;
96         led_counters[n] = pattern->duration;
97         led_set_mode(n, pattern->mode);
98 }
99
100 void pattern_init()
101 {
102         unsigned char i;
103
104         for (i = 0; i < N_LEDS; i++)
105                 led_set_pattern(i, off_pattern);
106
107         led_set_pattern(N_PWMLEDS+1, boot_pattern);
108         test_running = 0;
109 }
110
111 pattern_t *number_pattern(unsigned char num)
112 {
113         if (num >= 9)
114                 num = 9;
115
116         return pattern_num + sizeof(pattern_num)/sizeof(pattern_t)
117                 - 2 - 2*num;
118 }
119
120 static inline pattern_t *pattern_select(unsigned char n)
121 {
122         if (n < N_PWMLEDS && !pwmled_enabled(n))
123                 return off_pattern; // Don't mess with non-enabled LEDs
124         else if (n < N_PWMLEDS)
125                 return mode1_pattern;
126         else if (n == 3)
127                 return status_pattern_select(0);
128         else if (n == 4)
129                 return status_pattern_select(1);
130         return off_pattern;
131 }
132
133 void patterns_next_tick()
134 {
135         unsigned char i;
136
137         for (i = 0; i < N_LEDS; i++) {
138                 if (led_counters[i] == 0) {
139                         pattern_t *p = led_patterns[i];
140                         p++;
141                         if (p->duration == 0) { // END
142                                 p = pattern_select(i);
143                         }
144                         led_set_pattern(i, p);
145                 }
146
147                 if (led_counters[i] < PATTERN_FOREVER)
148                         led_counters[i]--;
149         }
150 }
151
152 void led_set_status(unsigned char status)
153 {
154         led_set_pattern(N_PWMLEDS+1, number_pattern(status));
155 }