Skip to main content
Visitor II
July 6, 2025
Question

STM32F2 need to abort HAL_I2C_Mem_Read_IT

  • July 6, 2025
  • 2 replies
  • 403 views

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.

    This topic has been closed for replies.

    2 replies

    Super User
    July 6, 2025

    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).

     

    July 7, 2025

    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. 

    Technical Moderator
    July 7, 2025

    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. 

    July 7, 2025

    Sorry, it returns HAL_ERROR.

    Technical Moderator
    July 8, 2025

    Hello @eric239955_stm1_stmicro 

    Could you please share the content of SR register when calling HAL_I2C_Master_Abort_IT().