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.

CC2650 is holding when Uart Read in call back mode

Other Parts Discussed in Thread: CC2650, CC2640

CC2650 Uart receive Data and UART write (Echo test ) , sometime Chip have holding on.

BLE can not connect and Find it on Holding time.

Do you have any suggestion?

code reference=>

Receive with Return Partial

This use case will read in UART_MODE_BLOCKING until the wanted amount of bytes is received or until a started reception is inactive for a 32-bit period. This UART_read() call can also be used when unknown amount of bytes shall be read. Note: The partial return is also possible in UART_MODE_CALLBACK mode.

* UART_Handle handle;
* UART_Params params;
* uint8_t rxBuf[100]; // Receive buffer
*
* // Init UART and specify non-default parameters
* UART_Params_init(&params);
* params.baudRate = 9600;
*
* // Open the UART and initiate the partial read
* handle = UART_open(Board_UART, &params);
* // Enable RETURN_PARTIAL
* // Begin read
* int rxBytes = UART_read(handle, rxBuf, 100));
* // Callback function
* static void readCallback(UART_Handle handle, void *rxBuf, size_t size)
* {
* // Copy bytes from RX buffer to TX buffer
* for(size_t i = 0; i < size; i++)
* txBuf[i] = ((uint8_t*)rxBuf)[i];
*
* // Echo the bytes received back to transmitter
* UART_write(handle, txBuf, size);
*
* // Start another read, with size the same as it was during first call to
* // UART_read()
* UART_read(handle, rxBuf, wantedRxBytes);
* }
  • Hi,

    It's hard to understand what is going on. Can you share your project setup details (i.e. SimpleBLEPeripheral)
    Also, your screen shot is using 115200 baud, but you are configuring for 9600 in code.

    Can you explain the BLE issues in more detail?

    Also, there is a UART example on the BLE Wiki: http://processors.wiki.ti.com/index.php/CC2640_NPI_UART_ECHO_EXAMPLE

    Best wishes

  • I use SimpleBLEPeripheral project modify

    baud is 115200 8 1 n And  Read use call back mode

    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {

        //(Add+)Abellee 20141118 Add Uart
      #ifdef UART_DEBUG
      UART_Params params;
      // Configure UART parameters.
      UART_Params_init(&params);
      params.baudRate = 115200;
      params.readDataMode = UART_DATA_BINARY;
      params.writeDataMode = UART_DATA_BINARY;
      params.dataLength = UART_LEN_8;
      params.stopBits = UART_STOP_ONE;
      params.readMode = UART_MODE_CALLBACK;
      params.writeMode = UART_MODE_BLOCKING;
      params.readReturnMode = UART_RETURN_FULL;//UART_RETURN_NEWLINE;//UART_RETURN_FULL;
      params.readEcho = UART_ECHO_OFF;
      params.readTimeout = BIOS_WAIT_FOREVER;
      #if (UART_CALL_BACK ==1)
      params.readCallback = Uart_ReadCallback;
      #else
      params.readCallback = NULL;
    #endif
      params.writeCallback = NULL;
      uartHandle = UART_open(Board_UART, &params);
    #endif
      //(Add-)Abellee 20141118 Add Uart

      // Initialize application
      SimpleBLEPeripheral_init();
      #ifdef UART_DEBUG
      print_msg("SimpleBLEPeripheral_init \r\n"); //(Add)Abellee 20141118 Add Uart
      print_msg("Baudrate = %d \r\n",params.baudRate); //(Add)Abellee 20141118 Add Uart
      UART_control(uartHandle, UARTCC26XX_RETURN_PARTIAL_ENABLE, NULL);
      UART_read(uartHandle, Uart_RxBuf, UART_FIFO_FULL_SIZE);
      #endif

    =================

    void Uart_ReadCallback(UART_Handle handle, void *rxBuf, size_t size)
    {
        //UART_writeCancel(uartHandle);
        //UART_readCancel(uartHandle);
        
        // Copy bytes from RX buffer to TX buffer
        for(size_t i = 0; i < size; i++)
        Uart_TxBuf[i] = ((uint8_t*)rxBuf)[i];

        // Echo the bytes received back to transmitter
        UART_write(uartHandle,(const Char *)&Uart_TxBuf, size);
        
        // Start another read, with size the same as it was during first call to
        // UART_read()
        UART_read(uartHandle, rxBuf, UART_FIFO_FULL_SIZE);
    }

    ==================

    I try UART example on the BLE Wiki: http://processors.wiki.ti.com/index.php/CC2640_NPI_UART_ECHO_EXAMPLE

    I try this example in smartRF06 EV board , but I need press Joytick Up key then Uart just put "Hello world" .

    Holding on before Key press.

  • Had the same problem,

    I notice that only UART with call back is working (as seen in the NPI example).

    And if you using UART_write too frequently, the data is corrupted.

    So i build up an UART task with message queue and memory allocation. the call back used to semaphore the task.

    It was the only way i succeed to handle it.

  • Yes , Uart write too freq , the data is corrupted.
    Read data again then system is crash.
    Write data use call back then read after call back .
    this issue is fix.
  • Hello!

    I am now having the same issue. Same code as you expose above! Is know working for you? If its so, Could you please provide the code you used or simply explain step by step how did you solved it?`

    Sincerely,

    Albert
  • Hi albert, i was not working on this project for a while now, and the TI-RTOS has been updated and the BLE stack also updated.

    I recommend to you to update to the latest versions and check out if any thing has been changed.

    If the problem still happen, then the solution is to start a new (ti-rtos) task with message queue.

    Instead of sending uart to the uart function, send them to the queue of that new task.

    then, the task should handle these queue and transmit the uart data when it can.

    the trigger to that task is the new queue insertion or the callback that indicate that uart tx has finish.

    sorry i cant send you code example, it's protected for my client.

  • Hi Netagel!
    thank you for you fast answer. I posposed the project for a while. Now I am working again with CC26xx and UART. I am trying but not getting success. My objective is to communicate some data to the PC over serial port. for example: when connected send a serial port notification "connected". The PC should be able to ask for some data over serial port as well. Could you check out if I am in the right direction.

    Sincerely,
    Albert


    // Queue object used for UART messages
    static Queue_Struct appUARTMsg;
    static Queue_Handle appUARTMsgQueue;



    void Uart_createTask(void)
    {

    Task_Params params;
    Task_Params_init(&params);
    params.priority = 1;
    params.stackSize = TASK_STACK_SIZE1;
    params.stack = taskStack1;

    Task_construct(&taskStruct1, taskFxn1, &params, NULL);
    }


    static void taskFxn1(UArg a0, UArg a1)
    {

    // Init UART and specify non-default parameters
    UART_Params_init(&params);
    params.baudRate = 115200;
    params.writeDataMode = UART_DATA_TEXT;
    params.readMode = UART_MODE_CALLBACK;
    params.writeMode = UART_MODE_CALLBACK;
    params.readDataMode = UART_DATA_BINARY;
    params.writeCallback = writeCallback;

    params.readCallback = readCallback;

    // Open the UART and initiate the first read
    handle_uart = UART_open(Board_UART, &params);
    wantedRxBytes = 1;
    //int rxBytes = UART_read(handle_uart, rxBuf, wantedRxBytes);

    while(true)
    {
    if (!Queue_empty(appUARTMsgQueue))
    {
    queueRec_t *pRec = Queue_head(appUARTMsgQueue);
    sbpUARTEvt_t *pMsg = (sbpUARTEvt_t *)pRec->pData;

    UART_write(handle_uart, pMsg, sizeof(pMsg));
    ICall_free(pMsg);
    }

    } // Wait forever
    }



    static void writeCallback(UART_Handle handle_uart, void *rxBuf, size_t size)
    {
    SPPBLEServer_enqueueUARTMsg(SBC_UART_CHANGE_EVT,rxBuf,size);
    }


    void SPPBLEServer_enqueueUARTMsg(uint8_t event, uint8_t *data, uint8_t len)
    {
    sbpUARTEvt_t *pMsg;
    // Create dynamic pointer to message.
    if (pMsg = ICall_malloc(sizeof(sbpUARTEvt_t)))
    {
    pMsg->event = event;
    memcpy(pMsg->data , data, len);
    pMsg->length = len;

    // Enqueue the message.
    Util_enqueueMsg(appUARTMsgQueue, sem, (uint8*)pMsg);
    }
    }