Issues compiling custom I2C driver

Hey,

Trying to compile a custom driver for an I2C device and running into issues getting the actual DT node to link with the driver at build time.

Specifically, (because it looks like it'll never go in) I'm trying to use this driver https://github.com/zephyrproject-rtos/zephyr/pull/48389 

My filesystem is set up as follows (other files omitted):

application_repo/
├─ drivers/
│  ├─ sensor/
│  │  ├─ mcp9600/
│  │  │  ├─ CMakeLists.txt
│  │  │  ├─ mcp9600.c
│  │  │  ├─ mcp9600.h
│  │  ├─ CMakeLists.txt
│  ├─ CMakeLists.txt
├─ dts/
│  ├─ bindings/
│  │  ├─ sensor/
│  │  │  ├─ microchip,mcp9600.yaml 
├─ boards/
│  ├─ arm/
│  │  ├─ board_name/
│  │  │  ├─ board_name.dts (and others) 
├─ src/
│  ├─ main.c
├─ CMakeLists.txt
├─ prj.conf

I have included all driver code in CMakeFiles correctly and removed all ifdef guards, and double checked the driver CMakeList is getting added with a fatal error test message.

I have added the device to the devicetree with this inside the i2c node (the other sensors work fine)

&i2c1 {
  label = "I2C1";
  clock-frequency = <100000>;
  compatible = "nordic,nrf-twim";
  status = "okay";
  pinctrl-0 = <&i2c1_default>;
  pinctrl-1 = <&i2c1_sleep>;
  pinctrl-names = "default", "sleep";

  lis2dh: lis2dh@19 {
    compatible = "st,lis2dh";
    label = "LIS2DH_I2C";
    reg = <0x19>;
    irq-gpios = <&gpio0 29 0>;
  };

  bme280: bme280@77 {
    compatible = "bosch,bme280";
    reg = <0x77>;
    label = "BME280_I2C";
  };

  mcp9600: mcp9600@67 {
    compatible = "microchip,mcp9600";
    label = "MCP9600_I2C";
    reg = <0x67>;
    status = "okay";
  };
};

I've tried also putting it in an overlay file just for this board as well.

It appears the node is getting compiled from DT as the following are all present in the build directory.

CONFIG_DT_HAS_MICROCHIP_MCP9600_ENABLED=y

set_target_properties(devicetree_target PROPERTIES "DT_NODE|/soc/peripheral@40000000/i2c@9000/mcp9600@67" TRUE)
set_target_properties(devicetree_target PROPERTIES "DT_NODELABEL|mcp9600" "/soc/peripheral@40000000/i2c@9000/mcp9600@67")
set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|reg" "103;")
set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|status" "okay")
set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|compatible" "microchip,mcp9600;")
set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|label" "MCP9600_I2C")
set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|wakeup-source" "False")
set_target_properties(devicetree_target PROPERTIES "DT_REG|/soc/peripheral@40000000/i2c@9000/mcp9600@67|NUM" "1")
set_target_properties(devicetree_target PROPERTIES "DT_REG|/soc/peripheral@40000000/i2c@9000/mcp9600@67|ADDR" "0x67;")
set_target_properties(devicetree_target PROPERTIES "DT_REG|/soc/peripheral@40000000/i2c@9000/mcp9600@67|SIZE" "NONE;")

extern const struct device DEVICE_DT_NAME_GET(DT_N_S_soc_S_peripheral_40000000_S_i2c_9000_S_mcp9600_67); /* dts_ord_96 */

But in the output map, the driver is never actually present causing my app to not compile. The zephyr_pre0.map file stops at __device_dts_ord_95 and doesn't include the mcp9600. You can see it include the other sensors here.

 .z_device_POST_KERNEL90_
                0x000000000002c29c       0x18 zephyr/drivers/sensor/bme280/libdrivers__sensor__bme280.a(bme280.c.obj)
                0x000000000002c29c                __device_dts_ord_94
 .z_device_POST_KERNEL90_
                0x000000000002c2b4       0x18 zephyr/drivers/sensor/lis2dh/libdrivers__sensor__lis2dh.a(lis2dh.c.obj)
                0x000000000002c2b4                __device_dts_ord_95
                0x000000000002c2cc                __device_APPLICATION_start = .
 *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_APPLICATION[0-9]_*)))
 *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_APPLICATION[1-9][0-9]_*)))
                0x000000000002c2cc                __device_SMP_start = .
 *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_SMP[0-9]_*)))
 *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_SMP[1-9][0-9]_*)))
                0x000000000002c2cc                __device_end = .

I've slightly changed the driver code from the PR, but the DT_INST_FOREACH_STATUS_OKAY macro is still not finding any instances to compile, I get a "too few arguments in invocation of macro Z_FOR_LOOP_1" error on that line.

I have included the correct #define DT_DRV_COMPAT microchip_mcp9600 in the c file as well.

#define MCP9600_DEFINE(inst)                                                                                                              \
  static struct mcp9600_data mcp9600_data_##inst;                                                                                         \
  static const struct mcp9600_config mcp9600_config_##inst = {                                                                            \
      .i2c = I2C_DT_SPEC_INST_GET(inst),                                                                                                  \
  };                                                                                                                                      \
                                                                                                                                          \
  DEVICE_DT_INST_DEFINE(inst, mcp9600_init, NULL, &mcp9600_data_##inst, &mcp9600_config_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
                        &mcp9600_api_functions);

DT_INST_FOREACH_STATUS_OKAY(MCP9600_DEFINE)

Do I need to put these files elsewhere? Every other sample I've looked at seems to follow this same structure. I'm on SDK 2.1.1 for reference. If needed I can share the full project in a confidential environment.

Thanks in advance Slight smile

Parents Reply Children
No Data
Related