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

Parents
  • 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 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

Reply
  • 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

Children
  • 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

  • Hello,

    And thank you for your patience.

    Now I have gone through your project and the link which you have posted.

    So basically, the screen (device) from solomon supports both the i2c and the spi interface.

    But previously we were configuring it wrong in the overlay.

    Now you have removed that part from the overlay, and I see that you were using "SHIELD=ssd..." parameter in building, and thats solomon device gets correctly configured in the DTS.

    When I modify the overlay based on the ssd-shield overlay, and I add config for this device (and its dependency) [CONFIG_SSD1306 and CONFIG_DISPLAY], then it is working good.

    So I think previously our overlay was not good, and also we need to enable driver for this device in the config.

    Below is the output snapshot like the previous one:

    And the project is attached just for reference:

    tocustomer.rar

    And whatever you have said about the prj.conf is probably not true. Kconfig is to define config options, ranges, dependencies, selections and default values, while the prj.conf is to use specific values for those configs for the application.

    You can read more on the zephyr about how build system works, and also the information in this ticket might be helpful for that.

    BR, Naeem

Related