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.

cc1310: Uart lost data or stuck after several minutes while receiving data

Other Parts Discussed in Thread: CC1310

Is there anybody occurs such a problem: the uart will lost data or stuck after several minutes while receiving data?
I just made such a test: I transmit 200 data to the CC1310 UART through USB serial port every 1s; then  I made a timer to triggle the monitor,which would detect whether the uart recevied data, if received, then printf the data length. Then I found that the uart would miss some data after several minutes, and take one or two more minutes, the uart would stuck and the system died.

The following is from my code:

#define UART_TASK_STACK_SIZE 1500
#define UART_TASK_PRIORITY   2
void UartTask_init(void) {

   UartFifo_init(&Uart_ReceiveFiFo);
    /* Create event used internally for state changes */
    Event_Params eventParam;
    Event_Params_init(&eventParam);
    Event_construct(&uartEvent, &eventParam);
    uartEventHandle = Event_handle(&uartEvent);

    /* Create the node task */
    Task_Params_init(&uartTaskParams);
    uartTaskParams.stackSize = UART_TASK_STACK_SIZE;
    uartTaskParams.priority = UART_TASK_PRIORITY;
    uartTaskParams.stack = &uartTaskStack;
    Task_construct(&uartTask, UartTaskFunction, &uartTaskParams, NULL);

}

// Callback function
void Uart_ReadCallback(UART_Handle handle, void *rxBuf, size_t size)
{
        memcpy(Uart_ReceiveFiFo.Buf, (uint8_t *)rxBuf, size);
        Uart_ReceiveFiFo.In += size;
 UART_read(handle, Uart_RxTempBuf, 1);
}

// Callback function
void Uart_WriteCallback(UART_Handle handle, void *txBuf, size_t size)
{
   // Start another read, with size the same as it was during first call to UART_read()
 UART_read(handle, Uart_RxTempBuf, 1);

}

Void UartTaskFunction(UArg arg0, UArg arg1)
{
 uint8_t tmp_data = 0; /* Create a UART with data processing off. */
 UART_Params uartParams;
 UART_Params_init(&uartParams);
 uartParams.readMode = UART_MODE_CALLBACK;
 uartParams.readCallback = Uart_ReadCallback;
 uartParams.writeCallback = Uart_WriteCallback;
 uartParams.writeMode = UART_MODE_CALLBACK;
 uartParams.writeDataMode = UART_DATA_BINARY;
 uartParams.readDataMode = UART_DATA_BINARY;
 uartParams.readReturnMode = UART_RETURN_FULL;
 uartParams.readEcho = UART_ECHO_OFF;
 uartParams.baudRate = 115200;
 uartHdl = UART_open(Board_UART0, &uartParams);

 if (uartHdl == NULL) {
  System_abort("Error opening the UART");
 }

 UART_read(uartHdl, Uart_RxTempBuf, 1);
     UART_write(uartHdl, "\r\nJust for a test......\r\n", 25);
 /* Loop forever echoing */
 while (1){
 }
}


static void clk0Fxn(UArg arg0)
{
 if(Uart_ReceiveFiFo.In)
 {
  Uart_PrintfStringDigital("\r\n cnt = ", Uart_ReceiveFiFo.In, 10);
  Uart_ReceiveFiFo.In = 0;
 }
}

 

Could you please tell what is going wrong?

  • We have seen similar buffer overrun issues with the UART driver. The next TIRTOS release will implement a Ring Buffer in the UART driver which should fix this. The TIRTOS release with this implemented is scheduled for mid September.

    Regards,
    TC.
  • Overall, it looks like you're reading 1 byte for every callback right? That seems quite inefficient and would require a substantial amount of CC1310 CPU instructions for each byte... I typically use a buffer of 128 bytes or so and manage my own ring buffer or double-buffer of sorts.
  • Also note, one problem with requesting a larger buffer e.g. 128 bytes is that if there is only, say, 33 bytes of data to read within the near-term, the driver may hang until its internal timeout is reached... but on the CC26xx and CC13xx devices, the UART peripheral supports a hardware timeout notification (firing the RX FIFO interrupt if the RX FIFO has data) if 32 bit-widths worth of time has elapsed with no incoming UART data.  You can activate this mode using a "special" UART_control command:

    #include <ti/drivers/uart/UARTCC26XX.h>
    
    ...
    
      UART_control(handle, UARTCC26XX_CMD_RETURN_PARTIAL_ENABLE, NULL);

    Fwiw- I have written code that manages a UART_MODE_CALLBACK chain with UARTCC26XX_CMD_RETURN_PARTIAL_ENABLE that accepts and processes GPS NMEA data sent once/second at 9600bps with no noticeable drops for 30+ minutes.  Although I have yet to try it at 115200, so take that with a grain of salt.

  • Thank you Eric! I am so glad that it seems work well when I try to do what you advice. : )
  • I am sorry to say that this problem still exist. I doubt tha whether the newest  TI-RTOS release has fixed this problem????

  • Could this be an issue with the timer instead of the UART, i.e. timer is triggering too early or too late? Can you add a time stamp to the print? Can you also attached the c file to the post.

    Also please look at Eric's post:

    "Overall, it looks like you're reading 1 byte for every callback right? That seems quite inefficient and would require a substantial amount of CC1310 CPU instructions for each byte... I typically use a buffer of 128 bytes or so and manage my own ring buffer or double-buffer of sorts."

    There is no HW handshaking implemented, so if the CPU is too slow then there can be data lost. Try reading a buffer of data instead of 1 char.

    Regards, TC.
  • Yes, I changed my configuration according to Eric's post and now I can read all the data from Uart but a new strange problem occurs: I can't send all the data through Uart_write and partial of them lost!! I am really confused. My code is list in annother post:
    e2e.ti.com/.../545027
    I don't know how to do with it.