2023-11-28 04:13 AM
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 :)
2023-11-28 05:02 AM - edited 2023-11-28 05:03 AM
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.
2023-11-28 05:57 AM
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
}
}
2023-11-28 06:26 AM
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:
2023-11-29 01:39 AM
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 :)