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.

Compiler/LAUNCHXL-CC1310: Collector not entering uart_read_callback function

Part Number: LAUNCHXL-CC1310

Tool/software: TI C/C++ Compiler

Hey guys,

I use sensor/collector example (newest SDK) and I am trying to make the collector read a cmd via UART. Note, that I was able to make the uartecho example work fine, also with callback mode.

I use my PC to write a cmd like "1\r\n" via UART to the launchpad which is connected via USB. I do then cause a HWI, which sets a collector event. In the collector event, I do the following:

    /* Perfom a HWI triggered factory reset */
    if(Collector_events & COLLECTOR_HWI_FACTORY_RESET)
    {
        if(allow_hwi_factoryReset)
        {
            UART_read(hUart, &rx_input, 1);
        }
        /* Clear the event */
        Util_clearEvent(&Collector_events, COLLECTOR_HWI_FACTORY_RESET);
    }

In the callback function I parse the message and I force the system to read until \n is found:

void readCmdCallback(UART_Handle handle, void *buffer, size_t size)
{
    uint8_t index = 0;
    uint16_t cmd = 0;
    bool EOL_found;
    uint8_t buffer_length = 8;
    char tx_output[buffer_length];

    if (rx_input == '\n')
    {
        EOL_found = true;
        tx_output[index] = '\n';
        //UART_write(hUart, &tx_output, index++);
        index = 0;

        /* convert msg into integer cmd */
        cmd = UARTmsgToInt(tx_output);
        /* execute the cmd */
        executeUartCmd(cmd);

        /* reset tx_output buffer */
        for (uint8_t i = 0; i < buffer_length; i++)
        {
            tx_output[i]= 0;
        }
    }
    else if(rx_input == '\r')
    {
        tx_output[index] = '\r';
        index++;
        EOL_found = false;
    }
    else
    {
        tx_output[index] = rx_input;
        index++;
        EOL_found = false;
    }
    
    if (EOL_found)
    {
        /* read until end of line has been found */
        UART_read(hUart, &rx_input, 1);
    }
}

I rebuild the message and then do some other stuff with it. However, I never enter the callback function. Here are my UART settings in main.c

    uartParams.baudRate = 115200;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.readCallback = readCmdCallback;
    uartParams.readEcho = UART_ECHO_OFF;
  1. Any idea why the system is not entering the callback function? Do you think, that the uart buffer is somehow erased and when UART_read is called in the collector event, there are no bytes to read?!
  2. Is using UART_read within the callback function a proper way, to make sure all bytes are read? (I dont know the actual length of the message.

Any advice is welcome

  • EDIT:

    What do you think of this approach?

            if(allow_hwi_factoryReset)
            {
                System_printf("HWI_Event\r\n");
                while (i < 2000)
                {
                    UART_read(hUart, &rx_input, 1);
                    Task_sleep(100); // 100 ticks = 1ms
                }
    
            }

    My idea is to call UART_read 2000 times, to make sure it checks the UART line often and long enough when the transmitter is a little off schedule. This code is executed on the collector side, I am not sure if blocking the task is an elegant way to do what I am trying (calling UART_read 2000 times within 2s) and I am not sure if the MAC layer is part of the main task and I would be blocking the whole system using Task_sleep?

  • Hi,

    What level of debugging have you performed? Do you get a valid UART handle when you call UART_open?
    By default, the collector uses one of the UART peripherals for printing out application messages on a serial terminal.

    The MAC task runs separately from the application task, so your use of Task_sleep should only affect the application layer (ie the application task will not do anything else but sleep and read UART for those 2 seconds).

    Regards,
    Toby

  • Hey Tobi,

    I actually use breakpoints to verify if the code goes into the callback function. I made some changes. Now I am calling a new function called check_UART.

    bool check_UART(void)
    {
        bool ret = false;
        ret = UART_read(hUart, &rx_input, 1);
        UART_write(hUart, &rx_input, 1);
    
        return(ret);
    }
    
    
    /* Reads a cmd-char from UART and converts it into an integer*/
    void readCmdCallback(UART_Handle handle, void *buffer, size_t size)
    {
        uint8_t index = 0;
        uint16_t cmd = 0;
        bool EOL_found;
        uint8_t buffer_length = 8;
        char tx_output[buffer_length];
        UART_write(hUart, &rx_input, 1);
    
        if (rx_input == '\n')
        {
            EOL_found = true;
            tx_output[index] = '\n';
    
            index = 0;
    
            /* convert msg into integer cmd */
            cmd = UARTmsgToInt(tx_output);
            /* execute the cmd */
            executeUartCmd(cmd);
    
            /* reset tx_output buffer */
            for (uint8_t i = 0; i < buffer_length; i++)
            {
                tx_output[i]= 0;
            }
        }
        else if(rx_input == '\r')
        {
            tx_output[index] = '\r';
            index++;
            EOL_found = false;
        }
        else
        {
            tx_output[index] = rx_input;
            index++;
            EOL_found = false;
        }
    
        if (EOL_found)
        {
            /* read until end of line has been found */
            UART_read(hUart, &rx_input, 1);
        }
    }

    As you can see, I also use UART_write to echo rx_input, however, nothing arrives.

    I know that the handle has to be correct, because I use System_printf(), which on a lower level uses the same UART handle. But regarding my breakpoints, look at them.

    For some reason the breakpoints seem not to work, but I dont know why. I tried on different positions in the code but it doesnt work anywhere. However, in another project file, the breakpoints work and are not crossed out.

  • If the UART handle is valid, then I don't immediately see why the callback is not being invoked.

    For the breakpoints issue, you may need to disable build optimization. Right-click project --> Properties:

     Also, please have a look at the zstack examples from the  CC13x2/CC26x2 SDK, which have a UI that involves both reading characters and printing through the UART. It seems to have functionality that matches your needs.

  • For no reason I understand without further ado the breakpoints were working again...however, when I write 5 times "1\r\n" from my pc to the USB port and then trigger 5 times UART_read function the status of UART_read is 0 for the first time and then 4 times -1. Digging down the UART_read function I could see that there are two possible error reasons for the return value to be -1. A not opened uart handle or the uart port is busy.

        if (!object->opened) {
            DebugP_log1("UART:(%p) not opened.", hwAttrs->baseAddr);
            return (UART_ERROR);
        }
    
        if (object->readSize) {
            /* Previous read is not done, return */
            DebugP_log1("UART:(%p) Could not read data, uart in use.",
                 ((UARTCC26XX_HWAttrsV2 const *)(handle->hwAttrs))->baseAddr);
    
            return (UART_ERROR);
        }

    Can you tell me where to find this DebugP_log1 ??

    I dont understand why no byte is read at all and thus no callback is triggered. I have all uart settings in main.c and all other uart functions in uartprint.c and only the callback function is defined as external function in uartprint.h. Remember I use the TI 15.4 stack collector example.

    I will also have a look at the zstack example since I also use the cc1352R1 I already have the sdk. Although I was able to adapt the uartecho example to my needs so that callback worked, I am not able to implement it into the collector example...

  • I was able to use the UART read callback mode in the collector example without any issues. After typing a character into Putty, the UART read callback triggered as expected.

    Can you try Putty as your serial terminal program? Can you try a simpler version of the program?

    Regarding DebugP_log1: https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/649181

    Also, please note that variables declared in your callback readCmdCallback will not retain their value after the callback function completes. This could cause you problems; if you need them to retain their values, try adding the static specifier (eg static uint8_t index;).

  • Hey Toby,

    I've been trying various stuff and I've also symplified my application however no luck...

    Then I was about to discuss some stuff here and re-read your answer and noticed the "static" specifier. Going back to my code I stumbled over a local variable definition at the top of the uart_printf.c file where I defined the input buffer as "char input". Changing this to "static char input" made the difference and triggered the callback.

    thanks for your help

    But one thing that still puzzles me. I call UART_read every 10s triggered by a collector event. However, my messages get echoed always almost immediately. Could it be that I only have to call UART_read once and afterwards if an RX byte receives the callback function will be called until UART_readCancel is called?