Showing results for 
Search instead for 
Did you mean: 

I2C issue when called from external file

Associate II

Hi There,


We have IO expander that is connected using I2C

File: Application.C has functions for change the IO value of the IO Expander

there is a UART that the user can connect to and change the value of the IO Expander (using CLI)


Following functions are at Application.C file


void PORT_Enable(uint8_t PORT_NUM){
  switch (PORT_NUM){
    case PORT1:
        PORT_Information[PORT_NUM].Enable_VBUS = 1;




void Set_Bit_IO_Expander2_Status_PDIO(uint8_t Data,uint8_t Index)
  PDIO_SET_RESET[0] = OUTPUT_PORT1;         //write command to output Port 1.0-1.7
  Data |= (1 << Index);                 // implement '1' into bit#index
  PDIO_SET_RESET[1] = Data;                //update byte to send to Set Port 1.0-1.7
  while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY){}
  pcal9555_writeRegister(&hi2c2, 0x42, PDIO_SET_RESET, 2);



the following function are at COM.C file


void executeSerialCommand1(char *uart1RxBuf)
  if(strcmp(uart1RxBuf,"port3 Enable") == 0){  



there is a loop with timmer that read the IO Expander's pins every 100mSec

this code is at Application.C file


void Application_Handler(void)
    //Do every 10ms
    if (TimeElapsed_10ms)
        TimeElapsed_10ms = 0;
    //Do every 100ms
    if (TimeElapsed_100ms)
        TimeElapsed_100ms = 0;


on startup, the system set all ports to '1'

therefore, there is no issue with "PORT_Enable()" function when calling it from the Application.C file


when using the UART to set port3 the application doesn't work properly and enters a loop

We use IO_Expander.C file for activating I2C communication


HAL_StatusTypeDef pcal9555_writeRegister(I2C_HandleTypeDef *hi2c, uint16_t address, uint8_t *pData, uint16_t Size){

   // HAL_Status = HAL_I2C_Master_Transmit_IT(hi2c,(uint16_t) ADT7411_ADDRESS, pData, Size);
    //return HAL_Status;

	HAL_Status = HAL_I2C_Master_Transmit_IT(hi2c,address, pData, Size);

    while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY){

        /* Error_Handler() function is called when Timeout error occurs.
           When Acknowledge failure occurs (Slave don't acknowledge its address)
           Master restarts communication */
        if ((HAL_I2C_GetError(hi2c) != HAL_I2C_ERROR_AF) && (HAL_I2C_GetError(hi2c) != HAL_I2C_ERROR_NONE))

	return HAL_Status;



it seams that HAL_Status is not READY when calling it from the UART so it has a loop at


while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY){



when we call the function from the Application.C file, there is no issue

print of the Watch list at the While statment:



any advice will be appreciated


thank you



Associate II

Any Help will be appreciated 🙂

Are you calling it from an interrupt / callback ?

If you're calling it from foreground and background you're going to encounter situations where you're mid usage.

Other than that look at how the functions / structures are shared between different files. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Since you have not attached the full project, we can only guess on the probable issue. You seems to access the I2c bus from timer as well as from the uart handler. you can put one volatile variable such as I2c busy or something to avoid simultaneous access to the bus. or alternately since you have the status already, you can take it from previous read, set the port expander IO in the next 100ms cycle  from a structure or variable. there will be max delay of 100ms only.

Associate II

Hi there,

It seams that this is the only reasonable situation,

i will check that and update you all