cancel
Showing results for 
Search instead for 
Did you mean: 

Wrong value transmitted over I2C bus by the microcontroller (0x58 instead of 0x0A)

MagSense
Associate II

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.

0693W00000NrwWSQAZ.png 

The routine I have in configuring the slave and running it in normal mode, is the following.

  1. Reset the slave using HAL_I2C_Master_Transmit().
  2. A delay of 100 ms.
  3. Config the slave using HAL_I2C_Master_Transmit().
  4. A delay of 1.5 ms.
  5. 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).

0693W00000NrwWrQAJ.png 

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.

0693W00000NrwXQQAZ.png 

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).

0693W00000NrwYiQAJ.png 

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!

1 ACCEPTED SOLUTION

Accepted Solutions

> My main question still remains unanswered as to how can such an event occur?

For example if you define your transmit buffer as a local variable and then exit the function which called HAL_I2C_Master_Transmit_IT ().

JW

View solution in original post

7 REPLIES 7

> I tried to see if the correct value is being sent from the µC to the slave, and it is indeed correct.

I don't believe.

Hack into the routine where Cube/HAL actually writes the bytes into the I2C data register, and add a line, which outputs the bytes to something like UART or stores them to some global array or something similar.

JW

Hi,

Thanks for the response!

I tried the following condition inside the HAL_I2C_Master_Transmit_IT function (right after the I2C_TransferConfig() function)

if(hi2c->pBuffPtr[0] == 0x0A)

{

//toggle pin

}

Everytime I see the pin toggle. But my first question is, how can such a thing happen? The I2C itself does not hold any data, right? It always points to the array we create/declare. Then how can it be possible? And we are not speaking about one bit shift. That was my main question, actually.

Thanks again!

> if(hi2c->pBuffPtr == 0x0A)

> {

> //toggle pin

> }

hi2c->pBuffPtr is presumably a pointer, I don't believe it's value is 0x0A and the pin toggles.

And I meant to check at the point where the write to Tx data register actually happens, i.e. https://github.com/STMicroelectronics/STM32CubeF3/blob/64707c404c8448f9c7e562839471a051a9192b1e/Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c.c#L4775

JW

Hi. Thanks. It was a typo. Corrected it now.

With the code section you are pointing, is actually pointing to the pointer of an existing array. Hence, the value should not change anyways, right? For me, this might help in finding the "source" of error within the code section but does not explain why such a value will be sent over I2C bus.

My main question still remains unanswered as to how can such an event occur? I cannot render it as sporadic as it is reproducible.

Thanks again!

> My main question still remains unanswered as to how can such an event occur?

For example if you define your transmit buffer as a local variable and then exit the function which called HAL_I2C_Master_Transmit_IT ().

JW

MagSense
Associate II

Hi. Its true that the transmit buffer variable was lost since it was a local variable. Thanks for the suggestion! Really helped!

I caught the data that is actually written to the TXDR and it was 0x58.Thanks!