diff --git a/samples/drivers/led_pwm/CMakeLists.txt b/samples/drivers/led_pwm/CMakeLists.txt new file mode 100644 index 00000000000000..909b20d9278434 --- /dev/null +++ b/samples/drivers/led_pwm/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13.1) + +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +project(led_pwm) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/drivers/led_pwm/README.rst b/samples/drivers/led_pwm/README.rst new file mode 100644 index 00000000000000..3749ca8e0b2e22 --- /dev/null +++ b/samples/drivers/led_pwm/README.rst @@ -0,0 +1,33 @@ +.. _led_pwm: + +LED PWM sample application +########################## + +Overview +******** + +This sample allows to test the led-pwm driver. The first "pwm-leds" compatible +device instance found in DT is used. For each LEDs attached to this device +(child nodes) the same test pattern (described below) is executed. The LED API +functions are used to control the LEDs. + +Test pattern +============ + +For each PWM LEDs (one after the other): + +- turn on +- turn off +- increase the brightness gradually up to the maximum level +- blink (0.1 sec on, 0.1 sec off) +- blink (1 sec on, 1 sec off) +- turn off + +Building and Running +******************** + +This sample can be built and executed on all the boards with PWM LEDs connected. +The LEDs must be correctly described in the DTS: the compatible property of the +device node must match "pwm-leds". And for each LED, a child node must be +defined and the PWM configuration must be provided through a "pwms" phandle's +node. diff --git a/samples/drivers/led_pwm/prj.conf b/samples/drivers/led_pwm/prj.conf new file mode 100644 index 00000000000000..2444040168a32a --- /dev/null +++ b/samples/drivers/led_pwm/prj.conf @@ -0,0 +1,6 @@ +CONFIG_LOG=y + +CONFIG_PWM=y + +CONFIG_LED=y +CONFIG_LED_PWM=y diff --git a/samples/drivers/led_pwm/sample.yaml b/samples/drivers/led_pwm/sample.yaml new file mode 100644 index 00000000000000..18c74bced0a4c2 --- /dev/null +++ b/samples/drivers/led_pwm/sample.yaml @@ -0,0 +1,8 @@ +sample: + description: Demonstration of the PWM LED driver + name: PWM LED sample +tests: + sample.drivers.led.led_pwm: + filter: dt_compat_enabled("pwm-leds") + tags: LED + depends_on: pwm diff --git a/samples/drivers/led_pwm/src/main.c b/samples/drivers/led_pwm/src/main.c new file mode 100644 index 00000000000000..71e3e6e4d05492 --- /dev/null +++ b/samples/drivers/led_pwm/src/main.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2020 Seagate Technology LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL); + +#if DT_NODE_HAS_STATUS(DT_INST(0, pwm_leds), okay) +#define LED_PWM_NODE_ID DT_INST(0, pwm_leds) +#define LED_PWM_DEV_NAME DT_INST_PROP_OR(0, label, "LED_PWM_0") +#else +#error "No LED PWM device found" +#endif + +#define LED_PWM_LABEL(led_node_id) DT_PROP_OR(led_node_id, label, NULL), + +const char *led_label[] = { + DT_FOREACH_CHILD(LED_PWM_NODE_ID, LED_PWM_LABEL) +}; + +const int num_leds = ARRAY_SIZE(led_label); + +#define MAX_BRIGHTNESS 100 + +#define FADE_DELAY_MS 10 +#define FADE_DELAY K_MSEC(FADE_DELAY_MS) + +/** + * @brief Run tests on a single LED using the LED API syscalls. + * + * @param led_pwm LED PWM device. + * @param led Number of the LED to test. + */ +static void run_led_test(const struct device *led_pwm, uint8_t led) +{ + int err; + uint16_t level; + + LOG_INF("Testing LED %d (%s)", led, led_label[led] ? : "no label"); + + /* Turn LED on. */ + err = led_on(led_pwm, led); + LOG_INF(" Turning on"); + if (err < 0) { + LOG_ERR("err=%d", err); + return; + } + k_sleep(K_MSEC(1000)); + + /* Turn LED off. */ + err = led_off(led_pwm, led); + LOG_INF(" Turning off"); + if (err < 0) { + LOG_ERR("err=%d", err); + return; + } + k_sleep(K_MSEC(1000)); + + /* Increase LED brightness gradually up to the maximum level. */ + LOG_INF(" Increasing brightness gradually"); + for (level = 0; level <= MAX_BRIGHTNESS; level++) { + err = led_set_brightness(led_pwm, led, level); + if (err < 0) { + LOG_ERR("err=%d brightness=%d\n", err, level); + return; + } + k_sleep(FADE_DELAY); + } + k_sleep(K_MSEC(1000)); + + /* Set LED blinking (on: 0.1 sec, off: 0.1 sec) */ + LOG_INF(" Blinking (on: 0.1 sec, off: 0.1 sec)"); + err = led_blink(led_pwm, led, 100, 100); + if (err < 0) { + LOG_ERR("err=%d", err); + return; + } + k_sleep(K_MSEC(5000)); + + /* Enable LED blinking (on: 1 sec, off: 1 sec) */ + LOG_INF(" Blinking (on: 1 sec, off: 1 sec)"); + err = led_blink(led_pwm, led, 1000, 1000); + if (err < 0) { + LOG_ERR("err=%d", err); + return; + } + k_sleep(K_MSEC(5000)); + + /* Turn LED off. */ + LOG_INF(" Turning off"); + err = led_off(led_pwm, led); + if (err < 0) { + LOG_ERR("err=%d", err); + return; + } +} + +void main(void) +{ + const struct device *led_pwm; + uint8_t led; + + led_pwm = device_get_binding(LED_PWM_DEV_NAME); + if (led_pwm) { + LOG_INF("Found device %s", LED_PWM_DEV_NAME); + } else { + LOG_ERR("Device %s not found", LED_PWM_DEV_NAME); + return; + } + + if (!num_leds) { + LOG_ERR("No LEDs found for %s", LED_PWM_DEV_NAME); + return; + } + + do { + for (led = 0; led < num_leds; led++) { + run_led_test(led_pwm, led); + } + } while (true); +}