Wrong value transmitted over I2C bus by the microcontroller (0x58 instead of 0x0A)
Hi all,
I am using STM32F303CB microcontroller, connected with a I2C slave which has no CLK stretching support. The I2C bus lines are pulled high with 4k75 ohms resistors and the lines have a serial resistor of 50 ohms (approx.). The schematic looks like the one in the image below.
The routine I have in configuring the slave and running it in normal mode, is the following.
- Reset the slave using HAL_I2C_Master_Transmit().
- A delay of 100 ms.
- Config the slave using HAL_I2C_Master_Transmit().
- A delay of 1.5 ms.
- Run the slave (from config mode to normal mode) using HAL_I2C_Master_Transmit_IT().
The circuit was implemented on certain number of PCBs and the routine works fine on most of them. However, on certain PCBs, the slave does not start properly and the issue was found to be with the step 5 of the routine I mentioned above.
Normally, the transmitted data should look like the image below (0x2A -> slave address, 0x0A -> memory location inside slave, 0x00 -> data to be written inside that memory).
However, on these certain PCBs, the memory location byte of the slave is transmitted improperly over the I2C bus. The µC is "supposedly" transmitting 0x58 instead of 0x0A.
Note - the CLK stretching also happens on a proper transmission and hence, shall be ruled out as the cause for this error.
If it was a bit shift or something, I can understand this kind of error. But it was far from a bit shift. 0x0A -> 0x58 shift is something that I cannot understand. Hence, I tested the analog side as well, and noticed that there was no spur/glitch detected (500 MS/second).
As I said earlier, the slave cannot control the I2C bus (no CLK stretching!). There are no interference happening on the PCBs. The test environment is the same for all the PCBs under testing. There are no voltage spikes or strange noise on the bus/voltage system.
Since the options from hardware side started depleting, I started investigating from the code perspective. I tried to see if the correct value is being sent from the µC to the slave, and it is indeed correct. Since the I2C peripheral itself does not have an internal buffer, it always points to the array that we mention in the function parameters. The value of the array variables are not updated at any moment. Hence, there is no chance of the variable being overwritten as the I2C communication is ongoing.
It will be great if someone has an idea of what I am dealing with. If more information is required, please feel free to ask and I shall share at once.
Thank you!