Skip to main content
Ciuffoly
Senior
March 26, 2020
Question

[SOLVED] --- BSP_I2C_Read() hang my STM32 app ---

  • March 26, 2020
  • 10 replies
  • 2005 views

I am developping a touch screen user interface to control an audio preampl and dac.

I have no problems with I2C bus to set the registers of CT7302PL and ES9018K2M but if I try to read a single register the application hang.

This is my I2C configuration.

//######################################################################################
//# DAC SECTION
//######################################################################################
void SetReg_ES9018K2M()
{
 unsigned char reg7, reg11;
 
 BSP_I2C_Write(0x90, 8, 0b10011001); // GPIO1 & GPIO2 as INPUT based on reg#21
 
 switch (inputsel)
 {
	 case 0:
		 //write_ext_eeprom( 1,0b10001100); old ?
	 	BSP_I2C_Write(0x90, 1, 0b10000100);
	 	BSP_I2C_Write(0x90, 21, 0b00000000);
	 	BSP_I2C_Write(0x90, 11, 0b00000000);
		 break;
 
	 case 1:
	 	BSP_I2C_Write(0x90, 1, 0b10000001);
	 	BSP_I2C_Write(0x90, 21, 0b01010000);
	 	BSP_I2C_Write(0x90, 11, 0b00110000); // 3
	 	break;
 
	 case 2:
	 	BSP_I2C_Write(0x90, 1, 0b10000001);
	 	BSP_I2C_Write(0x90, 21, 0b01010000);
	 	BSP_I2C_Write(0x90, 11, 0b01000000); // 4
	 	break;
 }
 
 reg11 = BSP_I2C_Read(0x90, 11);
 
}
 
 
 
void BSP_I2C_Init()
{
#define I2C_ADDRESS 0x3c
#define I2C_TIMING 0x00B1112E
 
 hi2c1.Instance = I2C1;
 hi2c1.Init.Timing = I2C_TIMING;
 hi2c1.Init.OwnAddress1 = I2C_ADDRESS;
 hi2c1.Init.OwnAddress1 = 0x78; // an unused address
 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
 hi2c1.Init.OwnAddress2 = 0;
 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
 hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
 
 I2Cx_Init(&hi2c1);
}

This topic has been closed for replies.

10 replies

waclawek.jan
Super User
March 26, 2020

Which STM32?

I2C is relatively tricky to get right. Observe the I2C bus, and try to match the "hanging" with events on the bus.

You might want to start with bit-banging it.

JW

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

I am using the STM32F746G-DISCO

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

The app hang and stop at -"1-" only if I use touch screen otherwise all is ok

unsigned char BSP_I2C_Read(uint8_t Addr, uint8_t Reg)
{
 uint8_t Value;
 
 BSP_LCD_DisplayStringAt(20, 170, "-1-", LEFT_MODE);
 
 I2Cx_ReadMultiple(&hi2c1, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&Value, 1);
 
 BSP_LCD_DisplayStringAt(20, 170, "-2-", LEFT_MODE);
 
 return Value;
}

waclawek.jan
Super User
March 26, 2020

Well, then there might be some problem in I2Cx_ReadMultiple(). Debug it as usually: instrument functions it's using, observe variables it is using, observe content of relevant peripheral (maily I2C presumably) registers, observe the bus...

JW

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

I have tried to use the TS_IO_Read(0x90, 11); instead of the BSP_I2C_Read(0x90, 11); because this does not hang the app but it return always 0.

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

The app lock here at "-114-" on HAL_StatusTypeDef HAL_I2C_Mem_Read()

BSP_LCD_DisplayStringAt(20, 170, "-114-", 0x03);
 
 
 /* Send Slave Address and Memory Address */
 
 if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
 
 {
 
 /* Process Unlocked */
 
 __HAL_UNLOCK(hi2c);
 
 return HAL_ERROR;
 
 }
 
 
 BSP_LCD_DisplayStringAt(20, 170, "-115-", 0x03);

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

Yes, adding the debug BSP_LCD_DisplayStrinAt() function sometimes the code work but after some seconds hang in this call.

if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
 {
 /* Process Unlocked */
 __HAL_UNLOCK(hi2c);
 return HAL_ERROR;
 }

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

-

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

-

Ciuffoly
CiuffolyAuthor
Senior
March 26, 2020

Solved with these functions instead of BSP_I2C_...

CAMERA_IO_Init();

CAMERA_IO_Write(0x90, 8, 0b10011001);

CAMERA_IO_Read(0x90, 64);

Ciuffoly
CiuffolyAuthor
Senior
March 28, 2020

Solved all I2C lock with 3 action on STM32F746-DISCO:

1) pull-up resistors 4700ohm to 3.3V on both SDA and SCL wire

2) Use CAMERA_IO_Init, Read and Write instead of BSP_I2S_Init, Reda and Write

3) Using the EXT/RF E2P connector (pin EXT_SDA/EXT_SCL) instead of CN7 connector (pin SDA/SCL)

The lock was inside this function:

static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
{
	int i = 0;
 
 while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
 {
#ifdef MY_TEST_TO_TRY_TO_UNLOCK
 // Using this code the function return the error without lock the my app
 // but I don't know how to recognize the error condition in the CAMERA_IO_Read()
	 if (i < 60000)
		 i++;
	 else
	 {
	 hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
	 hi2c->State = HAL_I2C_STATE_READY;
	 hi2c->Mode = HAL_I2C_MODE_NONE;
	 __HAL_UNLOCK(hi2c);
		 return HAL_ERROR;
	 }
#endif
 
#ifdef ORIGINAL
 /* Check for the Timeout */
 if (Timeout != HAL_MAX_DELAY)
 {
 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
 {
 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;
 }
 }
#endif
 }
 return HAL_OK;
}