Function naming refactor
[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         bool is_in_blink_mode;
71 } led_s;
72
73 static led_s s_info = {
74         .current_color = LED_COLOR_NONE,
75         .current_rgb_gpio_color = { 0, },
76         .current_rgb_l2c_color = { 0, },
77         0, };
78
79 #define  CHECK_GPIO_ERROR(pin, ret) \
80         if (ret != PERIPHERAL_ERROR_NONE) { \
81                 peripheral_gpio_close(pin); \
82                 _E("GPIO ERROR: %s, %s[%d]", get_error_message(ret), __FILE__, __LINE__); \
83                 return ; \
84         }
85
86 #define RGB_TO_REGISTER(val) ((unsigned)((float)val / 255.0f * 4095u))
87
88 static inline void _led_bi_set(bi_led_color_e color, bool store_current_color)
89 {
90         int red;
91         int green;
92
93         if (!s_info.use_bi_led) {
94                 _D("Bi led is turned OFF");
95                 return;
96         }
97
98 //      if (color == s_info.current_color) {
99 //              _D("No change in bi led");
100 //              return;
101 //      }
102
103         if (store_current_color) {
104                 s_info.current_color = color;
105         }
106
107         switch (color) {
108                 case LED_COLOR_RED:
109                         red = 1;
110                         green = 0;
111                         break;
112                 case LED_COLOR_GREEN:
113                         red = 0;
114                         green = 1;
115                         break;
116                 default:
117                         red = 0;
118                         green = 0;
119                         break;
120         }
121
122         if(s_info.is_in_blink_mode) {
123                 return;
124         }
125
126         int ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_RED], red);
127         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
128
129         ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_GREEN], green);
130         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
131
132         _D("BI: [%d, %d]", red, green);
133 }
134
135 static inline void _rgb_gpio_set(bool red, bool green, bool blue, bool store_current_color)
136 {
137         if (!s_info.use_rgb_gpio) {
138                 _D("gpio rgb led is turned OFF");
139                 return;
140         }
141
142 //      if (red == s_info.current_rgb_gpio_color[0] &&
143 //                      green == s_info.current_rgb_gpio_color[1] &&
144 //                      blue == s_info.current_rgb_gpio_color[2]) {
145 //              _D("No change in gpio led");
146 //              return;
147 //      }
148
149         if (store_current_color) {
150                 s_info.current_rgb_gpio_color[0] = red;
151                 s_info.current_rgb_gpio_color[1] = green;
152                 s_info.current_rgb_gpio_color[2] = blue;
153         }
154         _D("RGB GPIO: [%d, %d, %d]", red, green, blue);
155
156         if(s_info.is_in_blink_mode) {
157                 return;
158         }
159
160         int ret = peripheral_gpio_write(s_info.rgb_gpio[0], red);
161         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
162
163         ret = peripheral_gpio_write(s_info.rgb_gpio[1], green);
164         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
165
166         ret = peripheral_gpio_write(s_info.rgb_gpio[2], blue);
167         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
168 }
169
170 static inline void _rgb_l2c_set(int red, int green, int blue, bool store_current_color)
171 {
172         FUNCTION_START;
173         if (!s_info.use_rgb_l2c) {
174                 _D("l2c rgb led is turned OFF");
175                 return;
176         }
177
178 //      if (red == s_info.current_rgb_l2c_color[0] &&
179 //                      green == s_info.current_rgb_l2c_color[1] &&
180 //                      blue == s_info.current_rgb_l2c_color[2]) {
181 //              _D("No change in l2c led");
182 //              return;
183 //      }
184
185         if (store_current_color) {
186                 s_info.current_rgb_l2c_color[0] = red;
187                 s_info.current_rgb_l2c_color[1] = green;
188                 s_info.current_rgb_l2c_color[2] = blue;
189         }
190
191         if(s_info.is_in_blink_mode) {
192                 return;
193         }
194
195         int ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_R, 0, RGB_TO_REGISTER(red));
196         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
197
198         ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_G, 0, RGB_TO_REGISTER(green));
199         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
200
201         ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_B, 0, RGB_TO_REGISTER(blue));
202         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
203
204         _D("RGB L2C: [%d, %d, %d] -> [%d, %d, %d]", red, green, blue, RGB_TO_REGISTER(red), RGB_TO_REGISTER(green), RGB_TO_REGISTER(blue));
205         FUNCTION_END;
206 }
207
208 static gboolean _restore_bi_color_cb(gpointer data)
209 {
210         _led_bi_set(s_info.current_color, false);
211         return false;
212 }
213
214 static gboolean _restore_rgb_gpio_color_cb(gpointer data)
215 {
216         _rgb_gpio_set(s_info.current_rgb_gpio_color[0], s_info.current_rgb_gpio_color[1], s_info.current_rgb_gpio_color[2], false);
217         return false;
218 }
219
220 static gboolean _restore_rgb_l2c_color_cb(gpointer data)
221 {
222         FUNCTION_START;
223         _rgb_l2c_set(s_info.current_rgb_l2c_color[0], s_info.current_rgb_l2c_color[1], s_info.current_rgb_l2c_color[2], false);
224         FUNCTION_END;
225         return false;
226 }
227
228 static gboolean _restore_rgb_color_cb(gpointer data)
229 {
230         FUNCTION_START;
231         s_info.is_in_blink_mode = false;
232         _restore_bi_color_cb(data);
233         _restore_rgb_gpio_color_cb(data);
234         _restore_rgb_l2c_color_cb(data);
235
236         FUNCTION_END;
237
238         return false;
239 }
240
241 static peripheral_gpio_h _init_gpio(int default_gpio, char *key)
242 {
243         peripheral_gpio_h gpio;
244
245         int pin = 0;
246         bool modified = config_get_int_or_set_default(CONFIG_GRP_RPI, key, default_gpio, &pin);
247
248         _D("Initializing gpio: %d", pin);
249
250         if (modified) {
251                 config_save();
252         }
253
254         int ret = peripheral_gpio_open(pin, &gpio);
255         retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
256
257         ret = peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW);
258         retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
259
260         return gpio;
261
262 }
263
264 static void _init_bi_led(void)
265 {
266         bool modified = config_get_int_or_set_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_BI_LED, 1, &s_info.use_bi_led);
267         if (modified) {
268                 config_save();
269         }
270
271         _D("Use bi_led: %d", s_info.use_bi_led);
272
273
274         if (s_info.use_bi_led) {
275                 s_info.gpio_bi_led[LED_COLOR_RED] = _init_gpio(DEFAULT_BI_LED_RED, CONFIG_KEY_RPI_BI_LED_RED);
276                 s_info.gpio_bi_led[LED_COLOR_GREEN] = _init_gpio(DEFAULT_BI_LED_GREEN, CONFIG_KEY_RPI_BI_LED_GREEN);
277         } else {
278                 _D("BI-Led is turned OFF");
279         }
280 }
281
282 static void _init_rgb_gpio_led(void)
283 {
284         bool modified = config_get_int_or_set_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_GPIO_RGB, 1, &s_info.use_rgb_gpio);
285         if (modified) {
286                 config_save();
287         }
288
289         _D("Use rgb_gpio_led: %d", s_info.use_rgb_gpio);
290
291         if (!s_info.use_rgb_gpio) {
292                 _D("RGB GPIO is turned off");
293                 return;
294         }
295
296         s_info.rgb_gpio[0] = _init_gpio(DEFAULT_RGB_GPIO_R, CONFIG_KEY_RPI_RGB_GPIO_R);
297         s_info.rgb_gpio[1] = _init_gpio(DEFAULT_RGB_GPIO_G, CONFIG_KEY_RPI_RGB_GPIO_G);
298         s_info.rgb_gpio[2] = _init_gpio(DEFAULT_RGB_GPIO_B, CONFIG_KEY_RPI_RGB_GPIO_B);
299 }
300
301 void _init_l2c(int default_channel, char *config_key)
302 {
303         int channel;
304         bool modified = config_get_int_or_set_default(CONFIG_GRP_RPI, config_key, default_channel, &channel);
305         if (modified) {
306                 config_save();
307         }
308
309         int ret = resource_pca9685_init(channel, 60);
310         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
311 }
312
313 static void _init_rgb_l2c_led(void)
314 {
315         bool modified = config_get_int_or_set_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_L2C_RGB, 1, &s_info.use_rgb_l2c);
316         if (modified) {
317                 config_save();
318         }
319
320         _D("Use rgb_l2c_led: %d", s_info.use_rgb_l2c);
321
322         if (!s_info.use_rgb_l2c) {
323                 _D("RGB L2C is turned off");
324                 return;
325         }
326
327         _init_l2c(DEFAULT_RGB_L2C_R, CONFIG_KEY_RPI_RGB_L2C_R);
328         _init_l2c(DEFAULT_RGB_L2C_G, CONFIG_KEY_RPI_RGB_L2C_G);
329         _init_l2c(DEFAULT_RGB_L2C_B, CONFIG_KEY_RPI_RGB_L2C_B);
330 }
331
332 void resource_led_init(void)
333 {
334         FUNCTION_START;
335         _D("Initialize Led");
336         _init_rgb_gpio_led();
337         _init_bi_led();
338         _init_rgb_l2c_led();
339         FUNCTION_END;
340 }
341
342 void resource_led_destroy(void)
343 {
344         peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_RED]);
345         peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_GREEN]);
346
347         peripheral_gpio_close(s_info.rgb_gpio[0]);
348         peripheral_gpio_close(s_info.rgb_gpio[1]);
349         peripheral_gpio_close(s_info.rgb_gpio[2]);
350
351         _rgb_l2c_set(0, 0, 0, true);
352
353         resource_pca9685_fini(DEFAULT_RGB_L2C_R);
354         resource_pca9685_fini(DEFAULT_RGB_L2C_G);
355         resource_pca9685_fini(DEFAULT_RGB_L2C_B);
356 }
357
358 static void _set_rgb(char *key, bool store_current,
359                 int def_r_3bit, int def_g_3bit, int def_b_3bit,
360                 int def_r_24bit, int def_g_24bit, int def_b_24bit,
361                 bi_led_color_e bi_led)
362 {
363         int red, green, blue;
364         char final_key[PATH_MAX];
365
366         snprintf(final_key, PATH_MAX, "3bit.%s", key);
367         bool modified = config_get_rgb_with_default("Rpi.led", final_key, def_r_3bit, def_g_3bit, def_b_3bit, &red, &green, &blue);
368         _rgb_gpio_set(red, green, blue, store_current);
369
370         snprintf(final_key, PATH_MAX, "24bit.%s", key);
371         modified |= config_get_rgb_with_default("Rpi.led", final_key, def_r_24bit, def_g_24bit, def_b_24bit, &red, &green, &blue);
372         _rgb_l2c_set(red, green, blue, store_current);
373
374         int value;
375         snprintf(final_key, PATH_MAX, "bicolor.%s", key);
376         modified |= config_get_int_or_set_default("Rpi.led", final_key, bi_led, &value);
377         _led_bi_set(value, store_current);
378
379         if (modified) {
380                 config_save();
381         }
382 }
383
384 void resource_led_set_rgb_colors(char *key,
385                 int def_r_3bit, int def_g_3bit, int def_b_3bit,
386                 int def_r_24bit, int def_g_24bit, int def_b_24bit,
387                 bi_led_color_e bi_led)
388 {
389         FUNCTION_START;
390
391         _set_rgb(key, true, def_r_3bit, def_g_3bit, def_b_3bit, def_r_24bit, def_g_24bit, def_b_24bit, bi_led);
392
393         FUNCTION_END;
394 }
395
396 void resource_led_blink_rgb_colors(char *key,
397                 int def_r_3bit, int def_g_3bit, int def_b_3bit,
398                 int def_r_24bit, int def_g_24bit, int def_b_24bit,
399                 bi_led_color_e bi_led, int timeout)
400 {
401         FUNCTION_START;
402
403         _set_rgb(key, false, def_r_3bit, def_g_3bit, def_b_3bit, def_r_24bit, def_g_24bit, def_b_24bit, bi_led);
404         s_info.is_in_blink_mode = true;
405         g_timeout_add(timeout, _restore_rgb_color_cb, NULL);
406
407
408         FUNCTION_END;
409 }