1 /*
2 * Copyright (c) 2018 Workaround GmbH
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/device.h>
8 #include <errno.h>
9 #include <zephyr/drivers/led.h>
10 #include <zephyr/sys/util.h>
11 #include <zephyr/kernel.h>
12
13 #define LOG_LEVEL 4
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(main);
16
17 #define NUM_LEDS 4
18 #define BLINK_DELAY_ON 500
19 #define BLINK_DELAY_OFF 500
20 #define DELAY_TIME 2000
21 #define COLORS_TO_SHOW 8
22 #define VALUES_PER_COLOR 3
23
24 /*
25 * We assume that the colors are connected the way it is described in the driver
26 * datasheet.
27 */
28 #define LED_R 2
29 #define LED_G 1
30 #define LED_B 0
31
32 /*
33 * The following colors are shown in the given order.
34 */
35 static uint8_t colors[COLORS_TO_SHOW][VALUES_PER_COLOR] = {
36 { 0xFF, 0x00, 0x00 }, /*< Red */
37 { 0x00, 0xFF, 0x00 }, /*< Green */
38 { 0x00, 0x00, 0xFF }, /*< Blue */
39 { 0xFF, 0xFF, 0xFF }, /*< White */
40 { 0xFF, 0xFF, 0x00 }, /*< Yellow */
41 { 0xFF, 0x00, 0xFF }, /*< Purple */
42 { 0x00, 0xFF, 0xFF }, /*< Cyan */
43 { 0xF4, 0x79, 0x20 }, /*< Orange */
44 };
45
46 /*
47 * @brief scale hex values [0x00..0xFF] to percent [0..100].
48 *
49 * @param hex Hex value.
50 *
51 * @return Hex value scaled to percent.
52 */
scale_color_to_percent(uint8_t hex)53 static inline uint8_t scale_color_to_percent(uint8_t hex)
54 {
55 return (hex * 100U) / 0xFF;
56 }
57
58 /*
59 * @brief Set a color using the three RGB LEDs.
60 *
61 * @param dev LED device.
62 * @param r Red value in hex [0x00..0xFF].
63 * @param g Green value in hex [0x00..0xFF].
64 * @param b Blue value in hex [0x00..0xFF].
65 *
66 * @return 0 if successful, -ERRNO otherwise.
67 */
set_static_color(const struct device * dev,uint8_t r,uint8_t g,uint8_t b)68 static int set_static_color(const struct device *dev, uint8_t r, uint8_t g,
69 uint8_t b)
70 {
71 int ret;
72
73 r = scale_color_to_percent(r);
74 g = scale_color_to_percent(g);
75 b = scale_color_to_percent(b);
76
77 ret = led_set_brightness(dev, LED_R, r);
78 if (ret) {
79 LOG_ERR("Failed to set color.");
80 return ret;
81 }
82
83 ret = led_set_brightness(dev, LED_G, g);
84 if (ret) {
85 LOG_ERR("Failed to set color.");
86 return ret;
87 }
88
89 ret = led_set_brightness(dev, LED_B, b);
90 if (ret) {
91 LOG_ERR("Failed to set color.");
92 return ret;
93 }
94
95 return 0;
96 }
97
98 /*
99 * @brief Blink the LED in the given color.
100 *
101 * Currently it is only possible to create colors by turning the three LEDs
102 * completely on or off. Proper mixing is not supported by the underlying API.
103 *
104 * @param dev LED device.
105 * @param r Blink the red LED.
106 * @param g Blink the green LED.
107 * @param b Blink the blue LED.
108 * @param delay_on Time in ms the LEDs stay on.
109 * @param delay_off Time in ms the LEDs stay off.
110 *
111 * @return 0 if successful, -ERRNO otherwise.
112 */
blink_color(const struct device * dev,bool r,bool g,bool b,uint32_t delay_on,uint32_t delay_off)113 static int blink_color(const struct device *dev, bool r, bool g, bool b,
114 uint32_t delay_on, uint32_t delay_off)
115 {
116 int ret;
117
118 if (r) {
119 ret = led_blink(dev, LED_R, delay_on, delay_off);
120 if (ret) {
121 LOG_ERR("Failed to set color.");
122 return ret;
123 }
124 }
125
126 if (g) {
127 ret = led_blink(dev, LED_G, delay_on, delay_off);
128 if (ret) {
129 LOG_ERR("Failed to set color.");
130 return ret;
131 }
132 }
133
134 if (b) {
135 ret = led_blink(dev, LED_B, delay_on, delay_off);
136 if (ret) {
137 LOG_ERR("Failed to set color.");
138 return ret;
139 }
140 }
141
142 return 0;
143 }
144
145 /*
146 * @brief Helper function to turn off all LEDs connected to the driver.
147 *
148 * @param dev LED driver device.
149 *
150 * @return 0 if successful, -ERRNO otherwise.
151 */
turn_off_all_leds(const struct device * dev)152 static int turn_off_all_leds(const struct device *dev)
153 {
154 for (int i = 0; i < NUM_LEDS; i++) {
155 int ret = led_off(dev, i);
156
157 if (ret) {
158 return ret;
159 }
160 }
161
162 return 0;
163 }
164
main(void)165 int main(void)
166 {
167 const struct device *const dev = DEVICE_DT_GET_ANY(ti_lp5562);
168 int i, ret;
169
170 if (!dev) {
171 LOG_ERR("No \"ti,lp5562\" device found");
172 return 0;
173 } else if (!device_is_ready(dev)) {
174 LOG_ERR("LED device %s is not ready", dev->name);
175 return 0;
176 } else {
177 LOG_INF("Found LED device %s", dev->name);
178 }
179
180 LOG_INF("Testing leds");
181
182 while (1) {
183
184 for (i = 0; i < COLORS_TO_SHOW; i++) {
185 ret = set_static_color(dev,
186 colors[i][0],
187 colors[i][1],
188 colors[i][2]);
189 if (ret) {
190 return 0;
191 }
192
193 k_msleep(DELAY_TIME);
194 }
195
196 ret = turn_off_all_leds(dev);
197 if (ret < 0) {
198 return 0;
199 }
200
201 /* Blink white. */
202 ret = blink_color(dev, true, true, true, BLINK_DELAY_ON,
203 BLINK_DELAY_OFF);
204 if (ret) {
205 return 0;
206 }
207
208 /* Wait a few blinking before turning off the LEDs */
209 k_msleep(DELAY_TIME * 2);
210
211 /* Change the color of the LEDs while keeping blinking. */
212 for (i = 0; i < COLORS_TO_SHOW; i++) {
213 ret = set_static_color(dev,
214 colors[i][0],
215 colors[i][1],
216 colors[i][2]);
217 if (ret) {
218 return 0;
219 }
220
221 k_msleep(DELAY_TIME * 2);
222 }
223
224 ret = turn_off_all_leds(dev);
225 if (ret < 0) {
226 return 0;
227 }
228
229 k_msleep(DELAY_TIME);
230 }
231 return 0;
232 }
233