2024-08-06 10:58 AM
Hi,
Recently, we desighed a test board with STM32F103RB for UART communication with a wireless chip, and we found that the HAL_UART_ErrorCallback is triggered occasionally (the periods of errors vary betweent tens of minutes to hundreds of minutes), the error does not affect sending data from STM32F103RB to the wireless chip, but once an error occurs, the MCU does not receive any data from the wireless chip any more, at the moment, we have to reset the MCU to resolve this issue. However, we would like to reset the UART to resolve the issue if possible as there are some other tasks running on the MCU.
We tried the following, but it does not work:
HAL_UART_Abort_IT(uart);
HAL_UART_DeInit(uart);
uart->Instance = USART3;
uart->Init.BaudRate = WirelessUartBaudRate;
uart->Init.WordLength = UART_WORDLENGTH_8B;
uart->Init.StopBits = UART_STOPBITS_1;
uart->Init.Parity = UART_PARITY_NONE;
uart->Init.Mode = UART_MODE_TX_RX;
uart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart->Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(uart);
What is the correct way to do this?
Many thanks to any suggestion.
Chao
2024-08-06 11:16 AM
Normally you'd check the status and then explicitly or implicitly clear the error conditions.
On the F1's many of the receive error can be cleared by reading the DR,
ie
if (USART3->SR & Errors) // Noise, Framing, Parity, etc
USART3->DR;
Would suggest browsing the Reference Manual, USART register sections.
2024-08-06 05:25 PM
If the UART doesn't interrupt after awhile, then the interrupt wasn't successfully enabled. This happens if you don't check the HAL return status to be sure it returned HAL_OK
2024-08-07 02:03 AM
Hello @Chao
In your UART reset process you are not checking if the abort, Init and DeInit are successfully done. To do this please use the function below.
void Reset_UART(UART_HandleTypeDef *huart) {
// Clear any pending error flags
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF | UART_CLEAR_FEF | UART_CLEAR_NEF | UART_CLEAR_OREF);
// Abort ongoing UART transfer
if (HAL_UART_Abort_IT(huart) != HAL_OK) {
// Abort Error
Error_Handler();
}
// Deinitialize the UART
if (HAL_UART_DeInit(huart) != HAL_OK) {
// Deinitialization Error
Error_Handler();
}
// Reinitialize the UART
huart->Instance = USART3;
huart->Init.BaudRate = WirelessUartBaudRate;
huart->Init.WordLength = UART_WORDLENGTH_8B;
huart->Init.StopBits = UART_STOPBITS_1;
huart->Init.Parity = UART_PARITY_NONE;
huart->Init.Mode = UART_MODE_TX_RX;
huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart->Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(huart) != HAL_OK) {
// Initialization Error
Error_Handler();
}
}
2024-09-03 08:15 AM
Hi @Saket_Om
I did checks on the returns as you suggested :
void Uart::Reset()
{
// Clear any pending error flags
__HAL_UART_CLEAR_FLAG(uart, UART_FLAG_CTS | UART_FLAG_LBD | UART_FLAG_TC | UART_FLAG_RXNE);
// 这将同时清除 PE FE NE ORE 等4个FLAG
__HAL_UART_CLEAR_PEFLAG(uart);
// Abort ongoing UART transfer
if (HAL_UART_Abort_IT(uart) != HAL_OK) {
// Abort Error
resetError = 1;
}
// Deinitialize the UART
if (HAL_UART_DeInit(uart) != HAL_OK) {
// Deinitialization Error
resetError = 0x2;
}
// Reinitialize the UART
uart->Instance = USART3;
uart->Init.BaudRate = WirelessUartBaudRate;
uart->Init.WordLength = UART_WORDLENGTH_8B;
uart->Init.StopBits = UART_STOPBITS_1;
uart->Init.Parity = UART_PARITY_NONE;
uart->Init.Mode = UART_MODE_TX_RX;
uart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart->Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(uart) != HAL_OK) {
// Initialization Error
resetError = 0x4;
}
}
and retrieved resetError, and found resetError=0 that means all are HAL_OK.
However, it still sometimes works and some other times does not work as before.