cancel
Showing results for 
Search instead for 
Did you mean: 

UART how the overflow works ?

Xenon02
Associate III

Hello ! 

I've been wondering, how UART works in receiving side ? I have like maybe 4/5 questions ? 

-> What if I have a RX buffer that is full ? The flag is on and I didn't read the data. Then the new data comes after sometime, will it overwrite my data and still the flag will be on ? 

-> Is the data in the RX buffer loaded bit after bit or is it loaded whole word (8 bits) in one go and not bit by bit ? 

-> How do I know when I type HAL_UART_Transmit and after that the peripheral will be sending data and after transmit command I have the command HAL_UART_Receive, so how do I know it was fast enough to read the whole data without loosing any new or old data ? Like it was to late although the commands were one after another.

-> What if I used IT or DMA, they are non blocking, and questions like above like what if I type Transmit and Receive will I make it in time ? or what if I didn't read data and the buffer sets the flag and new data comes. 

These questions came out of curiosity because I read something about how UARTs looks like conceptually but I wondered how it looks like in practice. Because there are many types of commands in UART and wondered "what if" stuff. Also I know that RX works all the time and not only when I type HAL_UART_Receive so I wondered how it works when I have full data or when I type HAL_UART_Receive after HAL_UART_Transmit, will it be fast enough to read full buffor because this Receive commands reads full buffors and not bit by bit data. And what if I type HAL_UART_Receive after some time .. Yea I didn't know how to check it so maybe asking here won't be a problem ;> Sorry if it is. 

16 REPLIES 16
TDK
Guru

When only 3 characters are received, HAL_UART_Receive doesn't do anything with the other 47 bytes. They have the same value they had before the function was called.

I wouldn't spend time worry about how exactly ORE affects the peripheral. It is an error condition--you shouldn't be hitting it. The reference manual does explain it in detail, which I've explained and screenshotted in my first reply.

Receive must be called before data on the line is transmitted. There isn't a buffer or anything that stores it until the receive function is called.

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

I've read TDK post and most of it I understood, at least the part with what flag is what etc. 
But the speed of how the code is read etc, was a mystery. 

Okey example I have a code and I type this : 

//some initials after that UART
HAL_UART_Transmit(); 

HAL_UART_Receive();

//do other stuff

So yea Here is the Transmit function and it now sends data, after that the device on the other side of UART already sends data, but the code is being processed (HAL_UART_Receive();). How fast is the code ? Will it read and wait for the data (HAL_UART_Receive();) in time ? What if the device is faster ? like not 9600 baund but faster. 

I see there are mechanism that helps with reading data, and the RX reads only the final product which is what is in buffer, it reads it and quickly resets the flag. 

After typing it maybe the HAL_UART_Receive(); is fast enough, for every baund rate dunno. 
Maybe it is visible more what I tried to say here. But usually I see people call HAL_UART_Receive(); right after HAL_UART_Transmit(); so probably reading the RX must be immediate. At least maybe I understand it correctly that HAL_UART_Receive(); is being decoded very quickly like in nano seconds and the data is sent in ms so the program sits and waits for RX flag very very early maybe. And for faster baund rate it is also the same thing. 

so conclusion Even if after HAL_UART_Transmit(); the device on the other side is already sending data to the RX but the HAL_UART_Receive(); is being decoded right after HAL_UART_Transmit(); but it is faster than RX speed or something. So it waits for the RX. I guess. 

I didn't understood the part that this is not usable in real life cases. Hmmmm But what I said is correct then maybe that's the point that the command is read faster than the data that is comming to RX buffer. 

It depends on the device on the other end. Does it wait for all incoming data before sending? How long after receiving data does it wait before sending data? These are things you should know about the system before coding your solution. Logic analyzer is useful for seeing the raw signals and timing between them.

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

Wait a minute : 

> "Receive must be called before data on the line is transmitted. There isn't a buffer or anything that stores it until the receive function is called."

Receive must be called before data is transmited in line ? 
Usually I see this examples : 

HAL_UART_Transmit(); 

HAL_UART_Receive();

Receive command was called after transmit and it worked, what more the receive data is stored in the register DR, so it waits to be taken from Receive function. 

>"It depends on the device on the other end. Does it wait for all incoming data before sending? How long after receiving data does it wait before sending data? These are things you should know about the system before coding your solution. Logic analyzer is useful for seeing the raw signals and timing between them."

Hmmm I didn't think this way that the device waits before sending data hmmmm that's a good hint. 
I have some Logical analyzer need to find on youtube how to use it. 

To be honest I thought that UART on the device on the other end sends the RX data immidiatelly after receiving
data from TX STM32 side.But for 9600 baund rate 8 bits takes 1 ms, when he sends it immidiatelly right ? so when there is a wait timebefore the device on the other side sends RX data then this 1ms becomes longer arbitrally let's say 2ms or more !

But I haven't seen these examples on youtube ;< Do you have any examples where it is shown more about these wait times ?

Also I wantted to add one thing, After I call the HAL_UART_Transmit function, after transmiting bytes it stops the function, so then I call the HAL_UART_Receive function, calling this function takes time right ? But the RX line is already receiving data from the device on the other end right ? Is the function fast enough to execute everything and wait for the RX flag, before the already ongoing sending data is fulled ?

For 9600 baund rate speed maybe the execution is fast because it is minimum 1ms, but for other speeds ? I don't know how long the HAL_UART_Receive call takes time to read the function and then wait for the RX,
When he waits before even RX is flagged on the it means even if the transmission is on going the function is fast enough to be before even the RX flag is set on to read it and the OVR won't occure.

You've also mentioned in the first reply, what if the data starts sending during even the HAL_UART_Transmit call. I've been thinking what happens when data is comming the I am just calling the Receive function, because that's how it looks like in this simple example :

HAL_UART_Transmit();

//After leaving the Transmit function the device is sending data to RX

HAL_UART_Receive(); //RX is in being executed but some data is now in shift register, will this function be fast enough to be ready for RX flag before it is set ?

But your example can show me that even during transmission the data can be already sent to the RX, I haven't thought about it nor how to use it when HAL_UART_Transmit(); is blocking.

PS.

I've watched some example devices that uses UART, and usually I see that after sending TX data from STM to device is done, the device sends data to the STM RX immidiatelly,
atleast that's what it was written in the framework/simple graphs of how their UART works, haven't seen how much time I have before first byte comes.

So I wondered if the data is infact immidiatelly sent after receiving the TX data from STM, how fast is the Receive command is executed ? After executing it waits in this function and waits for RX to be flagged ? I mean if it's fast enough, calling the Receive function after Transmit function. The call for Receive function will be executing while the device will be sending the TX data to the RX of the device. I don't know if what I say is understandable so tell me if it's not. I am soon ending this post so don't worry. 

Thanks again for your time, sorry for the long reply, see ya ! 

Xenon02
Associate III

You know what thinking about it, maybe my post was to long.
But still this answer bugs me : "Receive must be called before data on the line is transmitted. There isn't a buffer or anything that stores it until the receive function is called.".

Hmmm You mean that HAL_UART_Receive must be called before data appears in transmit line (so it is the same as calling Receive function before data appears in RX line), makes not much sense, because After calling HAL_UART_Transmit it can send data right after ending calling the Transmit function and then we call Receive function like here : 

Xenon02_0-1704713400757.png

Like there are two starting HAL_UART_Receive, the red one is ideal that it if fast enough after transmit function that it starts waiting for RX flag in the starting bit of RX but what if function is slower and the call of HAL_UART_Receive end waiting in the second bit out of 8 bit of the receive data ? Dunno how fast this function is interpreted, probably the red one is ideal for the speed 9600, because it is 1ms and the function to read (HAL_UART_Receive) takes couple ns so we have like less than 1 ms spared time before the full data comes I guess, but for faster baund speed dunno. 

But like I said, I don't know why Receive must be called before data appears when I don't know if it fully appeared after HAL_UART_Transmit or not, usually in simple examples people call HAL_UART_Receive after HAL_UART_Transmit, but maybe data already appeared in RX line while calling HAL_UART_Receive so it doesn't make sense + there is this DR register to hold this 8 bit word for some time. 

Sorry and thanks.

 

Pavel A.
Evangelist III

@Xenon02 wrote:

Receive must be called before data is transmited in line ? 
Usually I see this examples : 

HAL_UART_Transmit(); 

HAL_UART_Receive();

What you wrote above applies to so called half duplex mode, when only one side can send and the other side must listen. There indeed are systems that work in this mode (think RS-485).

But often the UART is used in full duplex mode, when both TX and RX directions work independently at the same time. In this mode a device (such as a modem) can echo back received characters immediately after receiving them. The red vertical line on your picture that separates receive from transmit simply does not exist. They overlap. Will your code snippet work in this case? (Surprise! it won't). Therefore you have to start at least the receive process "in background" so that it won't  wait for transmit. Again as Mr. Kostka wrote, the functions to use are non-blocking  HAL_UART_Receive_IT or HAL_UART_Receive_DMA - but the latter has complications (the timeout thing, TL;DR) so eventually people write their own interrupt driven receive code. If this still does not make it clearer... just have a good nap, drink more water and search for more full-duplex examples.

 

> "What you wrote above applies to so called half duplex mode, when only one side can send and the other side must listen. There indeed are systems that work in this mode (think RS-485).

But often the UART is used in full duplex mode, when both TX and RX directions work independently at the same time. "

I used this same command setup in my Bluetooth, and in other uart devices as well. 
And It was set as full duplex, I saw a half duplex simple wire but maybe it was this exactly. 

I also used two different lines for TX and RX because I used two wires to connect RX and TX so I tried to show how both lines looks like. 

But if both TX and RX are sending at the same time then yea my code won't work because the assumption is that after sending the TX command the device will send data after receiving the full command, so after receiving full data it sends back data in the other lane. That's why there are two lanes. 

My questions were partly answered, I wondered just that if it worked like in my diagram which I believe some work like that. At least the Bluetooth worked like that I guess. Because I wrote the same code like in the examples I gave. 

I didn't know how to ask the question. Because it might be just to specific. I wondered if just the function is fast enough to be before the RX flag is ON, like in the picture. 

I just interpreted that maybe this HAL_UART_Receive in that diagram picture, the call itself is fast enough to wait for RX flag before 1ms passes for 9600 baund rate because the function maybe takes like ns to be executed so 1ms - some nano secons = couple of micro seconds, still some time to spare. For higher baund rate I dunno maybe the function is still fast enough to be ready for RX flag before the whole data is sent to the DR register. 

Still I don't know if my question was asked correctly. Because I feel like they hit the question but not specifically it. 

Thank you Pavel for the answer. I'll take a nap and drink water but still I am new to it so you know ;> 
I think a bit ahead of time analyzing it deeply. Simple concept of UART is simple but details can make me think and the detail was whether the function call when it works as half-duplex it sends data by Transmit function, after it sends full data the Receive function is called (HAL_UART_Receive) and I wondered how fast this function is executed/called dunno how to say it, how long it takes for this function to be ready to ready RX flag (it does other stuff before checking the RX flag so it must be prepared by that time some data is already being stored in shift register and after some time it is sent to the DR register which then sets the RX flag but will the function will be ready by that time ? As I mentioned while the code is being proccessed the data is comming from the device, so will it be fast enough the function to get to the point to wait and check the RX flag. 

I gave some assumptions and maybe they are true for slow baud rate like 9600 but for faster, I dunno.