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.

CC2640 UART driver

Other Parts Discussed in Thread: CC2640, CC2650

Hi,

Is there a TI example to measure the current draw from the CC2640 UART driver? I am using TI RTOS 2.18.

I ran the UART echo example on the CC2650 7x7 DK and measured the current with a high precision Fluke

meter on the VDD-EM pins with all jumpers removed. I am seeing a current offset of 1 mA on the meter.

My custom application (CC2640 4x4 package, BLE 2.2) uses the UART driver in read callback mode and

the SPI driver with 2 slaves. The application firmware with only the SPI driver achieves the 1uA standby current

draw. The UART activity is monitored for 5000 clock ticks on start up after which the UART driver is closed.

If no UART_read is done during this time, the standby current draw becomes as low as 1 uA. If the UART_read

is present, the application firmware shows a standby current draw offset of 1.5 mA which does not go away

even after the UART driver is closed.

Is there any issue with the UART read that can be tracked down?

Thanks,

Priya

  • Hi Priya,

    Priya Nadathur said:

    Is there a TI example to measure the current draw from the CC2640 UART driver?

    I don't have anything on hand, but let me see if there is something I can send across.

    Priya Nadathur said:

    If no UART_read is done during this time, the standby current draw becomes as low as 1 uA. If the UART_read

    is present, the application firmware shows a standby current draw offset of 1.5 mA which does not go away

    even after the UART driver is closed.

    Please provide more more details on your test case.  What do you mean by no "UART_read is done" (do you mean no data is received or do you remove the API)?

    Are you calling UART_readCancel() before closing the UART driver?  UART_readCancel() must be called before UART_close() if you have a If UART_read() which has not completed.

    Are you receiving data?  Have you verified your callback is being executed correctly?  

    -- Emmanuel

  • Emmanuel,

    Thank you for your reply. Here are details of my test scenario as requested:

    "Are you receiving data?"

    In this test case, there is nothing driving the UART. All GPIOs are defined as outputs and pulled down to low except for the SPI slave chip selects

    "What do you mean by no "UART_read is done" (do you mean no data is received or do you remove the API)?"

    I comment out the UART_read while waiting/checking for UART activity on power up (currently this time is 500000 clock ticks, 5000 clock ticks was also tried).

    "Are you calling UART_readCancel() before closing the UART driver?  UART_readCancel() must be called before UART_close() if you have a If UART_read() which has not completed."

    I added UART_readCancel this morning before closing the UART. If I am using the UART_read API, this is not making a difference.

    "Have you verified your callback is being executed correctly? "

    Yes, this has been verified successfully by some one else in the team with automated scripts. In one test set up I even comment out all parts of the callback routine other than waiting for the UART message. I also ran test set ups using all parts of the callback function. The current draw is not coming down.

    I have pasted sections of the code below.

    Looking forward to your feedback.

    Thanks,

    Priya

    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimpleBLEPeripheral_init();

      waitForUARTMessage();

      // Application main loop
      for (;;)
      {

    .................

     if (pEvt->event_flag & SBP_ADV_CB_EVT)
                {

                   if (!uartClosed) {
                                 if (ticks > 500000 && !talkMode) {
    //                             if (ticks > 5000) {
                                  UART_readCancel(uart);
                                     UART_close(uart);
                                     uartClosed = 1;
                                 }
                   }

    static void UART_enqueueMsg(uint8_t messageLength)
    {
        sbpEvt_t *pMsg;

        // Create dynamic pointer to message.

        if (pMsg = ICall_malloc(sizeof(sbpEvt_t)))
        {
            pMsg->hdr.event = UART_MSG_EVT;
            pMsg->hdr.state = messageLength;

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

    static void UARTCallback(UART_Handle uart, void *byte, size_t size)
    {
        static uint8_t value, i, length = 5;

        value = *((int*)byte);

    #if defined (Debug)
        System_printf("\nvalue= %x\t", value);
    #endif


        uart_rx_buf[i] = value;
        i++;

        // if the very first byte is a x55, set the talk mode flag and send a 1 byte
        // go into talk mode confirmation through UART
        // processingUARTMsg gets set just before entering the message into the RTOS queue.
        if (i == 1 && value != 0x01) {
            if (value == 0x55) {
                talkMode = 1;
                i = 0;
                length = 5;
                processingUARTMsg = 1;
                UART_enqueueMsg(1);
            }
        // if the first byte is not go into talk mode or SOH, re-set i and set message length to 5.
        // what happens when length is 5?
            else if (value != 0x01) {
                i = 0;
                length = 5;
            }
        }
        // Check for valid operation.
        // if message byte is not valid, re-set i and fix length at 5.
        else if (i == 2 && (value < 0x80 || value > 0x8f)) {
            i = 0;
            length = 5;
        }
    // if byte number 5 is 0, there are no following message bytes, send the message to the RTOS queue.
        else if (i == 5) {
            if (value == 0x00) {
                i = 0;
                length = 5;
                processingUARTMsg = 1;
                UART_enqueueMsg(5);
            }
            // determine correct message length for write into SNV
            // however read eeprom message format is different and value of length is in byte 6, not byte 5.
            else {
                length = value + 5;
            }
        }
        else if (i >= length) {
            i = 0;
            length = 5;
            processingUARTMsg = 1;
            UART_enqueueMsg(length);
        }

        waitForUARTMessage();
    }


    static void waitForUARTMessage(void)
    {
        uint8_t byte;

        if (!processingUARTMsg) {
            UART_read(uart, &byte, 1);
        }
    }

    .

  • Hi,

    thanks for reporting this. I guess what you see, is identical to this issue which is currently under investigation and will (hopefully) fixed in the next release.

  • 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.
  • hi Richard,

    any idea on when this issue will be resolved. this is because we are planning to use this part in our new designs. please advice if you know.

    thanks & BR

    pragash

  • Hi,

    in your above code, is there a possibility, that UART_read() is executed within callback context after calling UART_readCancel()? Please note that UART_readCancel() always fires the callback. The length might be 0, but after UART_readCancel(), the callback MUST NOT call UART_read(). Can you ensure that this is the case in your application?

    In the upcoming SDK release, this has been emphasized in the documentation. No functional changes have been made.