STM32F4 i2c bus-stuck-low with VL53L0X, embassy rust

Hello, when I am using VL53L0X sensors they are working but after a while they make i2c line stuck. ( SCL is high and SDA is pulled low ). I know the solution is use SCL as output pin and make it to send some pulses to release i2c line and I am doing so before I2C initialization during micro controller startup. But is there any solution to make it during STM32 normal runtime without resetting it? I am using i2c multiplexer TCA9548 with VL53L0X.

I have no experience with i2c multiplexer devices, but I would assume they should have properly implemented the protocol, and this seems apparently a buggy implementation of i2c on the master side.

are you using the chip's i2c controller peripheral or bit-banging i2c with gpio? either way, I would suggest to capture some i2c traffic from the bus using a logical analyzer. without seeing the actual signals, it's impossible to figure out what went wrong.

Well normally I am using i2c controller peripheral. But before i2c peripheral initialization I am using big-banging to send some impulses on SCL line to make sure that line is released. I am also using AS5600 with this multiplexer and they doesn't cause any problems, only VL53L0X are locking I2C line from time to time. But oscilloscope seems to be a good idea nevertheless.

that's not how i2c works, you cannot just strobe the SCL "several" pulses! the signals on the wires must adhere to the protocol, because the transceivers on slave devices
are stateful: if the bus transmits signals that is not proper i2c, the transceivers' state machine will likely be out of sync.

I don't know what you mean by "to make sure that line is released", SCL should only be driven by the bus master (slave devices stretching the clock is allowed by the protocol, but it is rarely used in practice, and as far as I know, it is only allowed during a transaction, not when the bus is idle).

does your circuit has some bug that you must workaround with software? unless the software can deterministically and reliably workaround it, you should really fixed the circuit hardware. for instance, suppose the problem is the microcontroller takes too long to initialize and leaving certain devices in unstable states but you cannot reset them in software, you can add proper reset logic to hold the devices' reset signals until the microcontroller is ready and then release them.

Well I took suggestion from this topic: STM32F1 I2C pins stuck low - STMicroelectronics Community .

IMHO, that post is really bad advice. and if you read the thread, the user actually identified the problem and fixed it in hardware: add the missing pull-up resisters.

according to the i2c protocol, except for the bus START and STOP condition, the data line is not allowed to change when the clock is high. if the SDA signal is stuck low, it's most likely the transceiver of some slave device is in the middle of a bus READ transaction and the data bit happens to be 0.

this is an erroneous situation, and if you continue to clock the bus, eventually the transceiver should indeed release the data bus (either because a data bit happens to be 1, or its internal bit counter resets), that's why it "seems to work" sometimes, for some devices. but the transceiver state machine is still in a unknown state! you can try to issue a bus STOP condition, hoping the device transceiver will return to IDLE state, but that's not guaranteed.

the real reason the bus can get stuck is because the slave i2c tranceivers are stateful and out of sync, and the root cause for that is either:

a) the device is not properly reset, or
b) the bus master messed up the i2c protocol in the first place.

you should really understand the root cause of the problem and solve it, but in either case, the proper fix definitely should NOT be: "just mess the bus more"