cancel
Showing results for 
Search instead for 
Did you mean: 

[stm32u585] program is stuck in HAL_UART_IRQHandler with TC flag

lll
Associate III

hello

Description:

I'm currently working with the STM32U585 and encountered an issue related to USART3

Most of the time the code works fine, but it occasionally gets trapped in HAL_UART_IRQHandler

I am using the DMA Receiver Timeout (RTO) and DMA TX, may code is:

void uart_tx_complete_cb(UART_HandleTypeDef *huart)
{
    if (...)
        HAL_UART_Transmit_DMA(huart, buf, len);
}
void uart_rx_error_cb(UART_HandleTypeDef *huart)
{
    HAL_UART_AbortReceive(huart);
    if (huart->ErrorCode & HAL_UART_ERROR_RTO)
    {
        ...
    }
    HAL_UART_Receive_DMA(huart, rx_buf, rx_buf_len);
}
HAL_UART_RegisterCallback(&huart3, HAL_UART_ERROR_CB_ID, uart_rx_error_cb);
HAL_UART_ReceiverTimeout_Config(&huart3, 100);
HAL_UART_EnableReceiverTimeout(&huart3);
HAL_UART_Receive_DMA(&TD_UART_HANDLE, rx_buf, rx_buf_len);
HAL_UART_RegisterCallback(&huart3, HAL_UART_TX_COMPLETE_CB_ID, uart_tx_complete_cb);

 

When the issue occurs, I found that the TC (Transmission Complete) flag is not being cleared:

1.PNG2.PNG

and HAL_UART_IRQHandler return at /* End if some error occurs */

1 ACCEPTED SOLUTION

Accepted Solutions
lll
Associate III

thank you all

@Ozone @Saket_Om @TDK 

I move HAL_UART_Transmit_DMA() out of uart_tx_complete_cb()

and use HAL_UARTEx_ReceiveToIdle_DMA() instead of HAL_UART_EnableReceiverTimeout()

to circumvent this issue, it seems to be working well

View solution in original post

6 REPLIES 6
Saket_Om
ST Employee

Hello @lll 

Did you investigate why it is not clearing the TC flag inside HAL_UART_IRQHandler?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om
TDK
Super User

You restart the transfer on every tx complete, so TC flag will continue to get set. What makes you think it is stuck? Stepping through should let you see the logic where it gets cleared. TC flag doesn’t necessarily even need to be cleared.

If it “works most of the time”, problem is likely not with the logic inside the handler.

If you feel a post has answered your question, please click "Accept as Solution".
lll
Associate III

TC and TCIE are both set, and HAL_UART_IRQHandler returned before:

/* UART in mode Transmitter (transmission end) -----------------------------*/

UART_EndTransmit_IT

 

After problem occurs, any suspension will stop at HAL_UART_IRQHandler, I set a breakpoint in uart_tx_complete_cb, and never go in it

Hello @lll 

Could you please share a minimal example to reproduce the issue ?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om
Ozone
Principal III

I think you can look up yourself  which operations clear the TC flag.

However, consider your callback routine takes too long,and flag is already set again when it exists.
In this case, you need to move processing code out of the interrupt context.

lll
Associate III

thank you all

@Ozone @Saket_Om @TDK 

I move HAL_UART_Transmit_DMA() out of uart_tx_complete_cb()

and use HAL_UARTEx_ReceiveToIdle_DMA() instead of HAL_UART_EnableReceiverTimeout()

to circumvent this issue, it seems to be working well