Adding another I2C node causes undefined reference to `__device_dts_ord_XXX'

Hello!

I am trying to merge two simple Zephyr applications that both use I2C. I have an application that uses the SBC_OLED01 display. I followed these instructions. The second application uses the LISH3DH accelerometer with the nordic example LIS2DH. Both are using the i2c0 node. When I compile them separately it works fine, but after I merge them I get the error undefined reference to `__device_dts_ord_XXX'. I have searched the devzone but have not found anything that could help me. I assume the error lies in the overlay file. Here is the overlay file:

arduino_i2c: &i2c0 {
	compatible = "nordic,nrf-twim";
	status = "okay";
	clock-frequency = <I2C_BITRATE_FAST>;
    zephyr,concat-buf-size = <4096>;
};


&i2c1 {
    status = "okay"; 
    /*  --> if uncomment this then I get the error
    lis2dh12: lis2dh12@18 {
		compatible = "st,lis2dh12", "st,lis2dh";
		reg = <0x18>;
		irq-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>, <&gpio0 30 GPIO_ACTIVE_HIGH>;
		disconnect-sdo-sa0-pull-up;
	};
     */
};

I have looked in the zephyr.dts file and I it looks okay:

 ....
 
 		i2c0: arduino_i2c: i2c@40003000 {
			compatible = "nordic,nrf-twim";
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40003000 0x1000 >;
			clock-frequency = < 0x61a80 >;
			interrupts = < 0x3 0x1 >;
			status = "okay";
			pinctrl-0 = < &i2c0_default >;
			pinctrl-1 = < &i2c0_sleep >;
			pinctrl-names = "default", "sleep";
			zephyr,concat-buf-size = < 0x1000 >;
			ssd1306_ssd1306_128x32: ssd1306@3c {
				compatible = "solomon,ssd1306fb";
				reg = < 0x3c >;
				width = < 0x80 >;
				height = < 0x20 >;
				segment-offset = < 0x0 >;
				page-offset = < 0x0 >;
				display-offset = < 0x0 >;
				multiplex-ratio = < 0x1f >;
				segment-remap;
				com-invdir;
				com-sequential;
				prechargep = < 0x22 >;
			};
		};
		spi0: spi@40003000 {
			compatible = "nordic,nrf-spi";
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40003000 0x1000 >;
			interrupts = < 0x3 0x1 >;
			max-frequency = < 0x7a1200 >;
			easydma-maxcnt-bits = < 0x10 >;
			status = "disabled";
			pinctrl-0 = < &spi0_default >;
			pinctrl-1 = < &spi0_sleep >;
			pinctrl-names = "default", "sleep";
		};
		i2c1: i2c@40004000 {
			compatible = "nordic,nrf-twi";
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40004000 0x1000 >;
			clock-frequency = < 0x186a0 >;
			interrupts = < 0x4 0x1 >;
			status = "okay";
			pinctrl-0 = < &i2c1_default >;
			pinctrl-1 = < &i2c1_sleep >;
			pinctrl-names = "default", "sleep";
			lis2dh12: lis2dh12@18 {
				compatible = "st,lis2dh12", "st,lis2dh";
				reg = < 0x18 >;
				irq-gpios = < &gpio0 0x1c 0x0 >, < &gpio0 0x1e 0x0 >;
				disconnect-sdo-sa0-pull-up;
			};
		};
 
 ...

I thought I need to add the CONFIG_I2C_1 flag in the .conf file, but it does not recognize the symbol. What could be issue of this error?


Thanks for the help!!!

OS: Windows

SDK: 2.4.1

IDE: Visual Studio Code

Hardware: nRF52840 DK

  • Update:

    I get the following error message:

    The ordinal number 132 in the device_generated.h corresponds to lisdh12:

    This means that the Python script does not generate the part of the code corresponding to lisdh12. A look at the prj.conf file shows that the LISDH sensor is set as follows:

    However, looking into the autoconf.h file, the macro is not generated:

    I do not know why is this the case, because I did set the flags in the prj.conf files. In the documentation it says  it only needs/depends on (I2C || SPI) && SENSOR. 

    What am I missing here?

  • Hello

    Thank you for contacting DevZone at NordicSemi. I have been assigned this ticket, however I did not get a chance to look at it today. I will look into this tomorrow.

    BR, Naeem

  • Hello again,

    Thank you for your patience.

    Based on the information you have provided, I have included following project configs:

    CONFIG_LOG=y
    CONFIG_I2C=y
    CONFIG_SENSOR=y
    CONFIG_LIS2DH=y
    
    CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD=y
    CONFIG_CBPRINTF_FP_SUPPORT=y

    And I am using this overlay where I have one ssd1306 on i2c0 and the lis2dh12 on the i2c1

    
    &i2c0{
            compatible = "nordic,nrf-twim";
            #address-cells = < 0x1 >;
            #size-cells = < 0x0 >;
            reg = < 0x40003000 0x1000 >;
            clock-frequency = < 0x61a80 >;
            interrupts = < 0x3 0x1 >;
            status = "okay";
            pinctrl-0 = < &i2c0_default >;
            pinctrl-1 = < &i2c0_sleep >;
            pinctrl-names = "default", "sleep";
            zephyr,concat-buf-size = < 0x1000 >;
            ssd1306_ssd1306_128x32: ssd1306@3c {
                    compatible = "solomon,ssd1306fb";
                    status = "okay";
    		reg = < 0x3c >;
    		width = < 0x80 >;
    		height = < 0x20 >;
    		segment-offset = < 0x0 >;
    		page-offset = < 0x0 >;
    		display-offset = < 0x0 >;
    		multiplex-ratio = < 0x1f >;
    		segment-remap;
    		com-invdir;
    		com-sequential;
    		prechargep = < 0x22 >;
    	};
    };
    
    
    &i2c1{
            compatible = "nordic,nrf-twi";
            status = "okay";
            pinctrl-0 = < &i2c1_default >;
            pinctrl-1 = < &i2c1_sleep >;
            pinctrl-names = "default", "sleep";
            lis2dh12: lis2dh12@18 {
                    compatible = "st,lis2dh12", "st,lis2dh";
                    reg = < 0x18 >;
                    irq-gpios = < &gpio0 0x1c 0x0 >, < &gpio0 0x1e 0x0 >;
                    disconnect-sdo-sa0-pull-up;
            };
    };
    
    
    &spi0 {
            status = "disabled";
    };
    
    &spi1 {
            status = "disabled";
    };
    
    

    In the main, I can access both I2C controllers like this:

    const struct device *devi2c0 = DEVICE_DT_GET(DT_NODELABEL(i2c0));
    const struct device *devi2c1 = DEVICE_DT_GET(DT_NODELABEL(i2c1));
    
    printk("devi2c0 = is %p, name is %s\n", devi2c0, devi2c0->name);
    printk("devi2c1 = is %p, name is %s\n", devi2c1, devi2c1->name);

    I can also access the LIS2DH12 sensor by using DEVICE_DT_GET_ONE() macro

    const struct device *devlis = DEVICE_DT_GET_ONE(st_lis2dh12);
    printk("devLIS = is %p, name is %s\n", devlis, devlis->name);

    However, this will not work for the SOLOMON device.

    The reason is that the solomon,ssd1306fb is a spi device with spi.yaml bindings

    Project is attached for reference. Regards, Naeem

    case314823.zip

  • Hi;

    I believe I've identified a solution to my issue, yet I'm puzzled by the underlying reason.

    However, this will not work for the SOLOMON device.

    The reason is that the solomon,ssd1306fb is a spi device with spi.yaml bindings

    Strange!!! I got it working on my nrf52840 board with the SOLOMON device.

    Project is attached for reference. Regards, Naeem

    case314823.zip

    Cool!!! I took your project and made it work for both thessd1306 and lis2dh12. Below is the console output and the project. 

    Project:

    case314823_2.zip

    Maybe, you can help me to understand why is this now working? I am also quite new to the Zephyr ecosystem. 

    As for my problem in my project, I found the "solution" after seeing and reading this Github post:

    "When I set I2C to y in my driver kconfig, my project was surprisingly compiled and passed, and there will be no previous problems."

    So I did the same and the project compiled confusingly. I had a Kconfig that I updated as follows:

    menu "NRF DM"
    
    config I2C
            default y
    
    config SENSOR
            default y
    
    config LIS2DH
            default y
    
    config PRINT_OUT_RESULT
    	bool "enable or disable printing the result out"
    	default n
    
    endmenu
    

    I believe when you add a Kconfig file to the project, it does not listen to the proj.conf file.In your project where you did not have a Kconfig file, it worked because it was not blocked by Kconfig file.

    The world of Zepyhr is quite strange.

    Thanks again for your help!!! 

  • Hello

    J0sh1101 said:
    I've identified a solution to my issue

    Great to know that you have made progress and have found a solution to your issue.

    J0sh1101 said:
    Maybe, you can help me to understand why is this now working?

    As I am working on another task, I will look at it next week and will respond to you accordingly.

    Appreciate your patience.

    Regards,

    Naeem

Related