cancel
Showing results for 
Search instead for 
Did you mean: 

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

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);
}

11 REPLIES 11

Solved with these functions instead of BSP_I2C_...

CAMERA_IO_Init();

CAMERA_IO_Write(0x90, 8, 0b10011001);

CAMERA_IO_Read(0x90, 64);

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;
}