dcfef73323820e24a0c6cf07f951e63210558bca
[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 <limits.h>
20 #include <stdlib.h>
21 #include <peripheral_io.h>
22 #include <time.h>
23 #include "log.h"
24 #include "resource/resource_led.h"
25 #include "resource/resource_PCA9685.h"
26 #include "config.h"
27
28 #define DEFAULT_BI_LED_RED 17
29 #define DEFAULT_BI_LED_GREEN 27
30
31 #define CONFIG_KEY_RPI_BI_LED_RED "bi.red"
32 #define CONFIG_KEY_RPI_BI_LED_GREEN "bi.green"
33 #define CONFIG_KEY_RPI_USE_BI_LED "bi.use"
34
35 #define CONFIG_KEY_RPI_RGB_GPIO_R "rgb.gpio.red"
36 #define CONFIG_KEY_RPI_RGB_GPIO_G "rgb.gpio.green"
37 #define CONFIG_KEY_RPI_RGB_GPIO_B "rgb.gpio.blue"
38 #define CONFIG_KEY_RPI_USE_GPIO_RGB "rgb.gpio.use"
39
40 #define CONFIG_KEY_RPI_RGB_L2C_R "rgb.l2c.red"
41 #define CONFIG_KEY_RPI_RGB_L2C_G "rgb.l2c.green"
42 #define CONFIG_KEY_RPI_RGB_L2C_B "rgb.l2c.blue"
43 #define CONFIG_KEY_RPI_USE_L2C_RGB "rgb.l2c.use"
44
45
46 #define DEFAULT_RGB_GPIO_R 14
47 #define DEFAULT_RGB_GPIO_G 15
48 #define DEFAULT_RGB_GPIO_B 18
49
50 #define DEFAULT_RGB_L2C_R 8
51 #define DEFAULT_RGB_L2C_G 9
52 #define DEFAULT_RGB_L2C_B 10
53
54 #define CONFIG_GRP_RPI "Rpi.led"
55
56
57 typedef struct _led_s {
58         peripheral_gpio_h gpio_bi_led[2];
59         peripheral_gpio_h rgb_gpio[3];
60         bi_led_color_e current_color;
61
62
63         bool current_rgb_gpio_color[3];
64         int current_rgb_l2c_color[3];
65
66         int use_bi_led;
67         int use_rgb_gpio;
68         int use_rgb_l2c;
69 } led_s;
70
71 static led_s s_info = {
72         .current_color = LED_COLOR_NONE,
73         .current_rgb_gpio_color = { 0, },
74         .current_rgb_l2c_color = { 0, },
75         0, };
76
77 #define  CHECK_GPIO_ERROR(pin, ret) \
78         if (ret != PERIPHERAL_ERROR_NONE) { \
79                 peripheral_gpio_close(pin); \
80                 _E("GPIO ERROR: %s, %s[%d]", get_error_message(ret), __FILE__, __LINE__); \
81                 return ; \
82         }
83
84 #define RGB_TO_REGISTER(val) ((unsigned)((float)val / 255.0f * 4095u))
85
86 static inline void _led_bi_set(bi_led_color_e color)
87 {
88         int red;
89         int green;
90
91         if (!s_info.use_bi_led) {
92                 _D("Bi led is turned OFF");
93                 return;
94         }
95
96         switch (color) {
97                 case LED_COLOR_RED:
98                         red = 1;
99                         green = 0;
100                         break;
101                 case LED_COLOR_GREEN:
102                         red = 0;
103                         green = 1;
104                         break;
105                 default:
106                         red = 0;
107                         green = 0;
108                         break;
109         }
110
111         int ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_RED], red);
112         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
113
114         ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_GREEN], green);
115         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
116
117         _D("BI: [%d, %d]", red, green);
118 }
119
120 static inline void _rgb_gpio_set(bool red, bool green, bool blue)
121 {
122         int ret = peripheral_gpio_write(s_info.rgb_gpio[0], red);
123         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
124
125         ret = peripheral_gpio_write(s_info.rgb_gpio[1], green);
126         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
127
128         ret = peripheral_gpio_write(s_info.rgb_gpio[2], blue);
129         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
130
131         _D("RGB GPIO: [%d, %d, %d]", red, green, blue);
132 }
133
134 static inline void _rgb_l2c_set(bool red, bool green, bool blue)
135 {
136 //#define R 51
137 //#define G 231
138 //#define B 157
139
140 //#define R 88
141 //#define G 51
142 //#define B 231
143
144
145         int ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_R, 0, RGB_TO_REGISTER(red));
146         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
147
148         ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_G, 0, RGB_TO_REGISTER(green));
149         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
150
151         ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_B, 0, RGB_TO_REGISTER(blue));
152         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
153
154         _D("RGB L2C: [%d, %d, %d] -> [%d, %d, %d]", red, green, blue, RGB_TO_REGISTER(red), RGB_TO_REGISTER(green), RGB_TO_REGISTER(blue));
155 }
156
157 static gboolean _restore_bi_color_cb(gpointer data)
158 {
159         _led_bi_set(s_info.current_color);
160         return false;
161 }
162
163 static gboolean _restore_rgb_gpio_color_cb(gpointer data)
164 {
165         _rgb_gpio_set(s_info.current_rgb_gpio_color[0], s_info.current_rgb_gpio_color[1], s_info.current_rgb_gpio_color[2]);
166         return false;
167 }
168
169 static gboolean _restore_rgb_l2c_color_cb(gpointer data)
170 {
171         _rgb_l2c_set(s_info.current_rgb_l2c_color[0], s_info.current_rgb_l2c_color[1], s_info.current_rgb_l2c_color[2]);
172         return false;
173 }
174
175 static peripheral_gpio_h _init_gpio(int default_gpio, char *key)
176 {
177         peripheral_gpio_h gpio;
178         int ret = PERIPHERAL_ERROR_NONE;
179         int pin = 0;
180         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, key, default_gpio, &pin);
181
182         _D("gpio: %d", pin);
183
184         if (modified) {
185                 config_save();
186         }
187
188         peripheral_gpio_open(pin, &gpio);
189         retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
190
191         peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW);
192         retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
193
194         return gpio;
195
196 }
197
198 static void _init_bi_led(void)
199 {
200         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_BI_LED, 1, &s_info.use_bi_led);
201         if (modified) {
202                 config_save();
203         }
204
205         if (s_info.use_bi_led) {
206                 s_info.gpio_bi_led[LED_COLOR_RED] = _init_gpio(DEFAULT_BI_LED_RED, CONFIG_KEY_RPI_BI_LED_RED);
207                 s_info.gpio_bi_led[LED_COLOR_GREEN] = _init_gpio(DEFAULT_BI_LED_GREEN, CONFIG_KEY_RPI_BI_LED_GREEN);
208         } else {
209                 _D("BI-Led is turned OFF");
210         }
211 }
212
213 static void _init_rgb_gpio_led(void)
214 {
215         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_GPIO_RGB, 1, &s_info.use_rgb_gpio);
216         if (modified) {
217                 config_save();
218         }
219
220         if (!s_info.use_rgb_gpio) {
221                 _D("RGB GPIO is turned off");
222                 return;
223         }
224
225         s_info.rgb_gpio[0] = _init_gpio(DEFAULT_RGB_GPIO_R, CONFIG_KEY_RPI_RGB_GPIO_R);
226         s_info.rgb_gpio[1] = _init_gpio(DEFAULT_RGB_GPIO_G, CONFIG_KEY_RPI_RGB_GPIO_G);
227         s_info.rgb_gpio[2] = _init_gpio(DEFAULT_RGB_GPIO_B, CONFIG_KEY_RPI_RGB_GPIO_B);
228 }
229
230 static void _init_rgb_l2c_led(void)
231 {
232         bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_L2C_RGB, 1, &s_info.use_rgb_l2c);
233         if (modified) {
234                 config_save();
235         }
236
237         if (!s_info.use_rgb_l2c) {
238                 _D("RGB L2C is turned off");
239                 return;
240         }
241
242         int ret = resource_pca9685_init(DEFAULT_RGB_L2C_R, 60);
243         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
244
245         ret = resource_pca9685_init(DEFAULT_RGB_L2C_G, 60);
246         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
247
248         ret = resource_pca9685_init(DEFAULT_RGB_L2C_B, 60);
249         ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
250 }
251
252 void resource_led_init(void)
253 {
254         _D("Initialize Led");
255         _init_bi_led();
256         _init_rgb_gpio_led();
257         _init_rgb_l2c_led();
258 }
259
260 void resource_led_destroy(void)
261 {
262         peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_RED]);
263         peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_GREEN]);
264
265         resource_pca9685_fini(DEFAULT_RGB_L2C_R);
266         resource_pca9685_fini(DEFAULT_RGB_L2C_G);
267         resource_pca9685_fini(DEFAULT_RGB_L2C_B);
268 }
269
270 void resource_bi_led_set(bi_led_color_e color)
271 {
272         _D("Set led to: %d", color);
273         if (color == s_info.current_color) {
274                 return;
275         }
276
277         s_info.current_color = color;
278         _led_bi_set(color);
279
280         peripheral_gpio_write(s_info.rgb_gpio[LED_COLOR_RED], 1);
281 }
282
283 void resource_bi_led_blink(bi_led_color_e color, unsigned timeout)
284 {
285         if (color == s_info.current_color) {
286                 return;
287         }
288
289         _led_bi_set(color);
290         g_timeout_add(timeout, _restore_bi_color_cb, NULL);
291 }
292
293 void resource_rgb_gpio_set(bool red, bool green, bool blue)
294 {
295         if (red == s_info.current_rgb_gpio_color[0] &&
296                         green == s_info.current_rgb_gpio_color[1] &&
297                         blue == s_info.current_rgb_gpio_color[2]) {
298                 return;
299         }
300
301
302         s_info.current_rgb_gpio_color[0] = red;
303         s_info.current_rgb_gpio_color[1] = green;
304         s_info.current_rgb_gpio_color[2] = blue;
305
306         _rgb_gpio_set(red, green, blue);
307 }
308
309 void resource_gpio_rgb_blink(bool red, bool green, bool blue, unsigned timeout)
310 {
311         if (red == s_info.current_rgb_gpio_color[0] &&
312                         green == s_info.current_rgb_gpio_color[1] &&
313                         blue == s_info.current_rgb_gpio_color[2]) {
314                 return;
315         }
316
317         _rgb_gpio_set(red, green, blue);
318         g_timeout_add(timeout, _restore_rgb_gpio_color_cb, NULL);
319 }
320
321 void resource_rgb_l2c_set(bool red, bool green, bool blue)
322 {
323         if (red == s_info.current_rgb_l2c_color[0] &&
324                         green == s_info.current_rgb_l2c_color[1] &&
325                         blue == s_info.current_rgb_l2c_color[2]) {
326                 return;
327         }
328
329
330         s_info.current_rgb_l2c_color[0] = red;
331         s_info.current_rgb_l2c_color[1] = green;
332         s_info.current_rgb_l2c_color[2] = blue;
333
334         _rgb_l2c_set(red, green, blue);
335 }
336
337 void resource_rgb_l2c_blink(bool red, bool green, bool blue, unsigned timeout)
338 {
339         if (red == s_info.current_rgb_l2c_color[0] &&
340                         green == s_info.current_rgb_l2c_color[1] &&
341                         blue == s_info.current_rgb_l2c_color[2]) {
342                 return;
343         }
344
345         _rgb_l2c_set(red, green, blue);
346         g_timeout_add(timeout, _restore_rgb_l2c_color_cb, NULL);
347 }
348