SDK2.2: Rx FIFO setup looks weired from test result

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

cross mob
Anonymous
Not applicable

Hi, I have a question about how to setup RX FIFO depth.

From SDK examples, I followed same setup for RX FIFO.for puart in my application see my capture below.

// BEGIN - puart interrupt

    //  The following lines enable interrupt when one (or more) bytes

    //  are received over the peripheral uart interface. This is optional.

    //  In the absense of this, the app is expected to poll the peripheral

    //  uart to pull out received bytes.

    // clear interrupt

    P_UART_INT_CLEAR(P_UART_ISR_RX_AFF_MASK);

    // set watermark to 1 byte - will interrupt on every byte received.

    P_UART_WATER_MARK_RX_LEVEL(1);

    // enable UART interrupt in the Main Interrupt Controller and RX Almost Full in the UART

    // Interrupt Controller

    P_UART_INT_ENABLE |= P_UART_ISR_RX_AFF_MASK;

    // Set callback function to app callback function.

    //puart_rxCb = puart_control_rx_callback;

    puart_rxCb = PUartRxCallback;

    // also register a listener from the caller if callback is valid

    if (callback)

      onReceiveCB = callback;

    // Enable the CPU level interrupt

    puart_enableInterrupt();

From the above logics, the RX will be interrupted per byte received, which is correct behavior,but upon Rx interrupt callback, I observed  in every case in my application, 1st interrupt callback found fifo is empty after 1 byte is received, and then the subsequent interrupt callback can fetch all characters in one pass until Rx FIFO is empty.

This looks to me strange, why not simply fetch all bytes until RX FIFO is empty in just one interrupt call back call?

To handle this behaviour, I need to save out received bytes to a global rx buffer and keep track for next buffer save location until either the rx buffer is full or upon a delimiter is received to signal response is valid. though with this logic my application can fetch all rx data I needed, but can I do it a simpler way to set the correct RX FIFO so I can do just in one pass to load my global rx buffer instead of segment it into consecutive saving until valid response is met?

See my workaround capture

// Application thread context uart interrupt handler.

// unused - Unused parameter.

void PUartRxCallback(void* unused) {

    // save received characters

    UINT32 number_of_received_bytes;

    char *pBuf;

    BOOL bResp = FALSE;

    if (BleAppConfig.Size < CFG_CMD_BUFSZ)

    {

        // Set receive buffer pointer to next save location

        pBuf = (char *)BleAppConfig.StrBuf + BleAppConfig.Size;

        number_of_received_bytes = PUartReceiveBytes(pBuf, CFG_CMD_BUFSZ-BleAppConfig.Size);

        ble_trace1("PUartRxCallback >> number_of_bytes_read: %d\r\n", number_of_received_bytes);

        ble_tracen((char *)BleAppConfig.StrBuf, number_of_received_bytes);

        if (number_of_received_bytes)

        {

            BleAppConfig.Size += number_of_received_bytes;

            if (BleAppConfig.Size >= CFG_CMD_BUFSZ)

            {

              BleAppConfig.Size = CFG_CMD_BUFSZ;

              bResp = TRUE;

            }

            else

            {

              UINT8 i;

              for (i=0; i<BleAppConfig.Size; i++)

              {

                if (BleAppConfig.StrBuf == '\n')

                {

                  bResp = TRUE;

                  break;

                }

              }

            }

           if (bResp)

           {

             onReceiveCB(BleAppConfig.StrBuf, BleAppConfig.Size);

           }

        }

    }

    else

    {

      // reset receive buffer and size

      BleAppConfig.Size = 0;

      memset(BleAppConfig.StrBuf, 0, sizeof(BleAppConfig.StrBuf));

    }

    // clear the interrupt

    P_UART_INT_CLEAR(P_UART_ISR_RX_AFF_MASK);

    // enable UART interrupt in the Main Interrupt Controller and RX Almost Full in the UART Interrupt Controller

    P_UART_INT_ENABLE |= P_UART_ISR_RX_AFF_MASK;

}

// Attempts to receive data from the peripheral uart.

// buffer - The buffer into which to read bytes.

// length - The number of bytes to read.

// Return The actual number of bytes read.

UINT32 PUartReceiveBytes(UINT8* buffer, UINT32 length) {

    UINT32 number_of_received_bytes = 0;

    // Need to receive at least 1 byte.

    if(!buffer || !length)

        return 0;

    // Try to receive length bytes

    while(length--)

    {

      if(!puart_read(buffer++)) {

        // If the FIFO is empty, break out, no more bytes are available.

        break;

      }

        number_of_received_bytes++;

    }

    // Return the actual number of bytes read.

    return number_of_received_bytes;

}

Any suggestions?

0 Likes
1 Solution
Anonymous
Not applicable

alexleung0316

Your workaround looks right.  You will get interupts, but some will fire early some will fire later.  The only work around is when you get the interupt look at the FIFO, if the FIFO is not empty, pop bytes until empty.

-Kevin

View solution in original post

0 Likes
2 Replies
Anonymous
Not applicable

Trace capture in console window

BleAppConfig.Id: 3

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 - 646220722c6176313033     <<< send packet is correct

16:42:16 - 16:42:16 - PUartRxCallback >> number_of_bytes_read: 1  << first rx cb only get 1 bytes

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 - 33

16:42:16 - 16:42:16 - PUartRxCallback >> number_of_bytes_read: 6 << 2nd rx cb get the remainig 6 bytes

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 - 33302e30300d    <<<< '\n' (0D) is decode and market as bResp TRUE to proceed onUartReceive

16:42:16 - 16:42:16 - onUARTReceive >>>

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 - no_of_chars: 6,  bParsed:1

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 -

16:42:16 - 16:42:16 - 33302e30300d

0 Likes
Anonymous
Not applicable

alexleung0316

Your workaround looks right.  You will get interupts, but some will fire early some will fire later.  The only work around is when you get the interupt look at the FIFO, if the FIFO is not empty, pop bytes until empty.

-Kevin

0 Likes