cancel
Showing results for 
Search instead for 
Did you mean: 

HAL Timeout on UART Receive

Lalit B
Associate
Posted on November 06, 2017 at 23:55

I'm setting up a UART channels to transmit and receive from a slave device.

I have Transmit working as I can see the slave is doing what's asked from the command sent to it.

On each command the slave reply's back with acknowledgement.

When I capture the ACK I get HAL_Timeout

Example

static uint16_t timeout = 25;   // milliseconds

static HAL_StatusTypeDef val_tx1, val_tx2;

static HAL_StatusTypeDef val_rx1, val_rx2;

val_tx1 = HAL_UART_Transmit_DMA(&huart1, buffer, buff_size); 

val_rx1 = HAL_UART_Receive(&huart1, rcv1_msg, rcvmsg1_size, timeout);

while (HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY){}

The execution is stuck forever in the while loop since the HAL UART state is HAL_TIMEOUT

I actually want to use UART Receive with interrupt which fills the RX buffer and I want to simply parse thru the buffer.

But when I use HAL_UART_Receive_IT() the return is always HAL_UART_STATE_BUSY_RX.

How do I go about fixing this.

Thanks.

#uart-tx #uart-rx #uart-it #stm32-usart #usart-stm32
4 REPLIES 4
Posted on November 07, 2017 at 01:21

May be you should be testing the return of 

HAL_UART_Receive(), and states other than READY?

A receive timeout may occur if the sending device hasn't sent data within the window you are expecting. You could make the timeout longer, or resubmit the request.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 07, 2017 at 21:03

Hello Clive,

Thanks for your response.

The return of HAL_UART_Receive() is HAL_OK for the first time around and then always HAL_TIMEOUT which means I'm not setting up my RX properly. On an oscilloscope I can see acknowledgement from the slave device for every command I send. I have given HAL_UART_Receive() sufficient timeout. But as I mentioned I would prefer to use HAL_UART_Receive_IT() instead since I want to generate an interrupt and execute its routine when I receive acknowledgement. How would I go about setting up interrupt?

Some Correction to the code I had provided in my first post...here is something what I'm trying to do.

static uint16_t timeout = 25;   // milliseconds

static HAL_StatusTypeDef val_tx1;

static HAL_StatusTypeDef val_rx1;

while(1)

{

   val_tx1 = HAL_UART_Transmit_DMA(&huart1, buffer, buff_size); 

   val_rx1 = HAL_UART_Receive(&huart1, rcv1_msg, rcvmsg1_size, timeout);

   while (HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY){}

   

   // more code here to modify buffer and buff_size to transmit new command to slave device

}

Thanks.

Posted on November 07, 2017 at 22:10

Ok, but not testing for results, and no handling of appropriate loop exit conditions...

HAL_UART_Transmit_DMA() will complete immediately, before the data has been sent, so the timeout is going to need to include the transit time of the outbound data.

HAL_UART_Receive() will block.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
first last1
Associate
Posted on July 07, 2018 at 16:34

Did you manage to fix this problem? I'm stuck on this too.