This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Flushing UART_read()

I'm using the UART_read() function in blocking mode, looking for the 1st two header bytes of a packet to uniquely identify that packet.

Based on the header test, I'll know how many more bytes to look for, in the case below it would be 6 more. This scheme works well, when only good, known packets come in, but I'm having a hard time dealing with garbage using the blocking mode, I cannot predict whether the byte stream will have as many or as few as the 2 or the 6 in the example below.

So I thought I could "flush" the uart stream of the garbage in a while loop reading 1 byte at a time until "num_char" returned 0, but that never happens.

num_char=UART_read(uart, &input[i++], 2); //parse 1st 2 bytes
if((input[i-1]==0x21)&&(input[i]==0x04)) //test for 0x21, 0x04
{
i++;
num_char=UART_read(uart, &input[i++],6); //get six more bytes
if(!Parse_IF1AM1(0))
ifam1_cnt++;
i=0;
data_ok=1;
}

  • Hi Saycoda,

    By definition, the blocking function will not return until the buffer is full (or an error occurs). That means that you cannot wait until 0 characters are returned since the read operations blocks.

    There are a few solutions that can be used to handle your issue:

    1. You can use the non-blocking mode with callbacks. (you would also need to use a timer function to cancel the read so you don't wait too much time before handling the bytes)
    2. Use the readTimeout configuration to return after a certain time.
    3. You can read one character at a time. Then, you analyze the bytes as they are read (you can either store each character in a buffer to analyze them all or you can have a state machine that controls which state you are in)

    All solutions will work. In my opinion, the first method is cleaner but you need to understand how to use timers and callbacks. The second will probably be the quickest fix for you. But you need the cases when you haven't received the "correct" number of data and when the data is wrong.

    Regards,

    Michel

  • I was looking around the UART drivers and found this additional information

    You can get the UART driver to return after a 32-bit period of serial bus inactivity by calling UARTCC26XX_control(hUart, UARTCC26XX_RETURN_PARTIAL_ENABLE, NULL);

    If the clock is running at 48MHz, it would return after about 89 seconds. This can be used with callbacks as well.
  • Are there examples of using Non-Blocking with Callbacks for the UART driver?

    Thanks 

  • After more thinking, I think the easiest way would probably be to use continuous reading but only one character at a time.
    The basic idea is to configure your UART in CALLBACK mode.

    // Initialization (this is the RX portion only)
    uartParams.readMode =        UART_MODE_CALLBACK;
    // Place your callback function below
    uartParams.readCallback =    SerialCallback;
    
    uartHandle = UART_open(0, &uartParams);
    
    // Start reading and wait for a single character
    UART_read(uartHandle, (void*) rxBuffer, 1);
    
    
    
    // Calback function
    Void SerialCallback(UART_Handle handle, void *rxBuf, size_t size)
    {
      size_t i;
       
      for (i = 0; i < size; i++)
      {
        // Store or handle your character here
      }
       
      // Prepare next read
      UART_read(mUartHandle, (void*) rxBuf, 1);
    }
    

    You can find good documentation about the API calls and it also includes an additional examples with continuous reading (when you look at device specific header files) here <TIRTOS_INSTALL_DIR>/docs/doxygen/html/index.html

    EDIT:

    Don't forget that you can search the forums and I'm sure other people have asked similar questions which could help you.

    Michel

  • There was a suggested answer and since there has been no active on this thread for more than a week, the suggested answer was marked as verify. Please feel free to select the "Reject Answer" button and reply with more details.