How do I extra the gpio phandle form a lis3dh device to the C code?

I have a lis3dh sensor where I want to configure the interrupts. I am currently struggling to extract the information from the irq-gpios phandle to the c driver. I went through the troubleshooting page for the device tree and found a website explanation that said it should work, but I am still unable to compile the code. 

I have a overlay define like this: 

&i2c0 {  
    mysensor: mysensor@18{
        compatible = "st,lis3dh";
        status = "okay";
        reg = < 0x18 >;
        irq-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>, <&gpio1 4 GPIO_ACTIVE_HIGH>;
    };
};

My driver tries to extract the data gpio information like this:

#define I2C1_NODE DT_NODELABEL(mysensor)

static const struct i2c_dt_spec dev_i2c = I2C_DT_SPEC_GET(I2C1_NODE);


//const struct gpio_dt_spec int1 = DT_IRQN_BY_IDX(DT_NODELABEL(mysensor), 0);
//const struct gpio_dt_spec int1 = GPIO_DT_SPEC_INST_GET_BY_IDX_COND(DT_NODELABEL(mysensor), irq_gpios, 0);
//const struct gpio_dt_spec int1 = GPIO_DT_SPEC_INST_GET_BY_IDX_OR(DT_NODELABEL(mysensor), irq_gpios, 0, {});
//const struct gpio_dt_spec int1 = DT_GPIO_CTLR_BY_IDX(I2C1_NODE, irq_gpios, 0);
const struct gpio_dt_spec int1 = DT_GPIO_CTLR_BY_IDX(I2C1_NODE, irq_gpios, 0);

I have received an error like this:

[50/149] Building C object CMakeFiles/app.dir/src/lis3dh/lis3dh.c.obj
FAILED: CMakeFiles/app.dir/src/lis3dh/lis3dh.c.obj 
C:\ncs\toolchains\cf2149caf2\opt\zephyr-sdk\arm-zephyr-eabi\bin\arm-zephyr-eabi-gcc.exe -DKERNEL -DNRF52840_XXAA -D_ANSI_SOURCE -D_FORTIFY_SOURCE=1 -D__LINUX_ERRNO_EXTENSIONS__ -D__PROGRAM_START -D__ZEPHYR__=1 -IC:/ncs/v2.6.0/zephyr/include -IC:/nordic_play_workfolder/LIS3DH/build_nrf52840_dk/zephyr/include/generated -IC:/ncs/v2.6.0/zephyr/soc/arm/nordic_nrf/nrf52 -IC:/ncs/v2.6.0/zephyr/lib/libc/newlib/include -IC:/ncs/v2.6.0/zephyr/soc/common/nordic_nrf/. -IC:/ncs/v2.6.0/zephyr/soc/arm/nordic_nrf/common/. -IC:/ncs/v2.6.0/nrf/include -IC:/ncs/v2.6.0/nrf/tests/include -IC:/ncs/v2.6.0/modules/hal/cmsis/CMSIS/Core/Include -IC:/ncs/v2.6.0/zephyr/modules/cmsis/. -IC:/ncs/v2.6.0/modules/hal/nordic/nrfx -IC:/ncs/v2.6.0/modules/hal/nordic/nrfx/drivers/include -IC:/ncs/v2.6.0/modules/hal/nordic/nrfx/mdk -IC:/ncs/v2.6.0/zephyr/modules/hal_nordic/nrfx/. -IC:/ncs/v2.6.0/modules/debug/segger/SEGGER -IC:/ncs/v2.6.0/modules/debug/segger/Config -IC:/ncs/v2.6.0/modules/debug/segger/SEGGER/DebugMon/include -isystem C:/ncs/v2.6.0/zephyr/lib/libc/common/include -isystem C:/ncs/v2.6.0/nrfxlib/crypto/nrf_cc310_platform/include -fno-strict-aliasing -Og -imacros C:/nordic_play_workfolder/LIS3DH/build_nrf52840_dk/zephyr/include/generated/autoconf.h -fno-common -g -gdwarf-4 -fdiagnostics-color=always -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfp16-format=ieee --sysroot=C:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/arm-zephyr-eabi -imacros C:/ncs/v2.6.0/zephyr/include/zephyr/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-pointer-sign -Wpointer-arith -Wexpansion-to-defined -Wno-unused-but-set-variable -Werror=implicit-int -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fno-reorder-functions --param=min-pagesize=0 -fno-defer-pop -fmacro-prefix-map=C:/nordic_play_workfolder/LIS3DH=CMAKE_SOURCE_DIR -fmacro-prefix-map=C:/ncs/v2.6.0/zephyr=ZEPHYR_BASE -fmacro-prefix-map=C:/ncs/v2.6.0=WEST_TOPDIR -ffunction-sections -fdata-sections -specs=nano.specs -std=c99 -MD -MT CMakeFiles/app.dir/src/lis3dh/lis3dh.c.obj -MF CMakeFiles\app.dir\src\lis3dh\lis3dh.c.obj.d -o CMakeFiles/app.dir/src/lis3dh/lis3dh.c.obj -c C:/nordic_play_workfolder/LIS3DH/src/lis3dh/lis3dh.c
In file included from C:/ncs/v2.6.0/zephyr/include/zephyr/devicetree.h:19,
                 from C:/ncs/v2.6.0/zephyr/include/zephyr/arch/arm/arch.h:20,
                 from C:/ncs/v2.6.0/zephyr/include/zephyr/arch/cpu.h:19,
                 from C:/ncs/v2.6.0/zephyr/include/zephyr/kernel_includes.h:37,
                 from C:/ncs/v2.6.0/zephyr/include/zephyr/kernel.h:17,
                 from C:/nordic_play_workfolder/LIS3DH/src/lis3dh/lis3dh.c:1:
C:/nordic_play_workfolder/LIS3DH/build_nrf52840_dk/zephyr/include/generated/devicetree_generated.h:13569:70: error: 'DT_N_S_soc_S_gpio_50000000' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_gpio_50000000_ORD'?
13569 | #define DT_N_S_soc_S_i2c_40003000_S_mysensor_18_P_irq_gpios_IDX_0_PH DT_N_S_soc_S_gpio_50000000
      |                                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
C:/ncs/v2.6.0/zephyr/include/zephyr/devicetree.h:4349:41: note: in expansion of macro 'DT_N_S_soc_S_i2c_40003000_S_mysensor_18_P_irq_gpios_IDX_0_PH'
 4349 | #define DT_CAT6(a1, a2, a3, a4, a5, a6) a1 ## a2 ## a3 ## a4 ## a5 ## a6
      |                                         ^~
C:/ncs/v2.6.0/zephyr/include/zephyr/devicetree.h:1592:9: note: in expansion of macro 'DT_CAT6'
 1592 |         DT_CAT6(node_id, _P_, prop, _IDX_, idx, _PH)
      |         ^~~~~~~
C:/ncs/v2.6.0/zephyr/include/zephyr/devicetree/gpio.h:54:9: note: in expansion of macro 'DT_PHANDLE_BY_IDX'
   54 |         DT_PHANDLE_BY_IDX(node_id, gpio_pha, idx)
      |         ^~~~~~~~~~~~~~~~~
C:/nordic_play_workfolder/LIS3DH/src/lis3dh/lis3dh.c:54:34: note: in expansion of macro 'DT_GPIO_CTLR_BY_IDX'
   54 | const struct gpio_dt_spec int1 = DT_GPIO_CTLR_BY_IDX(I2C1_NODE, irq_gpios, 0);
      |                                  ^~~~~~~~~~~~~~~~~~~
C:/ncs/v2.6.0/zephyr/include/zephyr/devicetree.h:4341:24: note: in expansion of macro 'DT_N_NODELABEL_mysensor'
 4341 | #define DT_CAT(a1, a2) a1 ## a2
      |                        ^~
C:/ncs/v2.6.0/zephyr/include/zephyr/devicetree.h:198:29: note: in expansion of macro 'DT_CAT'
  198 | #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label)
      |                             ^~~~~~
C:/nordic_play_workfolder/LIS3DH/src/lis3dh/lis3dh.c:44:19: note: in expansion of macro 'DT_NODELABEL'
   44 | #define I2C1_NODE DT_NODELABEL(mysensor)
      |                   ^~~~~~~~~~~~
C:/nordic_play_workfolder/LIS3DH/src/lis3dh/lis3dh.c:54:54: note: in expansion of macro 'I2C1_NODE'
   54 | const struct gpio_dt_spec int1 = DT_GPIO_CTLR_BY_IDX(I2C1_NODE, irq_gpios, 0);
      |                                                      ^~~~~~~~~
C:/nordic_play_workfolder/LIS3DH/src/lis3dh/lis3dh.c:69:27: error: redefinition of 'int1'
   69 | const struct gpio_dt_spec int1 ={
      |                           ^~~~
C:/nordic_play_workfolder/LIS3DH/src/lis3dh/lis3dh.c:54:27: note: previous definition of 'int1' with type 'const struct gpio_dt_spec'
   54 | const struct gpio_dt_spec int1 = DT_GPIO_CTLR_BY_IDX(I2C1_NODE, irq_gpios, 0);
      |                           ^~~~
[63/149] Linking C static library zephyr\arch\arch\arm\core\cortex_m\libarch__arm__core__cortex_m.a
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: 'C:\ncs\toolchains\cf2149caf2\opt\bin\cmake.EXE' --build 'c:\nordic_play_workfolder\LIS3DH\build_nrf52840_dk'

I can access the I2C node, that I defined but the gpio struct?

Thanks for the help!

  • Hi

    Which version of NCS are you using? Have you verfied that your address is correct according to your setup? 

    The pinconfig looks correct to me so the overlay should be good. If you remove the line "const struct gpio_dt_spec int1 = DT_GPIO_CTLR_BY_IDX(I2C1_NODE, irq_gpios, 0);" does it build then? I presume your case is somewhat the same as this case

    Could you post your prj.conf?

    Regards

    Runar

  • Hi

    Which version of NCS are you using?

    I am using the nRF Connect SDK v2.6.

    If you remove the line "const struct gpio_dt_spec int1 = DT_GPIO_CTLR_BY_IDX(I2C1_NODE, irq_gpios, 0);" does it build then?

    Yes, then it builds. I can extract the data and saved to 2c_dt_spec:

    Could you post your prj.conf?

    ofc, here is the prj.conf:

    # Logger module
    CONFIG_LOG=y
    CONFIG_LOG_MODE_MINIMAL=y
    
    
    CONFIG_NEWLIB_LIBC=y
    CONFIG_CBPRINTF_FP_SUPPORT=y
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
    
    
    
    # Button and LED library
    CONFIG_DK_LIBRARY=y
    CONFIG_BOOT_BANNER=n
    CONFIG_I2C=y

    I presume your case is somewhat the same as this case

    Maybe a little. I am trying to write my own driver and he is trying to use the existing driver which I have given up. The interface of the driver is far too complex to just write a few registers and is not intuitive.

    Have you verfied that your address is correct according to your setup?

    Which address are we talking about?

    I talked to someone who knows more about the device tree than I do and he said that the problem is the macro function "DT_NODELABEL(mysensor)" and not DT_GPIO_CTLR_BY_IDX() as I thought at first. This is strange because the macro function I2C_DT_SPEC_GET() works perfectly with DT_NODELABEL(), but DT_NODELABEL does not work with DT_GPIO_CTLR_BY_IDX. DT_NODE_LABEL uses the concatenation to create a define which can be found in devicetree_generated.h. In my case it is DT_N_S_soc_S_i2c_40003000_S_mysensor_18_P_irq_gpios_IDX_0_PH. The problem seems to be that it cannot find the define of DT_N_S_soc_S_gpio_50000000. (Now, the error message makes more sense.) At this point I do not understand why the DT_N_S_soc_S_gpio_50000000 is not created.

    Do you know anything more about this?

    (This device tree is really a hell.)

  • Thanks for the new info.  I will need to get back to you tomorrow after looking a bit more into it. However from what I can see you have not enabled the sensor in your prj.conf, try adding CONFIG_LIS3DH=y

    We have a lesson covering writing custom drivers here which might be helpful

    Regards

    Runar

  • Could you try adding the following Kconfig options

    CONFIG_SENSOR=y
    CONFIG_LIS2DH=y
    CONFIG_LIS3DH is not a thing so you would need to use LIS2DH. It might also be that you need to set compatible to 
    "st,lis3dh", "st,lis2dh";

    Regards
    Runar
  • Hello,

    Unfortunately it did not make any difference. I got that it could not set the CONFIG_LIS2DH:





    Do you know why is this happening?

Related