title: STM32 HAL I2C is returning OVR (overrun/under-run) error when using an interrupt driven approach
body: <p>I am attempting to implement an interrupt driven I2C slave that is continuously ready to receive (except when transmitting) on the STM32L051. The problem is that I keep receiving the HAL_I2C_ERROR_OVR error in the HAL_I2C_ErrorCallback. The below code is just an example and is configured to receive a 3 byte message and respond with a single byte status. Running this code triggers the OVR error once the master transmits and then appears to continuously trigger the I2C1_IRQHandler, tying up other operations. The slave cannot use stretching so I have disabled it as shown in the below code. I am fairly new to HAL and have mostly been using the STM32Fxx series with the std peripheral libraries. I have reviewed the published examples, even copied some into my more complex code-base, only to get the same OVR error. Do any of you guys have any suggestions/advice/etc. that could push me towards a workable solution?</p>
  
  <p>System Clock Speed: 16MHz</p>
  
  <p>I2C Bus Speed: 10KHz</p>
  
  <p>Thanks.</p>
  
  <pre><code>//**** Slave Rx/Tx ****//
  int main(void)
  {
    /* USER CODE BEGIN 1 */
      int responseSize = 1;
      int bytesToReceive = 3; 
      bool error = false; 
    /* USER CODE END 1 */
    /* MCU Configuration----------------------------------------------------------*/
    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  
    HAL_Init();
  
    /* Configure the system clock */
    SystemClock_Config();
  
  
    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_I2C1_Init();
  
    /* Initialize interrupts */
    MX_NVIC_Init();
  
    i2c_response[0] = 0x01;
    responseSize = 1;
  
    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
          //**** Slave Rx/Tx Interrupt based ****//
          if(slaveRxCallbackTriggered)
          {   
              slaveRxCallbackTriggered = false;
  
              if(responseSize &gt; 0)
              {
                  if(!IOModule_TransmitToMaster(i2c_response,responseSize))
                  {
                      error = true;
                  }
              }           
  
              IOModule_ReceiveFromMaster(bytesToReceive); 
          }
          else
              IOModule_ReceiveFromMaster(bytesToReceive);
  
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
  }
  
  /*------------------------------------------------------------------------------
      I2C Receive data from master
   *------------------------------------------------------------------------------*/
  bool IOModule_ReceiveFromMaster(int numberOfBytes)
  {
      bool result = false;
  
      if(HAL_I2C_GetState(&amp;hi2c1) == HAL_I2C_STATE_READY)
      {       
          HAL_StatusTypeDef status = HAL_I2C_Slave_Receive_IT(&amp;hi2c1, (uint8_t *)i2c_rx_array, numberOfBytes);
  
          if(status == HAL_OK)
          {
              result = true;
          }
      }
  
  
      return result;
  }
  
  /*------------------------------------------------------------------------------
      I2C Transmit data to master
   *------------------------------------------------------------------------------*/
  bool IOModule_TransmitToMaster(uint8_t txBuffer[], int bufferSize)
  {
      bool result = false;    
  
      while (HAL_I2C_GetState(&amp;hi2c1) != HAL_I2C_STATE_READY)
    {
    } 
  
      HAL_StatusTypeDef status = HAL_I2C_Slave_Transmit(&amp;hi2c1, (uint8_t*)txBuffer, bufferSize, 10000);
  
      HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);
  
      if(status == HAL_OK)
      {   
          result = true;
      }
  
      return result;
  }
  
  /*------------------------------------------------------------------------------
      I2C Slave Rx Complete Callback
   *------------------------------------------------------------------------------*/
  void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2CxHandle)
  {   
      slaveRxCallbackTriggered = true;
  }
  
  /*------------------------------------------------------------------------------
      I2C Error Callback
   *------------------------------------------------------------------------------*/
  void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
  {
      lastErrorCode = HAL_I2C_GetError(&amp;hi2c1);
  }
  
  //I2C1 init
  void MX_I2C1_Init(void)
  {
    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x000006C5;
    hi2c1.Init.OwnAddress1 = 0x24;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
    HAL_I2C_Init(&amp;hi2c1);
  
      /**Configure Analogue filter 
      */
    HAL_I2CEx_ConfigAnalogFilter(&amp;hi2c1, I2C_ANALOGFILTER_ENABLE);
  }
  
  
  void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
  {
    GPIO_InitTypeDef GPIO_InitStruct;
    if(hi2c-&gt;Instance==I2C1)
    {  
      /**I2C1 GPIO Configuration    
      PB6     ------&gt; I2C1_SCL
      PB7     ------&gt; I2C1_SDA 
      */
      GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
      GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
      HAL_GPIO_Init(GPIOB, &amp;GPIO_InitStruct);
  
      /* Peripheral clock enable */
      __HAL_RCC_I2C1_CLK_ENABLE();
    }
  }
  </code></pre>
  
  <p>Master Tx/Rx</p>
  
  <pre><code>int main(void)
  {
      //**** Master Tx/Rx ****//
      ioModule_response[0] = 0xA0;
      ioModule_response[1] = 0x01;
      ioModule_response[2] = 0xE3;
  
      while(1)
      {
          if(HAL_I2C_Master_Transmit(&amp;hi2c1, (uint16_t)0x24, (uint8_t*)ioModule_response, 3, 10000)== HAL_OK)
          {
              if(HAL_I2C_Master_Receive(&amp;hi2c1, (uint16_t)0x24, (uint8_t *)i2c_rx_array, 1, 10000) != HAL_OK)
              {
                              //Blink LED and Pause
                  LED_Show_StatusCode(2,false);
                  HAL_Delay(500);
              }
              else if(i2c_rx_array[0] != 1)
              {
                              //Blink LED and Pause
                  LED_Show_StatusCode(3,false);
                  HAL_Delay(500);
              }
          }
      }
  }
  </code></pre>
  
  <p>This is the STM32Cube MX generated IRQ Handler. </p>
  
  <pre><code>void I2C1_IRQHandler(void)
  {
    /* USER CODE BEGIN I2C1_IRQn 0 */
  
    /* USER CODE END I2C1_IRQn 0 */
    if (hi2c1.Instance-&gt;ISR &amp; (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {
      HAL_I2C_ER_IRQHandler(&amp;hi2c1);
    } else {
      HAL_I2C_EV_IRQHandler(&amp;hi2c1);
    }
    /* USER CODE BEGIN I2C1_IRQn 1 */
  
    /* USER CODE END I2C1_IRQn 1 */
  }
  </code></pre>
  
  <p>UPDATE: I am currently exploring the LL API as this seems more like the Standard Peripheral Libraries that I have used in the past. </p>