cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L0xx UART overrun error

Aman Kumar
Associate II
Posted on March 07, 2018 at 13:04

We are using the STM32L0 HAL implementation of the UART driver. The UART (115200,8-N-1) is used in interrupt mode and we have configured the interrupt to occur for every character. This is done so that we can implement a CLI at the application level. The target controller is STM32L071KB (32 MHz). 

The issue is that we run into a UART overrun error if the CLI is used by an automated test script such as TeraTerms TTL running at the set baud rate i.e. 115200. The only way to get it to work properly is by adding a 10 ms inter-character delay on the sender side.

We confirmed the error by looking at the UART ISR register where the ORE bit gets set. 

We have tried different baud rates , Oscillator clock frequencies as well but to no avail.

Interestingly running the same code on an STM32F4xx (180 MHz) series controller has no issues at all.

We have patched the HAL_UART_IRQ_Handler() routine with the latest updates from STM32 HAL V1.10.0. The HAL driver package we are using is V1.8.1. The implementation of the interrupt based driver in our software  is as per the reference application :UART_TwoBoards_ComIT

#uart-overrun-error #uart-interrupt #stm32l0xx #ore-bit
8 REPLIES 8
AvaTar
Lead
Posted on March 07, 2018 at 13:54

How long is the runtime of your interrupt routine ?   (Rhetorical question)

If it takes longer then the inter-character time, you will never get happy.

Beating it with brute force (faster MCU with higher core clock) is the second-best solution, better rework the code that runs in the interrupt context.

Posted on March 07, 2018 at 14:10

Sounds like you'll need to code a better interrupt/buffering scheme.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III
Posted on March 07, 2018 at 14:18

We are using the STM32L0 HAL implementation of the UART driver.

The HAL drivers for UARTs has been discussed here recently. A short answer... drop the HAL and use the LL API instead - yes, with RX interrupt for every char. In this way, the code is flexible and easy to understand (at least not more cryptic than the HAL).

HAL library can be considered for very high rates ( > 115200)  and large amount of data, which is not your case.

We have converted UARTs from HAL to LL in our projects and are happy. Can share the recipe.

Regards,

-- pa

Aman Kumar
Associate II
Posted on March 07, 2018 at 14:25

Yes we had a doubt on our ISR implementation as well so we tried doing the same test with the reference application mentioned above. We made it enter the 'Receiver' where it waits in a while(1) loop to receive a character and then print a character on UART. The ISR for such an application is very simple as shown below:

/**

* @brief Tx Transfer completed callback

* @param UartHandle: UART handle.

* @note This example shows a simple way to report end of IT Tx transfer, and

* you can add your own implementation.

* @retval None

*/

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)

{

/* Set transmission flag: trasfer complete*/

UartReady = SET;

}

/**

* @brief Rx Transfer completed callback

* @param UartHandle: UART handle

* @note This example shows a simple way to report end of IT Rx transfer, and

* you can add your own implementation.

* @retval None

*/

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

{

/* Set transmission flag: trasfer complete*/

UartReady = SET;

}

Even in this application we are able to create the ORE error at 115200 baud.

Posted on March 07, 2018 at 14:52

Interrupts can be preempted by other interrupts with higher priority.

I would suggest the following:

Toggle one GPIO on UART interrupt entry and exit, and another GPIO when the ORE flag is set.

View both GPIOs, together with the UART RX line, with a scope.

Set the scope trigger on the ORE flag toggle.

You might add a visualization of other events in your system with additional GPIOs.

Posted on March 07, 2018 at 15:03

Sorry, I don't quite understand how your code works. Does the 'application' loop waiting for 

UartReady

 flag set for every character? 

Then yes, this is not very efficient and overflows at 115200 are possible. Do you remember that UARTs in STM32 have no internal FIFO, like in the PC?

-- pa

Posted on March 07, 2018 at 15:28

Hi Pavel A,

Thank you for your response. I apologize for not posting the application code.

Here is the main loop:

/**/

System initializations along with UART init.

while(1)

{

/* ♯ ♯ -2- Put UART peripheral in reception process ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ */

if(HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)

{

Error_Handler();

}

/* ♯ ♯ -3- Wait for the end of the transfer ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ */

while (UartReady != SET)

{

}

/* Reset transmission flag */

UartReady = RESET;

/* ♯ ♯ -4- Start the transmission process ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ */

/* While the UART in reception process, user can transmit data through

'aTxBuffer' buffer */

if(HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)

{

Error_Handler();

}

/* ♯ ♯ -5- Wait for the end of the transfer ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ */

while (UartReady != SET)

{

}

/* Reset transmission flag */

UartReady = RESET;

}

This is the same structure used in the reference application. This application does not have any other peripheral/interrupt enabled at present.

Regards,

Aman

Posted on March 07, 2018 at 15:46

Your code blocks, basically precluding duplex operation, ie data loss receiving while transmitting multiple characters (more than one byte time ignoring the receive side).

You'd probably want to throw away the HAL mindset here, but at the very least discard the 'sequential' mindset and use the IRQ handler/callback to do something useful and acquire the data into a buffer, and dispatch a new IT request.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..