]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/control.c
patterns: 3 bits for duration, 5 bits for mode
[bike-lights.git] / firmware / control.c
1 #include <inttypes.h>
2 #include <stdlib.h> // for NULL
3
4 #include "lights.h"
5
6 static pattern_t panic_pattern[] = {
7         { 3, 1 }, // FIXME: will be 4, but let's be safe while testing
8         { 0, 1 },
9         { 3, 1 },
10         { 0, 1 },
11         { 3, 1 },
12         { 0, 1 },
13         { 3, 1 },
14         { 0, 1 },
15         { 3, 1 },
16         { 0, 1 },
17         { 3, 1 },
18         { 0, 1 },
19         { 3, 1 },
20         { 0, 1 },
21         { 3, 1 },
22         { 0, 1 },
23         { 3, 1 },
24         { 0, 1 },
25         { 3, 1 },
26         { 0, 1 },
27         { 3, 1 },
28         { 0, 1 },
29         PATTERN_END
30 };
31
32 pattern_t on1_pattern [] = {
33         { 1, 0x7 },
34         PATTERN_END
35 };
36
37 static pattern_t on2_pattern [] = {
38         { 2, 0x7 },
39         PATTERN_END
40 };
41
42 static pattern_t on3_pattern [] = {
43         { 3, 0x7 },
44         PATTERN_END
45 };
46
47 static pattern_t brake_pattern [] = {
48         { 4, 0x2 },
49         { 3, 0x7 },
50         PATTERN_END
51 };
52
53 static pattern_t normal2_pattern[] = {
54         { 2, 0x1 },
55         { 0, 0x1 },
56         { 2, 0x1 },
57         { 0, 0x7 },
58         { 1, 0x1 },
59         { 0, 0x1 },
60         { 1, 0x1 },
61         { 0, 0x7 },
62         PATTERN_END
63 };
64
65 static pattern_t normal3_pattern[] = {
66         { 3, 0x1 },
67         { 0, 0x1 },
68         { 3, 0x1 },
69         { 0, 0x7 },
70         { 1, 0x1 },
71         { 0, 0x1 },
72         { 1, 0x1 },
73         { 0, 0x7 },
74         PATTERN_END
75 };
76
77 static pattern_t normal4_pattern[] = {
78         { 4, 0x1 },
79         { 0, 0x1 },
80         { 4, 0x1 },
81         { 0, 0x7 },
82         { 1, 0x1 },
83         { 0, 0x1 },
84         { 1, 0x1 },
85         { 0, 0x7 },
86         PATTERN_END
87 };
88
89 static pattern_t slow1_pattern[] = {
90         { 1, 0x01 },
91         { 0, 0x7 },
92         { 0, 0x7 },
93         PATTERN_END
94 };
95
96 static pattern_t slow2_pattern[] = {
97         { 2, 0x01 },
98         { 0, 0x7 },
99         { 0, 0x7 },
100         PATTERN_END
101 };
102
103 static pattern_t slow3_pattern[] = {
104         { 3, 0x01 },
105         { 0, 0x7 },
106         { 0, 0x7 },
107         PATTERN_END
108 };
109
110 static unsigned char dim_mode, towbar_mode, braking;
111
112 void init_control()
113 {
114         dim_mode = 0;
115         towbar_mode = 0;
116         braking = 0;
117 }
118
119 void brake_on()
120 {
121         braking = 1;
122         gpio_set(0, 1);
123         led_set_pattern(N_PWMLEDS, status_led_pattern_select());
124         led_set_pattern(0, pwmled0_pattern_select());
125 }
126
127 void brake_off()
128 {
129         braking = 0;
130         gpio_set(0, 0);
131         led_set_pattern(N_PWMLEDS, status_led_pattern_select());
132         led_set_pattern(0, pwmled0_pattern_select());
133 }
134
135 void toggle_dim_mode()
136 {
137         dim_mode = !dim_mode;
138         pattern_reload();
139 }
140
141 void set_panic_mode()
142 {
143         if (!dim_mode)
144                 led_set_pattern(0, panic_pattern);
145
146         led_set_pattern(1, panic_pattern);
147         led_set_pattern(2, panic_pattern);
148         led_set_pattern(4, panic_pattern);
149 }
150
151 pattern_t *pwmled0_pattern_select()
152 {
153         if (battery_critical)
154                 return on1_pattern;
155
156         if (towbar_mode)
157                 return NULL;
158
159         if (braking)
160                 return brake_pattern;
161
162         switch (ambient_zone) {
163         case 0: return dim_mode ? NULL : number_pattern(2, 1);
164         case 1: return dim_mode ? slow1_pattern : normal2_pattern;
165         case 2: return dim_mode ? slow2_pattern : normal3_pattern;
166         case 3:
167         default: return dim_mode ? slow3_pattern : normal4_pattern;
168         }
169 }
170
171 pattern_t *pwmled1_pattern_select()
172 {
173 #ifndef TESTING_FW
174         return NULL;
175 #else
176         if (battery_critical)
177                 return on1_pattern;
178 #endif
179
180         if (towbar_mode) {
181                 switch (ambient_zone) {
182                 case 0:
183                 case 1:
184                         return dim_mode ? on2_pattern : on1_pattern;
185                 case 2: return dim_mode ? NULL : on2_pattern;
186                 case 3:
187                 default: return dim_mode ? NULL : on3_pattern;
188                 }
189         } else {
190                 switch (ambient_zone) {
191                 case 0: return dim_mode ? slow1_pattern : normal2_pattern;
192                 case 1: return dim_mode ? slow2_pattern : normal3_pattern;
193                 case 2: return dim_mode ? NULL : normal4_pattern;
194                 case 3:
195                 default: return NULL;
196                 }
197         }
198 }
199
200 pattern_t *pwmled2_pattern_select()
201 {
202 #ifndef TESTING_FW
203         if (battery_critical)
204                 return on1_pattern;
205 #endif
206
207         switch (ambient_zone) {
208         case 0: return dim_mode ? on2_pattern : on3_pattern;
209         case 1: return dim_mode ? slow1_pattern : normal2_pattern;
210         case 2:
211         case 3:
212         default:
213                 return dim_mode ? slow2_pattern : normal3_pattern;
214         }
215 }
216
217 pattern_t *status_led_pattern_select()
218 {
219         if (braking)
220                 return on1_pattern;
221
222         if (buttons_setup_in_progress())
223                 return buttons_setup_status0_pattern_select();
224
225         // FIXME: do something sane
226         return number_pattern(battery_gauge(), 0);
227 }
228
229 pattern_t *illumination_led_pattern_select()
230 {
231         if (battery_critical)
232                 return NULL;
233
234         switch (ambient_zone) {
235         case 0: return dim_mode
236                 ? number_pattern(1, 1)
237                 : on1_pattern;
238         case 1: return dim_mode
239                 ? number_pattern(2, 1)
240                 : number_pattern(3, 1);
241         case 2: return dim_mode
242                 ? number_pattern(1, 0)
243                 : number_pattern(2, 0);
244         case 3:
245         default: return dim_mode
246                 ? number_pattern(3, 0)
247                 : number_pattern(4, 0);
248         }
249 }
250
251 pattern_t *laser_pattern_select()
252 {
253         if (!dim_mode && ambient_zone <= 1)
254                 return number_pattern(2, 1);
255         else
256                 return NULL;
257 }