Changed the way that the led colors are stored in the config file
[apps/native/gear-racing-car.git] / src / resource / resource_led.c
1 /*
2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3 *
4 * Licensed under the Flora License, Version 1.1 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://floralicense.org/license/
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <glib.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <limits.h>
21 #include <stdlib.h>
22 #include <peripheral_io.h>
23 #include <time.h>
24 #include "log.h"
25 #include "resource/resource_led.h"
26 #include "resource/resource_PCA9685.h"
27 #include "config.h"
28
29 #define DEFAULT_BI_LED_RED 17
30 #define DEFAULT_BI_LED_GREEN 27
31
32 #define CONFIG_KEY_RPI_BI_LED_RED "bi.red"
33 #define CONFIG_KEY_RPI_BI_LED_GREEN "bi.green"
34 #define CONFIG_KEY_RPI_USE_BI_LED "bi.use"
35
36 #define CONFIG_KEY_RPI_RGB_GPIO_R "rgb.gpio.red"
37 #define CONFIG_KEY_RPI_RGB_GPIO_G "rgb.gpio.green"
38 #define CONFIG_KEY_RPI_RGB_GPIO_B "rgb.gpio.blue"
39 #define CONFIG_KEY_RPI_USE_GPIO_RGB "rgb.gpio.use"
40
41 #define CONFIG_KEY_RPI_RGB_L2C_R "rgb.l2c.red"
42 #define CONFIG_KEY_RPI_RGB_L2C_G "rgb.l2c.green"
43 #define CONFIG_KEY_RPI_RGB_L2C_B "rgb.l2c.blue"
44 #define CONFIG_KEY_RPI_USE_L2C_RGB "rgb.l2c.use"
45
46
47 #define DEFAULT_RGB_GPIO_R 23
48 #define DEFAULT_RGB_GPIO_G 24
49 #define DEFAULT_RGB_GPIO_B 25
50
51 #define DEFAULT_RGB_L2C_R 8
52 #define DEFAULT_RGB_L2C_G 9
53 #define DEFAULT_RGB_L2C_B 10
54
55 #define CONFIG_GRP_RPI "Rpi.led"
56
57
58 typedef struct _led_s {
59         peripheral_gpio_h gpio_bi_led[2];
60         peripheral_gpio_h rgb_gpio[3];
61         bi_led_color_e current_color;
62
63
64         bool current_rgb_gpio_color[3];
65         int current_rgb_l2c_color[3];
66
67         int use_bi_led;
68         int use_rgb_gpio;
69         int use_rgb_l2c;
70 } led_s;
71
72 static led_s s_info = {
73         .current_color = LED_COLOR_NONE,
74         .current_rgb_gpio_color = { 0, },
75         .current_rgb_l2c_color = { 0, },
76         0, };
77
78 #define  CHECK_GPIO_ERROR(pin, ret) \
79         if (ret != PERIPHERAL_ERROR_NONE) { \
80                 peripheral_gpio_close(pin); \
81                 _E("GPIO ERROR: %s, %s[%d]", get_error_message(ret), __FILE__, __LINE__); \
82                 return ; \
83         }
84
85 #define RGB_TO_REGISTER(val) ((unsigned)((float)val / 255.0f * 4095u))
86
87 static inline void _led_bi_set(bi_led_color_e color)
88 {
89         int red;
90         int green;
91
92         if (!s_info.use_bi_led) {
93                 _D("Bi led is turned OFF");
94                 return;
95         }
96
97         switch (color) {
98                 case LED_COLOR_RED:
99                         red = 1;
100                         green = 0;
101                         break;
102                 case LED_COLOR_GREEN:
103                         red = 0;
104                         green = 1;
105                         break;
106                 default:
107                         red = 0;
108                         green = 0;
109                         break;
110         }
111
112         int ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_RED], red);
113         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
114
115         ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_GREEN], green);
116         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
117
118         _D("BI: [%d, %d]", red, green);
119 }
120
121 static inline void _rgb_gpio_set(bool red, bool green, bool blue)
122 {
123         if (!s_info.use_rgb_gpio) {
124                 _D("gpio rgb led is turned OFF");
125                 return;
126         }
127
128         _D("RGB GPIO: [%d, %d, %d]", red, green, blue);
129
130         int ret = peripheral_gpio_write(s_info.rgb_gpio[0], red);
131         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
132
133         ret = peripheral_gpio_write(s_info.rgb_gpio[1], green);
134         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
135
136         ret = peripheral_gpio_write(s_info.rgb_gpio[2], blue);
137         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
138 }
139
140 static inline void _rgb_l2c_set(int red, int green, int blue)
141 {
142         FUNCTION_START;
143         if (!s_info.use_rgb_l2c) {
144                 _D("l2c rgb led is turned OFF");
145                 return;
146         }
147
148         int ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_R, 0, RGB_TO_REGISTER(red));
149         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
150
151         ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_G, 0, RGB_TO_REGISTER(green));
152         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
153
154         ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_B, 0, RGB_TO_REGISTER(blue));
155         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
156
157         _D("RGB L2C: [%d, %d, %d] -> [%d, %d, %d]", red, green, blue, RGB_TO_REGISTER(red), RGB_TO_REGISTER(green), RGB_TO_REGISTER(blue));
158         FUNCTION_END;
159 }
160
161 static gboolean _restore_bi_color_cb(gpointer data)
162 {
163         _led_bi_set(s_info.current_color);
164         return false;
165 }
166
167 static gboolean _restore_rgb_gpio_color_cb(gpointer data)
168 {
169         _rgb_gpio_set(s_info.current_rgb_gpio_color[0], s_info.current_rgb_gpio_color[1], s_info.current_rgb_gpio_color[2]);
170         return false;
171 }
172
173 static gboolean _restore_rgb_l2c_color_cb(gpointer data)
174 {
175         FUNCTION_START;
176         _rgb_l2c_set(s_info.current_rgb_l2c_color[0], s_info.current_rgb_l2c_color[1], s_info.current_rgb_l2c_color[2]);
177         FUNCTION_END;
178         return false;
179 }
180
181 static gboolean _restore_rgb_color_cb(gpointer data)
182 {
183         FUNCTION_START;
184
185         _restore_bi_color_cb(data);
186         _restore_rgb_gpio_color_cb(data);
187         _restore_rgb_l2c_color_cb(data);
188
189         FUNCTION_END;
190
191         return false;
192 }
193
194 static peripheral_gpio_h _init_gpio(int default_gpio, char *key)
195 {
196         peripheral_gpio_h gpio;
197
198         int pin = 0;
199         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, key, default_gpio, &pin);
200
201         _D("Initializing gpio: %d", pin);
202
203         if (modified) {
204                 config_save();
205         }
206
207         int ret = peripheral_gpio_open(pin, &gpio);
208         retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
209
210         ret = peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW);
211         retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
212
213         return gpio;
214
215 }
216
217 static void _init_bi_led(void)
218 {
219         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_BI_LED, 1, &s_info.use_bi_led);
220         if (modified) {
221                 config_save();
222         }
223
224         _D("Use bi_led: %d", s_info.use_bi_led);
225
226
227         if (s_info.use_bi_led) {
228                 s_info.gpio_bi_led[LED_COLOR_RED] = _init_gpio(DEFAULT_BI_LED_RED, CONFIG_KEY_RPI_BI_LED_RED);
229                 s_info.gpio_bi_led[LED_COLOR_GREEN] = _init_gpio(DEFAULT_BI_LED_GREEN, CONFIG_KEY_RPI_BI_LED_GREEN);
230         } else {
231                 _D("BI-Led is turned OFF");
232         }
233 }
234
235 static void _init_rgb_gpio_led(void)
236 {
237         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_GPIO_RGB, 1, &s_info.use_rgb_gpio);
238         if (modified) {
239                 config_save();
240         }
241
242         _D("Use rgb_gpio_led: %d", s_info.use_rgb_gpio);
243
244         if (!s_info.use_rgb_gpio) {
245                 _D("RGB GPIO is turned off");
246                 return;
247         }
248
249         s_info.rgb_gpio[0] = _init_gpio(DEFAULT_RGB_GPIO_R, CONFIG_KEY_RPI_RGB_GPIO_R);
250         s_info.rgb_gpio[1] = _init_gpio(DEFAULT_RGB_GPIO_G, CONFIG_KEY_RPI_RGB_GPIO_G);
251         s_info.rgb_gpio[2] = _init_gpio(DEFAULT_RGB_GPIO_B, CONFIG_KEY_RPI_RGB_GPIO_B);
252 }
253
254 void _init_l2c(int default_channel, char *config_key)
255 {
256         int channel;
257         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, config_key, default_channel, &channel);
258         if (modified) {
259                 config_save();
260         }
261
262         int ret = resource_pca9685_init(channel, 60);
263         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
264 }
265
266 static void _init_rgb_l2c_led(void)
267 {
268         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_L2C_RGB, 1, &s_info.use_rgb_l2c);
269         if (modified) {
270                 config_save();
271         }
272
273         _D("Use rgb_l2c_led: %d", s_info.use_rgb_l2c);
274
275         if (!s_info.use_rgb_l2c) {
276                 _D("RGB L2C is turned off");
277                 return;
278         }
279
280         _init_l2c(DEFAULT_RGB_L2C_R, CONFIG_KEY_RPI_RGB_L2C_R);
281         _init_l2c(DEFAULT_RGB_L2C_G, CONFIG_KEY_RPI_RGB_L2C_G);
282         _init_l2c(DEFAULT_RGB_L2C_B, CONFIG_KEY_RPI_RGB_L2C_B);
283 }
284
285 void resource_led_init(void)
286 {
287         FUNCTION_START;
288         _D("Initialize Led");
289         _init_rgb_gpio_led();
290         _init_bi_led();
291         _init_rgb_l2c_led();
292         FUNCTION_END;
293 }
294
295 void resource_led_destroy(void)
296 {
297         peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_RED]);
298         peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_GREEN]);
299
300         peripheral_gpio_close(s_info.rgb_gpio[0]);
301         peripheral_gpio_close(s_info.rgb_gpio[1]);
302         peripheral_gpio_close(s_info.rgb_gpio[2]);
303
304         resource_led_rgb_l2c_set(0, 0, 0);
305
306         resource_pca9685_fini(DEFAULT_RGB_L2C_R);
307         resource_pca9685_fini(DEFAULT_RGB_L2C_G);
308         resource_pca9685_fini(DEFAULT_RGB_L2C_B);
309 }
310
311 void resource_led_bi_set(bi_led_color_e color)
312 {
313         _D("Set led to: %d", color);
314         if (color == s_info.current_color) {
315                 _D("No change in bi led");
316                 return;
317         }
318
319         s_info.current_color = color;
320         _led_bi_set(color);
321 }
322
323 void resource_led_bi_blink(bi_led_color_e color, unsigned timeout)
324 {
325         if (color == s_info.current_color) {
326                 _D("No change in bi led");
327                 return;
328         }
329
330         _led_bi_set(color);
331         g_timeout_add(timeout, _restore_bi_color_cb, NULL);
332 }
333
334 void resource_led_rgb_gpio_set(bool red, bool green, bool blue)
335 {
336         if (red == s_info.current_rgb_gpio_color[0] &&
337                         green == s_info.current_rgb_gpio_color[1] &&
338                         blue == s_info.current_rgb_gpio_color[2]) {
339                 _D("No change in gpio led");
340                 return;
341         }
342
343
344         s_info.current_rgb_gpio_color[0] = red;
345         s_info.current_rgb_gpio_color[1] = green;
346         s_info.current_rgb_gpio_color[2] = blue;
347
348         _rgb_gpio_set(red, green, blue);
349 }
350
351 void resource_led_gpio_rgb_blink(bool red, bool green, bool blue, unsigned timeout)
352 {
353         if (red == s_info.current_rgb_gpio_color[0] &&
354                         green == s_info.current_rgb_gpio_color[1] &&
355                         blue == s_info.current_rgb_gpio_color[2]) {
356                 _D("No change in gpio led");
357                 return;
358         }
359
360         _rgb_gpio_set(red, green, blue);
361         g_timeout_add(timeout, _restore_rgb_gpio_color_cb, NULL);
362 }
363
364 void resource_led_rgb_l2c_set(int red, int green, int blue)
365 {
366         if (red == s_info.current_rgb_l2c_color[0] &&
367                         green == s_info.current_rgb_l2c_color[1] &&
368                         blue == s_info.current_rgb_l2c_color[2]) {
369                 _D("No change in l2c led");
370                 return;
371         }
372
373         s_info.current_rgb_l2c_color[0] = red;
374         s_info.current_rgb_l2c_color[1] = green;
375         s_info.current_rgb_l2c_color[2] = blue;
376
377         _rgb_l2c_set(red, green, blue);
378 }
379
380 void resource_led_rgb_l2c_blink(int red, int green, int blue, unsigned timeout)
381 {
382         if (red == s_info.current_rgb_l2c_color[0] &&
383                         green == s_info.current_rgb_l2c_color[1] &&
384                         blue == s_info.current_rgb_l2c_color[2]) {
385                 _D("No change in l2c led");
386                 return;
387         }
388
389         _rgb_l2c_set(red, green, blue);
390         g_timeout_add(timeout, _restore_rgb_l2c_color_cb, NULL);
391 }
392
393 void resource_led_set_rgb_colors(char *key,
394                 int def_r_3bit, int def_g_3bit, int def_b_3bit,
395                 int def_r_24bit, int def_g_24bit, int def_b_24bit,
396                 bi_led_color_e bi_led)
397 {
398         FUNCTION_START;
399
400         int red, green, blue;
401         char final_key[PATH_MAX];
402
403         snprintf(final_key, PATH_MAX, "3bit.%s", key);
404         bool modified = config_get_rgb_with_default("Rpi.led", final_key, def_r_3bit, def_g_3bit, def_b_3bit, &red, &green, &blue);
405         resource_led_rgb_gpio_set(red, green, blue);
406
407         _D("%s: 3bit color: [%d, %d, %d]", final_key, red, green, blue);
408
409         snprintf(final_key, PATH_MAX, "24bit.%s", key);
410         modified |= config_get_rgb_with_default("Rpi.led", final_key, def_r_24bit, def_g_24bit, def_b_24bit, &red, &green, &blue);
411         resource_led_rgb_l2c_set(red, green, blue);
412
413         _D("%s: 24bit color: [%d, %d, %d]", final_key, red, green, blue);
414
415         int value;
416         snprintf(final_key, PATH_MAX, "bicolor.%s", key);
417         modified |= config_get_int_with_default("Rpi.led", final_key, bi_led, &value);
418         resource_led_bi_set(value);
419
420         if (modified) {
421                 config_save();
422         }
423
424         _D("%s: bicolor: [%d]", final_key, value);
425
426         FUNCTION_END;
427 }
428
429 void resource_led_blink_rgb_colors(char *key,
430                 int def_r_3bit, int def_g_3bit, int def_b_3bit,
431                 int def_r_24bit, int def_g_24bit, int def_b_24bit,
432                 bi_led_color_e bi_led, int timeout)
433 {
434         FUNCTION_START;
435
436         resource_led_set_rgb_colors(key, def_r_3bit, def_g_3bit, def_b_3bit, def_r_24bit, def_g_24bit, def_b_24bit, bi_led);
437
438         g_timeout_add(timeout, _restore_rgb_color_cb, NULL);
439
440
441         FUNCTION_END;
442 }