1 /*
2 * Copyright (c) 2020 Seagate Technology LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/device.h>
8 #include <zephyr/devicetree.h>
9 #include <errno.h>
10 #include <zephyr/drivers/led.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/kernel.h>
13
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL);
16
17 #define LED_PWM_NODE_ID DT_COMPAT_GET_ANY_STATUS_OKAY(pwm_leds)
18
19 const char *led_label[] = {
20 DT_FOREACH_CHILD_SEP_VARGS(LED_PWM_NODE_ID, DT_PROP_OR, (,), label, NULL)
21 };
22
23 const int num_leds = ARRAY_SIZE(led_label);
24
25 #define MAX_BRIGHTNESS 100
26
27 /**
28 * @brief Run tests on a single LED using the LED API syscalls.
29 *
30 * @param led_pwm LED PWM device.
31 * @param led Number of the LED to test.
32 */
run_led_test(const struct device * led_pwm,uint8_t led)33 static void run_led_test(const struct device *led_pwm, uint8_t led)
34 {
35 int err;
36 int16_t level;
37
38 LOG_INF("Testing LED %d - %s", led, led_label[led] ? : "no label");
39
40 /* Turn LED on. */
41 err = led_on(led_pwm, led);
42 if (err < 0) {
43 LOG_ERR("err=%d", err);
44 return;
45 }
46 LOG_INF(" Turned on");
47 k_sleep(K_MSEC(1000));
48
49 /* Turn LED off. */
50 err = led_off(led_pwm, led);
51 if (err < 0) {
52 LOG_ERR("err=%d", err);
53 return;
54 }
55 LOG_INF(" Turned off");
56 k_sleep(K_MSEC(1000));
57
58 /* Increase LED brightness gradually up to the maximum level. */
59 LOG_INF(" Increasing brightness gradually");
60 for (level = 0; level <= MAX_BRIGHTNESS; level++) {
61 err = led_set_brightness(led_pwm, led, level);
62 if (err < 0) {
63 LOG_ERR("err=%d brightness=%d\n", err, level);
64 return;
65 }
66 k_sleep(K_MSEC(CONFIG_FADE_DELAY));
67 }
68 k_sleep(K_MSEC(1000));
69
70 /* Decrease LED brightness gradually down to the minimum level. */
71 LOG_INF(" Decreasing brightness gradually");
72 for (level = MAX_BRIGHTNESS; level >= 0; level--) {
73 err = led_set_brightness(led_pwm, led, level);
74 if (err < 0) {
75 LOG_ERR("err=%d brightness=%d\n", err, level);
76 return;
77 }
78 k_sleep(K_MSEC(CONFIG_FADE_DELAY));
79 }
80 k_sleep(K_MSEC(1000));
81
82 #if CONFIG_BLINK_DELAY_SHORT > 0
83 /* Start LED blinking (short cycle) */
84 err = led_blink(led_pwm, led, CONFIG_BLINK_DELAY_SHORT, CONFIG_BLINK_DELAY_SHORT);
85 if (err < 0) {
86 LOG_ERR("err=%d", err);
87 return;
88 }
89 LOG_INF(" Blinking "
90 "on: " STRINGIFY(CONFIG_BLINK_DELAY_SHORT) " msec, "
91 "off: " STRINGIFY(CONFIG_BLINK_DELAY_SHORT) " msec");
92 k_sleep(K_MSEC(5000));
93 #endif
94
95 #if CONFIG_BLINK_DELAY_LONG > 0
96 /* Start LED blinking (long cycle) */
97 err = led_blink(led_pwm, led, CONFIG_BLINK_DELAY_LONG, CONFIG_BLINK_DELAY_LONG);
98 if (err < 0) {
99 LOG_ERR("err=%d", err);
100 LOG_INF(" Cycle period not supported - "
101 "on: " STRINGIFY(CONFIG_BLINK_DELAY_LONG) " msec, "
102 "off: " STRINGIFY(CONFIG_BLINK_DELAY_LONG) " msec");
103 } else {
104 LOG_INF(" Blinking "
105 "on: " STRINGIFY(CONFIG_BLINK_DELAY_LONG) " msec, "
106 "off: " STRINGIFY(CONFIG_BLINK_DELAY_LONG) " msec");
107 }
108 k_sleep(K_MSEC(5000));
109 #endif
110
111 /* Turn LED off. */
112 err = led_off(led_pwm, led);
113 if (err < 0) {
114 LOG_ERR("err=%d", err);
115 return;
116 }
117 LOG_INF(" Turned off, loop end");
118 }
119
main(void)120 int main(void)
121 {
122 const struct device *led_pwm;
123 uint8_t led;
124
125 led_pwm = DEVICE_DT_GET(LED_PWM_NODE_ID);
126 if (!device_is_ready(led_pwm)) {
127 LOG_ERR("Device %s is not ready", led_pwm->name);
128 return 0;
129 }
130
131 if (!num_leds) {
132 LOG_ERR("No LEDs found for %s", led_pwm->name);
133 return 0;
134 }
135
136 do {
137 for (led = 0; led < num_leds; led++) {
138 run_led_test(led_pwm, led);
139 }
140 } while (true);
141 return 0;
142 }
143