AnsweredAssumed Answered

HAL Interrupt Driven I2C OVR Error

Question asked by parker.devin on Jul 13, 2016
Latest reply on Jul 15, 2016 by FTITI.Walid
I am attempting to implement an interrupt driven I2C slave 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?

Thanks.

//main
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 > 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(&hi2c1) == HAL_I2C_STATE_READY)
     {          
          HAL_StatusTypeDef status = HAL_I2C_Slave_Receive_IT(&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(&hi2c1) != HAL_I2C_STATE_READY)
  {
  } 
     
     HAL_StatusTypeDef status = HAL_I2C_Slave_Transmit(&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(&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(&hi2c1);

    /**Configure Analogue filter 
    */
  HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE);
}


void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if(hi2c->Instance==I2C1)
  {  
    /**I2C1 GPIO Configuration    
    PB6     ------> I2C1_SCL
    PB7     ------> 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, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  }
}

Outcomes