This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Implementing WS2812 Driver NCS (undefined reference to `__device_dts_ord_61')

I'm trying to implement the WS2812 driver in my own project. I'm referencing the sample code stored in zephyr/samples/drivers/led_ws2812. I have copied over all of the correct configuration files, however, I'm getting an error when I try to define the strip device struct. The line shown here is throwing the error: 

#define STRIP_NODE		DT_ALIAS(led_strip)
#define STRIP_NUM_PIXELS	DT_PROP(DT_ALIAS(led_strip), chain_length)

// I believe this is the problem somehow: 
static const struct device *strip = DEVICE_DT_GET(STRIP_NODE);

The error I'm getting on compile is: 

undefined reference to `__device_dts_ord_61'

I have triple-checked all of my includes, my proj.conf is exactly the same as the sample, and my nrf52dk_nrf52832.overlay has the correct configuration. What am I missing? The sample compiles just fine.

Alternately, how is the *strip definition different than a normal sensor definition? For example, I have initialized my accelerometer as such: 

const struct device *sensor = device_get_binding("LIS3DH");

Is there a way to follow that same convention for my LED strip that would prevent this error I am seeing? Calling device_get_binding("WS2812") results in a NULL device. See below for my overlay file:

&i2c1 {
	compatible = "nordic,nrf-twim";
	status = "okay";
	sda-pin = <30>;
	scl-pin = <31>;
    clock-frequency = <I2C_BITRATE_FAST>;
    
    lis2dh@18 {
        compatible = "st,lis2dh";        
        reg = <0x18>;
        label = "LIS3DH";
    };    
};

#include "../nrf52-bindings.h"

&arduino_spi { /* MOSI on D11 / P0.23 */
	compatible = "nordic,nrf-spim";
	led_strip: ws2812@0 {
		compatible = "worldsemi,ws2812-spi";
		label = "WS2812";

		/* SPI */
		reg = <0>; /* ignored, but necessary for SPI bindings */
		spi-max-frequency = <SPI_FREQ>;

		/* WS2812 */
		chain-length = <10>; /* arbitrary; change at will */
		spi-one-frame = <ONE_FRAME>;
		spi-zero-frame = <ZERO_FRAME>;
	};
};

/ {
	aliases {
		led-strip = &led_strip;
	};
};

Parents
  • Alternately, how is the *strip definition different than a normal sensor definition? For example, I have initialized my accelerometer as such: 

    Using device_get_binding() has been the main way of getting a device set in the device tree, which operates at run-time. However, there has been created some new macros recently that allows you to get the device during the preprocessor phase. 

    https://github.com/nrfconnect/sdk-zephyr/commit/c2d852a17106dc49e7c086a055522cb857ce5780 

    This will cause you to get errors when building the project instead while running it.

    It seems like more and more samples are going away from device_get_binding() and using DEVICE_DT_* macros instead:

    https://github.com/nrfconnect/sdk-zephyr/commit/2c793f72aeada2f5f29881e4036ec86bed636bd8

    https://github.com/nrfconnect/sdk-zephyr/commit/1dbf6f78273da80a5c1143a45e3df87f00370582

    https://github.com/nrfconnect/sdk-zephyr/commit/363a1d6c842a69706303bfd40a8d1ecc2615274d

    Is there a way to follow that same convention for my LED strip that would prevent this error I am seeing? Calling device_get_binding("WS2812") results in a NULL device. See below for my overlay file:

    I don't think the issue is related to the way you're getting the device, I think there is some issue with the generated dts definitions. If device_get_binding returns null, it means it couldn't find a node with the label "WS2812".  See https://github.com/nrfconnect/sdk-zephyr/blob/v2.6.0-rc1-ncs1-rc1/include/device.h#L542 

    Can you attach the file <sample>/build/zephyr/zephyr.dts? See if you can find the following inside it:

    		spi2: arduino_spi: spi@40023000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40023000 0x1000 >;
    			interrupts = < 0x23 0x1 >;
    			status = "okay";
    			label = "SPI_2";
    			compatible = "nordic,nrf-spim";
    			sck-pin = < 0x19 >;
    			mosi-pin = < 0x17 >;
    			miso-pin = < 0x18 >;
    			cs-gpios = < &arduino_header 0x10 0x1 >;
    			led_strip: ws2812@0 {
    				compatible = "worldsemi,ws2812-spi";
    				label = "WS2812";
    				reg = < 0x0 >;
    				spi-max-frequency = < 0x3d0900 >;
    				chain-length = < 0x10 >;
    				spi-one-frame = < 0x70 >;
    				spi-zero-frame = < 0x40 >;
    			};
    		};

    Best regards,

    Simon

  • I see on line 248 of my zephyr.dts file contains the arduino_spi node bound to spi2. It contains the led_strip component. Doesn't this tell me that the device tree overlay is building correctly? Why else would I still be receiving this error? 

    main.c:141: undefined reference to `__device_dts_ord_60'

  • Yes, I agree with you, it seems like all the dts definitions are generated correctly, so I'm actually not sure what's going on here. 

    I was able to build the sample zephyr/samples/drivers/led_ws2812 using the board nrf52dk_nrf52832. So one approach to figure out what's causing the issue it to start with that sample, and gradually, step by step add stuff from your main sample (from prj.conf, main.c, overlay files and so on). Every time you add something new, build the sample, then you'll eventually figure out what's causing it to fail.

    Please share the solution if you find the cause. If you're not able to figure it out, would you be able to upload your sample in zipped format? Then I could take a look at it.

  • Hey Simon, thanks. I've been through this exercise a few times now. The compile error only occurs when I add code to interact with the strip device. 

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

    Defined as such: 

    #define STRIP_NODE		DT_ALIAS(led_strip)
    #define STRIP_NUM_PIXELS	DT_PROP(DT_ALIAS(led_strip), chain_length)
    
    struct led_rgb pixels[STRIP_NUM_PIXELS];
    
    static const struct device *strip = DEVICE_DT_GET(STRIP_NODE);

    Attached is the zip file directory. I just combined the peripheral_dis sample with the ws812 sample. As noted, the error occurs only after defining the strip node and calling device_is_ready. The WS812 sample compiles fine for me with no modification. But, pulling it into a new project throws the error. 

    dis_led_test.zip 

  • I think it would be interesting to do it the opposite way, start with the WS812 sample and add stuff from the peripheral_dis sample until it breaks. Then you will figure out what in the peripheral_dis sample that causes the issue.

    I can look into it tomorrow.

Reply Children
Related