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