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.

UART Read callback does not get called.

Other Parts Discussed in Thread: CC2650, CC2640

Hi everybody

I konw that there are already some threads about this problem. Unfortunately none of these answers the question. I try to setup a UART communication from a CC2650/SmartRF06EB running a modified SimpleBLECentral Bluetooth low energy exampe project to my Windows PC. Writing data from the CC2650 to the PC (I use HyperTerminal) works fine. Unfortunately I am not able to transmit any data from the PC to the CC2650 because the read callback function never gets called. Here some of my code:

bool InitUART()
{
    UART_Params_init(&uartParams);
    uartParams.baudRate  = UART_BAUD_RATE;
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.writeMode = UART_MODE_BLOCKING;
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_NEWLINE;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.readTimeout = UART_WAIT_FOREVER;
    uartParams.readCallback = UartReadCallback;

    uartHandle = UART_open(CC2650_UART0, &uartParams);

    if (!uartHandle)
    {
      return false;
    }

    int ret = UART_read(uartHandle, uartRxBuf, 2); //read 2 bytes

    if (ret == UART_ERROR)
    {
      return false;
    }

    return true;
}

static void SimpleBLECentral_init(void)
{
  uint8_t i;
     
  // Setup discovery delay as a one-shot timer
  Util_constructClock(&startDiscClock, SimpleBLECentral_startDiscHandler, DEFAULT_SVC_DISCOVERY_DELAY, 0, false, 0);
 
  Board_initKeys(SimpleBLECentral_keyChangeHandler);
 
  Board_openLCD();
 
  ledPinHandle = PIN_open(&ledPinState, pLedPinTable);

  // Initialize UART
  bool initUARTSuccess = InitUART();

  if (!initUARTSuccess)
  {
      LCD_WRITE_STRING_VALUE("UART open failed: ", (uint32_t)uartHandle, 10, LCD_PAGE3);
  }
  else
  {
      LCD_WRITE_STRING("UART open success", LCD_PAGE3);
  }

  ...

void UartReadCallback(UART_Handle handle, void *rxBuf, size_t size) // Gets never called.
{
    LCD_WRITE_STRING("UART read CB", LCD_PAGE5);

    if (size <= 0)
    {
        return;
    }

    // Start another read
    UART_read(uartHandle, uartRxBuf, 2);
}

The initialization is successful: "UART open success" get written to the display. But the callback never gets called. If I replace UART_WAIT_FOREVER by a fixed timeout (e.g. 100) the callback function also never gets called.

Is my procedure correct? I do not use a separate task for the UART communication. Is that ok?

I also do not want to implement any complicated memory-hungry network layer as described here:

  • The UART read callback function should be brief to not disrupt thread timing. In your case you want an SPI transfer to the LCD during call back which is better processed through putting it in the RTOS queue. (search for enqueue message in your BLEcentral .c file for a model, and section 3.5.2 of BLE stack).

    Priya
  • What version of TIRTOS are you using?

    Can you tell if the following function "UARTCC26XX_swiIntFxn" is getting called? This is where the readCallback function would get called from.
    Of course, some interrupt needs to trigger an ISR (when your PC tries to write to the 2650) so that this swi function would get called and it would call your callback.

    Judah
  • Thank you for then answer! For the final product, I will for sure replace the direct call of functions inside the callback by a queue or mailbox based system. The LCD_WRITE_STRING call cannot be the probelm, because if I replace it by

    PIN_setOutputValue(ledPinHandle, Board_LED1, 1);

    I do not see LED1 turning on.

  • I use TI RTOS Version 2.16.0.08. This is written in Code composer -> Help -> Installation details.

    In the SimpleBLEPeripheral example project, I click in the project explorer in CCS on Drivers -> UART -> UARTCC26XX.c and open th file. In this file there are many functions (e.g. writeFinishedDoCallback, UARTCC26XX_hwiIntFxn , UARTCC26XX_init, ...) but there is no function called UARTCC26XX_swiIntFxn. But if I navigate with windows explorer to C:\ti\tirtos_cc13xx_cc26xx_2_16_00_08\products\tidrivers_cc13xx_cc26xx_2_16_00_08\packages\ti\drivers\uart and open the file UARTCC26XX.c, in this file I find a function called UARTCC26XX_swiIntFxn.

    Is it possible that there is a problem with the versions of these files or that these files are auto-generated?
  • Fabien,

    I was told in the Bluetooth forum to keep the extent of program execution in the callback function to a minimum. I am assuming any processing on the callback takes time, UART read, pin driver action etc. I'm sure the RTOS experts can clarify this for you.

    Priya

  • Definitely sounds like some sort of mismatch here. Is your project pointing to 2_16_00_08?
  • If I right clikc on the file UARTCC26XX.c in my project and look at the resolved path it is

    C:\ti\tirtos_simplelink_2_13_00_06\packages\ti\drivers\uart\UARTCC26XX.c

    The mentioned SWI function is NOT in this file.

    But it is in the file

    C:\ti\tirtos_cc13xx_cc26xx_2_16_00_08\products\tidrivers_cc13xx_cc26xx_2_16_00_08\packages\ti\drivers\uart

    So it seems that for simplelink the UART driver works a little different. Probably it is not a SWI but I need a semaphore inj an additional task?

    My project is based on the SimpleBLECentral example. I did not modify and include paths.

  • I soved the Problem: My UART terminal sends the typed text when I press ENTER, but a "\n" is not sent. So the configuration with uartParams.readReturnMode = UART_RETURN_NEWLINE; is working now. Nice!

  • Reading and writing is working "more or less" now. I would like to have it more reliable. How am I supposed to use the UART driver to do parallel read and write? For me this is not clear from this description:
    C:/ti/tirtos_simplelink_2_13_00_06/docs/doxygen/html/_u_a_r_t_c_c26_x_x_8h.html

    I use UART_read in callback mode and UART_write in blocking mode. But after a single write, I do not get any more read callbacks. I was able to fix this using a timer that performs a new UART_read every 100ms but that is definitely not the way to go. DO you have any advice?
  • Can you start a new thread? You can reference this one in that thread.

    Thanks,
    Todd