I am facing an issue with the I2C communication. During the first run the communication between the MCU and the sensor is okay then I can read and write in the sensor's registers without a problem.
However, when I try to debug a second time I receive HAL_BUSY when I am trying to communicate with the sensor, the communication is just reestablished when the power supply of the board is cut and then fed again.
The Code snippet to write to the register is the following:
HAL_StatusTypeDef MAX30105_WriteRegister(uint8_t reg_addr, uint8_t reg_value){
HAL_StatusTypeDef returnValue = HAL_ERROR;
//Check if the MAX30105 is ready in a trial of 5 times
HAL_StatusTypeDef result = HAL_I2C_IsDeviceReady(&hi2c1, MAX30105_ADDR, 5, 10);
if (result == HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
{
returnValue = HAL_I2C_Mem_Write(&hi2c1, MAX30105_ADDR, reg_addr , 1, ®_value, sizeof(reg_value), 10);
if(returnValue != HAL_OK)
return returnValue;
}
return returnValue;
}
The I2C setup is:
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
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;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
I tried in the boards STM32F407G and STM32F103 Blue Pill, both the same issue happened.
The sensor is MAX30105 from Maxim.
Is there something that I am missing for the I2C communication that results in such problem?
If you re-debug, your MCU is reset, but your sensor is not. Therefore, the sensor is in a state which your MCU does not expect, and the communication doesnt work. Probably, the sensor is pulling down SDA and waiting for more clock cycles to finish its transmission.
In case you don't know how I2C communication works: Both SCL and SDA lines are pulled up to Vcc. SCL should only be pulled down by the master, but all devices on the bus can pull down SDA. If multiple devices "disagree" on the status of the bus, one device might pull down SDA, while the master stops toggling SCL. This kills the bus.
You should either power cycle your system or clear the I2C bus by sending 9 clock cycles. In 9 clock cycles, any pending transmission of your sensor should be finished and you can resume your communication.