cancel
Showing results for 
Search instead for 
Did you mean: 

UART Overrun

Sirac
Associate III
Posted on May 10, 2017 at 18:44

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 !

#hal #over-run #irq #uart
1 REPLY 1
Sirac
Associate III
Posted on May 17, 2017 at 11:31

I find a solution, I don't know if it's the best and if it works every time but for me it works.

So, as I disable the Irq when I find a line ( ), if 2 others char arrived in the uart before the line is handled, the overrun occure.

So, to prevent that, I had this :

if(modemRxBuffer.line == false && modemRxBuffer.idIn < UART_MODEM_BUFFER_SIZE-1){
 //Some code
}else{
//Line added
//The buffer is flushed by reading the RDR register
READ_REG(huart->Instance->RDR);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I also activate the IRQ in theHAL_UART_ErrorCallback (only if the line is handled) :

if(modemRxBuffer.line == false){
HAL_UART_Receive_IT(huart, (uint8_t *)&modemRxBuffer.buffer[modemRxBuffer.idIn], 1);
}�?�?�?