cancel
Showing results for 
Search instead for 
Did you mean: 

How to Reset an UART after an error

Chao
Senior

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

 

4 REPLIES 4

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Karl Yamashita
Lead III

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

 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
Saket_Om
ST Employee

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();
    }
}

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

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.