blob: 0b59afaf8825a371b94c4bbdb7d4399b6fbe07fd [file] [log] [blame]
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file Sample app to demonstrate PWM-based RGB LED control
*/
#include <zephyr.h>
#include <sys/printk.h>
#include <device.h>
#include <drivers/pwm.h>
/*
* Extract devicetree configuration.
*/
#define RED_NODE DT_ALIAS(red_pwm_led)
#define GREEN_NODE DT_ALIAS(green_pwm_led)
#define BLUE_NODE DT_ALIAS(blue_pwm_led)
#if DT_NODE_HAS_STATUS(RED_NODE, okay)
#define RED_CTLR_NODE DT_PWMS_CTLR(RED_NODE)
#define RED_CHANNEL DT_PWMS_CHANNEL(RED_NODE)
#define RED_FLAGS DT_PWMS_FLAGS(RED_NODE)
#else
#error "Unsupported board: red-pwm-led devicetree alias is not defined"
#define RED_CTLR_NODE DT_INVALID_NODE
#define RED_CHANNEL 0
#define RED_FLAGS 0
#endif
#if DT_NODE_HAS_STATUS(GREEN_NODE, okay)
#define GREEN_CTLR_NODE DT_PWMS_CTLR(GREEN_NODE)
#define GREEN_CHANNEL DT_PWMS_CHANNEL(GREEN_NODE)
#define GREEN_FLAGS DT_PWMS_FLAGS(GREEN_NODE)
#else
#error "Unsupported board: green-pwm-led devicetree alias is not defined"
#define GREEN_CTLR_NODE DT_INVALID_NODE
#define GREEN_CHANNEL 0
#define GREEN_FLAGS 0
#endif
#if DT_NODE_HAS_STATUS(BLUE_NODE, okay)
#define BLUE_CTLR_NODE DT_PWMS_CTLR(BLUE_NODE)
#define BLUE_CHANNEL DT_PWMS_CHANNEL(BLUE_NODE)
#define BLUE_FLAGS DT_PWMS_FLAGS(BLUE_NODE)
#else
#error "Unsupported board: blue-pwm-led devicetree alias is not defined"
#define BLUE_CTLR_NODE DT_INVALID_NODE
#define BLUE_CHANNEL 0
#define BLUE_FLAGS 0
#endif
/*
* 50 is flicker fusion threshold. Modulated light will be perceived
* as steady by our eyes when blinking rate is at least 50.
*/
#define PERIOD_USEC (USEC_PER_SEC / 50U)
#define STEPSIZE_USEC 2000
static int pwm_set(const struct device *pwm_dev, uint32_t pwm_pin,
uint32_t pulse_width, pwm_flags_t flags)
{
return pwm_pin_set_usec(pwm_dev, pwm_pin, PERIOD_USEC,
pulse_width, flags);
}
enum { RED, GREEN, BLUE };
void main(void)
{
const struct device *pwm_dev[3];
uint32_t pulse_red, pulse_green, pulse_blue; /* pulse widths */
int ret;
printk("PWM-based RGB LED control\n");
pwm_dev[RED] = DEVICE_DT_GET(RED_CTLR_NODE);
pwm_dev[GREEN] = DEVICE_DT_GET(GREEN_CTLR_NODE);
pwm_dev[BLUE] = DEVICE_DT_GET(BLUE_CTLR_NODE);
if (!device_is_ready(pwm_dev[RED])) {
printk("Error: red PWM device %s is not ready\n", pwm_dev[RED]->name);
return;
}
if (!device_is_ready(pwm_dev[GREEN])) {
printk("Error: green PWM device %s is not ready\n", pwm_dev[GREEN]->name);
return;
}
if (!device_is_ready(pwm_dev[BLUE])) {
printk("Error: blue PWM device %s is not ready\n", pwm_dev[BLUE]->name);
return;
}
while (1) {
for (pulse_red = 0U; pulse_red <= PERIOD_USEC;
pulse_red += STEPSIZE_USEC) {
ret = pwm_set(pwm_dev[RED], RED_CHANNEL,
pulse_red, RED_FLAGS);
if (ret != 0) {
printk("Error %d: "
"red write failed\n",
ret);
return;
}
for (pulse_green = 0U; pulse_green <= PERIOD_USEC;
pulse_green += STEPSIZE_USEC) {
ret = pwm_set(pwm_dev[GREEN], GREEN_CHANNEL,
pulse_green, GREEN_FLAGS);
if (ret != 0) {
printk("Error %d: "
"green write failed\n",
ret);
return;
}
for (pulse_blue = 0U; pulse_blue <= PERIOD_USEC;
pulse_blue += STEPSIZE_USEC) {
ret = pwm_set(pwm_dev[BLUE],
BLUE_CHANNEL,
pulse_blue,
BLUE_FLAGS);
if (ret != 0) {
printk("Error %d: "
"blue write failed\n",
ret);
return;
}
k_sleep(K_SECONDS(1));
}
}
}
}
}