1 /*
2 * Copyright (c) 2016 Intel Corporation
3 * Copyright (c) 2020 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /**
9 * @file Sample app to demonstrate PWM-based LED fade
10 */
11
12 #include <zephyr/kernel.h>
13 #include <zephyr/sys/printk.h>
14 #include <zephyr/device.h>
15 #include <zephyr/drivers/pwm.h>
16
17 #define PWM_LED_ALIAS(i) DT_ALIAS(_CONCAT(pwm_led, i))
18 #define PWM_LED_IS_OKAY(i) DT_NODE_HAS_STATUS_OKAY(DT_PARENT(PWM_LED_ALIAS(i)))
19 #define PWM_LED(i, _) IF_ENABLED(PWM_LED_IS_OKAY(i), (PWM_DT_SPEC_GET(PWM_LED_ALIAS(i)),))
20
21 #define MAX_LEDS 10
22 static const struct pwm_dt_spec pwm_leds[] = {LISTIFY(MAX_LEDS, PWM_LED, ())};
23
24 #define NUM_STEPS 50U
25 #define SLEEP_MSEC 25U
26
main(void)27 int main(void)
28 {
29 uint32_t pulse_widths[ARRAY_SIZE(pwm_leds)];
30 uint32_t steps[ARRAY_SIZE(pwm_leds)];
31 uint8_t dirs[ARRAY_SIZE(pwm_leds)];
32 int ret;
33
34 printk("PWM-based LED fade. Found %d LEDs\n", ARRAY_SIZE(pwm_leds));
35
36 for (size_t i = 0; i < ARRAY_SIZE(pwm_leds); i++) {
37 pulse_widths[i] = 0;
38 steps[i] = pwm_leds[i].period / NUM_STEPS;
39 dirs[i] = 1U;
40 if (!pwm_is_ready_dt(&pwm_leds[i])) {
41 printk("Error: PWM device %s is not ready\n", pwm_leds[i].dev->name);
42 return 0;
43 }
44 }
45
46 while (1) {
47 for (size_t i = 0; i < ARRAY_SIZE(pwm_leds); i++) {
48 ret = pwm_set_pulse_dt(&pwm_leds[i], pulse_widths[i]);
49 if (ret) {
50 printk("Error %d: failed to set pulse width for LED %d\n", ret, i);
51 }
52 printk("LED %d: Using pulse width %d%%\n", i,
53 100 * pulse_widths[i] / pwm_leds[i].period);
54
55 if (dirs[i] == 1) {
56 if (pulse_widths[i] + steps[i] >= pwm_leds[i].period) {
57 pulse_widths[i] = pwm_leds[i].period;
58 dirs[i] = 0U;
59 } else {
60 pulse_widths[i] += steps[i];
61 }
62 } else {
63 if (pulse_widths[i] <= steps[i]) {
64 pulse_widths[i] = 0;
65 dirs[i] = 1U;
66 } else {
67 pulse_widths[i] -= steps[i];
68 }
69 }
70 }
71
72 k_sleep(K_MSEC(SLEEP_MSEC));
73 }
74 return 0;
75 }
76