cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_Receive() always timeout.

Bryan Guo
Associate II
Posted on April 27, 2017 at 06:18

Hi all,

I met a strange problem that if I input something via a terminal before I call 

HAL_UART_Receive(); It will always timeout. And it will not recover until I reboot the board.

My code is as bellow.  What can I do to reset the status? Or enable the interrupt again?

while (1)

{

sprintf(aTxBuffer,'\r\nSTM32CubeMX rocks %d times \t', ++nbtime);

HAL_UART_Transmit(&huart2,(uint8_t *) aTxBuffer, strlen(aTxBuffer), 5000);

uart_rst = HAL_UART_Receive(&huart2,(uint8_t *) aRxBuffer, 2, 2000);

if(uart_rst==HAL_OK)

{

HAL_UART_Transmit(&huart2,(uint8_t *) str_ack, strlen(str_ack), 5000);

}

else if(uart_rst==HAL_TIMEOUT)

{

HAL_UART_Transmit(&huart2,(uint8_t *) str_to, strlen(str_to), 5000);

}

else

{

HAL_UART_Transmit(&huart2,(uint8_t *) str_err, strlen(str_err), 5000);

}

HAL_Delay(2000);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

#uart
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on May 02, 2017 at 10:02

Hi,

My understanding of what could happen : as soon as Receiver is enabled (CR1_RE bit set to 1, I think this is your case), if a character is received, RXNE flag will be set to 1. On 2nd character received, if first one has not been read from RDR, data could not be transferred to RDR, and then Overrun error flag is raised. Then, any other data received while OVR is set is lost.

To make sure that above scenario corresponds to your use case, please check value of RXNE and OVR flags prior calling Receive procedure in case you entered some characters before.

If you want to discard previously received characters, you could clear OVR and RXNE flags prior calling

HAL_UART_Receive()

.

Let me know if this helps.

Regards

Guenael

View solution in original post

9 REPLIES 9
Bryan Guo
Associate II
Posted on April 27, 2017 at 14:54

I also tried HAL_UART_Receive_IT().  It can enter the callback only once.

Posted on May 02, 2017 at 10:02

Hi,

My understanding of what could happen : as soon as Receiver is enabled (CR1_RE bit set to 1, I think this is your case), if a character is received, RXNE flag will be set to 1. On 2nd character received, if first one has not been read from RDR, data could not be transferred to RDR, and then Overrun error flag is raised. Then, any other data received while OVR is set is lost.

To make sure that above scenario corresponds to your use case, please check value of RXNE and OVR flags prior calling Receive procedure in case you entered some characters before.

If you want to discard previously received characters, you could clear OVR and RXNE flags prior calling

HAL_UART_Receive()

.

Let me know if this helps.

Regards

Guenael

Posted on May 03, 2017 at 07:13

I add the code __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF|UART_CLEAR_OREF); before calling HAL_UART_Receive_IT().  It works. 

Posted on September 11, 2017 at 21:32

Cadier.Guenael

Hi Guenael,

I am facing same problem with HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

I am able to receive single user input like 1,2,3,4 but when I try to receive large packets of data(say 1k Bytes), the receive gets timed out everytime after receiving first couple of bytes. Even though theRxXferSize andRxXferCount gets set to 0x404, the control goes intoUART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) and returns TIMEOUT.

What could be the problem. I havenot modified anything in the HAL receive API. Please help.

P.S.: I am using STML053 and I am trying to receive a binary file using tera term. Reference software package:

http://www.st.com/en/embedded-software/x-cube-iap-usart.html

Thanks,

Harsha

Posted on September 11, 2017 at 21:43

Ok, and baud rate and timeout is WHAT?

The timeout isn't reset for each byte received, it accounts for the TOTAL time for ALL the bytes requested.

Is a timeout bad? It contains the maximum amount of time. Isn't HAL_TIMEOUT equivalent to HAL_OK of only RxXferCount bytes, bounded by time?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 11, 2017 at 23:00

Baud rate is 115200 and timeout is assigned to a macro which I did change to max value. But it still doesn't receive anything in the pdata buffer. It just waits inside 

UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)

 until TIME_OUT.

The baud rate, parity, stop bit of tera term matches with the configuration of USART. So there is no conflict with that.

Isn't HAL_TIMEOUT equivalent to HAL_OK of only RxXferCount bytes, bounded by time?

>> 

According to my understanding the HAL_UART_Receive() should receive data of specified Size into pdata buffer before getting timed out. I am receiving single byte of data when I have Size=1 . But when I try HAL_UART_Receive using 1k Size data, nothing is written into RDR. S

hould I 

flush the DR register every time I receive new byte ? If yes how do I do it inside the HAL_UART_Receive() ? 

Thanks,

Harsha

Posted on September 12, 2017 at 01:56

I'm not a HAL expert.

Is it actually receiving anything, ie is TeraTerm sending anything to you in this situation, or is it waiting for some response/acknowledgement from you? Have you processed the data successfully, and not placed some fixed expectation on how much should be received. Have a T-Feed off the received data and monitor it in another terminal, matching what you see at the STM32 with what is seen independently.

Write your own X-Modem protocol if that help with the flow/mechanics.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
tian leixin
Associate
Posted on March 07, 2018 at 17:04

I get a trouble when using this function!

HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_UART_Receive 

when the rx data length less than size or equal with size,it works.When I try to send more data ,this function can't receive data any more

code as follow:

while(1)

{

res = HAL_UART_Receive(&console_uart,test,10,2000);

if(res == HAL_OK)

{

}

else if(res == HAL_TIMEOUT)

{

printf('timeout\n');

}

else if(res == HAL_BUSY)

{

printf('busy\n');

}

printf('%s',test);

memset(test,0,100);

}

}

Posted on March 08, 2018 at 09:31

Hi

leixin.tian

‌,

Am I right ?

If you transmit 8 chars, you get 'timeout' output + string print

If you transmit 10 chars, you get test buffer printed out (string print)

If you transmit 12 chars, you get test buffer printed out (string print), then 'timeout'

In case of 12 chars sending, issue could be that while you are processing output of message and buffer printf (10, further characters received (11th and 12th) are leading IP to Overrun error case.

Once overrun has been encountered, RXNE flag will not go High again till OVR flag is cleared. Could you check value of OVR flag in SR/ISR register of your UART, when you consider reception is frozen ?

Note than depending on test buffer content, %s print could output more than the 10 chars received ...

Regards

Guenael