zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.75k stars 6.56k forks source link

A DTS Issue for tca9546a multiplexor driver #56879

Closed zafersn closed 1 year ago

zafersn commented 1 year ago

Hi,

I am trying to use a bme sensors over the tca9546 a multiplexor, here is the dts defination. When I call my sensor by DEVICE_DT_GET(DT_ALIAS(temp_sensor)); macro I am getting main.c:80: undefined reference to __device_dts_ord_117 error in complining time although it works when I call mux channel instead of sensor. But this time im getting runtime error because program doesnt write/read correct sensor register addresses.

error with restart loop:

*** Booting Zephyr OS build v3.2.99-ncs1 ***
initializing...
Found device "mux_i2c@1", getting sensor data
*** Booting Zephyr OS build v3.2.99-ncs1 ***
initializing...
Found device "mux_i2c@1", getting sensor data
*** Booting Zephyr OS build v3.2.99-ncs1 ***
initializing...
Found device "mux_i2c@1", getting sensor data
*** Booting Zephyr OS build v3.2.99-ncs1 ***
initializing...
Found device "mux_i2c@1", getting sensor data

Where am I doing wrong or missing something?

aliases:

aliases {
        temp-sensor = &envir_sens;
        humidity-sensor = &envir_sens;
        pressure-sensor = &envir_sens;
};

dts:

&i2c1 {
    compatible = "nordic,nrf-twim";
    pinctrl-0 = <&i2c1_default>;
    pinctrl-1 = <&i2c1_sleep>;
    pinctrl-names = "default", "sleep";
    mux:tca9546a@70 {
        compatible = "ti,tca9546a";
        reg = <0x70>;
        status = "okay";
        #address-cells = <1>;
        #size-cells = <0>;  
        ch0:mux_i2c@0 {
            compatible = "ti,tca9546a-channel";
            reg = <0>;
            status = "okay";
            #address-cells = <1>;
            #size-cells = <0>;
            yic_gnss:yic91009ebgg@42 {
                compatible = "yic,yic91009ebgg";
                vin-supply = <&pwrout6>;
                reg = <0x42>;
            };
        };
        ch1:mux_i2c@1 {
            compatible = "ti,tca9546a-channel";
            reg = <1>;
            status = "okay";
            #address-cells = <1>;
            #size-cells = <0>;
            envir_sens: bme680@76 {
                status = "okay";
                compatible = "bosch,bme680";
                // vin-supply = <&pwrout1>;
                reg = <0x76>;
            };  
        };
        ch2:mux_i2c@2 {
            compatible = "ti,tca9546a-channel";
            reg = <2>;
            status = "okay";
            #address-cells = <1>;
            #size-cells = <0>;
            optical: vcnl4040@60 {
                compatible = "vishay,vcnl4040-extr";
                reg = <0x60>;
                led-current = <50>;
                led-duty-cycle = <320>;
                proximity-it = "8";
                als-it = <80>;
                vin-supply = <&pwrout7>;
                int-gpios = <&gpio0 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;   // connected to the io expander
            };
        };
        ch3:mux_i2c@3 {
            compatible = "ti,tca9546a-channel";
            reg = <3>;
            status = "okay";
            #address-cells = <1>;
            #size-cells = <0>;
            bq_bat: bq27z561@55{
                compatible = "ti,bq274xx";
                reg = <0x55>;
                int-gpios = <&gpio0 16 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
                design-voltage = <3300>;
                design-capacity = <1000>;
                taper-current = <100>;
                terminate-voltage = <2800>;         
            };
        };
    };
};

prj.conf

CONFIG_STDOUT_CONSOLE=y
CONFIG_GPIO=y
CONFIG_I2C=y
CONFIG_CBPRINTF_FP_SUPPORT=y
CONFIG_SENSOR=y
CONFIG_BME680=n
CONFIG_ADXL362=n
CONFIG_BQ274XX=n
CONFIG_BME680_NET=y
CONFIG_I2C_TCA954X=y
CONFIG_I2C_TCA954X_ROOT_INIT_PRIO=61
CONFIG_I2C_TCA954X_CHANNEL_INIT_PRIO=62
void main(void)
{
    printf("initializing...\n");
    bool isSensorBmeActive = true;
    int64_t timestamp = 0;
/*************************** BME680 **********************/

    //const struct device *bme_dev = DEVICE_DT_GET(DT_NODELABEL(ch1)); // no compiling error but it doesnt work
    const struct device *bme_dev = DEVICE_DT_GET(DT_ALIAS(temp_sensor));

    if (bme_dev == NULL) {
        /* No such node, or the node does not have status "okay". */
        printk("\nError: no bme device found.\n");
        return;
    }

    if (!device_is_ready(bme_dev)) {
        printk("\nError: Device \"%s\" is not ready; "
               "check the driver initialization logs for errors.\n",
               bme_dev->name);
        return;
    }
    printk("Found device \"%s\", getting sensor data\n", bme_dev->name);

    while (1)
    {
        /* measuring T H P */
        k_sleep(K_MSEC(1000));

         timestamp = k_uptime_get();
        if(isSensorBmeActive)
        {
            struct sensor_value bmeValue[BME_CHANNELS];
            double value_array[BME_CHANNELS];

            sensorBme_getData(bme_dev, &bmeValue[0]);

            value_array[0] = sensor_value_to_double(&bmeValue[0]);
            value_array[1] = sensor_value_to_double(&bmeValue[1]);
            value_array[2] = sensor_value_to_double(&bmeValue[2]);
            printk ("tst: %d, tmp: %.2f, prs: %.2f, hum: %.2f \n",(uint32_t)timestamp, value_array[0],value_array[1],value_array[2]);
        }
    }
}

BTW, I am working on nrf 9160 sip based custom board with ncs 2.2.0

The Zephyr fork in nRF Connect SDK (sdk-zephyr) contains all commits from the upstream Zephyr repository up to and including cd16a8388f71a6cce0cea871f75f6d4ac8f56da9, with some nRF Connect SDK specific additions. The current nRF Connect SDK main branch is based on revision cd16a8388f of Zephyr.

zafersn commented 1 year ago

I fixed issue by editting sensor driver.c . rest of them are ok

static const struct sensor_driver_api bme680_api_funcs = {
    .sample_fetch = bme680_sample_fetch,
    .channel_get = bme680_channel_get,
};

static struct bme680_data bme680_data = {
    .dev.delay_ms = &k_sleep,
    .dev.write = &bme680_reg_write,
    .dev.read = &bme680_reg_read,
    .dev.intf = BME680_I2C_INTF,
};

static const struct bme680_config bme680_config = {
    .bus = I2C_DT_SPEC_INST_GET(0)
};

DEVICE_DT_INST_DEFINE(0, bme680_init, NULL, &bme680_data,
              &bme680_config, POST_KERNEL, CONFIG_BME_SENSOR_INIT_PRIORITY,
              &bme680_api_funcs);

to

static const struct sensor_driver_api bme680_api_funcs = {
    .sample_fetch = bme680_sample_fetch_netfeasa,
    .channel_get = bme680_channel_get_netfeasa,
};

static struct bme680_data bme680_data = {
    .dev.delay_ms = &k_sleep,
    .dev.write = &bme680_reg_write,
    .dev.read = &bme680_reg_read,
    .dev.intf = BME680_I2C_INTF,
};

#define BME_IDEFINE(inst)                           \
    static const struct bme680_config bme680_cfg_##inst = {     \
        .bus = I2C_DT_SPEC_INST_GET(inst),              \
    };                                  \
    SENSOR_DEVICE_DT_INST_DEFINE(inst, bme680_init, NULL,           \
        &bme680_data, &bme680_cfg_##inst,           \
        POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,           \
        &bme680_api_funcs);

DT_INST_FOREACH_STATUS_OKAY(BME_IDEFINE)