cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5A5 -- I2C Timeout waiting for TXIS flag --

ahsank
Associate II

Hello all,

I have been trying to get I2C communication working on my NUCLEO-U5A5ZJ-Q board based on STM32U5A5ZJJT6U. First I have used STM32-CUBE-IDE and CUBE-MX to generate code but I was getting error when I try to transmit so I write a custom code which is also attached attached and after doing a bit of stepping through the code, it looks as though a HAL_TIMEOUT occurs when the I2C driver executes the I2C_WaitOnTXISFlagUntilTimeout() function and the exact error I am getting is as below

if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;

/* Process Unlocked */
__HAL_UNLOCK(hi2c);

return HAL_ERROR; /// HERE IT RETURNS ERROR IN MY CASE ///////
}

I have looked through the datasheet for this particular micro to figure out why this flag would not be set, but it is not immediately clear and it is controlled by HW. Is there something wrong with my setup?

Also I have changed main as follow:

int main(void)
{
HAL_Init(); // Initialize the HAL library

SystemClock_Config(); // Configure the system clock

__HAL_RCC_GPIOB_CLK_ENABLE(); // Enable GPIOB clock
__HAL_RCC_I2C1_CLK_ENABLE(); // Enable I2C1 clock

GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; // Configure GPIO pins for I2C1 SCL and SDA
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; // Alternate function open-drain
GPIO_InitStruct.Pull = GPIO_PULLUP; // Enable internal pull-up resistors
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // High-speed output
GPIO_InitStruct.Alternate = GPIO_AF4_I2C2; // I2C1 alternate function
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); // Initialize GPIO pins

hi2c1.Instance = I2C2; // Select I2C1 peripheral
//hi2c1.Init.Timing = 0xE14;
hi2c1.Init.Timing = 0x30420F13;
//hi2c1.Init.ClockSpeed = 100000; // I2C clock speed (100 kHz)
//hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; // I2C duty cycle
hi2c1.Init.OwnAddress1 = 0; // Not used in master mode
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; // 7-bit addressing mode
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; // No dual addressing
hi2c1.Init.OwnAddress2 = 0; // Not used in master mode
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; // No general call
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // Enable clock stretching
if (HAL_I2C_Init(&hi2c1) != HAL_OK) // Initialize I2C peripheral
{
Error_Handler(); // Handle initialization error
}

uint8_t sendData[] = {0x01}; // Data to be sent over I2C

while (1)
{
if (HAL_I2C_Master_Transmit(&hi2c1, 0x20, sendData, sizeof(sendData), 10000) != HAL_OK)
{
Error_Handler(); // Handle transmission error   ////////////////////// HERE ITS RETURNING ERROR AFTER TIME OUT EXPIRE ///////////////////////////
}
}
}

Any help would be greatly appreciated.

Thanks!

11 REPLIES 11
TDK
Guru

> hi2c1.Instance = I2C2

Clearly this is a modification you've done (among others). Unless you have deep insight into how CubeMX is generating code and how HAL uses that code, I wouldn't make such modifications.

I would go back and use CubeMX generated code as-is rather than modifying it.

If you want to use I2C2 instead of I2C1, change it in CubeMX and regenerate the code.

If you feel a post has answered your question, please click "Accept as Solution".
Rushali
Associate III

Hello  ahsank,

After looking at your code it seems like you are using I2C2 for the communication purpose. You are using PF0 and PF1 for SDA and SCL. But while initializing clock you have enabled GPIO Port B clock(Change it to GPIOF's Clock).Also initialize  I2C2 peripherial instead of I2C1 as mentioned by @TDK ,.

Hope after rectification it may work.

ahsank
Associate II

I have recreated new project using cube IMX and use I2C2 PF0 and PF1 but not getting any output , I have been using picoscope to see it

ahsank
Associate II

ahsank_0-1707405846517.png

if i just toggle PF0 and PF1 I am getting correct output but If I send data using i2c using following main while loop and obv configuration done by cube IMX 

  while (1)
  {
/* USER CODE END WHILE */
uint8_t sendData[] = {0xF2};
 
HAL_I2C_Master_Transmit(&hi2c2, 0x20, sendData, sizeof(sendData),0xFFFFF);
 
/* USER CODE BEGIN 3 */
  }
I am not getting proper output like this
Rushali
Associate III

 Dear @ahsank ,

Can you please share your latest configuration for I2C2 peripheral. Also tell what I2C peripheral you are using(Is it Arduino board, LCD, or something else.)

static void MX_I2C2_Init(void)
{

/* USER CODE BEGIN I2C2_Init 0 */

/* USER CODE END I2C2_Init 0 */

/* USER CODE BEGIN I2C2_Init 1 */

/* USER CODE END I2C2_Init 1 */
hi2c2.Instance = I2C2;
hi2c2.Init.Timing = 0x00000E14;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
Error_Handler();
}

Here is configuration of i2S I am using , it is created by Mx-Cube
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}

/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C2_Init 2 */

/* USER CODE END I2C2_Init 2 */

}

I am not using any i2c peripheral at a moment.

What board is this?

Do you have pullups on SDA/SCL lines? If so what values?

What waveform do you see on SDA/SCL during a HAL_I2C_IsDeviceReady call?

 

If you feel a post has answered your question, please click "Accept as Solution".
ahsank
Associate II

its a NUCLEO-U5A5ZJ-Q board
I have tried by enabling and disabling pullups but no success
The configuration when pullup enabled is as follow

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);

/*Configure GPIO pins : PF0 PF1 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

the wave for SDA and SCL is shown as below

ahsank_0-1707497066971.png

@TDK 

Not sure I understand this test. You've initialized PF0 and PF1 as GPIO outputs and set them to a low level. They look to be low on your scope. That all is functioning as expected, yes?

If you want PF0/PF1 to be I2C pins, you need to initialize them as such. CubeMX should generate the code to do this for you.

 

If you feel a post has answered your question, please click "Accept as Solution".