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.
21 #include <peripheral_io.h>
24 #include "resource/resource_led.h"
25 #include "resource/resource_PCA9685.h"
28 #define DEFAULT_BI_LED_RED 17
29 #define DEFAULT_BI_LED_GREEN 27
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"
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"
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"
46 #define DEFAULT_RGB_GPIO_R 23
47 #define DEFAULT_RGB_GPIO_G 24
48 #define DEFAULT_RGB_GPIO_B 25
50 #define DEFAULT_RGB_L2C_R 8
51 #define DEFAULT_RGB_L2C_G 9
52 #define DEFAULT_RGB_L2C_B 10
54 #define CONFIG_GRP_RPI "Rpi.led"
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;
63 bool current_rgb_gpio_color[3];
64 int current_rgb_l2c_color[3];
71 static led_s s_info = {
72 .current_color = LED_COLOR_NONE,
73 .current_rgb_gpio_color = { 0, },
74 .current_rgb_l2c_color = { 0, },
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__); \
84 #define RGB_TO_REGISTER(val) ((unsigned)((float)val / 255.0f * 4095u))
86 static inline void _led_bi_set(bi_led_color_e color)
91 if (!s_info.use_bi_led) {
92 _D("Bi led is turned OFF");
101 case LED_COLOR_GREEN:
111 int ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_RED], red);
112 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
114 ret = peripheral_gpio_write(s_info.gpio_bi_led[LED_COLOR_GREEN], green);
115 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
117 _D("BI: [%d, %d]", red, green);
120 static inline void _rgb_gpio_set(bool red, bool green, bool blue)
122 if (!s_info.use_rgb_gpio) {
123 _D("gpio rgb led is turned OFF");
127 _D("RGB GPIO: [%d, %d, %d]", red, green, blue);
129 int ret = peripheral_gpio_write(s_info.rgb_gpio[0], red);
130 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
132 ret = peripheral_gpio_write(s_info.rgb_gpio[1], green);
133 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
135 ret = peripheral_gpio_write(s_info.rgb_gpio[2], blue);
136 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
139 static inline void _rgb_l2c_set(int red, int green, int blue)
141 if (!s_info.use_rgb_l2c) {
142 _D("l2c rgb led is turned OFF");
146 int ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_R, 0, RGB_TO_REGISTER(red));
147 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
149 ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_G, 0, RGB_TO_REGISTER(green));
150 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
152 ret = resource_pca9685_set_value_to_channel(DEFAULT_RGB_L2C_B, 0, RGB_TO_REGISTER(blue));
153 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
155 _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 static gboolean _restore_bi_color_cb(gpointer data)
160 _led_bi_set(s_info.current_color);
164 static gboolean _restore_rgb_gpio_color_cb(gpointer data)
166 _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 static gboolean _restore_rgb_l2c_color_cb(gpointer data)
172 _rgb_l2c_set(s_info.current_rgb_l2c_color[0], s_info.current_rgb_l2c_color[1], s_info.current_rgb_l2c_color[2]);
176 static peripheral_gpio_h _init_gpio(int default_gpio, char *key)
178 peripheral_gpio_h gpio;
181 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, key, default_gpio, &pin);
183 _D("Initializing gpio: %d", pin);
189 int ret = peripheral_gpio_open(pin, &gpio);
190 retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
192 ret = peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW);
193 retv_error_message(ret != PERIPHERAL_ERROR_NONE, ret, 0);
199 static void _init_bi_led(void)
201 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_BI_LED, 1, &s_info.use_bi_led);
206 if (s_info.use_bi_led) {
207 s_info.gpio_bi_led[LED_COLOR_RED] = _init_gpio(DEFAULT_BI_LED_RED, CONFIG_KEY_RPI_BI_LED_RED);
208 s_info.gpio_bi_led[LED_COLOR_GREEN] = _init_gpio(DEFAULT_BI_LED_GREEN, CONFIG_KEY_RPI_BI_LED_GREEN);
210 _D("BI-Led is turned OFF");
214 static void _init_rgb_gpio_led(void)
216 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_GPIO_RGB, 1, &s_info.use_rgb_gpio);
221 if (!s_info.use_rgb_gpio) {
222 _D("RGB GPIO is turned off");
226 s_info.rgb_gpio[0] = _init_gpio(DEFAULT_RGB_GPIO_R, CONFIG_KEY_RPI_RGB_GPIO_R);
227 s_info.rgb_gpio[1] = _init_gpio(DEFAULT_RGB_GPIO_G, CONFIG_KEY_RPI_RGB_GPIO_G);
228 s_info.rgb_gpio[2] = _init_gpio(DEFAULT_RGB_GPIO_B, CONFIG_KEY_RPI_RGB_GPIO_B);
231 void _init_l2c(int default_channel, char *config_key)
234 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, config_key, default_channel, &channel);
239 int ret = resource_pca9685_init(channel, 60);
240 ret_error_message(ret != PERIPHERAL_ERROR_NONE, ret);
243 static void _init_rgb_l2c_led(void)
245 bool modified = config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_USE_L2C_RGB, 1, &s_info.use_rgb_l2c);
250 if (!s_info.use_rgb_l2c) {
251 _D("RGB L2C is turned off");
255 _init_l2c(DEFAULT_RGB_L2C_R, CONFIG_KEY_RPI_RGB_L2C_R);
256 _init_l2c(DEFAULT_RGB_L2C_G, CONFIG_KEY_RPI_RGB_L2C_G);
257 _init_l2c(DEFAULT_RGB_L2C_B, CONFIG_KEY_RPI_RGB_L2C_B);
260 void resource_led_init(void)
262 _D("Initialize Led");
263 _init_rgb_gpio_led();
268 void resource_led_destroy(void)
270 peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_RED]);
271 peripheral_gpio_close(s_info.gpio_bi_led[LED_COLOR_GREEN]);
273 peripheral_gpio_close(s_info.rgb_gpio[0]);
274 peripheral_gpio_close(s_info.rgb_gpio[1]);
275 peripheral_gpio_close(s_info.rgb_gpio[2]);
277 resource_rgb_l2c_set(0, 0, 0);
279 resource_pca9685_fini(DEFAULT_RGB_L2C_R);
280 resource_pca9685_fini(DEFAULT_RGB_L2C_G);
281 resource_pca9685_fini(DEFAULT_RGB_L2C_B);
284 void resource_bi_led_set(bi_led_color_e color)
286 _D("Set led to: %d", color);
287 if (color == s_info.current_color) {
291 s_info.current_color = color;
295 void resource_bi_led_blink(bi_led_color_e color, unsigned timeout)
297 if (color == s_info.current_color) {
302 g_timeout_add(timeout, _restore_bi_color_cb, NULL);
305 void resource_rgb_gpio_set(bool red, bool green, bool blue)
307 if (red == s_info.current_rgb_gpio_color[0] &&
308 green == s_info.current_rgb_gpio_color[1] &&
309 blue == s_info.current_rgb_gpio_color[2]) {
314 s_info.current_rgb_gpio_color[0] = red;
315 s_info.current_rgb_gpio_color[1] = green;
316 s_info.current_rgb_gpio_color[2] = blue;
318 _rgb_gpio_set(red, green, blue);
321 void resource_gpio_rgb_blink(bool red, bool green, bool blue, unsigned timeout)
323 if (red == s_info.current_rgb_gpio_color[0] &&
324 green == s_info.current_rgb_gpio_color[1] &&
325 blue == s_info.current_rgb_gpio_color[2]) {
329 _rgb_gpio_set(red, green, blue);
330 g_timeout_add(timeout, _restore_rgb_gpio_color_cb, NULL);
333 void resource_rgb_l2c_set(int red, int green, int blue)
335 if (red == s_info.current_rgb_l2c_color[0] &&
336 green == s_info.current_rgb_l2c_color[1] &&
337 blue == s_info.current_rgb_l2c_color[2]) {
341 s_info.current_rgb_l2c_color[0] = red;
342 s_info.current_rgb_l2c_color[1] = green;
343 s_info.current_rgb_l2c_color[2] = blue;
345 _rgb_l2c_set(red, green, blue);
348 void resource_rgb_l2c_blink(int red, int green, int blue, unsigned timeout)
350 if (red == s_info.current_rgb_l2c_color[0] &&
351 green == s_info.current_rgb_l2c_color[1] &&
352 blue == s_info.current_rgb_l2c_color[2]) {
356 _rgb_l2c_set(red, green, blue);
357 g_timeout_add(timeout, _restore_rgb_l2c_color_cb, NULL);