I would like to control the RGB LED on the board.
I followed the drievr example provided by the nrf sdk, but it doesn't work.
As far as I understand, I don't need the signal inversion because SDOUT is directly connected to the LED.
VDD seems to be sourced from Pin P1.14 and thus I included it in the driver.
When I run the program, I get the following error message:
couldn't update strip: -5
[00:03:27.076,904] <err> i2s_nrfx: Cannot write in state: 3
[00:03:27.076,904] <err> ws2812_i2s: Failed to write data: -5
So, I think the I2S bus is not initialized correctly, or there is a problem with the data transmission, e.g. incorrect timing.
prj.conf
CONFIG_LOG=y CONFIG_LED_STRIP=y CONFIG_LED_STRIP_LOG_LEVEL_DBG=y
adafruit_feather_nrf52840_nrf52840.overlay#include <zephyr/dt-bindings/led/led.h>
&pinctrl {
i2s0_default_alt: i2s0_default_alt {
group1 {
psels = <NRF_PSEL(I2S_SDOUT, 0, 16)>,
<NRF_PSEL(I2S_LRCK_M, 0, 25)>,
<NRF_PSEL(I2S_SDIN, 0, 26)>,
<NRF_PSEL(I2S_SCK_M, 0, 27)>;
};
};
};
i2s_led: &i2s0 {
status = "okay";
pinctrl-0 = <&i2s0_default_alt>;
pinctrl-names = "default";
led_strip: ws2812@0 {
compatible = "worldsemi,ws2812-i2s";
//i2s-dev = < &i2s_led >;
reg = <0>;
chain-length = <1>; // arbitrary; change at will
color-mapping = <LED_COLOR_ID_GREEN LED_COLOR_ID_RED LED_COLOR_ID_BLUE>;
//out-active-low;
reset-delay = <120>;
supply-gpios = <&gpio1 14 (GPIO_ACTIVE_HIGH)>;
};
};
/ {
aliases {
led-strip = &led_strip;
};
};
main.c
/* New: LED Strip */
#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
#include <zephyr/device.h>
#include <zephyr/drivers/led_strip.h>
#include <zephyr/drivers/gpio.h>
#include <dk_buttons_and_leds.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#define STRIP_NODE DT_ALIAS(led_strip)
#define STRIP_NUM_PIXELS DT_PROP(DT_ALIAS(led_strip), chain_length)
#define RGB(_r, _g, _b) { .r = (_r), .g = (_g), .b = (_b) }
static const struct led_rgb colors[] = {
RGB(0x0f, 0x00, 0x00), /* red */
RGB(0x00, 0x0f, 0x00), /* green */
RGB(0x00, 0x00, 0x0f), /* blue */
};
static struct led_rgb pixels[STRIP_NUM_PIXELS];
static const struct device *const strip = DEVICE_DT_GET(STRIP_NODE);
int main(void)
{
if (device_is_ready(strip)) {
printk("Found LED strip device %s\n", strip->name);
}
else
{
printk("LED strip device %s is not ready\n", strip->name);
return 0;
}
size_t color = 0;
int rc;
while (1)
{
for (size_t cursor = 0; cursor < ARRAY_SIZE(pixels); cursor++)
{
memset(&pixels, 0x00, sizeof(pixels));
memcpy(&pixels[cursor], &colors[color], sizeof(struct led_rgb));
rc = led_strip_update_rgb(strip, pixels, STRIP_NUM_PIXELS);
if (rc) {
printk("couldn't update strip: %d\n", rc);
}
k_sleep(K_MSEC(500));
}
color = (color + 1) % ARRAY_SIZE(colors);
dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
}
return 0;
}