cancel
Showing results for 
Search instead for 
Did you mean: 

uart_ERROR callback triggered but errorCode is zero

DavidWahlberg
Associate II

I am programming a STM32 nucleo-f746ZG development board where I am using USART2 with RX interrupt.

I have setup USART using CubeMx (async, baud:250Khz, data: 8, stopBit: 2, noParity). I am reading a single byte from a DMX stream by calling HAL_UART_Receive_IT(&huart2, rx_buff, 1);

Furthermore, I have declared the two callbacks: HAL_UART_RxCpltCallback() and HAL_UART_ErrorCallback().

I am using the error_callback to detect whenever there is a BREAK in the DMX-stream (afterwards 512 bytes will be recieved) which will trigger an FRAME_ERROR.

The problem is that when the HAL_UART_Error_callback is called, the errorCode from the uart (error = huart->ErrorCode) is returning 0. I am assuming that if the error_callback is being triggered, there must be a value in ErrorCode != 0.

I will check if the error is a frameError and not an overrun error for instance.

 

I hope someone has an answer to this 🙂

4 REPLIES 4
Sarra.S
ST Employee

Hello @DavidWahlberg 

 >>I am assuming that if the error_callback is being triggered, there must be a value in ErrorCode != 0.

There are different values of ErrorCode indicating different error types. 

You can do something like this to determine what error occurred to handle it appropriately.

 

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
  if (huart->ErrorCode & HAL_UART_ERROR_PE) {
    // parity error
  }
  if (huart->ErrorCode & HAL_UART_ERROR_FE) {
    // frame error
  }
  // etc...
}

 Refer to UART Error Code  to check each error code  

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thank you for fast reply!

I am aware that i can check each type of error. The problem is that reading the value of huart->ErrorCode is 0, and because of that, none of the if statements will be true.

my error callback is:

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{

	if(huart == &huart2)
	{
		uint32_t error = huart->ErrorCode;

		if(error & HAL_UART_ERROR_FE)
		{
			//frame error detected
			dmxCounter = 0; //reset counter
			__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_FE); //clear frame error flag
			HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); // toggle led to indicate frame error

		}

		if(error & HAL_UART_ERROR_ORE)
		{
			//overrun error
			__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_ORE); //clear overrun flag
			__HAL_UART_FLUSH_DRREGISTER(huart); //flush data
		}

		HAL_UART_Receive_IT(&huart2, byteRead_buff, 1); // restart uart RX
	}

}
TDK
Guru

Set a breakpoint and step through HAL_UART_IRQHandler to understand where ErrorCode gets set when an error is triggered.

Looks like it gets set correctly here to me:

https://github.com/STMicroelectronics/stm32f7xx_hal_driver/blob/87047e59aa3883da281a7de519723545e6be4513/Src/stm32f7xx_hal_uart.c#L2171

 

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

Hi

I managed to find the issue by stepping.

The RxCompleteteCallback will, what I have experienced, always be called first and afterwards ErrorCallback only if

HAL_UART_Receive_IT(&huart2, byteRead_buff, 1) (1 byte).

I was at the very end of RxCompleteCallback calling HAL_UART_Receive_IT(&huart2, byteRead_buff, 1) to init a new interrupt, which reset the huart->errorCode variable. And because of that the value was always 0 when the ErrorCallback was called afterwards.

However, If calling HAL_UART_Receive_IT(&huart2, byteRead_buff, 2) (read: >1 byte) the errorCallback will be called first (if an error happened) and no RxCompleteCallback.

In my usecase I need to read every single byte one at a time to look for a frameError to know when a complete new DMX frame will come.

My solution is, since the RxCompleteCallback is always being call first, to read the huart->errorCode in the RxCompleteCallback, do the logic (frameError true or not) and at the end call HAL_UART_Receive_IT(&huart2, byteRead_buff, 1). This means no code written in uartErrorCallback.

I hope it makes sense 🙂