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.

CCS/LAUNCHXL-CC1310: Collector reading UART cmds

Part Number: LAUNCHXL-CC1310
Other Parts Discussed in Thread: CC1310

Tool/software: Code Composer Studio

Hey guys,

I have a cc1310 Launchpad as collector (collector/sensor example). I've been through UART Echo example and UART.h file reference so far. I can set a HWI at the collector, which sets an event in the collector. When this event is processed in collector.c I want to read the UART line to see if there is some new information.

Here some info regarding the UART line content:

  • There could be no message
  • At the moment, the message is a value between 1-9 however, the length could increase, so I'd like to read until a new line is detected

So far I dont know which settings to use:

  • Callback or blocking?
  • Are readDataMode = Binary and readReurnMode = UART_RETURN_NEWLINE correct?
  • Should I use UART_read? If yes, which arguments should i set?!
  • What further settings should I make?

Kind regards

Slev1n

  • Hey Slev1n,

    Slev1n said:
    Callback or blocking?

    I would recommend using callback mode so that you don't interrupt application critical tasks during every UART read operation.

    Slev1n said:
    Are readDataMode = Binary and readReurnMode = UART_RETURN_NEWLINE correct?

    This looks correct.

    Take a look at the UART.h file for more detailed descriptions on settings (also available here).

  • Thank you for your answer Ammar.

    I am currently overwhelmed by the complexity of a simple UART read. The fact that I am quite new to C doesn't make it easier. I will try again to itemize my questions.

    • Is it correct, that the arguments given to read_UART() are automatically passed to the callback function arguments?

    E.g. UART_read(uart_handle, input, 5) causes the callback function to be readCallback(uart_handle, input, 5)

    • I saw some examples posting a semaphore in the callback function. What is this semaphore good for in this case?
    • If I choose to use such a semaphore, do I have to create a new task just for that semaphore?! Would I have to assign the semaphore to the new task ressources?!
    • If I set UART_RETURN_NEWLINE and I set the number of bytes to read to 100 and the message only consists of "1\r\n". Will it just read the 1 and then stop or wait until 100 bytes are reached?!
    • What do I actually have to do in the callback function? Can I just parse the buffer? Would it be enough to write cmd = buffer[0] (i.e. it would be 1 according to my example from above)

    Any help is welcome

  • That is my first try, however the callback functions is never executed.

    char input[255];
    int int_input[5];
    
    void readCallback(UART_Handle handle, void *buffer, size_t num)
    {
        /* Convert char into integer */
        int cmd = input[0] - '0';
        int_input[0] = cmd + 3;
    
    }
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        char        input;
        const char  echoPrompt[] = "2\r\n";
        UART_Handle uart;
        UART_Params uartParams;
    
        /* Call driver init functions */
        GPIO_init();
        UART_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_TEXT;
        uartParams.readDataMode = UART_DATA_TEXT;
        uartParams.readReturnMode = UART_RETURN_NEWLINE;
        uartParams.readMode = UART_MODE_CALLBACK;
        uartParams.readCallback = &readCallback;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uart = UART_open(Board_UART0, &uartParams);
    
        if (uart == NULL) {
            /* UART_open() failed */
            while (1);
        }
    
        UART_write(uart, echoPrompt, sizeof(echoPrompt));
        int i = 1;
        /* Loop forever echoing */
        while (1) {
            UART_read(uart, &input, 5);
            if (i==1)
            {
                UART_write(uart, &int_input, 5);
                i = 2;
            }
    
        }
    }

  • Hey Slev1n,

    After further investigation, it looks like the use of  UART_DATA_TEXT (consequently UART_RETURN_NEWLINE) is not supported (see https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/489671?CC13XX-UART-RETURN-NEWLINE).

    As your code states, you should enter the callback when your buffer is full. With the following settings, I was able to have the callback entered when the buffer is full.

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_NEWLINE;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;
    uartParams.readCallback = &uart0ReadCallback;
    uartParams.readMode = UART_MODE_CALLBACK;

    Remember to increase the size of our buffer (char input[xx];).

    In the callback function, you can parse the full buffer.

    To briefly shed light on your question regarding semaphores: each semaphore pends/posts a specific task. So yes, you'll have to create a task to use the semaphores described in the linked post.

    I recommend taking a look at our Simplelink Academy modules (http://dev.ti.com/tirex/explore/node?a=eCfARaV__2.20.00.38&node=AL.iEm6ATaD6muScZufjlQ__pTTHBmu__LATEST&r=eCfARaV__LATEST&r=eCfARaV__2.40.00.20 ) for more information on TI-RTOS and how to get started.

  • Hey Ammar,

    thank you for your response.

    Regarding the semaphore. Since I am using the sensor collector example, I already have a task with some stack defined and would be able to implement a semaphore, however, I dont think I need one in my application.

    I changed the uart parameter, but still, I the callback function is not entered.

    int int_input[3];
    char input[3];
    const char  echoPrompt[] = "23456789\r\n"; UART_write(uart, echoPrompt, sizeof(echoPrompt)); int i = 1; /* Loop forever echoing */ while (1) { UART_read(uart, &input, 3); if (i==1) { UART_write(uart, &int_input, 3); i = 2; } }

    Still got few questions:

    • Any idea why callback is not entered?
    • Does the callback function wait until the buffer "input" is full?! I dont want to wait until its full, but until the \n is reached in the read string  to enter the callback, because I dont know how long the message will be. or what is UART_RETURN_NEWLINE good for then?!
    • I increased the echoPrompt content to definitely fill the buffer but no success

    Thank you for your help

  • Slev1n said:
    Does the callback function wait until the buffer "input" is full?! I dont want to wait until its full, but until the \n is reached in the read string  to enter the callback, because I dont know how long the message will be. or what is UART_RETURN_NEWLINE good for then?!

    The callback function should be entered when you send 3 characters through UART (because you've passed in a size of 3 to the UART_read() function). Unfortunately there isn't support for the UART_RETURN_NEWLINE but it is being worked on for future releases.

    In this case, it may be easier for you to read one character at a time. When you enter the callback function, store the character (if it's not the /n char) in a buffer for use by your application. You can add a conditional statement to check if you've received the /n char. 

  • Ah, ok passing only 1 char and then making a conditional statement makes sense. I will try your approach and report back.

    kind regards

    Slev1n

  • The code still does not enter the callback function although I set UART_read(uart, &input, 1). Are my settings correct?!

        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readMode = UART_MODE_CALLBACK;
        uartParams.readCallback = &readCallback;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uart = UART_open(Board_UART0, &uartParams);
    
        if (uart == NULL) {
            /* UART_open() failed */
            while (1);
        }
            UART_write(uart, echoPrompt, sizeof(echoPrompt));
        /* Loop forever echoing */
        while (1)
        {
            UART_read(uart, &input, 1);
        }
    }

    Besides, I tried parsing the message.

    void readCallback(UART_Handle handle, void *buffer, size_t num)
    {
         if(input == '\n')
        {
            success = true; //set flag that cmd was read completely
            index = 0;
        }
        else
        {
            /* Convert char into integer */
            int cmd = input - '0';
            int_input[index] = cmd + 3;
            index++;
        }
    }
    
    
    

    Is this the right way to parse the message, check if \n is reached and convert a char into an integer?!

    EDIT: I checked the return value of the UART_read function and it is always -1, so I guess there is an error. Any idea what this could mean?! Again, are any settings wrong?

    Does it have anything to do with the fact that I am using a CC1310 launchpad?!

  • Slev1n, At this point I would recommend importing a clean uartecho example and trying again. Your settings are correct, so the callback should get entered. If "input" is not defined as a global, then accessing it in your callback will result in some error. In the uartecho example, "input" is defined inside the main thread, so be sure to exercise caution there.
  • Ok, so I guess besides some of the uart functions not working for the cc1310, it was only my fault that I never entered the callback function. Because I did not read the example correctly or rather misunderstood it. I never entered anything into the putty console, so there was just nothing to read for the uart_read function. Pretty stupid of me, because I thought the written characters of uart_write could be read by uart_read...dont know why I thought that maybe I was confused by all the "echo" stuff.

    However, it does work the way I programmed it and I think I can use it for my approach. If I stumble over something new, I will open a new thread.

    kind regards and thank you for your help Ammar

    Slev1n