TCA9548A i2c multiplexer interfacing with nrf5340

Hello, 

I am trying to interface a TCA9548A Multiplexer on my custom board. I am able to set up the channels and read the channel status' with device_get_binding successfully. However when I try to get the child node (the sensors) from each channel it returns NULL at runtime when I use:

const struct device *sensor[2];
sensor = device_get_binding(SENSOR_NAME);

and it gives me an undefined reference error at compile time when I attempt to use: 

const struct device *sens0 = DEVICE_DT_GET(DT_NODELABEL(bmp280_1));
(See full build error below)
Error message:
FAILED: zephyr/zephyr_pre0.elf zephyr/zephyr_pre0.map 
: && ccache /opt/nordic/ncs/toolchains/20d68df7e5/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc  -gdwarf-4 zephyr/CMakeFiles/zephyr_pre0.dir/misc/empty_file.c.obj -o zephyr/zephyr_pre0.elf  -fuse-ld=bfd  -T  zephyr/linker_zephyr_pre0.cmd  -Wl,-Map=/Users/nyameaama/Documents/MARS-Flight-System-Firmware/base-firmware-V2/build/zephyr/zephyr_pre0.map  -Wl,--whole-archive  app/libapp.a  zephyr/libzephyr.a  zephyr/arch/common/libarch__common.a  zephyr/arch/arch/arm/core/aarch32/libarch__arm__core__aarch32.a  zephyr/arch/arch/arm/core/aarch32/cortex_m/libarch__arm__core__aarch32__cortex_m.a  zephyr/arch/arch/arm/core/aarch32/cortex_m/cmse/libarch__arm__core__aarch32__cortex_m__cmse.a  zephyr/arch/arch/arm/core/aarch32/mpu/libarch__arm__core__aarch32__mpu.a  zephyr/lib/libc/picolibc/liblib__libc__picolibc.a  zephyr/lib/libc/common/liblib__libc__common.a  zephyr/soc/soc/arm/common/cortex_m/libsoc__arm__common__cortex_m.a  zephyr/subsys/random/libsubsys__random.a  zephyr/subsys/bluetooth/common/libsubsys__bluetooth__common.a  zephyr/subsys/bluetooth/host/libsubsys__bluetooth__host.a  zephyr/subsys/net/libsubsys__net.a  zephyr/drivers/bluetooth/libdrivers__bluetooth.a  zephyr/drivers/clock_control/libdrivers__clock_control.a  zephyr/drivers/console/libdrivers__console.a  zephyr/drivers/entropy/libdrivers__entropy.a  zephyr/drivers/gpio/libdrivers__gpio.a  zephyr/drivers/i2c/libdrivers__i2c.a  zephyr/drivers/pinctrl/libdrivers__pinctrl.a  zephyr/drivers/serial/libdrivers__serial.a  zephyr/drivers/timer/libdrivers__timer.a  modules/nrf/subsys/nrf_security/src/zephyr/libmbedtls_zephyr.a  modules/nrf/modules/tfm/zephyr/libtfm_api_nrf.a  modules/trusted-firmware-m/libtfm_api.a  modules/hal_nordic/nrfx/libmodules__hal_nordic__nrfx.a  modules/segger/libmodules__segger.a  -Wl,--no-whole-archive  zephyr/kernel/libkernel.a  zephyr/CMakeFiles/offsets.dir/./arch/arm/core/offsets/offsets.c.obj  -L"/opt/nordic/ncs/toolchains/20d68df7e5/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/thumb/v8-m.main/nofp"  -L/Users/nyameaama/Documents/MARS-Flight-System-Firmware/base-firmware-V2/build/zephyr  -lgcc  zephyr/arch/common/libisr_tables.a  tfm/secure_fw/s_veneers.o  -Wl,--gc-sections  -Wl,--build-id=none  -Wl,--sort-common=descending  -Wl,--sort-section=alignment  -Wl,-u,_OffsetAbsSyms  -Wl,-u,_ConfigAbsSyms  -nostdlib  -static  -Wl,-X  -Wl,-N  -Wl,--orphan-handling=warn  -Wl,-no-pie  -DPICOLIBC_INTEGER_PRINTF_SCANF  modules/nrf/subsys/nrf_security/src/libmbedcrypto.a  /opt/nordic/ncs/v2.5.0/nrfxlib/crypto/nrf_oberon/lib/cortex-m33/soft-float/liboberon_mbedtls_3.0.13.a  modules/nrf/subsys/nrf_security/src/libmbedcrypto_base.a  -mcpu=cortex-m33  -mthumb  -mabi=aapcs  -mfp16-format=ieee  /opt/nordic/ncs/v2.5.0/nrfxlib/crypto/nrf_oberon/lib/cortex-m33/soft-float/liboberon_3.0.13.a  --specs=picolibc.specs  -lc  -lgcc && cd /Users/nyameaama/Documents/MARS-Flight-System-Firmware/base-firmware-V2/build/zephyr && /opt/nordic/ncs/toolchains/20d68df7e5/Cellar/cmake/3.20.5/bin/cmake -E true
/opt/nordic/ncs/toolchains/20d68df7e5/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: app/libapp.a(main.c.obj): in function `main':
/Users/nyameaama/Documents/MARS-Flight-System-Firmware/base-firmware-V2/build/../src/main.c:223: undefined reference to `__device_dts_ord_98'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

This means I am unable to continue to read/write and setup the drivers for any of the sensors. For some reason it is able to see the mux channels but when I try to reference any of the sensors in the channels, it says they do not exist. Could you help me?

Here is my configuration and code

DeviceTree:

&i2c0 {
    bus_0_mux_1: bus_0_mux_1@70{
        compatible = "ti,tca9548a";
        reg = < 0x70 >;  
        label = "bus_0_mux_1";
		#address-cells = <1>;
        #size-cells = <0>;

        ch0: mux_i2c@0 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_0";
            reg = <0x0>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            bmp280_1: bmp280_1@76 {
                compatible = "i2c-device";
                reg = <0x76>;
                status = "okay";
                label = "BMP280_1";
            };
        };

		ch1: mux_i2c@1 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_1";
            reg = <0x1>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            bmp280_2: bmp280_2@76 {
                compatible = "i2c-device";
                reg = <0x76>;
                label = "BMP280_2";
            };
        };

		ch2: mux_i2c@2 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_2";
            reg = <0x2>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            bmp280_3: bmp280_3@76 {
                compatible = "i2c-device";
                reg = <0x76>;
                label = "BMP280_3";
            };
        };

		ch3: mux_i2c@3 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_3";
            reg = <0x3>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            icm42688: icm42688@68 {
                compatible = "i2c-device";
                reg = <0x68>;
                label = "ICM42688";
            };
        };

		ch4: mux_i2c@4 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_4";
            reg = <0x4>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            bmi088_acc: bmi088_acc@18 {
                compatible = "i2c-device";
                reg = <0x18>;
                label = "BMI088-ACC";
            };

			bmi088_gyro: bmi088_gyro@68 {
                compatible = "i2c-device";
                reg = <0x68>;
                label = "BMI088-GYRO";
            };

		};
        
		ch5: mux_i2c@5 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_5";
            reg = <0x5>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            lsm303_acc_1: lsm303_acc_1@19 {
                compatible = "i2c-device";
                reg = <0x19>;
                label = "LSM303_ACC_1";
            };

			lsm303_mag_1: lsm303_mag_1@1E {
                compatible = "i2c-device";
                reg = <0x1E>;
                label = "LSM303_MAG_1";
            };

		};

		ch6: mux_i2c@6 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_6";
            reg = <0x6>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            lsm303_acc_2: lsm303_acc_2@19 {
                compatible = "i2c-device";
                reg = <0x19>;
                label = "LSM303_ACC_2";
            };

			lsm303_mag_2: lsm303_mag_2@1E {
                compatible = "i2c-device";
                reg = <0x1E>;
                label = "LSM303_MAG_2";
            };

		};

		ch7: mux_i2c@7 {
            compatible = "ti,tca9548a-channel";
            label = "i2c0_mux_7";
            reg = <0x7>;
            status = "okay";
            #address-cells = <0x1>;
            #size-cells = <0x0>;

            lsm303_acc_3: lsm303_acc_3@19 {
                compatible = "i2c-device";
                reg = <0x19>;
                label = "LSM303_ACC_3";
            };

			lsm303_mag_3: lsm303_mag_3@1E {
                compatible = "i2c-device";
                reg = <0x1E>;
                label = "LSM303_MAG_3";
            };

		};

    };

	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-names = "default";
};

board defconfig:

CONFIG_I2C=y
CONFIG_I2C_TCA954X=y
CONFIG_I2C_TCA954X_ROOT_INIT_PRIO=61
CONFIG_I2C_TCA954X_CHANNEL_INIT_PRIO=62

main.c

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch0), okay)
#define I2C_0_CTRL_NODE_ID DT_NODELABEL(ch0)
#define I2C_0_CTRL_DEV_NAME DT_LABEL(I2C_0_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch1), okay)
#define I2C_1_CTRL_NODE_ID DT_NODELABEL(ch1)
#define I2C_1_CTRL_DEV_NAME DT_LABEL(I2C_1_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch2), okay)
#define I2C_2_CTRL_NODE_ID DT_NODELABEL(ch2)
#define I2C_2_CTRL_DEV_NAME DT_LABEL(I2C_2_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif*/

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch3), okay)
#define I2C_3_CTRL_NODE_ID DT_NODELABEL(ch3)
#define I2C_3_CTRL_DEV_NAME DT_LABEL(I2C_3_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch4), okay)
#define I2C_4_CTRL_NODE_ID DT_NODELABEL(ch4)
#define I2C_4_CTRL_DEV_NAME DT_LABEL(I2C_4_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch5), okay)
#define I2C_5_CTRL_NODE_ID DT_NODELABEL(ch5)
#define I2C_5_CTRL_DEV_NAME DT_LABEL(I2C_5_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch6), okay)
#define I2C_6_CTRL_NODE_ID DT_NODELABEL(ch6)
#define I2C_6_CTRL_DEV_NAME DT_LABEL(I2C_6_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(ch7), okay)
#define I2C_7_CTRL_NODE_ID DT_NODELABEL(ch7)
#define I2C_7_CTRL_DEV_NAME DT_LABEL(I2C_7_CTRL_NODE_ID)
#else
#error "I2C 0 controller device not found"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(bmp280_1), okay)
#define SENSOR_0_DEV_NAME DEVICE_DT_GET(DT_NODELABEL(bmp280_1))
#else
#error "Sensor 0 device not found"
#endif


int main(){
    const struct device *sensor[2];
    const struct device *ch[8];

    ch[0] = device_get_binding(I2C_0_CTRL_DEV_NAME);
    ch[1] = device_get_binding(I2C_1_CTRL_DEV_NAME);
    ch[2] = device_get_binding(I2C_2_CTRL_DEV_NAME);
    ch[3] = device_get_binding(I2C_3_CTRL_DEV_NAME);
    ch[4] = device_get_binding(I2C_4_CTRL_DEV_NAME);
    ch[5] = device_get_binding(I2C_5_CTRL_DEV_NAME);
    ch[6] = device_get_binding(I2C_6_CTRL_DEV_NAME);
    ch[7] = device_get_binding(I2C_7_CTRL_DEV_NAME);

    for (int i = 0; i < 8; i++)
    {
        if (ch[i] == NULL)
        {
            printk("Could not get I2C mux channel %d", i);
        }else{
            printk("Channel Success");
        }
    }

    const struct device *sens0 = DEVICE_DT_GET(DT_NODELABEL(bmp280_1));
    if (sens0 == NULL){
        printk("Could not get device");
    }else{
        printk("Got device");
    }
}

Parents Reply Children
Related