2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
8 * http://floralicense.org/license/
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.
22 #include <peripheral_io.h>
25 #include "resource/resource_led.h"
26 #include "resource/resource_PCA9685.h"
29 #define DEFAULT_BI_LED_RED 17
30 #define DEFAULT_BI_LED_GREEN 27
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"
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"
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"
47 #define DEFAULT_RGB_GPIO_R 23
48 #define DEFAULT_RGB_GPIO_G 24
49 #define DEFAULT_RGB_GPIO_B 25
51 #define DEFAULT_RGB_L2C_R 8
52 #define DEFAULT_RGB_L2C_G 9
53 #define DEFAULT_RGB_L2C_B 10
55 #define CONFIG_GRP_RPI "Rpi.led"
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;
64 bool current_rgb_gpio_color[3];
65 int current_rgb_l2c_color[3];
72 static led_s s_info = {
73 .current_color = LED_COLOR_NONE,
74 .current_rgb_gpio_color = { 0, },
75 .current_rgb_l2c_color = { 0, },
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__); \
85 #define RGB_TO_REGISTER(val) ((unsigned)((float)val / 255.0f * 4095u))
87 static inline void _led_bi_set(bi_led_color_e color)
92 if (!s_info.use_bi_led) {
93 _D("Bi led is turned OFF");
102 case LED_COLOR_GREEN:
112 int ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_RED], red);
113 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
115 ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_GREEN], green);
116 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
118 _D("BI: [%d, %d]", red, green);
121 static inline void _rgb_gpio_set(bool red, bool green, bool blue)
123 if (!s_info.use_rgb_gpio) {
124 _D("gpio rgb led is turned OFF");
128 _D("RGB GPIO: [%d, %d, %d]", red, green, blue);
130 int ret = peripheral_gpio_write(s_info.rgb_gpio[0], red);
131 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
133 ret = peripheral_gpio_write(s_info.rgb_gpio[1], green);
134 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
136 ret = peripheral_gpio_write(s_info.rgb_gpio[2], blue);
137 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
140 static inline void _rgb_l2c_set(int red, int green, int blue)
143 if (!s_info.use_rgb_l2c) {
144 _D("l2c rgb led is turned OFF");
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);
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);
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);
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));
161 static gboolean _restore_bi_color_cb(gpointer data)
163 _led_bi_set(s_info.current_color);
167 static gboolean _restore_rgb_gpio_color_cb(gpointer data)
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]);
173 static gboolean _restore_rgb_l2c_color_cb(gpointer data)
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]);
181 static gboolean _restore_rgb_color_cb(gpointer data)
185 _restore_bi_color_cb(data);
186 _restore_rgb_gpio_color_cb(data);
187 _restore_rgb_l2c_color_cb(data);
194 static peripheral_gpio_h _init_gpio(int default_gpio, char *key)
196 peripheral_gpio_h gpio;
199 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, key, default_gpio, &pin);
201 _D("Initializing gpio: %d", pin);
207 int ret = peripheral_gpio_open(pin, &gpio);
208 retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
210 ret = peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW);
211 retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
217 static void _init_bi_led(void)
219 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_BI_LED, 1, &s_info.use_bi_led);
224 _D("Use bi_led: %d", s_info.use_bi_led);
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);
231 _D("BI-Led is turned OFF");
235 static void _init_rgb_gpio_led(void)
237 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_GPIO_RGB, 1, &s_info.use_rgb_gpio);
242 _D("Use rgb_gpio_led: %d", s_info.use_rgb_gpio);
244 if (!s_info.use_rgb_gpio) {
245 _D("RGB GPIO is turned off");
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);
254 void _init_l2c(int default_channel, char *config_key)
257 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, config_key, default_channel, &channel);
262 int ret = resource_pca9685_init(channel, 60);
263 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
266 static void _init_rgb_l2c_led(void)
268 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_L2C_RGB, 1, &s_info.use_rgb_l2c);
273 _D("Use rgb_l2c_led: %d", s_info.use_rgb_l2c);
275 if (!s_info.use_rgb_l2c) {
276 _D("RGB L2C is turned off");
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);
285 void resource_led_init(void)
288 _D("Initialize Led");
289 _init_rgb_gpio_led();
295 void resource_led_destroy(void)
297 peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_RED]);
298 peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_GREEN]);
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]);
304 resource_led_rgb_l2c_set(0, 0, 0);
306 resource_pca9685_fini(DEFAULT_RGB_L2C_R);
307 resource_pca9685_fini(DEFAULT_RGB_L2C_G);
308 resource_pca9685_fini(DEFAULT_RGB_L2C_B);
311 void resource_led_bi_set(bi_led_color_e color)
313 _D("Set led to: %d", color);
314 if (color == s_info.current_color) {
315 _D("No change in bi led");
319 s_info.current_color = color;
323 void resource_led_bi_blink(bi_led_color_e color, unsigned timeout)
325 if (color == s_info.current_color) {
326 _D("No change in bi led");
331 g_timeout_add(timeout, _restore_bi_color_cb, NULL);
334 void resource_led_rgb_gpio_set(bool red, bool green, bool blue)
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");
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;
348 _rgb_gpio_set(red, green, blue);
351 void resource_led_gpio_rgb_blink(bool red, bool green, bool blue, unsigned timeout)
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");
360 _rgb_gpio_set(red, green, blue);
361 g_timeout_add(timeout, _restore_rgb_gpio_color_cb, NULL);
364 void resource_led_rgb_l2c_set(int red, int green, int blue)
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");
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;
377 _rgb_l2c_set(red, green, blue);
380 void resource_led_rgb_l2c_blink(int red, int green, int blue, unsigned timeout)
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");
389 _rgb_l2c_set(red, green, blue);
390 g_timeout_add(timeout, _restore_rgb_l2c_color_cb, NULL);
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)
400 int red, green, blue;
401 char final_key[PATH_MAX];
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);
407 _D("%s: 3bit color: [%d, %d, %d]", final_key, red, green, blue);
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);
413 _D("%s: 24bit color: [%d, %d, %d]", final_key, red, green, blue);
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);
424 _D("%s: bicolor: [%d]", final_key, value);
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)
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);
438 g_timeout_add(timeout, _restore_rgb_color_cb, NULL);