Skip to main content
ADrub.1
Associate II
June 4, 2025
Question

Work of the HAL_UARTEx_ReceiveToIdle function in non blocked mode

  • June 4, 2025
  • 2 replies
  • 1018 views

Hi all! What event is generated if the MCU receives a data packet equal to the buffer value passed to the HAL_UARTEx_ReceiveToIdle_IT (or HAL_UARTEx_ReceiveToIdle_DMA) function? There will essentially be two events: HAL_UART_RXEVENT_TC and HAL_UART_RXEVENT_IDLE . But which of them will be available in the HAL_UARTEx_RxEventCallback ?

2 replies

TDK
Super User
June 4, 2025

Please use english on this forum.

> Hi all! What event is generated if the MCU receives a data packet equal to the buffer value passed to the function HAL_UARTEx_ReceiveToIdle_IT (or HAL_UARTEx_ReceiveToIdle_DMA)? In fact, there will be two events: HAL_UART_RXEVENT_TC and HAL_UART_RXEVENT_IDLE. But which one will be available in HAL_UARTEx_RxEventCallback ?

 

Whichever one occurs first. If the buffer is filled, function returns immediately. If IDLE happens, function returns. The RxSize parameter is updated with the number of characters received. If it's equal to Size, the buffer is full and TC happened. Otherwise, IDLE happened.

 * @note HAL_OK is returned if reception is completed (expected number of data has been received)
 * or if reception is stopped after IDLE event (less than the expected number of data has been received)
 * In this case, RxLen output parameter indicates number of data available in reception buffer.

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
ADrub.1
ADrub.1Author
Associate II
June 4, 2025

Thanks for the reply!)

Yes, I know that. The question is slightly different here. For example, I called the HAL_UARTEx_ReceiveToIdle_IT() function and passed a buffer size of 100 bytes. Then we received a packet of exactly 100 bytes. So, the question is, which event will be generated? After all, two events actually occurred!)

I'm asking this to understand how to recognize that we have received a packet if it is exactly the same size as the buffer.

Pavel A.
Super User
June 4, 2025

A good question. There's a race condition as you have seen. As soon as the HAL "driver" sees completion of I/O (enough bytes received) it disables all interrupt sources, including the IDLE (or RTO if used). These interrupts share the same vector so cannot preempt one another. But the interrupt handler can test for IDLE before checking end of transfer. By the way TC is *transmit* complete and you deal with receive? 

Bottom line, better write your own "driver" using the HAL as reference. This will suit your needs much better and will avoid confusion about the HAL library peculiarities. Examples are available.

 

TDK
Super User
June 6, 2025

I tested this on the F4. It works exactly as expected. No IDLE events are missed.

Sending 4 bytes at a time into a 16 byte buffer. event: (0=HT, 1=TC, 2=IDLE).

event=2, tail=0, head=4
event=1, tail=4, head=8
event=2, tail=8, head=8
event=2, tail=8, head=12
event=0, tail=12, head=16
event=2, tail=16, head=16
event=2, tail=16, head=4
event=1, tail=4, head=8
event=2, tail=8, head=8
event=2, tail=8, head=12
event=0, tail=12, head=16
event=2, tail=16, head=16

 

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
 static uint16_t tail = 0;
 /* Prevent unused argument(s) compilation warning */
 UNUSED(huart);
 UNUSED(Size);
 HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
 HAL_UART_RxEventTypeTypeDef event = HAL_UARTEx_GetRxEventType(huart);
 printf("event=%d, tail=%d, head=%d\n", (int)event, (int)tail, (int)Size);
 tail = Size;
}

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
Karl Yamashita
Principal
June 6, 2025

@TDK wrote:

I tested this on the F4. It works exactly as expected. No IDLE events are missed.

Sending 4 bytes at a time into a 16 byte buffer. event: (0=HT, 1=TC, 2=IDLE).

event=2, tail=0, head=4
event=1, tail=4, head=8
event=2, tail=8, head=8
event=2, tail=8, head=12
event=0, tail=12, head=16
event=2, tail=16, head=16
event=2, tail=16, head=4
event=1, tail=4, head=8
event=2, tail=8, head=8
event=2, tail=8, head=12
event=0, tail=12, head=16
event=2, tail=16, head=16

I noticed your event values didn't match your labeling based off receiving 4 bytes at a time.  

You have TC and HT values swapped.

/**
 * @brief HAL UART Rx Event type definition
 * @note HAL UART Rx Event type value aims to identify which type of Event has occurred
 * leading to call of the RxEvent callback.
 * This parameter can be a value of @ref UART_RxEvent_Type_Values :
 * HAL_UART_RXEVENT_TC = 0x00U,
 * HAL_UART_RXEVENT_HT = 0x01U,
 * HAL_UART_RXEVENT_IDLE = 0x02U,
 */
typedef uint32_t HAL_UART_RxEventTypeTypeDef;

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
TDK
Super User
June 6, 2025

Yes, my typo, not HAL's bug. Thanks for catching.

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