2025-11-07 4:35 AM - last edited on 2025-11-07 4:43 AM by Andrew Neil
Hello,
It is the first time I am using STM32 and migrating my code from texas instruments controller using USART3. I want to receive data and then transmit data of different sizes. I get a problem that I see appears often but in my case I cannot see why it appears. I want to use USART on port C, PC4 = Tx and PC5 = Rx. I have a partner sending data via uart and I can see the data is on the Rx line but somehow it does not come to the buffer. I get to the interrupt handler and then Error callback. I am using the receive to Idle with interrupts when data is received. The first expected data is 10 bytes, my rx buffer is 1024 big and my rx buffer is defined , not NULL. I call the function for receive directly after my partner device is on and I have got the reply this device is on. The partner device is making 10 attempts to send the same data and without answer is shutting down. It starts sending shortly after it is on.
My uart onfiguration is as follows:
handleUart3.Instance = USART3;
handleUart3.Init.BaudRate = 115200;
handleUart3.Init.WordLength = UART_WORDLENGTH_8B;
handleUart3.Init.StopBits = UART_STOPBITS_1;
handleUart3.Init.Parity = UART_PARITY_NONE;
handleUart3.Init.Mode = UART_MODE_TX_RX;
handleUart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
handleUart3.Init.OverSampling = UART_OVERSAMPLING_16;
handleUart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
handleUart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
handleUart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&handleUart3) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&handleUart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&handleUart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&handleUart3) != HAL_OK)
{
Error_Handler();
}
HAL_NVIC_SetPriority(USART3_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
__HAL_UART_CLEAR_FEFLAG(&handleUart3);
__HAL_UART_CLEAR_NEFLAG(&handleUart3);
__HAL_UART_CLEAR_OREFLAG(&handleUart3);
Then all I do is call the receive function and wait for interrupts
uint8 *uartRxBuf; // pointing to a buffer that is created for this communication handler, uint8 * const buffPtr
HAL_UARTEx_ReceiveToIdle_IT(handleUart3, uartRxBuf, 1024);Then the code somes here
void USART3_IRQHandler(void)
{
HAL_UART_IRQHandler(&handleUart3);
}
and eventually HAL_UART_ErrorCallback()
Do you have any tips how to debug more and what can go wrong?
Edited to apply source code formatting - please see How to insert source code for future reference.
2025-11-07 5:52 AM
After 10 bytes, the 1024 byte buffer isn't even half full so not callbacks are triggered. Same thing after 100 bytes (10 tries).
If you want to handle each burst of data, consider using HAL_UARTEx_ReceiveToIdle_IT instead and using the HAL_UARTEx_RxEventCallback callback to process things on the idle/HT/TC interrupts.
If HAL_UART_ErrorCallback gets called, look at the flags in the uart handle to understand why.
2025-11-07 6:10 AM
Sorry, I did not get it. I am using this same function already. I have the Rx extended callback as well but the code never gets there. Only the error callback gets reached. I can see the USART_ISR_ORE and USART_CR1_RXNEIE_RXFNEIE are set in the handler.
I clear the interrupts before calling the receive function like this:
if (isr & USART_ISR_FE) __HAL_UART_CLEAR_FEFLAG(&handleUart3);
if (isr & USART_ISR_NE) __HAL_UART_CLEAR_NEFLAG(&handleUart3);
if (isr & USART_ISR_ORE) __HAL_UART_CLEAR_OREFLAG(&handleUart3);
if (isr & (USART_ISR_RXNE_RXFNE)) (void)&handleUart3.Instance->RDR;
2025-11-07 7:01 AM
Hello @GTanova
What is the flag that trigger the error callback and what is the error code you are getting?
2025-11-07 7:09 AM
My code gets into this line from the handler HAL_UART_IRQHandler()
/* UART Over-Run interrupt occurred -----------------------------------------*/
if (((isrflags & USART_ISR_ORE) != 0U)
&& (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}I understand it as an overrun error.
2025-11-07 10:38 AM
Yes the RX overrun error is notorious. It can occur when the other side sends while you're initializing the UART and something gets received before you begin reading. Just clear it ASAP and keep running.
2025-11-07 12:47 PM
Actually RX overrun lies in the very nature of HAL.
I wrote firmware for hundreds of MCU devices with UART communication. HAL UART stuff isn't suitable for anything - it has no right to work for any slave device, so for me it is not usable. I believe the concept of enabling reception more than once is simply ill. The only thing really needed for data reception is "byte received" callback with no need/requirement of enabling reception in it or anywhere else. I believe HAL2 should introduce this alternate (and, at least for me - the only reliable) model of UART reception.