Skip to main content
Explorer
September 19, 2024
Question

UART TEACK flag stays reset at the end of HAL_UART_Init() - STM32U073

  • September 19, 2024
  • 7 replies
  • 4661 views

Hello, during my tests I have come across a strange issue. During the initializing phase, my application was hitting a WWDG reset (after ~400ms) constantly. This only happened after a couple resets (toggling the NRST pin LOW). 

I have concluded during debugging, that when this repeated resetting of the WWDG state occured, it is because the program is hanging on the autogenerated (via STM32CubeIDE) init function:

 

HAL_UART_Init(&huart2)

 

Looking further, it actually finishes most of the function code but hangs on the last function:

 

return (UART_CheckIdleState(huart));

 

It specifically hangs when doing the below check:

 

if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)

 

What baffles me, is how this is not repeatable behaviour. Most of the times I restart the MCU, it proceeds as intentioned. But sometimes it starts doing this infinite game of checking TEACK so long that WWDG resets it.

Before this code is executed, only other peripheral initilaization code is performed.

Any ideas?

Edit: Adding my current auto-generated USART parameters from the usart.c file

 

void MX_USART2_UART_Init(void)
{

 /* USER CODE BEGIN USART2_Init 0 */

 /* USER CODE END USART2_Init 0 */

 /* USER CODE BEGIN USART2_Init 1 */

 /* USER CODE END USART2_Init 1 */
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 1000000;
 huart2.Init.WordLength = UART_WORDLENGTH_9B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_EVEN;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
 huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
 if (HAL_UART_Init(&huart2) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART2_Init 2 */

 /* USER CODE END USART2_Init 2 */

}

 

:)

    This topic has been closed for replies.

    7 replies

    Super User
    September 19, 2024

    How are clocks set up? What's the UART's kernel clock?

    Is there some signal on the Rx pin?

    Do you really set baud on 1MBaud?

    Read out and check/post UART registers.

    JW

    Explorer
    September 19, 2024

    Hi @waclawek.jan , I added the CLK setup in the post attachments. There is a signal pretty frequently on the RX Pin. The UART Registers seem to be in order as far as I can tell (most of it is in the default reset value).

    Yes, I really do set the baud to 1Mbaud.

    Super User
    September 19, 2024

    I don't have answers for you, but as you are pushing things at the edge, with the highest possible baudrate and an unusually high APB divider... maybe you tapped into a genuine marginal hardware bug?

    One way to tackle this might be simply ignoring TEACK, which would require to modify the Cube function or write your own - but that's easy, as you've said, most of the UART registers are at their reset values.

    JW

    Explorer
    September 20, 2024

    Reducing the Baudrate has seemed to not impact anything, I will try to play around with the dividers and see. However maybe it would be worth to get an ST person involved. I'll reply if I get any results with reconfiguring the clock settings. Thanks! @waclawek.jan 

    ST Employee
    September 24, 2024

    Hello @StefanInfi

    For the moment I couldn't reproduce this behavior 

    What I tried to do (using same usart2/ clock config) is very simple:

    while (1)
     {
     /* USER CODE END WHILE */
     SET_BIT(huart2.Instance->CR1, USART_CR1_TE);
     uint32_t tickstart = HAL_GetTick();
     uint32_t timeout = 1000; // 1 second timeout
     
     HAL_StatusTypeDef status = UART_WaitOnFlagUntilTimeout(&huart2, USART_ISR_TEACK, RESET, tickstart, timeout);
     if (status == HAL_OK)
     {
     HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // Toggle an LED to indicate TEACK flag is set
     }
     else
     {
     HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6); // Toggle another LED to indicate TEACK flag is not set within timeout
     }
    

     In this case the TEACK flag is successfully set (LED5 toggles) 

    SarraS_0-1727187961433.png

    Will you be able to share the project reproducing the issue to investigate more! 

    Thank you! 

    Explorer
    September 25, 2024

    Hi @Sarra.S , thank you for trying to reproduce the issue!

    However, I think you should also then have the uart RX pin receive a 10 byte stream (1Mbaud, even parity) every 50ms. I forgot to mention I also have even parity enabled (which is probably not relevant). This should be done by another MCU.

    I would use the HAL functions included in the cubeMX generated files to do the UART init, since it more accurately replicates my setup. 

    If nothing is able to reproduce the issue, I would share my code with you but please then lets be in touch via email.

    ST Employee
    September 25, 2024

    Hi @StefanInfi 
    Indeed, as mentioned by @waclawek.jan, handling a 1Mbaud with a 16Mhz clock source is the limit. To relax this on RX, could you try to initialize your USART2 with OverSampling_8 configuration :

    huart2.Init.OverSampling = UART_OVERSAMPLING_8;

    Regards

    Explorer
    September 30, 2024

    Sorry for the long wait @Guenael Cadier . During my testing I had also done this, and also toyed with other clock configurations but it seemed to have no effect.

    Graduate
    December 21, 2024

    Hey @Guenael Cadier,

    we have exaclty the same behaviour. We use an STM32H750IB with multiple UARTs. Our firmware is splitt into 2 different parts (our custom bootloader, application firmware). From the application firmware we have a GPIO PD3 which is used to indicate if we run in the bootloader or application firmware. 

    In the application firmware HAL v1.11.1, bootloader HAL v1.11.0. 

    The application code runs in XiP from the external flash while the BL runs in the internal flash. In XiP we use Cache as well as a well configured MPU. 

    To jump into the bootloader we simple set PD3 high and then reset the H7. From time to time we have the problem that the MX_USART2_UART_Init() stucks in the line: 

     /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
     return (UART_CheckIdleState(huart));

    TEACK and REACK are just not set. But I would say this is only the case in 10% of the cases. 

    Interesstingly this can also happen when we hold the RST by hand down, set PD3 high and let the system run. So it is not related to the PD3, it seems to be related to the time when we push the RST button. If we completly power cycle the chip this issue does not happen. But when we check the UART RX and TX lines they look completly normal. What could be the reason for it? Or do you have any idea of what we can try? 

    Best regards,

    Eric

    ST Employee
    January 2, 2025

    Hi @ESawa.1

    Is your question related to this one, answered in a separate topic ?
    Regards

    Graduate
    October 22, 2025

    Yes this was the reason for it. We can close the question here.