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 UART RX connect with TX

Other Parts Discussed in Thread: CC2650, SYSBIOS

I use the RF06EB & CC2650. I get the UART function by using the Drivers/UART/UART.c. And I need to connect RX and TX to a half duplex line. But in this case, when I receive data after have sent some data, we received the data sent before. It seems like the RX buffer get the same data when sending some data.

For example, we send five bytes 0x11 0x22 0x33 0x44 0x55, then expect to receive two bytes 0x66 0x77, but we received seven bytes 0x11 0x22 0x33 0x44 0x55 0x66 0x77in fact.


Is there any way to make the RX buffer not to receive data while the TX sending? Or is there a way to clear the RX buffer except by reading all the received data out?

 

  • Hello Kang,
    Could you share the code snippet you use?
    Which project did you use as a starting point?
  • Hello Eirik,

    Thanks for your reply.

    We used the project of HostTest in BLE2.1.

    The code is shown below. We call  function ISO7816_App_CreateTask in the main.

    When we receive two bytes, we expect to receive 0x66 0x77. But we received 0x11 0x22.  For test, we continue to receive five bytes more, we received 0x33 0x44 0x55 0x66 0x77.

    #include <ti/sysbios/knl/Task.h>
    #include "Board.h"
    #include <ti/drivers/UART.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <inc/hw_uart.h>

    #define TASK_STACK_SIZE 512
    #define TASK_PRI        1
    char            iso7816_taskStack[TASK_STACK_SIZE];
    Task_Struct     iso7816_taskStruct;

    unsigned char iso7816_txData[] = {0x11,0x22,0x33,0x44,0x55};
    unsigned char iso7816_rxData[8];

    UART_Params params;
    UART_Handle iso7816_hUART;
    Semaphore_Struct iso7816_sem;
    Semaphore_Handle iso7816_hSem;

    static void uartRxCb(UART_Handle handle, void *buf, size_t count)

      //Wake task to echo
      Semaphore_post(iso7816_hSem);
    }

    void iso7816_taskFxn(UArg a0, UArg a1)
    {

      UART_Params_init(&params); 
     
      params.readMode     = UART_MODE_CALLBACK;
      params.readReturnMode = UART_RETURN_FULL;
      params.writeMode    = UART_MODE_BLOCKING;
      params.readCallback = uartRxCb;
      params.readDataMode = UART_DATA_BINARY;
      params.parityType = UART_PAR_EVEN;
      params.stopBits = UART_STOP_TWO;
      params.readEcho     = UART_ECHO_OFF;
      params.baudRate     = 16129;
     
      Semaphore_Params sParams;
      Semaphore_Params_init(&sParams);
      sParams.mode = Semaphore_Mode_BINARY;
     
      Semaphore_construct(&iso7816_sem, 0, &sParams);
      iso7816_hSem = Semaphore_handle(&iso7816_sem);
      
      iso7816_hUART = UART_open(CC2650_UART0, &params);
     
      UART_read(iso7816_hUART, iso7816_rxData, 3); //receive three bytes.
      Semaphore_pend(iso7816_hSem, 60000);

      //send 0x11,0x22,0x33,0x44,0x55, the other MCU will response 0x66,0x77
      UART_write(iso7816_hUART, iso7816_txData, 5);   

      UART_read(iso7816_hUART, iso7816_rxData, 2); //receive two bytes
      Semaphore_pend(iso7816_hSem, 60000); 

      UART_read(iso7816_hUART, iso7816_rxData, 5);  //Test to receive five bytes more
      Semaphore_pend(iso7816_hSem, 60000);
    }

    void ISO7816_App_CreateTask(void)
    {
      Task_Params params;
      Task_Params_init(&params);
      params.priority = TASK_PRI;
      params.stackSize = TASK_STACK_SIZE;
      params.stack = iso7816_taskStack;
     
      Task_construct(&iso7816_taskStruct, iso7816_taskFxn, &params, NULL); 
    }

  • Hi,

    Have you checked that the data is correct using a logic analyzer?

    I see you are using a strange baud rate (16129 baud per seconds). This is not typically possible to generate exactly using a 48MHz clock and can cause corruption to received data. See the technical reference manual SWCU117 for details on baud rate generation.

    Also, the wait time in your application (60000 = 10 minutes) should ideally be changed to be independent of the tick period in TI RTOS (600 * 1000 / Clock_tickPeriod). You could also just use BIOS_WAIT_FOREVER when testing.

    Regards,
    Svend
  • Hello svendbt,
    I have checked the data using an oscilloscope, and I am sure the data transfor in the I/O line is correct.
    We need the baud rate (16129bps), and our protocol allow some deviation. It seems that the communication is right at present.
    The wait time(60000) is used for test, I think it is a long enough time. While debugging, UART_read() receive data successfully, but not
    the expect ones.
  • Can you provide the plot of Rx/TX lines during the full transaction? What is the baud rate when data is sent between the two devices? Have you ensured you are using common ground between the two boards?

    Regards,
    Svend
  • Hi svendbt,

    There is another test, the transaction is shown in following oscillogams. In this test the other MCU responsed 6E00 instead of 6677.

    The oscillogram 1 shows the full transaction, there are four pieces of data. The data1(0x3B) and the data2(0x10,0x96) is the init data(3 bytes) from the other MCU. Then the CC2650 sends data3(0x11,0x22,0x33,0x44,0x55) to the other MCU. The data4(0x6E,0x00) is the response from the MCU to the CC2650.

    The oscillogram 2 shows the data3 and data4 by zooming in. We can see the baud rate is 16129bps. Also, I'm sure we used common ground.

  • We connect the CC2650 with the other MCU as follow.


    When the TX was sending data, it seems that the RX FIFO buffer received them at the same time.

  • Hi Kang,

    The fact that you are shorting RX and TX would be a good idea to explain in the original post.

    When you do this the TX from CC2650 will drive the line high when it is not transmitting so when the MCU tries to send data you will have very high current draw and the devices can potentially reset due to this or you can get corrupted data. You might get around this by using open-drain IO mode on both sides with a pull-up externally the way a I2C bus works.

    The issue you are seeing is expected behavior. From the "Power management" chapter in the UART driver documentation:

    After a successful UART_read(): The device is allowed to enter standby, but RX remains on.

    • Note: Device might enter standby while a byte is being received if UART_read() is not called again after a successful read. This could result in corrupt data being received.
    • Note: Application thread should typically either issue another read after UART_read() completes successfully, or call UART_readCancel() to disable RX and thus assuring that no data is received while entering standby.


    Documentation for this can be found here: C:/ti/tirtos_simplelink_2_13_00_06/docs/doxygen/html/_u_a_r_t_c_c26_x_x_8h.html

    Regards,
    Svend

  • Hi svend,

    Thank you. I see.

    We have tried to call UART_readCancel() before UART_write(), but the issue remains. It looks that the UART_readCancel() was failed to stop the RX FIFO receiving data.
    Now, we deal with the issue by reading all the data in the RX FIFO after UART_write() at once. But this will add a bit of delay time between UART_write() and
    UART_read(). Is there a way to clear the RX FIFO quickly? Maybe by modifying the register?

    There is another question, you said there will be very high current draw when the MCU tries to send data. Is it useful if we only set the mode of TX to PIN_OPENDRAIN when the TX is not transmitting?

  • Hello Kang,

    This seems due to a known bug in the current driver which will be fixed for the TI RTOS version being released next week.

    If UART_read reads in the number of bytes you expect it to, readCancel will simply return and the UART will keep RX enabled.
    There will be an API to clear the RX FIFO also in this new driver version.

    Both sides need to set their output as open drain (or disable the output) when not transmitting to avoid high current draw. If you have good control of timing on both sides this might work fine, otherwise you might need to always keep the TX in open drain.

    Regards,
    Svend

  • Hi Svend,

    Ok, I understand.

    Thank you very much!