samples: basic: rgb_led: use pwm_dt_spec

Simplify the sample by using pwm_dt_spec.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2022-04-04 20:52:40 +02:00 committed by Carles Cufí
parent f60bb8741b
commit cd2d867fa6
2 changed files with 32 additions and 95 deletions

View File

@ -9,11 +9,12 @@ Overview
This is a sample app which drives an RGB LED using PWM.
There are three single-color component LEDs in an RGB LED. Each component LED
is driven by a PWM port where the pulse width is changed from zero to a fusion
flicker threshold (the minimum flicker rate where the LED is perceived as being
steady), causing each component LED to step from dark to max brightness. Three
**for** loops (one for each component LED) generate a gradual range of color
changes from the RGB LED, and the sample repeats forever.
is driven by a PWM port where the pulse width is changed from zero to the period
indicated in Devicetree. Such period should be fast enough to be above the
flicker fusion threshold (the minimum flicker rate where the LED is perceived as
being steady). The sample causes each LED component to step from dark to max
brightness. Three **for** loops (one for each component LED) generate a gradual
range of color changes from the RGB LED, and the sample repeats forever.
Requirements
************

View File

@ -13,118 +13,54 @@
#include <device.h>
#include <drivers/pwm.h>
/*
* Extract devicetree configuration.
*/
static const struct pwm_dt_spec red_pwm_led =
PWM_DT_SPEC_GET(DT_ALIAS(red_pwm_led));
static const struct pwm_dt_spec green_pwm_led =
PWM_DT_SPEC_GET(DT_ALIAS(green_pwm_led));
static const struct pwm_dt_spec blue_pwm_led =
PWM_DT_SPEC_GET(DT_ALIAS(blue_pwm_led));
#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_set_usec(pwm_dev, pwm_pin, PERIOD_USEC, pulse_width, flags);
}
enum { RED, GREEN, BLUE };
#define STEP_SIZE PWM_USEC(2000)
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);
if (!device_is_ready(red_pwm_led.dev) ||
!device_is_ready(green_pwm_led.dev) ||
!device_is_ready(blue_pwm_led.dev)) {
printk("Error: one or more PWM devices not ready\n");
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);
for (pulse_red = 0U; pulse_red <= red_pwm_led.period;
pulse_red += STEP_SIZE) {
ret = pwm_set_nsec_pulse_dt(&red_pwm_led, pulse_red);
if (ret != 0) {
printk("Error %d: "
"red write failed\n",
ret);
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);
for (pulse_green = 0U;
pulse_green <= green_pwm_led.period;
pulse_green += STEP_SIZE) {
ret = pwm_set_nsec_pulse_dt(&green_pwm_led,
pulse_green);
if (ret != 0) {
printk("Error %d: "
"green write failed\n",
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);
for (pulse_blue = 0U;
pulse_blue <= blue_pwm_led.period;
pulse_blue += STEP_SIZE) {
ret = pwm_set_nsec_pulse_dt(
&blue_pwm_led, pulse_blue);
if (ret != 0) {
printk("Error %d: "
"blue write failed\n",