Question about reading of PUART FIFO buffer on CYW20719

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

cross mob
DmDo_4696101
Level 1
Level 1

Hi all.

In my project, I have to read incoming data from the PUART buffer as fast as possible.

As far as I understand, reading data byte by byte using wiced_hal_puart_read() is not a fastes way.

In the PUART API, I found a wiced_hal_puart_synchronous_read() function that reads a set of bytes from a FIFO buffer.

This function needs a "length" parameter that determines how many bytes I would like to read.

But how can I know how many bytes were received into the FIFO buffer or alternatively FIFO is full? (according to the datasheet the chip has a FIFO buffer of 256 bytes). I only found the wiced_hal_puart_rx_fifo_not_empty() function, but it indicates to any existing data in the buffer, but how much I can read I still don't know.

Thank you.

0 Likes
1 Solution
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

The "length" parameter of wiced_hal_puart_synchronous_read() should be filled with the length you desired to read, not the actual length the FIFO buffer currently saved.

wiced_hal_puart_synchronous_read() will firstly recognize how many bytes you are going to read. Secondly it will try to copy the exact number of bytes from the FIFO buffer, which makes two possible situations for itself:

  1. The buffered FIFO length >= the length you specify.
    This is the easiest situation to go. It will copy the exact number of bytes to the destination and return immediately.
  2. The buffered FIFO length < the length you specify.
    In this situation, It copies as much as possible content from FIFO at first. Then it shall suspend the execution and wait until enough new bytes has arrived because it's an synchronous function. Before you get enough bytes from the FIFO, your program (the actual thread running this function) will stall in this function call.

Now you could see the differences between wiced_hal_puart_synchronous_read() and wiced_hal_puart_read(). Differ from the former, the latter is a asynchronous function which won't block your execution. When the latter can't get the desired byte, it will return with an error code immediately and move on. So it's hard to say the latter is slower than the former due to multiple factors should be taken in consideration, though it just reads one byte at a time.

Usually it's recommended to read from PUART as the code example demonstrates with interrupt callback:

void puart_rx_interrupt_callback(void* unused)

{

    /* There can be at most 16 bytes in the HW FIFO.*/

    uint8_t  readbyte=0;

    if (TRUE == wiced_hal_puart_read( &readbyte ))

    {

        /* send one byte via the TX line. */

        wiced_hal_puart_write( readbyte+1 );

    }

    else

    {

        WICED_BT_TRACE("PUART read failed!!\n\r");

    }

    wiced_hal_puart_reset_puart_interrupt( );

}

Using interrupt callback to read from PUART makes the code handy and achieve good RX speed also.

Best regards

View solution in original post

2 Replies
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

The "length" parameter of wiced_hal_puart_synchronous_read() should be filled with the length you desired to read, not the actual length the FIFO buffer currently saved.

wiced_hal_puart_synchronous_read() will firstly recognize how many bytes you are going to read. Secondly it will try to copy the exact number of bytes from the FIFO buffer, which makes two possible situations for itself:

  1. The buffered FIFO length >= the length you specify.
    This is the easiest situation to go. It will copy the exact number of bytes to the destination and return immediately.
  2. The buffered FIFO length < the length you specify.
    In this situation, It copies as much as possible content from FIFO at first. Then it shall suspend the execution and wait until enough new bytes has arrived because it's an synchronous function. Before you get enough bytes from the FIFO, your program (the actual thread running this function) will stall in this function call.

Now you could see the differences between wiced_hal_puart_synchronous_read() and wiced_hal_puart_read(). Differ from the former, the latter is a asynchronous function which won't block your execution. When the latter can't get the desired byte, it will return with an error code immediately and move on. So it's hard to say the latter is slower than the former due to multiple factors should be taken in consideration, though it just reads one byte at a time.

Usually it's recommended to read from PUART as the code example demonstrates with interrupt callback:

void puart_rx_interrupt_callback(void* unused)

{

    /* There can be at most 16 bytes in the HW FIFO.*/

    uint8_t  readbyte=0;

    if (TRUE == wiced_hal_puart_read( &readbyte ))

    {

        /* send one byte via the TX line. */

        wiced_hal_puart_write( readbyte+1 );

    }

    else

    {

        WICED_BT_TRACE("PUART read failed!!\n\r");

    }

    wiced_hal_puart_reset_puart_interrupt( );

}

Using interrupt callback to read from PUART makes the code handy and achieve good RX speed also.

Best regards

Hi, thank you for the answer. Now I understand how wiced_hal_puart_synchronous_read() works.

Problem with wiced_hal_puart_read() is  when I use this function in rx_interrupt, the interrupt triggeres slower than the UART data arrives. In this case, the data accumulates in the FIFO buffer and I have to read it in the following way:

void platfrom_puart_rx_intr_callback(void *arg)

{

    uint8_t uart_rdata;

    while(wiced_hal_puart_read(&uart_rdata))

    {

        data_buffer[buffer_pos] = uart_rdata;   

        buffer_pos ++;

    }

    wiced_hal_puart_reset_puart_interrupt();

}

In this case, I get an analog of the function wiced_hal_puart_synchronous_read().

Maybe this is because I use another interrupt (timer) in the project. And this interrupt blocks the receiving of UART data for a while?

0 Likes