AnsweredAssumed Answered

UART Overrun

Question asked by Jordan imbert on May 10, 2017
Latest reply on May 17, 2017 by Jordan imbert

Hello, I'm using stm32l476 board discovery. A GSM modem is connected to the STM32 through RS232 to UART driver. The UART is configured with IRQ and hard flow control (RTS and CTS).

 

 

Here, is my IRQ callback :

if(huart->Instance == UART_MODEM_INST){

          //Si on a pas déja une ligne dispo dans le buffer et si il y a de la place
          if(rxBuffer.line == false && rxBuffer.idIn < UART_MODEM_BUFFER_SIZE-1){
               rxBuffer.idIn++;

               //buffer plein
               if(rxBuffer.idIn >= UART_MODEM_BUFFER_SIZE-1){
                    //On force à lire la ligne pour vider le buffer
                    rxBuffer.line = true;
               }

               rxBuffer.buffer[rxBuffer.idIn] = '\0';

               if(rxBuffer.idIn > 2 && rxBuffer.buffer[rxBuffer.idIn-2] == '\r' &&  rxBuffer.buffer[rxBuffer.idIn-1] == '\n'){
                    rxBuffer.line = true;
                    __HAL_UART_DISABLE(huart);
               }else{
                    HAL_UART_Receive_IT(huart, &rxBuffer.buffer[rxBuffer.idIn], 1);
               }
          }

 

I copy caracters into a buffer and when the end line caracter arrived, I set a flag (rxBuffer.line) and I disable uart to (normally) prevent OVERRUN error. 

 

When a line is available, I handle it this way:

 

uint32_t tickStart = HAL_GetTick();

        //Waiting the line before timeout
     while(rxBuffer.line == false){

          if(HAL_GetTick() - tickStart > timeout){
               //RAZ pour etre sur
               rxBuffer.idIn = 0;
               HAL_UART_Receive_IT(&uartModemHandler, &rxBuffer.buffer[rxBuffer.idIn], 1);
               return(STATUS_TIMEOUT);
          }
     }

//Copy the string
     if(rxBuffer.idIn <= p_length){
          strncpy(p_char, rxBuffer.buffer, rxBuffer.idIn+1);
     }else{
          strncpy(p_char, rxBuffer.buffer, p_length);
     }
//Reset buffer to be ready for a new line
     rxBuffer.idIn = 0;
     rxBuffer.line = false;
     rxBuffer.buffer[0] = '\0';
//Uart is now enable to receive caracters
     __HAL_UART_ENABLE(&uartModemHandler);
     HAL_UART_Receive_IT(&uartModemHandler, &rxBuffer.buffer[0], 1);
return(STATUS_OK);

 

I constantly receive Overrun error and I manage it like this:

 

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart){
     if(huart->Instance == UART_MODEM_INST){
         __HAL_UART_CLEAR_OREFLAG(huart);
          READ_REG(huart->Instance->ISR);
          READ_REG(huart->Instance->RDR);
     }
}

 

 

I don't understand why overrun occure every time, more over with flow control ! What is wrong with my code ? Someone have a better way to manage the UART?

 

Thank's !

Outcomes