cancel
Showing results for 
Search instead for 
Did you mean: 

Flush a UART FIFO

sjackson
Associate II
Posted on November 21, 2008 at 16:26

Flush a UART FIFO

6 REPLIES 6
sjackson
Associate II
Posted on May 17, 2011 at 09:56

The UART FIFOs on the STR9 have a total of 16 slots (bytes) each for both transmit and receive. According to the manual, you can set the up to trigger interrupts at different FIFO levels, from 1/8 full to 7/8 full. This means that the FIFO interrupt trigger can be set in two bytes increments. This apparently means that if I send some data that consists of an odd number of bytes, that one could be left in the buffer and become ''stale.'' For example, I have a 3 byte data packet and I send the first two bytes and after a short delay, the third byte. If the two bytes complete transmission the third, from my interpretation, would sit in the buffer until another byte is put into the FIFO. A similar situation occurs with the receive FIFOs.

My question is, is there a way to automatically flush buffers to ensure that no data becomes stale, or am I stuck polling UART flags to see if anything is left in there?

Going with the transmission example, if I don't want to send dummy bytes to flush out my buffer, is there some command that can be issued to force any remaining FIFO characters to be transmitted even if the FIFO hasn't reached the prescribed level?

Thanks.

mark9
Associate II
Posted on May 17, 2011 at 09:56

It took me a while to figure this one out. Fortunately, there is an easy answer, at least for receive. There is a interrupt bit that you can turn on (RTIM) that will cause an interrupt if the receive FIFO doesn't receive any input for a particular small interval of time. So set RTIM and RXIM to get the ''FIFO-nearly full'' and ''FIFO-stale'' interrupts, and you can drain the receive FIFO.

You don't really need this for transmit. The transmit FIFO automatically empties. If you *really* need to know when the last bit of the last byte was transmitted on the physical port, then you are a little stuck, unless you can afford to turn on Loopback mode, and use the RX interrupts to figure out when the TX is done. But normally you don't need to know when the TX fifo is empty.

sjackson
Associate II
Posted on May 17, 2011 at 09:56

Unfortunately this doesn't seem to help much. I currently have my receive FIFO set to 1/4 full (4 bytes). If I use the debugger to step through my receive ISR, I might get one byte out of the FIFO using the following code before the Rx FIFO Empty flag (RXFE) in UART1_FR is set and the RTIM flag is not set (indicating that the FIFO really is empty). Shouldn't I at least be able to get four bytes out since my ISR doesn't go off until the FIFO has received four bytes?

Here's the code I use to receive data in my UART ISR:

Code:

if (UART_GetITStatus(UART1, UART_IT_Receive) == SET) { <BR> while(UART_GetFlagStatus(UART1, UART_FLAG_RxFIFOEmpty) != SET){ <BR> ByteRx = UART1->DR; <BR> SendToQueue(ByteRx); <BR> } <BR> UART_ClearITPendingBit(UART1, UART_IT_Receive); <BR>}

I can step through the while loop and receive one byte and then there's nothing left.

What am I doing wrong?

[ This message was edited by: SJackson on 14-11-2008 21:17 ]

mark9
Associate II
Posted on May 17, 2011 at 09:56

Try getting rid of the first if() statement and just let the while loop drain. You could check both the Receive flag and the Receive Timeout flag if you wanted to be pedantic, but otherwise there is no reason to use the if() statement since the conditional check of the RxFIFOEmpty is good enough.

btw, I suggest not using the STR91X library in interrupt routines. They are written horribly inefficiently. Just access the registers directly.

sjackson
Associate II
Posted on May 17, 2011 at 09:56

lakata:

I tried out your suggestions, but came up with the same result: the UART seems to receive as many bytes as the FIFO interrupt level is set to (or one if I'm single stepping through the code in debug mode), and then quits.

If I don't use the FIFOs, things seem to go OK for awhile, then the UART starts dropping bytes seemingly at random, and finally refuses to acknowledge any incoming data at all.

I can't predict when any of these failures will happen and have not been able to nail down a certain sequence of events that will cause it to happen.

mark9
Associate II
Posted on May 17, 2011 at 09:56

Are you sure you are setting the RTIM (aka UART_IT_ReceiveTimeOut) interrupt enable?

UART_ITConfig(UART0,UART_IT_Receive|UART_IT_ReceiveTimeOut|UART_IT_Transmit, ENABLE);