AnsweredAssumed Answered

STM32F4 UART Rx Interrupt Overflow Error

Question asked by jcovi on Nov 9, 2015
Latest reply on Nov 12, 2015 by jcovi
Hello,

I am currently attempting to get the HAL UART functions to read the incoming serial data from a GPS module. From a high level POV, I have the UART rx callback function set to parse the byte that was read in (simply add to a global buffer if the byte is valid GPS data) and then start a new HAL UART IT receive transaction. The issue occurs inside the parsing function when the full GPS message has been received as I write this out to a separate UART for debugging (connected to my computers COM port). It seems that the overflow error is occurring (maybe due to the time it takes to write this out) and thereafter it causes the Error callback routine to be serviced. 

I can alleviate this by using "__HAL_UART_CLEAR_OREFLAG(&huart5);" but I don't see why I need this as an overflow should not be occurring (I am reading in a single byte every time the tx interrupt occurs). From my understanding, the UART should be ignoring data that is coming in while inside the interrupt routine.

Am I missing something fundamental here or is there simply a better way to do this?

Initialization routine for UART5:
void MX_UART5_Init(void)
{
 
  huart5.Instance = UART5;
  huart5.Init.BaudRate = 38400;
  huart5.Init.WordLength = UART_WORDLENGTH_8B;
  huart5.Init.StopBits = UART_STOPBITS_1;
  huart5.Init.Parity = UART_PARITY_NONE;
  huart5.Init.Mode = UART_MODE_TX_RX;
  huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart5.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart5);
}


MSP Init function that gets called inside HAL_UART_Init():
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  if(huart->Instance==UART5)
  {
  /* USER CODE BEGIN UART5_MspInit 0 */
   
  /* USER CODE END UART5_MspInit 0 */
    /* Peripheral clock enable */
    __UART5_CLK_ENABLE();
     
    /**UART5 GPIO Configuration 
    PC12     ------> UART5_TX
    PD2     ------> UART5_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
   
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
   
    /* Peripheral interrupt init*/
    HAL_NVIC_SetPriority(UART5_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(UART5_IRQn);
  /* USER CODE BEGIN UART5_MspInit 1 */
   
  /* USER CODE END UART5_MspInit 1 */
  }
}


UART5 IRQ Handler Function:
/**
* @brief This function handles UART5 global interrupt.
*/
void UART5_IRQHandler(void)
{
  /* USER CODE BEGIN UART5_IRQn 0 */
   
  /* USER CODE END UART5_IRQn 0 */

  HAL_UART_IRQHandler(&huart5);

  /* USER CODE BEGIN UART5_IRQn 1 */

  HAL_NVIC_ClearPendingIRQ(UART5_IRQn);

  /* USER CODE END UART5_IRQn 1 */
}

*** The receive function is called for the first time in main.c to start it off ***

HAL UART Receive callback function:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if(huart == &huart5)
  {
    //__HAL_UART_FLUSH_DRREGISTER(&huart5);
    //__HAL_UART_CLEAR_OREFLAG(&huart5);
 
    parse_gps_data(gps_byte);
     
    HAL_UART_Receive_IT(&huart5,gps_byte,1);
  }
}


Snippet from parse GPS data routine once full message has been received:
uint8_t gps_byte[2];
char gps_buf[100];   // Increasing size of this does not fix the overflow issue
char gps_msg[100];  // Increasing size of this does not fix the overflow issue
 
void parse_gps_data(uint8_t* data_array)
{   // Called by UART5 interrupt routine
  char data = data_array[0]; //Get single received byte
  switch(data)
  {
    ......
    ...... 
    ......
  
    case '\n': //End of GPS message
      if(gps_buf[0] == '$')
      {
        if( local_checksum == 16*hex_to_int(gps_buf[gps_buf_count-3]) + hex_to_int(gps_buf[gps_buf_count-2]) )
        { // Check received checksum and proceed if no errors
          memcpy(gps_msg,gps_buf,gps_buf_count-1);
          gps_msg[gps_buf_count-1] = 0;
          STM_UART_TX(gps_msg);  //ERROR IS OCCURRING DUE TO THIS!
          STM_UART_TX("\r\n");
          //__HAL_UART_CLEAR_OREFLAG(&huart5); //ERROR IS FIXED IF I USE THIS BUT AN OVERFLOW STILL OCCURS AND IS CAUSING ISSUES WITH MY CODE IN OTHER AREAS
            
          gps_msg_ready = 1;
        }
      }
    break;
  
    ......
    ......
    ......
  }
  
  gps_buf_count = gps_buf_count > 99 ? 0 : gps_buf_count;
}

Outcomes