Knowing when UART FIFO is full

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

in the discussion Re: Peripheral UART: To FIFO, or not to FIFO it is mentioned that the function puart_write will never overflow the FIFO and it always checks to see if the FIFO full before writing

However, the question is : What happens when FIFO is full ?? form my observations puart_write will silently drop the characters and return (it does not block). so how to tell when this is the case and my characters was not in fact written into the FIFO ? the function returns void so there is no status to check ?

same question in different wording : is there any way to tell when FIFO is full ?

Thanks !

1 Solution
Anonymous
Not applicable

it seems that on-ROM UART routines check for P_UART_TX_FIFO_IS_EMPTY(), however this value is always 0x8. I'm assuming a hardware issue.

to get any meaningful info about FIFO status you have to rely on the interrupt status P_UART_INT_STATUS, but be careful that application-level interrupts routines are serialized and NOT executed in time. this makes the TX FIFO empty intruppt pretty useless. so the interrupt routine is useless *but* the interrupt status flag still conveys correct information.

so, my recommendation is to enable TX FIFO empty interrupt, ignore the routine (just leave it empty) and poll for status in your application code. just be careful not to trip the watchdog timer.

here is my code :

// enable TX done interrupt
P_UART_WATER_MARK_TX_LEVEL(0);
P_UART_INT_ENABLE |= P_UART_ISR_TX_FAE_MASK;

while(*data != '\0')
{
    P_UART_INT_CLEAR(P_UART_ISR_TX_FAE_MASK);
    while((P_UART_INT_STATUS & P_UART_ISR_TX_FAE_MASK) != P_UART_ISR_TX_FAE_MASK);

    uint32_t count = 1;
    while((*data != '\0') && (count <= 15))
    {
        P_UART_TX_FIFO(*data);
        count++;
        data++;
    }
}

P_UART_INT_ENABLE &= ~P_UART_ISR_TX_FAE_MASK;

View solution in original post

8 Replies
MichaelF_56
Moderator
Moderator
Moderator
250 sign-ins 25 comments on blog 10 comments on blog

Go here: WICED Smart User's Guide

And take a look at the thread called UART Routines

This one describes in detail the behavior of the Tx side of the PUART and even provides some code examples to monitor/manage the interface.

The first link above also contains alot of other helpful material on the PUART, including pointers for issues such as missing bytes on the Rx side as well (often caused by the part going into sleep): Peripheral UART missing bytes

Anonymous
Not applicable

Hello mwf_mmfae

The threads and links you sent does not provide the answer I'm seeking, maybe I'm missing it ? can you be a little more specific ?

again, I'm asking what happens when FIFO is full at the routines paurt_write ? according to Re: Peripheral UART: To FIFO, or not to FIFO it never overflows the FIFO, so something must be happening, right ?

0 Likes

Those functions are synchronous calls. They will not overflow the HW FIFO, but if the data you are trying to send is long enough and/or the UART baud rate is slow enough, you will watch dog eventually.

0 Likes
Anonymous
Not applicable

arvinds

First, by "those functions" I'm assuming you are referring to puart_synchronousWrite

You say puart_synchronousWrite will not overflow the FIFO, then what will happen when it is called with a mesage longer than the FIFO ?

Normally we have 2 options :

* ignore the extra bytes (and ideally return an error code with actual written bytes, overflow error, ...)

* block until the buffer is empty enough.

from the word "synchronous" in the function name and your note about tripping the watch dog timer I'm guessing you think the second behavior is correct.

however, try to run this simple call :

puart_synchronousWrite("a buffer that is longer than 16 bytes\n\r", 39);

using baud 9600 it gives the following output on the terminal

a buffer that i

Please give me background on how his function works, or any other function that gives reliable and consistent info regarding the UART FIFO

0 Likes
Anonymous
Not applicable

Hi sheref.younan

1. synchronousWrite will drop characters if you start overflowing

2. puart_Write will wait till FIFO is empty

3. If you wait long enough then you will watchdog. 

Hope this helps,

Kevin

0 Likes
Anonymous
Not applicable

all the following 3 code snippets drop UART characters

// First code snippet : using puart_synchronousWrite

puart_synchronousWrite("a buffer that is longer than 16 bytes\n\r", 39);

// Second code snippet : using puart_print

puart_print("a buffer that is longer than 16 bytes\n\r");

// Third code snippet : using puart_write

uint8_t* data = "a buffer that is longer than 16 bytes\n\r";

while(*data != '\0')

{

     puart_write(*data);

     data++;

}

0 Likes
Anonymous
Not applicable

But to see the effect of dropping UART characters you need to set baud to 9600, higher bauds drain the FIFO too quickly and you notice no issues.

0 Likes
Anonymous
Not applicable

it seems that on-ROM UART routines check for P_UART_TX_FIFO_IS_EMPTY(), however this value is always 0x8. I'm assuming a hardware issue.

to get any meaningful info about FIFO status you have to rely on the interrupt status P_UART_INT_STATUS, but be careful that application-level interrupts routines are serialized and NOT executed in time. this makes the TX FIFO empty intruppt pretty useless. so the interrupt routine is useless *but* the interrupt status flag still conveys correct information.

so, my recommendation is to enable TX FIFO empty interrupt, ignore the routine (just leave it empty) and poll for status in your application code. just be careful not to trip the watchdog timer.

here is my code :

// enable TX done interrupt
P_UART_WATER_MARK_TX_LEVEL(0);
P_UART_INT_ENABLE |= P_UART_ISR_TX_FAE_MASK;

while(*data != '\0')
{
    P_UART_INT_CLEAR(P_UART_ISR_TX_FAE_MASK);
    while((P_UART_INT_STATUS & P_UART_ISR_TX_FAE_MASK) != P_UART_ISR_TX_FAE_MASK);

    uint32_t count = 1;
    while((*data != '\0') && (count <= 15))
    {
        P_UART_TX_FIFO(*data);
        count++;
        data++;
    }
}

P_UART_INT_ENABLE &= ~P_UART_ISR_TX_FAE_MASK;