Skip to main content
Sebastian K.
Associate III
August 9, 2017
Question

Question about behaviour of HAL_UART_Transmit_IT

  • August 9, 2017
  • 6 replies
  • 2566 views
Posted on August 09, 2017 at 17:42

Hello everyone,

I am having some trouble understanding the behaviour of the HAL_UART_Transmit_IT and HAL_UART_Receive_IT routines. I am using two NUCLEO-F767ZI boards that communicate via UART1 in a request/reply fashion - the 'client' sends a one-byte command and the 'server' immediately replies with the associated message. Both boards use a state machine which is programmed to ensure that at all times only one Receive_IT or Transmit_IT can be running. All the communication is carried out in interrupt mode. I have working IRQ handlers and Tx/Rx Completed Callbacks on both.

As I am running through a series of requests and replies, repeated every 10 ms by the client, the client board always starts to hang after a couple of cycles. But what is weird is that it seems to work fine only if I omit receiving the last reply of the server in a cycle, and skip directly to the next request without calling a HAL_UART_Receive_IT on the client. But from what I can see, the TxCpltCallback on the server side is still executed, although the client never called a Receive!

So I guess my question is: What is the behaviour of HAL_UART_Transmit_IT if nobody is answering on the other side?

Is there any other way a TxCpltCallback can be triggered? Do I have to clear any flags manually if I want to do what I described?

#nucleo-f767zi #uart
This topic has been closed for replies.

6 replies

Tesla DeLorean
Guru
August 9, 2017
Posted on August 09, 2017 at 18:58

>>What is the behaviour of HAL_UART_Transmit_IT if nobody is answering on the other side?

It shouldn't care, it is stuffing data into a dumb pipe as fast as the USART flags the output buffer is clear for new data (ie signalling TXE, one byte at a time)

One should be wary of using HAL_Delay(), or waiting for multiple characters in a callback, it is called in interrupt context, do minimal work and leave. The HAL and example code have a lot of code that blocks when that is highly undesirable.

The use of HAL_UART_Transmit_IT() and it's interactivity with the other side, is all on your side of the fence. Is your protocol stuck on a rigid number of bytes, or patterns? Is it capable of resync/recovery when the planets don't align perfectly?

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Sebastian K.
Associate III
August 9, 2017
Posted on August 09, 2017 at 19:29

Hello Clive, thanks for answering.

Indeed, I am not using any HAL_Delay() and the callbacks are only used to advance the state machine, and copy a few bytes at the maximum.

When you say the USART is 'signalling TXE, one byte at a time', what is happening to those bytes if they are not read at the receiver's end?  Does it just keep stuffing data from the TDR to the shift register? If so, what's the point of using an interrupt-driven function if it starts transmitting even though there is no receiver?

In the meantime I noticed I do get Overrun errors on the receiver's end, I just cannot pinpoint yet where exactly they happen...

Tesla DeLorean
Guru
August 9, 2017
Posted on August 09, 2017 at 20:19

>>what is happening to those bytes if they are not read at the receiver's end? 

Nothing on the the transmission side,the USART is just wiggling a pin up and down, if nothing is connected or listening it doesn't care. It is a blind interface. If you implement RTS/CTS flow control you can stop the Tx side.

On the Rx side if you don't pull the data you received the register will overrun once the next byte is received, and that will be flagged, and you must read the data register to clear that state.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..