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