2025-07-06 9:36 AM
I have an issue where a HAL_I2C_Mem_Read_IT transaction just seems to hang. It is plausible that this peripheral is temporarily unavailable and I already have working retry logic for the case where this call returns the "AF" error. The hang may or may not be related, but I'd like to abort it and try again. It isn't easy to get an I2C trace of this, but not impossible. In any case, I'd like to add some code to address this issue if possible.
2025-07-06 3:47 PM - edited 2025-07-06 3:53 PM
You can set timeout for the I2C operation (using some TIM or systick interrupt) and call HAL_I2C_Master_Abort_IT.
Then you can probe the I2C SCL pin for "stuck" condition and try recovery as usual (make 9 SCL pulses, re-initialize the I2C).
2025-07-06 5:34 PM
I tried that, but HAL_I2C_Master_Abort_IT returns an error (HAL_Busy) in this case. In another post on this forum someone else also reported this. Apparently, Master_Abort works for some transactions but not the Mem transactions. Your other comment suggests that disabling and reenabling the I2C peripheral might work.
2025-07-07 2:15 AM
Hello @eric239955_stm1_stmicro
The function HAL_I2C_Master_Abort_IT cannot return HAL_BUSY.
HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
{
/* Declaration of temporary variables to prevent undefined behavior of volatile usage */
HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
/* Prevent unused argument(s) compilation warning */
UNUSED(DevAddress);
/* Abort Master transfer during Receive or Transmit process */
if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && ((CurrentMode == HAL_I2C_MODE_MASTER) ||
(CurrentMode == HAL_I2C_MODE_MEM)))
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->PreviousState = I2C_STATE_NONE;
hi2c->State = HAL_I2C_STATE_ABORT;
/* Disable Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
/* Generate Stop */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
hi2c->XferCount = 0U;
/* Disable EVT, BUF and ERR interrupt */
__HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
/* Call the corresponding callback to inform upper layer of End of Transfer */
I2C_ITError(hi2c);
return HAL_OK;
}
else
{
/* Wrong usage of abort function */
/* This function should be used only in case of abort monitored by master device */
/* Or periphal is not in busy state, mean there is no active sequence to be abort */
return HAL_ERROR;
}
}
An alternatif to solve your issue is to call HAL_I2C_Master_Abort_IT in the Error callback function.
2025-07-07 8:30 AM
Sorry, it returns HAL_ERROR.
2025-07-08 1:16 AM
Hello @eric239955_stm1_stmicro
Could you please share the content of SR register when calling HAL_I2C_Master_Abort_IT().