Hi,
I am using six vl53l0x (a laser time-of-flight sensor) on two I2C busses (three each), and device_get_binding() returns NULL on all but one.
The vl53l0x is special in that regard that it cannot be pin-strapped to a device-address, instead it always comes up as address 0x29, and has a SW command to assign it a new address. So when using multiple vl53l0x on one I2C bus the mechanism is to keep all-but-one in reset, assign a new address, and release the next from reset. This mechanism seems to work fine with this loop getting called with 0..5:
void vl53l0x_init_addr(int n)
{
const struct device *i2c1 = device_get_binding(DT_LABEL(DT_PATH(soc, i2c_40005400)));
const struct device *i2c2 = device_get_binding(DT_LABEL(DT_PATH(soc, i2c_40005800)));
switch (n)
{
case 0:
xshut_release(PORTPIN_TOF_C_XSHUT);
vl53l0x_hop_to_addr(i2c1, 0x31);
vl53l0x[2].vl53l0x = device_get_binding(DT_LABEL(DT_NODELABEL(vl53l0x_c)));
break;
case 1:
xshut_release(PORTPIN_TOF_B_XSHUT);
vl53l0x_hop_to_addr(i2c1, 0x30);
vl53l0x[1].vl53l0x = device_get_binding(DT_LABEL(DT_NODELABEL(vl53l0x_b)));
break;
case 2:
xshut_release(PORTPIN_TOF_A_XSHUT);
vl53l0x[0].vl53l0x = device_get_binding(DT_LABEL(DT_NODELABEL(vl53l0x_a)));
break;
case 3:
xshut_release(PORTPIN_TOF_F_XSHUT);
vl53l0x_hop_to_addr(i2c2, 0x31);
vl53l0x[5].vl53l0x = device_get_binding(DT_LABEL(DT_NODELABEL(vl53l0x_f)));
break;
case 4:
xshut_release(PORTPIN_TOF_E_XSHUT);
vl53l0x_hop_to_addr(i2c2, 0x30);
vl53l0x[4].vl53l0x = device_get_binding(DT_LABEL(DT_NODELABEL(vl53l0x_e)));
break;
case 5:
xshut_release(PORTPIN_TOF_D_XSHUT);
vl53l0x[3].vl53l0x = device_get_binding(DT_LABEL(DT_NODELABEL(vl53l0x_d)));
break;
}
}
However when testing lateron, only vl53l0x[0].vl53l0x has an address, the other five are 0. Note that vl53l0x[0].vl53l0x gets actually set in the third call to the above function.
for (int i = 0; i < N_VL53L0X; i++)
{
printf("DEV[%d] = %p\r\n", i, vl53l0x[i].vl53l0x);
}
Prints:
DEV[0] = 0x20020f04
DEV[1] = 0x0
DEV[2] = 0x0
DEV[3] = 0x0
DEV[4] = 0x0
DEV[5] = 0x0
I am using an DT-overlay which is
&i2c1 {
status = "okay";
clock-frequency = < 100000 >;
pinctrl-0 = < &i2c1_scl_pb6 &i2c1_sda_pb9 >;
vl53l0x_a: tofi2c1@29 {
compatible = "st,vl53l0x";
reg = < 0x29 >;
label = "VL53L0X_A";
};
vl53l0x_b: tofi2c1@30 {
compatible = "st,vl53l0x";
reg = < 0x30 >;
label = "VL53L0X_B";
};
vl53l0x_c: tofi2c1@31 {
compatible = "st,vl53l0x";
reg = < 0x31 >;
label = "VL53L0X_C";
};
};
&i2c2 {
status = "okay";
clock-frequency = < 100000 >;
pinctrl-0 = < &i2c2_scl_pf1 &i2c2_sda_pf0 >;
vl53l0x_d: tofi2c2@29 {
compatible = "st,vl53l0x";
reg = < 0x29 >;
label = "VL53L0X_D";
};
vl53l0x_e: tofi2c2@30 {
compatible = "st,vl53l0x";
reg = < 0x30 >;
label = "VL53L0X_E";
};
vl53l0x_f: tofi2c2@31 {
compatible = "st,vl53l0x";
reg = < 0x31 >;
label = "VL53L0X_F";
};
};
Is this "dynamic" behaviour unsupported in current DT and/or the zephyr vl53l0x driver implementation, or am I missing some detail on how to implement this properly?
I am on an nucleo-144 STM32F767ZI eval board.
Thanks & best regards,
matthias