cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32G491 I2C multimaster mode

abhijith_raj
Associate III

Hi,

I need to configure the I2C master on my STM32G491 to operate in a multimaster setup. It is currently connected to a slave device, but we also plan to connect another I2C master to the same bus. The slave device supports I2C multimaster communication.

On the STM32 side, do I need to enable any specific settings to support multimaster mode? From community forums and FAQs, I’ve learned that I need to handle arbitration loss and bus errors, and then retry the transmission. Is that sufficient, or is there anything else I should check for?

1 REPLY 1
Pmanauth
ST Employee

Hello,

We have an example I2C multimaster doing a communication between two Masters (on one board using two different instances) and a Slave (on another board) in FW STM32H5.

In terms of configuration, you don't need anything particular, just make sure the masters have different own address.

On the Masters' side, you may need to check in your error callback if there is an Acknowledge error and if it's the case DeInit and Init again your I2C to discard the error. That way, you will be able to restart your communication.

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
  /** Error_Handler() function is called when error occurs.
    * 1- When Slave don't acknowledge it's address, Master restarts communication.
    * 2- When Master don't acknowledge the last data transferred, Slave don't care in this example.
    */
  if (HAL_I2C_GetError(hi2c) != HAL_I2C_ERROR_AF)
  {
    /* Workaround deadlock appear due to BUS error detection Errata 64209: START badly generated after misplaced STOP */
    /* Workaround deadlock appear due to BUS error detection Errata I2C-090401 : Robustness issue when receiving an
       illegal void message (no SCL edges between a START and a STOP condition) */
    HAL_I2C_DeInit(hi2c);
    HAL_I2C_Init(hi2c);
  }
}

On the Slave's side, you will have to do the same for the Bus error. 

 void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
  /** Error_Handler() function is called when error occurs.
    * 1- When Slave don't acknowledge it's address, Master restarts communication.
    * 2- When Master don't acknowledge the last data transferred, Slave don't care in this example.
    */
  if (HAL_I2C_GetError(hi2c) == HAL_I2C_ERROR_BERR)
  {
    /* Workaround deadlock appear due to BUS error detection Errata 64209: START badly generated after misplaced STOP */
    /* Workaround deadlock appear due to BUS error detection Errata I2C-090401 : Robustness issue when receiving an
       illegal void message (no SCL edges between a START and a STOP condition) */
    HAL_I2C_DeInit(hi2c);
    HAL_I2C_Init(hi2c);
  }
  else if (HAL_I2C_GetError(hi2c) != HAL_I2C_ERROR_AF)
  {
    Error_Handler();
  }
}

 I suggest you check the examples I2C_TwoBoards_MultiMasterIT_Slave and I2C_TwoBoards_MultiMasterIT_Master in the H5 FW to have a better view of how we implemented this use case.