Skip to main content
Graduate
August 6, 2024
Question

How to Reset an UART after an error

  • August 6, 2024
  • 3 replies
  • 4612 views

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

 

    This topic has been closed for replies.

    3 replies

    Graduate II
    August 6, 2024

    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.

    Graduate II
    August 7, 2024

    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

     

     

    Technical Moderator
    August 7, 2024

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

     

    ChaoAuthor
    Graduate
    September 3, 2024

    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.