Setting up devicetree for I2C device that has address changed

I'm currently working on a project that uses the MLX90640 IR sensor.  By default, this device has an I2C address of 0x33, but it can be set up with one of 127 different I2C addresses.

This is how I have the device tree set up:

	&i2c0 {
		compatible = "nordic,nrf-twim";
		status = "okay";
		pinctrl-0 = <&i2c0_default>;
		pinctrl-1 = <&i2c0_sleep>;
		pinctrl-names = "default", "sleep";
		clock-frequency = <I2C_BITRATE_STANDARD>;

		mlx90640: mlx90640@33 {
			compatible = "mlx90640";
			reg = <0x33>;
			label = "MLX90640";
		};

What I'm trying to understand is, if I go in and change the I2C address of the device, what happens to the device pointer I have that is linked to the device tree entry?

#define I2C0_NODE DT_NODELABEL(mlx90640)
static const struct i2c_dt_spec mlx90640_i2c = I2C_DT_SPEC_GET(I2C0_NODE);

All of the Zephyr I2C API's require referencing the device pointer, but if I change the I2C address, I'm guessing this will no longer be valid.  So I'm not sure how I reference the device once I've changed the I2C address.

Anyone done this before and can help me work out how to get it functioning?

Regards,

Mike

  • Hi there,

    I'm not sure I understand the question. The device node label will be updated once you rebuild your project.

    Are you getting any build errors?

    Please elaborate on the question.

    regards

    Jared 

  • Hi Jared,

    Sorry - I probably should have provided more detail.

    I am trying to write some firmware that enables me to change the I2C address on a batch of these MLX90640 sensors, doing this one sensor at a time.  I have about 20 in my application, and I need them all to be unique so I can access the info of each of them over the same I2C bus.

    So, sequence is:

    1. I connect one sensor up to my DK
    2. Check that I can access it via is default address (0x33)
    3. Take the updated address as input via UART
    4. Reconfigure the sensor to that new I2C address
    5. Then check that I can access it via the new address.
    6. I then remove that sensor from the I2C bus, and connect up the next sensor
    7. Then repeat steps 1-6 with the next sensor

    So, I don't want to have to rebuild everything between steps 4-5 and 5-6.

    I've not actually tried this approach as yet (still waiting for the sensors to arrive), but as I understand it, this code:

    static const struct i2c_dt_spec mlx90640_i2c = I2C_DT_SPEC_GET(I2C0_NODE);

    Will simply populate the values of the i2c_dt_spec structure with the device and addr info from the device tree.  So, in theory, when I get to step 5, I just need up update the value of mlx90640_i2c.addr with the new address (e.g. 0x40) and I should then be able to read/write to it.

    Does that sound like it will work?

    Regards,

    Mike

  • Mike,

    I think the best approach would be to use i2c_transfer() instead of i2c_transfer_dt(), since the former takes the address as an argument instead of using the address that is specified in the devicetree node.

    regards

    Jared 

Related