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.

RTOS/CC2650: UART_read losing characters not reading full string.

Part Number: CC2650

Tool/software: TI-RTOS

Hi, 

I am trying to implement a simple application where I can receive data on the CC2650 through UART and send it to my phone over BLE. The data in the UART is received at a baud rate of 460800 8N1. 

I am receiving about 75 characters every 500ms through the UART.

A sample of how the data looks like :

*@CKT~ 01 FAULT*ACKT~ 02 DONE*BCKT~ 03 DONE*CCKT~ 04 DONE*:@ FTV4-500-60
*:@State, C*:AState, O*:BState, O*:CState, O*:@ FTV4-500-60
*@ 80.44 V -425.9 A*A 80.44 V -425.9 A*B 80.44 V -425.9 A*C 80.44 V -425.9 A*:@ FTV4-500-60

with a few null characters at random places.

When I send this same data through Realterm serial monitor, I get the entire string, but when I try to read from the actual UART port (data received from another board) I am losing lots of characters. I am also monitoring the actual values received (from the other board) on the UART using another serial terminal so there is no problem in receiving the data, only while reading it.

Here is how I have implemented the read:

void myIdleFunc()
{

    for (;;)
           {
                 
             UART_read(handle, &input, 100);
             UART_write(handle,&input, 100);
             
           }
}

UART_read is in BLOCKING mode with no timeout.

Here myIdleFunc() is a function that runs in the idle task.

The output that I am getting is:

I have also tried UART_echo example as well as several other options using CALLBACK method, changing the buffer size,invoking UART_read in a clock function, UART_read with timeout,etc. All have worse results than this method.

My suspicion is that UART_read stops reading when it hits a NULL value like strlen(). Is this true? If so how can I read past the NULL, how can I change the UART driver to copy past the null value.

Another possible problem might be that '*CCKT~ 04 DONE*:@ FTV4-500-' is right around 32 characters which is the maximum size of the buffer in the UART driver implementation.

Is there any other approach I should try, been stuck on this problem for a really long time.

I'm pretty sure my installation settings are right I've used on several other programs and faced no problems.

Code Composer Studio

Version: 9.0.1.00004

  • Hi Aravindh,

    Have you tried sending data with no null characters?

    Thanks,

    Alexis

  • Hi Alexis,

    I really don't think the null values would be the problem because I'm simulating the same data stream through a serial monitor with several null characters. 

    Moreover I cannot change the data stream I am getting in the UART as it comes from a Coldfire MCU whose firmware I do not have access to.

    And as can be seen in the output the null characters between the words are read. Is there any way to increase the size of the input buffer beyond 32 bytes?

    But I am certain that the data being sent is correct as I verified by directly reading it on a UART to USB cable. 

    So my problem lies in reading the data,:

    I'm receiving 100 characters every 500ms. But the input buffer size is only 32 bytes, so the first 32 characters are read correctly , but when the next UART read is invoked it again reads another 32 characters but not from where it left off last time. So I'm losing characters inbetween reads.

    The solution to this seems to be to increase to the input buffer size beyond 32 or decrease the time taken between consecutive reads.

    I am not sure how to do both, any help would be appreciated.

    Thank you.

  • Hi Aravindh,

    Have you looked at the "Receive Continuously in UART_MODE_CALLBACK" use case? It can be found here:

    <SDK_INSTALL_DIR>/docs/tidrivers/doxygen/html/_u_a_r_t_c_c26_x_x_8h.html

    Thanks,

    Alexis

  • Hey Alexis, 

    I tired all of the implementations n the link that you mentioned.

    But unfortunately none of them work. Would using a ring buffer implementation in UART_read be of any use. I don't completely understand the difference in using the FIFO implementation and the ring buffer implementation.

    Thank you for the help, and quick response,

    Aravindh.

  • Hi,

    Also when the Rx buffer is receiving data, what happens when the data exceeds 32 bytes does it fall off and is it lost or, does it overwrite the buffer from the beginning? Is there a way to switch between these modes?

    Thanks.

  • Hi Aravindh,

    Can you include a code snippet of how you are configuring your UART?

    Thanks,

    Alexis


  • Hey,

    this is inside my main() function.


    int main(){ /* Register Application callback to trap asserts raised in the Stack */ RegisterAssertCback(AssertHandler); PIN_init(BoardGpioInitTable); #ifndef POWER_SAVING /* Set constraints for Standby, powerdown and idle mode */ Power_setConstraint(PowerCC26XX_SB_DISALLOW); Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW); #endif // POWER_SAVING /* Initialize the RTOS Log formatting and output to UART in Idle thread. * Note: Define xdc_runtime_Log_DISABLE_ALL to remove all impact of Log. * Note: NULL as Params gives 115200,8,N,1 and Blocking mode */ UART_init(); char i[5] = "hello"; System_printf("%s\n",i); // System_flush(); Types_FreqHz freq; BIOS_getCpuFreq(&freq); System_printf("hi: %d, lo: %d", freq.hi, freq.lo); System_flush(); uint32_t timeout = 20000; UART_Params params; // // Init UART and specify non-default parameters UART_Params_init(&params); params.baudRate = 460800; // params.writeDataMode = UART_DATA_BINARY; // params.readTimeout = 5000*(1000/Clock_tickPeriod); params.readMode = UART_MODE_CALLBACK; params.readDataMode = UART_DATA_BINARY; // params.readReturnMode = UART_RETURN_FULL; params.readEcho = UART_ECHO_OFF; // params.writeMode = UART_MODE_BLOCKING; // params.writeCallback = UART_writeCB; params.readCallback = readCallback; // params.stopBits = UART_STOP_ONE; // params.parityType = UART_PAR_NONE; // params.dataLength = UART_LEN_8; // params.readTimeout = timeout; handle = UART_open(Board_UART, &params); .. .. .. }
    Thanks,
    Aravindh