diff --git a/samples/basic/rgb_led/README.rst b/samples/basic/rgb_led/README.rst index b043f06c290..3f6a6b67862 100644 --- a/samples/basic/rgb_led/README.rst +++ b/samples/basic/rgb_led/README.rst @@ -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 ************ diff --git a/samples/basic/rgb_led/src/main.c b/samples/basic/rgb_led/src/main.c index effddb47e94..1d253eeaf1b 100644 --- a/samples/basic/rgb_led/src/main.c +++ b/samples/basic/rgb_led/src/main.c @@ -13,118 +13,54 @@ #include #include -/* - * 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",