NRF5340, WS2812, I2S

Hello.

I'm trying to use WS2812 leds with I2S. I'm using two boards for testing: an NRF5340DK and my board based on the HOLYIOT-21069-5340 module.

I'm using a zephyr/samples/drivers/led/led_strip as an example.

I need the control signal to be on P1.00. I'm trying it with the NRF5340DK board first.

Here's my overlay file:

#include <zephyr/dt-bindings/led/led.h>

/ {
    aliases {
        ledstrip = &ledstrip;
    };
};

&pinctrl {
    i2s0_default_alt: i2s0_default_alt {
		group1 {
			psels = <NRF_PSEL(I2S_SCK_M, 1, 15)>,
				<NRF_PSEL(I2S_LRCK_M, 1, 12)>,
				<NRF_PSEL(I2S_SDOUT, 1, 0)>; // Output pin to LED strip
		};
    };
};

&i2s0 {
    status = "okay";
    pinctrl-0 = <&i2s0_default_alt>;
    pinctrl-names = "default";

	ledstrip: ws2812@0 {
		compatible = "worldsemi,ws2812-i2s";

		reg = <0>;
		chain-length = <2>; /* arbitrary; change at will */
		color-mapping = <LED_COLOR_ID_GREEN
					LED_COLOR_ID_RED
					LED_COLOR_ID_BLUE>;
		reset-delay = <500>;
	};
};

&uart0 {
    status = "disabled";
};

&i2c1 {
    status = "disabled";
};

&spi4 {
    status = "disabled";
};

&pwm0 {
    status = "disabled";
};

&qspi {
    status = "disabled";
};

&usbd {
    status = "disabled";
};

&usbreg {
    status = "disabled";
};


If I use pin P1.00, nothing works — the pin stays high all the time. If I use P1.01 or P1.13, everything works.

P1.00 is listed in the description as a "General purpose I/O." Nothing seems to be connected to it on the board either. Why can't I use it?

The second problem occurs when I try to use my board. The board is based on a HOLYIOT-21069-5340 module with nRF5340 QKAA.

I use the exact same code without rebuilding it.

I'm just doing a "west flash," but instead of a NRF5340DK board, I'm connecting my HOLYIOT-21069-5340 module. And for some reason, the driver stops working, and I get the following messages in debug:

[00:00:00.000,213] <dbg> ws2812_i2s: ws2812_i2s_init: Word clock: freq 100000 Hz period 10 us
*** Booting Zephyr OS build v4.3.0-7395-g768095e06b41 ***
[00:00:00.000,274] <inf> main: Found LED strip device ws2812@0
[00:00:00.000,274] <inf> main: Displaying pattern on strip
[00:00:01.001,403] <err> i2s_nrfx: Cannot write in state: 3
[00:00:01.001,434] <err> ws2812_i2s: Failed to write data: -5
[00:00:01.001,434] <err> main: couldn't update strip: -5
[00:00:02.001,586] <err> i2s_nrfx: Cannot write in state: 3
[00:00:02.001,586] <err> ws2812_i2s: Failed to write data: -5
[00:00:02.001,586] <err> main: couldn't update strip: -5

My prj.conf:

CONFIG_LOG=y
CONFIG_LED_STRIP=y
CONFIG_LED_STRIP_LOG_LEVEL_DBG=y

CONFIG_SPI=y
CONFIG_I2S=y
CONFIG_WS2812_STRIP_I2S=y

CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n

I do it simply:

1. Build: west build -b nrf5340dk/nrf5340/cpuapp --sysbuild

2. Flash: west flash

3. Debug output: west rtt

  • Hi,

     

    If I use pin P1.00, nothing works — the pin stays high all the time. If I use P1.01 or P1.13, everything works.

    P1.00 is listed in the description as a "General purpose I/O." Nothing seems to be connected to it on the board either. Why can't I use it?

    Try disabling the gpio pin forwarder to the network core by adding this to your overlay:

    &gpio_fwd {
    	status = "disabled";
    };

     

    The second problem occurs when I try to use my board. The board is based on a HOLYIOT-21069-5340 module with nRF5340 QKAA.

    I use the exact same code without rebuilding it.

    I'm just doing a "west flash," but instead of a NRF5340DK board, I'm connecting my HOLYIOT-21069-5340 module. And for some reason, the driver stops working, and I get the following messages in debug:

    Does your custom board include both DCDC inductors and an external LF clk?

    If not, you will need to CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y

     

    Kind regards,

    Håkon

  • Does your custom board include both DCDC inductors and an external LF clk?

    If not, you will need to CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y

    I added to prj.conf:

    CONFIG_CLOCK_CONTROL=y
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n
    

    But there are no changes, I still get messages on my board:

    [00:00:00.000,335] <inf> main: Found LED strip device ws2812@0
    [00:00:00.000,366] <inf> main: Displaying pattern on strip
    [00:00:00.053,161] <err> i2s_nrfx: Cannot write in state: 3
    [00:00:00.053,192] <err> ws2812_i2s: Failed to write data: -5
    [00:00:00.053,192] <err> main: couldn't update strip: -5
    

  • Hi,

     

    Have you done any changes to the .c file? Do you use the exact same .hex for the DK as for your board?

    This indicates that the module is draining its transfer:

    <err> i2s_nrfx: Cannot write in state: 3

    as state=3 means I2S_STATE_STOPPING, indicating that a former transfer is on-going when triggering a new one.

    I would recommend that you scope the I2S pins in both working scenario and non-working scenario, and see if there is a specific difference.

      

    Kind regards,

    Håkon

  • It's the exact same code. The same .hex file. I don't recompile the project, I just upload it to both boards.

    I tried selecting different pins, and there were always no error messages on the NRF5340DK, but on my board, I get the same error messages every time I try to send it.

  • The I2S settings allow to select a clock source (docs.zephyrproject.org/.../nordic,nrf-i2s.html).

    As far as I understand, the I2C unit is clocked from the 32 MHz bus, not the 32 kHz bus. Therefore, switching the 32 kHz bus to the RC source didn't help.

    I tried all the available options (PCLK32MPCLK32M_HFXO), but the result was exactly the same. I checked the debugger, and the error appears starting with the second attempt to send. This means, for some reason, the first attempt to send never completes.

    It's possible there really is a clocking issue, but I don't see what could be wrong. On this board, the UART, SPI, and BLE are working. This means the high-frequency bus is clocked.

Related