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 dir = 1U;
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 if (!pwm_is_ready_dt(&pwm_leds[i])) {
40 printk("Error: PWM device %s is not ready\n", pwm_leds[i].dev->name);
41 return 0;
42 }
43 }
44
45 while (1) {
46 for (size_t i = 0; i < ARRAY_SIZE(pwm_leds); i++) {
47 ret = pwm_set_pulse_dt(&pwm_leds[i], pulse_widths[i]);
48 if (ret) {
49 printk("Error %d: failed to set pulse width for LED %d\n", ret, i);
50 }
51 printk("LED %d: Using pulse width %d%%\n", i,
52 100 * pulse_widths[i] / pwm_leds[i].period);
53
54 if (dir) {
55 if (pulse_widths[i] + steps[i] >= pwm_leds[i].period) {
56 pulse_widths[i] = pwm_leds[i].period;
57 dir = 0U;
58 } else {
59 pulse_widths[i] += steps[i];
60 }
61 } else {
62 if (pulse_widths[i] <= steps[i]) {
63 pulse_widths[i] = 0;
64 dir = 1U;
65 } else {
66 pulse_widths[i] -= steps[i];
67 }
68 }
69 }
70
71 k_sleep(K_MSEC(SLEEP_MSEC));
72 }
73 return 0;
74 }
75