cancel
Showing results for 
Search instead for 
Did you mean: 

I2C STM32CubeMX HAL code: Target receive in interrupt mode TransferDirection issue

TFdev
Associate II
Hello,
 
I want to use an I2C port of a STM32F411 MCU (MCU_A) in target mode to receive data from another MCU (MCU_B), MCU_B code already existing and verified with other receivers.
I configured the project with STM32CubeMX, with interrupts enabled to handle communication in interrupt mode.
I used MX standard settings to generate CubeIDE project with HAL code.
With some effort for setting up the initialization and other code for MCU_A in CubeIDE, communication looks ok from sending MCU_B perspective.
Additional check of SDA and SCL signals with DSO looks ok to. 
But the problem was: No data was transfered to the receive data buffer in MCU_A.
 
After several hours of debugging, I found a suspicious code section in the HAL code (stm32f4xx_hal_i2c.c).
In the HAL function 
    static void I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c, uint32_t IT2Flags)
which is called in 
    HAL_I2C_EV_IRQHandler ()
when adress matches, the direction flag received from MCU_B is evaluated:
    if (I2C_CHECK_FLAG(IT2Flags, I2C_FLAG_TRA) == RESET)
    {
      TransferDirection = I2C_DIRECTION_TRANSMIT;
    }
With the documentation in the STM32F411 reference manual for I2C_SR2 register
   Bit 2 TRA: Transmitter/receiver
   0: Data bytes received
   1: Data bytes transmitted
   This bit is set depending on the R/W bit of the address byte, at the end of total address 
   phase.
and other code parts 
   #define I2C_CHECK_FLAG(__ISR__, __FLAG__)         ((((__ISR__) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET)
   #define I2C_FLAG_TRA                    0x00100004U
I came to the conclusion, that the HAL direction evaluation code sets an inverted TransferDirection.
 
After changing the evaluation in HAL code to 
    if (I2C_CHECK_FLAG(IT2Flags, I2C_FLAG_TRA) == SET)
the tranmitted data from MCU_B is transfered to the receive data buffer in MCU_A as expected.
 
Question:
Can you confirm that there is an error in the HAL code generated by STM32CubeMX as described above?
If not:
Can you please give me any hints what is wrong with my implementation and resolution approach?
(I of course can give more information and code in this case, if necessary)
 
Thanks,
 
Christian
 
1 ACCEPTED SOLUTION

Accepted Solutions

 

Hello Saket_Om,

thank you very much for taking the time to review my code and for providing such a detailed explanation.

I now understand that the code in the official GitHub examples handles TransferDirection according to the definition you provided.

The issue on my side was caused by code taken from a tutorial in the ST community:

https://community.st.com/t5/stm32-mcus/how-to-create-an-i2c-target-device-using-the-stm32cube-library/ta-p/49844

In that code, the subsequent evaluation of TransferDirection appears to be inverted:

void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
  Transfer_Direction = TransferDirection;
  if (Transfer_Direction != 0)
  {
    /*##- Start the transmission process #####################################*/
    /* While the I2C in reception process, user can transmit data through
       "aTxBuffer" buffer */
    if (HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, (uint8_t *)aTxBuffer, TXBUFFERSIZE, I2C_FIRST_AND_LAST_FRAME) != HAL_OK)
    {
      /* Transfer error in transmission process */
      Error_Handler();
    }
...

I have also seen that other community members reported problems similar to mine when using the code from that example. The tutorial references a different MCU, but I would not expect that to affect the TransferDirection handling.

I would appreciate it if you could take a look at that tutorial as well and, if my conclusion is correct this time, consider updating or correcting the code provided there.

Best regards,

Christian

View solution in original post

5 REPLIES 5
Saket_Om
ST Employee

Hello @TFdev 

Did the address match occur?

Please refer to the example I2C_TwoBoards_ComIT where slave board receive data from master board in IT mode.  

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

Hello,

thank you for your reply and for pointing me to the example project.

I have looked at the example, and it is certainly useful as a general reference for I2C communication. However, it does not address the specific point of my question, which is about the HAL code generated and provided in the STM32CubeMX / CubeIDE workflow for my project.

To answer your question directly: yes, the address match does occur. It is exactly this event that leads to the call of the function I mentioned above.

Let me clarify my concern:
I am not trying to get I2C communication working “somehow.” With the modification described in my original post, I already have the communication working as expected.

My actual question is whether the HAL code in this case is incorrect, or whether I am misunderstanding something in my implementation or in the intended use of the generated HAL workflow.

Since this is my first project using STM32CubeMX together with CubeIDE and HAL, I cannot fully exclude a mistake on my side. However, based on my debugging and on the documented meaning of the TRA bit, it appears that the direction evaluation in the HAL function may be inverted.

Our intention is to use the STM32 ecosystem as a long-term MCU platform, and for portability across devices we would like to stay as close as possible to the official HAL-based workflow.

So I would appreciate it if you could take another look specifically at the HAL code section quoted in my post and comment on whether my analysis is correct.

And if this is not the right forum for reporting a suspected issue in the provided software, could you please let me know what the proper reporting channel or process is?

Thank you for your support.

Best regards,
Christian

Just saw that my version infos got lost. I'm using 

STM32CubeIDE Version: 2.1.1
STM32CubeMX Version: 6.17.0

 

Hello @TFdev 

The HAL code is not inverted. For the STM32F4 I2C peripheral in slave mode, the TRA bit in I2C_SR2 indicates the slave transfer role: TRA = 0 means the slave is in receiver mode, so the master is writing to the slave, and TRA = 1 means the slave is in transmitter mode, so the master is reading from the slave. In the HAL implementation, TransferDirection is named from the master/bus transaction point of view, where I2C_DIRECTION_TRANSMIT means “master transmits” and I2C_DIRECTION_RECEIVE means “master receives.” Therefore, mapping TRA == 0 to I2C_DIRECTION_TRANSMIT is consistent with the reference manual and does not by itself indicate an error in the HAL code.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

 

Hello Saket_Om,

thank you very much for taking the time to review my code and for providing such a detailed explanation.

I now understand that the code in the official GitHub examples handles TransferDirection according to the definition you provided.

The issue on my side was caused by code taken from a tutorial in the ST community:

https://community.st.com/t5/stm32-mcus/how-to-create-an-i2c-target-device-using-the-stm32cube-library/ta-p/49844

In that code, the subsequent evaluation of TransferDirection appears to be inverted:

void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
  Transfer_Direction = TransferDirection;
  if (Transfer_Direction != 0)
  {
    /*##- Start the transmission process #####################################*/
    /* While the I2C in reception process, user can transmit data through
       "aTxBuffer" buffer */
    if (HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, (uint8_t *)aTxBuffer, TXBUFFERSIZE, I2C_FIRST_AND_LAST_FRAME) != HAL_OK)
    {
      /* Transfer error in transmission process */
      Error_Handler();
    }
...

I have also seen that other community members reported problems similar to mine when using the code from that example. The tutorial references a different MCU, but I would not expect that to affect the TransferDirection handling.

I would appreciate it if you could take a look at that tutorial as well and, if my conclusion is correct this time, consider updating or correcting the code provided there.

Best regards,

Christian