How to control WS2812 via I2S on Adafruit Feather nRF52840 Express

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;
}


Schematic

Parents
  • Hi,

    I don't have a better suggestion that to start with the example as it is, and run on the nRF52840:
    \zephyr\samples\drivers\led\led_strip\

    Rename the \zephyr\samples\drivers\led\led_strip\boards\thingy52_nrf52832.overlay to \zephyr\samples\drivers\led\led_strip\boards\nrf52840dk_nrf52840.overlay

    And update the pins to fit your setup, and also power the led strip externally for now.

    Edit: Looking at your description it seems that might be what you have already done. I guess the next step then is to connect a logic analyzer to see if that may shed any light on the problem (do i2s execute as expected).

    Kenneth

Reply
  • Hi,

    I don't have a better suggestion that to start with the example as it is, and run on the nRF52840:
    \zephyr\samples\drivers\led\led_strip\

    Rename the \zephyr\samples\drivers\led\led_strip\boards\thingy52_nrf52832.overlay to \zephyr\samples\drivers\led\led_strip\boards\nrf52840dk_nrf52840.overlay

    And update the pins to fit your setup, and also power the led strip externally for now.

    Edit: Looking at your description it seems that might be what you have already done. I guess the next step then is to connect a logic analyzer to see if that may shed any light on the problem (do i2s execute as expected).

    Kenneth

Children
No Data
Related