]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/control.c
2b1a7369f39f24e8b949e0d8e60aa73eb91d18fc
[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         { PWM_PAT(2, 0, 0), D_1 },
8         { PWM_PAT(0, 0, 2), D_1 },
9         { PWM_PAT(0, 0, 0), D_1 },
10         { PWM_PAT(2, 0, 0), D_1 },
11         { PWM_PAT(0, 0, 2), D_1 },
12         { PWM_PAT(0, 0, 0), D_1 },
13         { PWM_PAT(2, 0, 0), D_1 },
14         { PWM_PAT(0, 0, 2), D_1 },
15         { PWM_PAT(0, 0, 0), D_1 },
16         { PWM_PAT(2, 0, 0), D_1 },
17         { PWM_PAT(0, 0, 2), D_1 },
18         { PWM_PAT(0, 0, 0), D_1 },
19         { PWM_PAT(2, 0, 0), D_1 },
20         { PWM_PAT(0, 0, 2), D_1 },
21         { PWM_PAT(0, 0, 0), D_1 },
22         { PWM_PAT(2, 0, 0), D_1 },
23         { PWM_PAT(0, 0, 2), D_1 },
24         { PWM_PAT(0, 0, 0), D_1 },
25         { PWM_PAT(2, 0, 0), D_1 },
26         { PWM_PAT(0, 0, 2), D_1 },
27         { PWM_PAT(0, 0, 0), D_1 },
28         PATTERN_END
29 };
30
31 static pattern_t slow_pattern[] = {
32         { PWM_PAT(1, 0, 0), D_1 },
33         { PWM_PAT(0, 0, 1), D_1 },
34         { PWM_PAT(0, 0, 0), D_13 },
35         PATTERN_END
36 };
37
38 static pattern_t fast_pattern[] = {
39         { PWM_PAT(2, 0, 0), D_1 },
40         { PWM_PAT(0, 0, 2), D_1 },
41         { PWM_PAT(2, 0, 0), D_1 },
42         { PWM_PAT(0, 0, 2), D_1 },
43         { PWM_PAT(0, 0, 0), D_8 },
44         { PWM_PAT(1, 0, 0), D_1 },
45         { PWM_PAT(0, 0, 1), D_1 },
46         { PWM_PAT(1, 0, 0), D_1 },
47         { PWM_PAT(0, 0, 1), D_1 },
48         { PWM_PAT(0, 0, 0), D_8 },
49         PATTERN_END
50 };
51
52 static pattern_t night_pattern[] = {
53         { PWM_PAT(3, 0, 1), D_3 },
54         { PWM_PAT(2, 0, 0), D_8 },
55         { PWM_PAT(3, 0, 1), D_1 },
56         { PWM_PAT(2, 0, 0), D_2 },
57         { PWM_PAT(3, 0, 1), D_1 },
58         { PWM_PAT(2, 0, 0), D_8 },
59         PATTERN_END
60 };
61
62 pattern_t on_pattern[] = {
63         { 1, D_8 },
64         PATTERN_END
65 };
66
67 // #define TEST_PATTERN 1
68 #ifdef TEST_PATTERN
69 pattern_t test_pattern[] = {
70         { PWM_PAT(1, 0, 0), D_13 },
71         { PWM_PAT(2, 0, 0), D_13 },
72         { PWM_PAT(0, 0, 1), D_13 },
73         { PWM_PAT(0, 0, 2), D_13 },
74         PATTERN_END
75 };
76 #endif
77
78 volatile err_flags_t err_flags;
79 static unsigned char dim_mode, towbar_mode;
80
81 void init_control()
82 {
83         dim_mode = 0;
84         towbar_mode = 0;
85         err_flags.any_flag = 0;
86 #ifdef notyet
87         err_flags.booting = 1;
88 #endif
89
90         pwmled_select_brightness();
91 }
92
93 void brake_on()
94 {
95         err_flags.braking = 1;
96         gpio_set(0, 1);
97         led_set_pattern(N_STATUS_LED, status_led_pattern_select());
98         pwmleds_update_mode();
99 }
100
101 void brake_off()
102 {
103         err_flags.braking = 0;
104         gpio_set(0, 0);
105         led_set_pattern(N_STATUS_LED, status_led_pattern_select());
106         pwmleds_update_mode();
107 }
108
109 void toggle_dim_mode()
110 {
111         dim_mode = !dim_mode;
112         pwmled_select_brightness();
113         pattern_reload();
114 }
115
116 void set_panic_mode()
117 {
118         // if error, clean it up
119         if (err_flags.booting)
120                 err_flags.booting = 0;
121         else if (err_flags.err_pwmled2)
122                 err_flags.err_pwmled2 = 0;
123         else if (err_flags.err_pwmled1)
124                 err_flags.err_pwmled1 = 0;
125         else if (err_flags.err_pwmled0)
126                 err_flags.err_pwmled0 = 0;
127         else if (err_flags.err_battery)
128                 err_flags.err_battery = 0;
129         else {
130                 led_set_pattern(0, panic_pattern);
131                 led_set_pattern(N_ILLUM_LED, panic_pattern);
132         }
133 }
134
135 pattern_t *pwmled_pattern_select()
136 {
137 #ifdef TEST_PATTERN
138         return tmp_pattern;
139 #endif
140         if (err_flags.err_battery)
141                 return slow_pattern;
142
143         if (ambient_shadow)
144                 return night_pattern;
145
146         switch (ambient_zone) {
147         case 0: return night_pattern;
148         case 1:
149         case 2:
150         case 3:
151         default:
152                 return dim_mode ? slow_pattern : fast_pattern;
153         }
154 }
155
156 pattern_t *status_led_pattern_select()
157 {
158         if (err_flags.booting)
159                 return number_pattern(1, 1);
160
161         if (err_flags.err_pwmled2)
162                 return number_pattern(5, 1);
163
164         if (err_flags.err_pwmled1)
165                 return number_pattern(4, 1);
166
167         if (err_flags.err_pwmled0)
168                 return number_pattern(3, 1);
169
170         if (err_flags.err_battery)
171                 return number_pattern(2, 1);
172
173         if (err_flags.braking)
174                 return on_pattern;
175
176         if (buttons_setup_in_progress())
177                 return buttons_setup_status0_pattern_select();
178
179         // FIXME: do something sane
180         return number_pattern(battery_gauge(), 0);
181 }
182
183 pattern_t *illumination_led_pattern_select()
184 {
185         if (buttons_setup_in_progress())
186                 return buttons_setup_status1_pattern_select();
187
188         if (err_flags.err_battery)
189                 return NULL;
190
191         if (ambient_shadow)
192                 return on_pattern;
193
194         switch (ambient_zone) {
195         case 0: return dim_mode
196                 ? number_pattern(1, 1)
197                 : on_pattern;
198         case 1: return dim_mode
199                 ? number_pattern(2, 1)
200                 : number_pattern(3, 1);
201         case 2: return dim_mode
202                 ? number_pattern(1, 0)
203                 : number_pattern(2, 0);
204         case 3:
205         default: return dim_mode
206                 ? number_pattern(3, 0)
207                 : number_pattern(4, 0);
208         }
209 }
210
211 pattern_t *laser_pattern_select()
212 {
213         if (!dim_mode && ambient_zone <= 1)
214                 return number_pattern(2, 1);
215         else
216                 return NULL;
217 }
218
219 void pwmled_select_brightness()
220 {
221         uint16_t brightness = PWMLED_BRIGHTNESS(0, 2, 1, 0, 2); // default
222
223         if (err_flags.err_battery) {
224                 brightness = PWMLED_BRIGHTNESS(0, 0, 0, 0, 0);
225         } else if (ambient_zone == 0) {
226                 if (dim_mode)
227                         brightness = PWMLED_BRIGHTNESS(0, 1, 0, 0, 1);
228                 else
229                         brightness = PWMLED_BRIGHTNESS(1, 3, 2, 1, 3);
230         } else if (ambient_zone == 1) {
231                 if (dim_mode)
232                         brightness = PWMLED_BRIGHTNESS(0, 1, 0, 0, 1);
233                 else
234                         brightness = PWMLED_BRIGHTNESS(0, 2, 1, 0, 2);
235         } else if (ambient_zone == 2) {
236                 brightness = PWMLED_BRIGHTNESS(1, 3, 2, 1, 3);
237         } else if (ambient_zone == 3) {
238                 brightness = PWMLED_BRIGHTNESS(2, 4, 2, 2, 4);
239         }
240
241         pwmled_set_brightness(brightness);
242 }