cancel
Showing results for 
Search instead for 
Did you mean: 

stm32 uart interrupt stops working after ~1 hour

VWied.1
Associate III

I am using an STM32L073 chip. I have 2 UARTs but only the huart1's receive is using interrupts. I start the Rx interrupt at start-up and then the interrupts are being set at the end of the interrupt function. (see code below)

My issue is that after about an hour, the interrupts stop triggering. The rest of my program continues to work. The HAL_UART_ErrorCallback never gets called.

My huart1 is set up as 8E1.

The speed of messages that cause this problem is an 11 char message every second.

Is there any way I can identify why my interrupts are not triggering anymore? is there another HAL error function I can check in a thread to see if a flag was set somewhere that I can clear?

NOTE: huart1 is transmitting using "HAL_UART_Transmit(huart1, payload, length, TIMEOUT_100MS);

This function is in a thread that doesn't need to be fast, so I am not worried about using interrupts or DMA with this. 

#define LENGTH_OF_MESSAGE 11
 
uint8_t rxBuffer[LENGTH_OF_MESSAGE] = {0};
 
void resetUartInterrupts()
{
	memset(rxBuffer, 0, LENGTH_OF_MESSAGE);
	HAL_UART_Receive_IT(huart1, rxBuffer, 1);
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *uartHandler)
{
      //check to see if action is recieved while waiting for it
      if (rxBuffer[0] == 0)
      {
            if (isActionChar(rxBuffer[0]))
            {
                    //  now grab the rest of the message
                    HAL_UART_Receive_IT(uartHandler, &rxBuffer[1], LENGTH_OF_MESSAGE - 1);
            }
            else
            {
                     //not an action character, keep waiting for one
                     resetUartInterrupts();
            }
      }
      else
      {
             saveMessageToRxQueue();
             //wait for next action char
             resetUartInterrupts();
      }
}
 
 
// this code is never called
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if(huart == huart1)
	{
                resetUartInterrupts();
	}
}

8 REPLIES 8
TDK
Guru

Debug the program. When the issue occurs, hit pause and examine the huart1 handle to see where the state machine is at. Examine the status register and ORE bit to ensure an overrun hasn't occurred.

It would be good to monitor the return value from HAL_UART_Receive_IT and handle the error if it's not HAL_OK.

If you feel a post has answered your question, please click "Accept as Solution".
S.Ma
Principal

Stack issue? Latency issue?

Try half baudrate speed.

VWied.1
Associate III

So I have run some tests over the weekend. It seems that the HAL_UART_Receive_IT function call returns HAL_BUSY. I stepped through the function and the lower-level error code is HAL_UART_STATE_BUSY_RX.

My receive line is only receiving 2-3 messages a second. Each message is 11 bytes. So this isn't a busy Rx line.

I am also getting issues where the HAL_UART_Receive_IT function returns HAL_OK but then doesn't seem to actually set up the interrupt. Because of this, my error handling fails to catch this. I am currently looking into the huart right now. Is there a specific bit in the huart->instance->ISR that I can query to see if the interrupt is set properly?

> It seems that the HAL_UART_Receive_IT function call returns HAL_BUSY.

This means that the "state machine" of the HAL UART driver thinks that previous operation is not complete, or the UART is in failure state that requires attention and explicit reset when handled.

It is poorly documented, need to read the source.

Many people write their own UART drivers anyway,

> I am also getting issues where the HAL_UART_Receive_IT function returns HAL_OK but then doesn't seem to actually set up the interrupt. 

Need to read the driver source, again. It is complicated, and you'll want to write your own (with error detection and recovery).

YPear.1
Associate II

I"m having a very similar issue on a STM32L031xx. The UART RX interrupt stops firing or the HAL_UART_RxCpltCallback stops getting called after 1-60mins. The MCU seems to be working otherwise.

Was there a fix for this?

Perhaps check the noise, framing, parity, overrun error statuses, and clear them if necessary.

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

YES! So there seems to be a bug in the HAL_UART library that the UART registers are not handled properly. What I did was:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *uartHandler){
    if (HAL_UART_Receive_IT(myUartHardware, rxBuffer, LENGTH_OF_MESSAGE) ==  HAL_OK)
    {
        //handle success case here
    }
    else
    {
        HAL_UART_AbortReceive(myUartHardware);
        HAL_UART_Receive_IT(myUartHardware, g3Comms.rxBuffer, 1);
    }
}

To fix the broken HAL_UART struct, if the interrupt call fails, you can abort the receive and then retry. This has fixed my issues every time.