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/LP-CC2652RB: How to receive uart input into a variable?

Part Number: LP-CC2652RB

Tool/software: Code Composer Studio

How can i data display from uart into console by using system_printf (); command. Can i receive uart data into a variable? 

  • What OS are you using on the 2652?

  • Shivam,

    I would recommend looking at the UART echo example to see how to read and write to the UART.

    https://dev.ti.com/tirex/explore/node?node=AE5vt5FbesOc0NdnkcpdSw__pTTHBmu__LATEST  

    There is also a SimpleLink Academy training on various methods of debug printing, including system_printf() here: https://dev.ti.com/tirex/explore/node?node=ANqagjxZxWnBRB7bx0EnOw__pTTHBmu__LATEST 

    Regards,

    Daniel

  • I am using NOTOS code from uart echo example in the CCS IDE.

  • Okay thanks daniel, can i recieve uart data into a char or string variable and pass it to systemprintf()

  • As Uart_read & Uart_write functions have int type return values. How can i pass the value read by Uart_read into system_printf().

    Thanks in advance.

  • Shivam,

    Please refer to the driver documentation, here: https://dev.ti.com/tirex/explore/content/simplelink_cc13x2_26x2_sdk_4_20_01_04/docs/tidrivers/doxygen/html/_u_a_r_t_8h.html#a15d77f489566ff9f7c9c28d25e9a0135 

    uart_read() puts the data into a buffer. 

    Parameters
    handle	A UART_Handle returned by UART_open()
    buffer	A pointer to an empty buffer to which received data should be written
    size	The number of bytes to be written into buffer
    
    Returns
    Returns the number of bytes that have been read from the UART, UART_STATUS_ERROR on an error.

    Regards,

    Daniel

  • Okay thanks daniel, so you mean to say that i can use that buffer for passing into system_printf().
    Is it okay if i use system_printf(&buffer).

  • Shivam,

    Please read the documentation for system_pintf(). You need to pass a string, so you need to convert the buffer from a char array to a string.

    https://dev.ti.com/tirex/explore/content/simplelink_cc13x2_26x2_sdk_4_20_01_04/docs/tirtos/sysbios/docs/cdoc/index.html#xdc/runtime/System.html#printf

    - Daniel

  • Okay thanks a lot daniel, can you tell how can i access that buffer, as for converting char to string i can do type casting.

    Thanks in advance. 

  • Shivam,

    Please see the example I linked previously, which shows to use a buffer to store the character received from uart_read().

    You can also see code examples in the documentation here: https://dev.ti.com/tirex/explore/content/simplelink_cc13x2_26x2_sdk_4_20_01_04/docs/tidrivers/doxygen/html/_u_a_r_t_8h.html 

    Regards,

    Daniel

  • Okay Thanks. So i can make the following changes to the code as below.

    // Import the UART driver definitions
    #include <ti/drivers/UART.h>
    // One-time initialization of UART driver
    UART_init();
    // Initialize UART parameters
    UART_Params params;
    UART_Params_init(&params);
    params.baudRate = 9600;
    params.readMode = UART_MODE_BLOCKING;
    params.writeMode = UART_MODE_BLOCKING;
    params.readTimeout = UART_WAIT_FOREVER;
    params.writeTimeout = UART_WAIT_FOREVER;
    // Open the UART
    UART_Handle uart;
    uart = UART_open(CONFIG_UART0, &params);
    // Read from the UART
    int32_t readCount;
    uint8_t buffer[BUFSIZE];
    readCount = UART_read(uart, buffer, BUFSIZE);
    // Write to the UART
    UART_write(uart, buffer, BUFSIZE);
    // Close the UART
    UART_close(uart);

    In this code above i can use readcount as a condition check for a particular character let say '\n' and then use buffer in systemprintf() as below.

    if (readCount == '\n')

    {

    System_printf(buffer);

    }

    So my goal is to receive a line comma separated characters terminated by \n , store it in buffer and then print the buffer using system_printf(buffer)

    Am i right?

    Thanks in advance.

  • Shivam,

    No, the return of UART_read() is the number of bytes written, so if you do 

    if (readCount == '\n')

    You are comparing the number of bytes read by the driver to the char '\n'.

    - Daniel

  • Then how can I receive each incoming line of characters till '\n' and then store them in a buffer and then clear that buffer.

    Thanks,

    Shivam

  • Shivam,

    One way to do this is to check each character you read in to the buffer one-by-one using the UART_read() function in a loop.

    Regards,

    Daniel

  • Okay but uart_read returns the number of bytes read, i have to check the incoming character, however i am able to do it now by accessing the char input variable in the uartecho code, but since this is a char variable i have to convert it into an array or string and store all of it into the sd card.

    How to do it?

    Thanks,

    Shivam

  • You cannot compare the UART_read() *return* value to '/n'. You must compare the *buffer* (or buffer[n] if buffer is an array) to '/n'.

    The important thing is the UART_read() function puts the data into the buffer so you need to check the buffer not the return value.

    -Daniel

  • Okay daniel, thanks. Can you tell me the maximum size that can be passed to the buffer in uart and is it possible to convert the received uart char to string or any inbuilt function similar to readstringuntil in arduino. Some thing like this below.

    https://www.arduino.cc/reference/en/language/functions/communication/serial/readstringuntil/

    readStringUntil() reads characters from the serial buffer into a String. The function terminates if it times out (see setTimeout()).

    Thanks in advance.

  • The size of the buffer depends on your application.

    There is not a direct equivalent to the Adruino command you posted above, but you could probably view the source for the command and reverse engineer it to work on a CC2652 device.

    I would recommend you read the driver documentation, which contains examples and explanations of the UART driver. https://dev.ti.com/tirex/explore/content/simplelink_cc13x2_26x2_sdk_4_30_00_54/docs/drivers/doxygen/html/_u_a_r_t_c_c26_x2_8h.html 

    Specifically, look at the "Use Cases" section which shows example application code. The example "Receive with Return Partial" uses UARTCC26X2_CMD_RETURN_PARTIAL_ENABLE which is similar to what you are describing above, I think. It allows the UART_read() to return when the number of bytes requested are read, or if the read times out.

    Regards,

    Daniel

  • Okay then how can i change the buffer size in uart_read command function.

  • Shivam,

    This is shown in the documentation I linked above.

    UART_Handle handle;
    UART_Params params;
    uint8_t rxBuf[100];         // Receive buffer
    uint32_t timeoutUs = 5000;  // 5ms timeout, default timeout is no timeout (BIOS_WAIT_FOREVER)
    // Init UART and specify non-default parameters
    UART_Params_init(&params);
    params.baudRate      = 9600;
    params.writeDataMode = UART_DATA_BINARY;
    params.readTimeout   = timeoutUs / ClockP_getSystemTickPeriod(); // Default tick period is 10us
    // Open the UART and do the read
    handle = UART_open(CONFIG_UART, &params);
    int rxBytes = UART_read(handle, rxBuf, 100);

    This makes the buffer a 100 byte array (uint8_t rxBuf[100];) and UART_read() reads 100 bytes into rxBuf (int rxBytes = UART_read(handle, rxBuf, 100);)

    -Daniel

  • Okay so i am receiving the uart data and i have to write the same data into sd card for this i am using fatsd code after uart_read and uart_write function, but i am unable to write data into the sd card.
    There is no data i am able to write and the code gets stuck.

    /*
     * Copyright (c) 2017-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== fatsd.c ========
     */
    #include <file.h>
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    /* Driver configuration */
    #include "ti_drivers_config.h"
    #include <third_party/fatfs/ffcio.h>
    #include <ti/drivers/UART.h>
    #include <ti/display/Display.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SDFatFS.h>
    /* Buffer size used for the file copy process */
    #ifndef CPY_BUFF_SIZE
    #define CPY_BUFF_SIZE       2048
    #endif
    
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    const char inputfile[] = "fat:"STR(DRIVE_NUM)":input.txt";
    const char outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
    
    const char textarray[] = \
    "***********************************************************************\n"
    "0         1         2         3         4         5         6         7\n"
    "01234567890123456789012345678901234567890123456789012345678901234567890\n"
    "This is some text to be inserted into the inputfile if there isn't\n"
    "already an existing file located on the media.\n"
    "If an inputfile already exists, or if the file was already once\n"
    "generated, then the inputfile will NOT be modified.\n"
    "***********************************************************************\n";
    
    static Display_Handle display;
    
    /* File name prefix for this filesystem for use with TI C RTS */
    char fatfsPrefix[] = "fat";
    
    unsigned char cpy_buff[CPY_BUFF_SIZE + 1];
    
    /*
     *  ======== mainThread ========
     *  Thread to perform a file copy
     *
     *  Thread tries to open an existing file inputfile[]. If the file doesn't
     *  exist, create one and write some known content into it.
     *  The contents of the inputfile[] are then copied to an output file
     *  outputfile[]. Once completed, the contents of the output file are
     *  printed onto the system console (stdout).
     */
    void *mainThread(void *arg0)
    {
        char        input;
        UART_Handle uart;
        UART_Params uartParams;
        SDFatFS_Handle sdfatfsHandle;
        /* Call driver init functions */
        GPIO_init();
        UART_init();
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        /* Turn on user LED */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
        /* 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_FULL;
        uartParams.baudRate = 115200;
        uart = UART_open(CONFIG_UART_0, &uartParams);
        if (uart == NULL) {
                /* UART_open() failed */
                while (1);
            }
            /* Loop forever echoing */
            while (input!='\n')
            {
                UART_read(uart, &input, 1);
                UART_write(uart, &input, 1);
            }
                /* Variables for the CIO functions */
                    FILE *src, *dst;
    
                    /* Variables to keep track of the file copy progress */
                    unsigned int bytesRead = 0;
                    unsigned int bytesWritten = 0;
                    unsigned int filesize;
                    unsigned int totalBytesCopied = 0;
    
                    /* Call driver init functions */
                    GPIO_init();
                    UART_init();
                    Display_init();
                    SDFatFS_init();
    
                    /* Configure the LED pin */
                    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
                    /* Turn on user LED */
                    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
                    /* add_device() should be called once and is used for all media types */
                    add_device(fatfsPrefix, _MSA, ffcio_open, ffcio_close, ffcio_read,
                        ffcio_write, ffcio_lseek, ffcio_unlink, ffcio_rename);
    
                    /* Open the display for output */
                    display = Display_open(Display_Type_UART, NULL);
                    if (display == NULL) {
                        /* Failed to open display driver */
                        while (1);
                    }
                    Display_printf(display, 0, 0, "Starting the fatsd example\n");
                    Display_printf(display, 0, 0,
                        "This example requires a FAT filesystem on the SD card.\n");
                    Display_printf(display, 0, 0,
                        "You will get errors if your SD card is not formatted with a filesystem.\n");
    
                    /* Mount and register the SD Card */
                    sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
                    if (sdfatfsHandle == NULL) {
                        Display_printf(display, 0, 0, "Error starting the SD card\n");
                        while (1);
                    }
                    else {
                        Display_printf(display, 0, 0, "Drive %u is mounted\n", DRIVE_NUM);
                    }
    
                    /* Try to open the source file */
                    src = fopen(inputfile, "r");
                    if (!src) {
                        Display_printf(display, 0, 0, "Creating a new file \"%s\"...",
                            inputfile);
    
                        /* Open file for both reading and writing */
                        src = fopen(inputfile, "w+");
                        if (!src) {
                            Display_printf(display, 0, 0,
                                "Error: \"%s\" could not be created.\nPlease check the "
                                "Board.html if additional jumpers are necessary.\n",
                                inputfile);
                            Display_printf(display, 0, 0, "Aborting...\n");
                            while (1);
                        }
    
                        fwrite(textarray, 1, strlen(textarray), src);
                        fflush(src);
    
                        /* Reset the internal file pointer */
                        rewind(src);
    
                        Display_printf(display, 0, 0, "done\n");
                    }
                    else {
                        Display_printf(display, 0, 0, "Using existing copy of \"%s\"\n",
                            inputfile);
                    }
    
                    /* Create a new file object for the file copy */
                    dst = fopen(outputfile, "w");
                    if (!dst) {
                        Display_printf(display, 0, 0, "Error opening \"%s\"\n", outputfile);
                        Display_printf(display, 0, 0, "Aborting...\n");
                        while (1);
                    }
                    else {
                        Display_printf(display, 0, 0, "Starting file copy\n");
                    }
    
                    /*  Copy the contents from the src to the dst */
                    while (true) {
                        /*  Read from source file */
                        bytesRead = fread(cpy_buff, 1, CPY_BUFF_SIZE, src);
                        if (bytesRead == 0) {
                            break; /* Error or EOF */
                        }
    
                        /*  Write to dst file */
                        bytesWritten = fwrite(cpy_buff, 1, bytesRead, dst);
                        if (bytesWritten < bytesRead) {
                            Display_printf(display, 0, 0, "Disk Full\n");
                            break; /* Error or Disk Full */
                        }
    
                        /*  Update the total number of bytes copied */
                        totalBytesCopied += bytesWritten;
                    }
    
                    fflush(dst);
    
                    /* Get the filesize of the source file */
                    fseek(src, 0, SEEK_END);
                    filesize = ftell(src);
                    rewind(src);
    
                    /* Close both inputfile[] and outputfile[] */
                    fclose(src);
                    fclose(dst);
    
                    Display_printf(display, 0, 0,
                        "File \"%s\" (%u B) copied to \"%s\" (Wrote %u B)\n",
                        inputfile, filesize, outputfile, totalBytesCopied);
    
                    /* Now output the outputfile[] contents onto the console */
                    dst = fopen(outputfile, "r");
                    if (!dst) {
                        Display_printf(display, 0, 0, "Error opening \"%s\"\n", outputfile);
                        Display_printf(display, 0, 0, "Aborting...\n");
                        while (1);
                    }
    
                    /* Print file contents */
                    while (true) {
                        /* Read from output file */
                        bytesRead = fread(cpy_buff, 1, CPY_BUFF_SIZE, dst);
                        if (bytesRead == 0) {
                            break; /* Error or EOF */
                        }
                        cpy_buff[bytesRead] = '\0';
                        /* Write output */
                        Display_printf(display, 0, 0, "%s", cpy_buff);
                    }
    
                    /* Close the file */
                    fclose(dst);
    
                    /* Stopping the SDCard */
                    SDFatFS_close(sdfatfsHandle);
                    Display_printf(display, 0, 0, "Drive %u unmounted\n", DRIVE_NUM);
                    return (NULL);
            }
     /*  ======== fatfs_getFatTime ========
     */
    int32_t fatfs_getFatTime(void)
    {
        /*
         *  FatFs uses this API to get the current time in FatTime format.  User's
         *  must implement this function based on their system's timekeeping
         *  mechanism.  See FatFs documentation for details on FatTime format.
         */
        /* Jan 1 2017 00:00:00 */
        return (0x4A210000);
    }
    

    Thanks,

    shivam

  • You are reading the UART data into a single byte, not an array of bytes.

    char        input; <-- is a single char (1 byte)
    

    while (input!='\n')
            {
                UART_read(uart, &input, 1);
                UART_write(uart, &input, 1);
            }

    this loop writes over that single byte over and over. It does not create an array of bytes. It reads in 1 byte to the variable `input` then writes the same byte to the UART.

    I don't see anywhere where you are trying to write the UART buffer to the SD card.

    Also, you are opening GPIO and UART drivers twice, and initializing GPIOs twice.

    Where does your code get stuck? There are lots of println debugging statements. Are you reading those on your terminal? Are you using breakpoints or watching variables? You should probably step through your code so you can understand what is happening in the system.

    -Daniel

  • You are reading the UART data into a single byte, not an array of bytes.

    this loop writes over that single byte over and over. It does not create an array of bytes. It reads in 1 byte to the variable `input` then writes the same byte to the UART. : Yes i know that, infact it will be okay if i am able to write the data byte by byte.

    I don't see anywhere where you are trying to write the UART buffer to the SD card. : Yes in the attached file i am just trying to write sample data into SD card while also receiving uart data on the terminal when i am trying to insert the fatsd code in the while loop.

    Also, you are opening GPIO and UART drivers twice, and initializing GPIOs twice. : This i will fix

    Where does your code get stuck? There are lots of println debugging statements. Are you reading those on your terminal? Are you using breakpoints or watching variables? You should probably step through your code so you can understand what is happening in the system. :  As i mentioned before after while loop it doesnt work and i am not able to view the println statement in the terminal.

    Can you tell me a simple code after uart_read & uart_write where i can write a received uart char into the sd card. You tell just the code leaving the other declarations etc that i will manage. It will be a great help.

  • Thanks daniel, further i have narrowed down the code. Please refer the whole code in attachment and just the important part in syntax highlighter. Still its getting stuck. In the while (1) loop i am just able to see the uart data only once and then it gets stuck, however i expect the data to be continuously coming and a dummy textarray[] data (declared and defined in attached file) to be written in sd card inputfile. That is what i want. Thanks a lot for your patience.

     while(1)
           {
               GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
               int rxBytes = UART_read(handle, rxBuf, 200);
               UART_write(handle, rxBuf, 200);
               src = fopen(inputfile, "w+");
               fwrite(textarray, 1, strlen(textarray), src);
               fflush(src);
               rewind(src);
               fclose(src);
               SDFatFS_close(sdfatfsHandle);
           }

    I am also attaching the snapshot of debugging where the program gets stuck in line 

     int rxBytes = UART_read(handle, rxBuf, 200); but when sd relevant code is commented then it doesnot get stuck there.

    #include <file.h>
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <third_party/fatfs/ffcio.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/SDFatFS.h>
    /* Driver configuration */
    #include "ti_drivers_config.h"
    /* Driver configuration */
    #include "ti_drivers_config.h"
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    const char inputfile[] = "fat:"STR(DRIVE_NUM)":input.txt";
    const char outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
    const char textarray[] = \
    "***********************************************************************\n"
    "0         1         2         3         4         5         6         7\n"
    "01234567890123456789012345678901234567890123456789012345678901234567890\n"
    "This is some text to be inserted into the inputfile if there isn't\n"
    "already an existing file located on the media.\n"
    "If an inputfile already exists, or if the file was already once\n"
    "generated, then the inputfile will NOT be modified.\n"
    "***********************************************************************\n";
    
    char fatfsPrefix[] = "fat";
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        UART_Handle handle;
        UART_Params params;
        SDFatFS_Handle sdfatfsHandle;
        FILE *src;
        char rxBuf[250];         // Receive buffer
        /* Call driver init functions */
            GPIO_init();
            UART_init();
            SDFatFS_init();
            /* Configure the LED pin */
            GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
            add_device(fatfsPrefix, _MSA, ffcio_open, ffcio_close, ffcio_read,
                ffcio_write, ffcio_lseek, ffcio_unlink, ffcio_rename);
            /* Mount and register the SD Card */
                sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
    
    
        // Init UART and specify non-default parameters
        UART_Params_init(&params);
        params.baudRate      = 115200;
        params.writeDataMode = UART_DATA_BINARY;
        // Open the UART and do the read
        handle = UART_open(CONFIG_UART_0, &params);
        if (handle == NULL) {
               /* UART_open() failed */
               while (1);
           }
           /* Turn on user LED to indicate successful initialization */
    
           while(1)
           {
               GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
               int rxBytes = UART_read(handle, rxBuf, 200);
               UART_write(handle, rxBuf, 200);
               src = fopen(inputfile, "w+");
               fwrite(textarray, 1, strlen(textarray), src);
               fflush(src);
               rewind(src);
               fclose(src);
               SDFatFS_close(sdfatfsHandle);
           }
    
    }
    
    /*
     *  ======== fatfs_getFatTime ========
     */
    int32_t fatfs_getFatTime(void)
    {
        /*
         *  FatFs uses this API to get the current time in FatTime format.  User's
         *  must implement this function based on their system's timekeeping
         *  mechanism.  See FatFs documentation for details on FatTime format.
         */
        /* Jan 1 2017 00:00:00 */
        return (0x4A210000);
    }
    
    

  • In your loop you close the SDFatFS driver, and never reopen it.

    You may also being too much in the loop to the point where you will miss UART data. I think it would be easier to read in all the UART data, then write the whole string to the SDCard.

    You should probably get each piece working (FatFS SD writes, UART read) working before combing so you can isolate issues.

    -Daniel

  • In your loop you close the SDFatFS driver, and never reopen it. : I have tried to open the driver in the loop itself but still its not working.

    You may also being too much in the loop to the point where you will miss UART data. I think it would be easier to read in all the UART data, then write the whole string to the SDCard. : I am sending a large amount of data , can't i read and write it byte by byte, i have tried this also but its not happening. i have also tried to read a portion of it and it is also not giving result. 

    You should probably get each piece working (FatFS SD writes, UART read) working before combing so you can isolate issues. : I have tried each piece working separately and both of them are working separately but dont work when i am merging them in a single code. 

    One of the reasons that may be that i am using the xds110 uart connection for display and xds 110 is also connected to hardware uart where i am receiving the data. However i have disconnected the hardware uart RX jumper with XDS110 uart, then i am recieving the data from another microcontroller.  Would it be good to receive the data through another uart which is not connected to xds110 by default.

  • Hi Daniel,

    I have also tried opening and closing the SDFatFs driver in the driver still its getting stuck. Please see the code below.

     handle = UART_open(CONFIG_UART_0, &params);
        if (handle == NULL) {
               /* UART_open() failed */
               while (1);
           }
           /* Turn on user LED to indicate successful initialization */
    
           while(1)
           {
               GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
               UART_read(handle, &rxBuf, 1);
               //UART_write(handle, &rxBuf, 1);
               /* Mount and register the SD Card */
                       sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
                       src = fopen(inputfile, "w+");
                       fwrite(textarray, 1, strlen(textarray), src);
                       fflush(src);
                       rewind(src);
                       fclose(src);
                       SDFatFS_close(sdfatfsHandle);
                       GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
           }
    

  • HI daniel please refer this code below, i have found out that the program is getting stuck in fwrite statement. How can i solve it? if you notice i am using GPIO_LED0 for debugging the LED stays ON even when i am switching it off after fwrite in while loop.

    Please help me it will be a great help.

    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
           while(1)
           {
    
               UART_read(handle, &rxBuf, 1);
    
               //UART_write(handle, &rxBuf, 1);
               /* Mount and register the SD Card */
                       sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
    
                       src = fopen(inputfile, "w+");
    
                       fwrite(textarray, 1, strlen(textarray), src);
                       GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF); // The code is not coming to this statement.
                       fflush(src);
                       rewind(src);
                       fclose(src);
                       SDFatFS_close(sdfatfsHandle);
    
    
           }

  • Are you making sure you successfully opened the file?

    /* Open file for both reading and writing */
            src = fopen(inputfile, "w+");
            if (!src) {
                Display_printf(display, 0, 0,
                    "Error: \"%s\" could not be created.\nPlease check the "
                    "Board.html if additional jumpers are necessary.\n",
                    inputfile);
                Display_printf(display, 0, 0, "Aborting...\n");
                while (1);
            }

    Once again, you probably want to do the initialization and opening of handles outside of the loop since there is going to be a lot of overhead opening and closing the handles just to read 1 UART character.

    -Daniel

  • Yes, i have tried opening the handles before loop. However i want to inform you that the code is getting stuck in Uart_read() statement not in fwrite(). Sorry for inconvenience. I have used debugger to view it.

    What should i do to avoid getting it stuck in Uart_read()?

    Thanks & Regards,

    shivam

  • What is the status returned from Uart_read()? Does the handle open OK?

    What is the hardware setup? Have you attached a logic analyzer to make sure the data is coming in the way you expect? 

  • What is the status returned from Uart_read()? Does the handle open OK?

    Uart_open returns success status. But the problem is in Uart_read().
    Please refer the code below:

    void *mainThread(void *arg0)
    {
        UART_Handle handle;
        UART_Params params;
        char rxBuf;         // Receive buffer
        SDFatFS_Handle sdfatfsHandle;
        FILE *src;
        /* Call driver init functions */
            GPIO_init();
            UART_init();
            SDFatFS_init();
            /* Configure the LED pin */
            GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
            add_device(fatfsPrefix, _MSA, ffcio_open, ffcio_close, ffcio_read,
                ffcio_write, ffcio_lseek, ffcio_unlink, ffcio_rename);
                // Init UART and specify non-default parameters
        UART_Params_init(&params);
        params.baudRate      = 115200;
        // Create a UART with data processing off.
        params.writeDataMode = UART_DATA_TEXT;
        params.readDataMode = UART_DATA_TEXT;
        params.readReturnMode = UART_RETURN_NEWLINE;
        //params.readEcho = UART_ECHO_OFF;
        params.baudRate = 115200;
           /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
               // Open the UART and do the read
                  handle = UART_open(CONFIG_UART_0, &params);
                  if (handle == NULL) {
                         /* UART_open() failed */
    
                         while (1);
    
                     }
    
                  UART_read(handle, &rxBuf, 1);
                 
                  //UART_write(handle, &rxBuf, 1);
    
               //UART_write(handle, &rxBuf, 1);
               /* Mount and register the SD Card */
                       sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
                       src = fopen(inputfile, "r");
                          if (!src) {
                              /* Open file for both reading and writing */
                              src = fopen(inputfile, "w+");
                              if (!src) {
                                  while (1);
                              }
                              fwrite(textarray, 1, strlen(textarray), src);
    
    
           }
                                             fclose(src);
                                             SDFatFS_close(sdfatfsHandle);
    }
    

     

    What is the hardware setup? Have you attached a logic analyzer to make sure the data is coming in the way you expect? 

    I am connecting arduino TX to TICC2652LP RX and removing the RX jumper with XDS110 section. No i have not attached a logic analyzer to view it.

     

    I think there is problem in usage of UART_read(). It should be used in a callback mode and then merge it with sd code.
    Please help me as its taking too long for me.

    Thanks,

    shivam

  • Shivam,

    Can you elaborate about what the issue with UART_read() is? Not returning anything to the read buffer? Getting stuck in the function? Have you used the debugger to step into the function? Have you verified that the UART_read() works without the SD Card code?

    Regards,

    Daniel

  • Thanks for your patience Daniel.
    I have used the debugger, yes the UART_read() works without the SD Card code perfectly.
    I have had a small progress now i am able to write dummy code into the SD Card along with receiving one character from uart. I mean i am able to receive the character only once and simultaneously file write is happening. I am attaching the code however i want to continously receive the uart data and write a dummy text into it as well.

    #include <file.h>
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    #include <third_party/fatfs/ffcio.h>
    
    //#include <ti/display/Display.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SDFatFS.h>
    #include <ti/drivers/UART2.h>
    /* XDC module Headers */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    /* Driver configuration */
    #include "ti_drivers_config.h"
    static sem_t sem;
    static volatile size_t numBytesRead;
    /* Buffer size used for the file copy process */
    #ifndef CPY_BUFF_SIZE
    #define CPY_BUFF_SIZE       2048
    #endif
    
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    const char inputfile[] = "fat:"STR(DRIVE_NUM)":input.txt";
    const char outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
    
    const char textarray[] ="Hello from shivam";
    
    //static Display_Handle display;
    
    /* Set this to the current UNIX time in seconds */
    const struct timespec ts = {
        .tv_sec = 1469647026,
        .tv_nsec = 0
    };
    
    /* File name prefix for this filesystem for use with TI C RTS */
    char fatfsPrefix[] = "fat";
    
    unsigned char cpy_buff[CPY_BUFF_SIZE];
    /*
     *  ======== callbackFxn ========
     */
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count,
            void *userArg, int_fast16_t status)
    {
        if (status != UART2_STATUS_SUCCESS) {
            /* RX error occured in UART2_read() */
            while (1);
        }
    
        numBytesRead = count;
        sem_post(&sem);
    }
    
    
    /*
     *  ======== mainThread ========
     *  Thread to perform a file copy
     *
     *  Thread tries to open an existing file inputfile[]. If the file doesn't
     *  exist, create one and write some known content into it.
     *  The contents of the inputfile[] are then copied to an output file
     *  outputfile[]. Once completed, the contents of the output file are
     *  printed onto the system console (stdout).
     */
    void *mainThread(void *arg0)
    {
        char              input;
        const char        echoPrompt[] = "Echoing characters:\r\n";
        UART2_Handle      handle;
        UART2_Params      uartParams;
        int32_t           semStatus;
        uint32_t          status = UART2_STATUS_SUCCESS;
        SDFatFS_Handle sdfatfsHandle;
        /* Create semaphore */
        semStatus = sem_init(&sem, 0, 0);
    
        if (semStatus != 0) {
            /* Error creating semaphore */
            while (1);
        }
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
        uartParams.readMode = UART2_Mode_CALLBACK;
        uartParams.readCallback = callbackFxn;
        uartParams.baudRate = 115200;
    
        handle = UART2_open(CONFIG_UART2_0, &uartParams);
    
        if (handle == NULL) {
            /* UART2_open() failed */
            while (1);
        }
    
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        /* Pass NULL for bytesWritten since it's not used in this example */
        UART2_write(handle, echoPrompt, sizeof(echoPrompt), NULL);
    
        /* Loop forever echoing */
        while (1) {
            numBytesRead = 0;
    
            /* Pass NULL for bytesRead since it's not used in this example */
            status = UART2_read(handle, &input, 1, NULL);
    
            if (status != UART2_STATUS_SUCCESS) {
                /* UART2_read() failed */
                while (1);
    
            }
    
            /* Do not write until read callback executes */
            sem_wait(&sem);
    
            if (numBytesRead > 0) {
                status = UART2_write(handle, &input, 1, NULL);
                GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
                /* Variables for the CIO functions */
                 FILE *src;
                 /* Call driver init functions */
                 GPIO_init();
    
                 SDFatFS_init();
    
                 /* Configure the LED pin */
                 GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
                 /* add_device() should be called once and is used for all media types */
                 add_device(fatfsPrefix, _MSA, ffcio_open, ffcio_close, ffcio_read,
                     ffcio_write, ffcio_lseek, ffcio_unlink, ffcio_rename);
    
                 /* Open the display for output */
                 //display = Display_open(Display_Type_UART, NULL);
                 //if (display == NULL) {
                     /* Failed to open display driver */
                    // while (1);
                 //}
    
                 /* Initialize real-time clock */
                 clock_settime(CLOCK_REALTIME, &ts);
    
                 /* Turn on user LED */
                 GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
                 //Display_printf(display, 0, 0, "Starting the fatsd example\n");
                 //Display_printf(display, 0, 0,
                    // "This example requires a FAT filesystem on the SD card.\n");
                 //Display_printf(display, 0, 0,
                     //"You will get errors if your SD card is not formatted with a filesystem.\n");
    
                 /* Mount and register the SD Card */
                 sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
                 //if (sdfatfsHandle == NULL) {
                     //Display_printf(display, 0, 0, "Error starting the SD card\n");
                    // while (1);
                 //}
                 //else {
                    // Display_printf(display, 0, 0, "Drive %u is mounted\n", DRIVE_NUM);
                 //}
    
                 /* Try to open the source file */
                 src = fopen(inputfile, "r");
                 if (!src) {
                     //Display_printf(display, 0, 0, "Creating a new file \"%s\"...",
                         //inputfile);
    
                     /* Open file for both reading and writing */
                     src = fopen(inputfile, "w+");
                     if (!src) {
                         //Display_printf(display, 0, 0,
                            // "Error: \"%s\" could not be created.\nPlease check the "
                            // "Board.html if additional jumpers are necessary.\n",
                            // inputfile);
                         //Display_printf(display, 0, 0, "Aborting...\n");
                         while (1);
                     }
    
                     fwrite(textarray, 1, strlen(textarray), src);
                     fflush(src);
    
                     /* Reset the internal file pointer */
                     rewind(src);
    
                     //Display_printf(display, 0, 0, "done\n");
                 }
                 else {
                     //Display_printf(display, 0, 0, "Using existing copy of \"%s\"\n",
                         //inputfile);
                 }
                 /* Close  inputfile[]  */
                 fclose(src);
                 /* Stopping the SDCard */
                 SDFatFS_close(sdfatfsHandle);
                 //Display_printf(display, 0, 0, "Drive %u unmounted\n", DRIVE_NUM);
    
    
                if (status != UART2_STATUS_SUCCESS) {
                    /* UART2_write() failed */
                    while (1);
                }
            }
            return (NULL);
        }
    
    }
    
    /*
     *  ======== fatfs_getFatTime ========
     */
    int32_t fatfs_getFatTime(void)
    {
        time_t seconds;
        uint32_t fatTime;
        struct tm *pTime;
    
        /*
         *  TI time() returns seconds elapsed since 1900, while other tools
         *  return seconds from 1970.  However, both TI and GNU localtime()
         *  sets tm tm_year to number of years since 1900.
         */
        seconds = time(NULL);
    
        pTime = localtime(&seconds);
    
        /*
         *  localtime() sets pTime->tm_year to number of years
         *  since 1900, so subtract 80 from tm_year to get FAT time
         *  offset from 1980.
         */
        fatTime = ((uint32_t)(pTime->tm_year - 80) << 25) |
            ((uint32_t)(pTime->tm_mon) << 21) |
            ((uint32_t)(pTime->tm_mday) << 16) |
            ((uint32_t)(pTime->tm_hour) << 11) |
            ((uint32_t)(pTime->tm_min) << 5) |
            ((uint32_t)(pTime->tm_sec) >> 1);
    
        return ((int32_t)fatTime);
    }
    

    regards,

    shivam

  • Already try to help you in . It won't help to create countless post for the same issue.

  • Please dont post your same reply everywhere. Daniel has been helping me very well, while you stopped replying me that is why i created another post. If you can't support don't create a problem for others.

  • Basically, the steps are:

    1. Use fatsd example as base.

    2. Add uart thread into fatsd example.

    3. Use semaphore to control posting message received in uart thread to fatsd thread to write into fatsd.

    Hope this helps.

  • Yes i am following the steps 1 , 2 & 3 mentioned above. With these steps i am able receive only one character at a time and then again receive it after pressing reset. I am also able to write a dummy data once into the file. However i want to contiously receive the uart data and simulatneously. 
    If i dont do fopen/fwrite/fclose in uart thread then how i will be able to write the uart data into sd card.
    Please refer the code attached above else suggest a short code only for uart contious receive and write.

    Thanks,

    shivam

  • Shivam,

    YiKai's suggestion is a good approach (multiple threads and using Semaphores). Also like YiKai mentioned, posting in multiple threads makes support difficult since it's hard to keep track. Please keep threads focused to a single question so that we can help answer. 

    Another approach would be to use UART in continuous callback mode, as seen here: https://dev.ti.com/tirex/explore/content/simplelink_cc13x2_26x2_sdk_4_30_00_54/docs/drivers/doxygen/html/_u_a_r_t_c_c26_x_x_8h.html#USE_CASE_CB 

    You would then use the callback function to create the array/string you want to to write to the SD card.

    Regards,

    Daniel

  • Many thanks Daniel. I will try this as well.
    I have tried yikai's suggestion but i am able to read and write only one byte after press of reset button on the launchpad. I think i am not able to use semaphore or the code is getting stuck somewhere. I have also tried debugging it line by line but unable to do it as i get file not found errors. Please refer my current code and see if you can help on it. I understand that i should not create multiple threads and keep threads focussed but since i was not getting support that is why i created them. I am little bit new to this environment and want to learn it and apply in my university project to move away from arduino. Still i apologize for the inconvenience caused.

    Thanks,

    shivam

    #include <file.h>
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    #include <third_party/fatfs/ffcio.h>
    
    //#include <ti/display/Display.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SDFatFS.h>
    #include <ti/drivers/UART2.h>
    /* XDC module Headers */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    /* Driver configuration */
    #include "ti_drivers_config.h"
    static sem_t sem;
    static volatile size_t numBytesRead;
    /* Buffer size used for the file copy process */
    #ifndef CPY_BUFF_SIZE
    #define CPY_BUFF_SIZE       2048
    #endif
    
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    const char inputfile[] = "fat:"STR(DRIVE_NUM)":input.txt";
    const char outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
    
    //const char textarray[] ="Hello from shivam";
    
    //static Display_Handle display;
    
    /* Set this to the current UNIX time in seconds */
    const struct timespec ts = {
        .tv_sec = 1469647026,
        .tv_nsec = 0
    };
    
    /* File name prefix for this filesystem for use with TI C RTS */
    char fatfsPrefix[] = "fat";
    
    unsigned char cpy_buff[CPY_BUFF_SIZE];
    /*
     *  ======== callbackFxn ========
     */
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count,
            void *userArg, int_fast16_t status)
    {
        if (status != UART2_STATUS_SUCCESS) {
            /* RX error occured in UART2_read() */
            //while (1);
        }
    
        numBytesRead = count;
        sem_post(&sem);
    }
    
    
    /*
     *  ======== mainThread ========
     *  Thread to perform a file copy
     *
     *  Thread tries to open an existing file inputfile[]. If the file doesn't
     *  exist, create one and write some known content into it.
     *  The contents of the inputfile[] are then copied to an output file
     *  outputfile[]. Once completed, the contents of the output file are
     *  printed onto the system console (stdout).
     */
    void *mainThread(void *arg0)
    {
        char              input;
        //const char        echoPrompt[] = "Echoing characters:\r\n";
        UART2_Handle      handle;
        UART2_Params      uartParams;
        int32_t           semStatus;
        uint32_t          status = UART2_STATUS_SUCCESS;
        SDFatFS_Handle sdfatfsHandle;
        /* Create semaphore */
        semStatus = sem_init(&sem, 0, 0);
    
        if (semStatus != 0) {
            /* Error creating semaphore */
            //while (1);
        }
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
        uartParams.readMode = UART2_Mode_CALLBACK;
        uartParams.readCallback = callbackFxn;
        uartParams.baudRate = 115200;
    
        handle = UART2_open(CONFIG_UART2_0, &uartParams);
    
        if (handle == NULL) {
            /* UART2_open() failed */
            //while (1);
        }
    
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        /* Pass NULL for bytesWritten since it's not used in this example */
        //UART2_write(handle, echoPrompt, sizeof(echoPrompt), NULL);
    
        /* Loop forever echoing */
        while (1) {
            numBytesRead = 0;
    
            /* Pass NULL for bytesRead since it's not used in this example */
            status = UART2_read(handle, &input, 1, NULL);
    
            if (status != UART2_STATUS_SUCCESS) {
                /* UART2_read() failed */
                //while (1);
    
            }
    
            /* Do not write until read callback executes */
            sem_wait(&sem);
    
           if (numBytesRead > 0) {
                status = UART2_write(handle, &input, 1, NULL);
                GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
                /* Variables for the CIO functions */
                 FILE *src;
                 /* Call driver init functions */
                 GPIO_init();
    
                 SDFatFS_init();
    
                 /* Configure the LED pin */
                 GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
                 /* add_device() should be called once and is used for all media types */
                 add_device(fatfsPrefix, _MSA, ffcio_open, ffcio_close, ffcio_read,
                     ffcio_write, ffcio_lseek, ffcio_unlink, ffcio_rename);
                 /* Initialize real-time clock */
                 clock_settime(CLOCK_REALTIME, &ts);
                 /* Turn on user LED */
                 GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
                 /* Mount and register the SD Card */
                 sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
                     /* Open file for both reading and writing */
                     src = fopen(inputfile, "w+");
                     fwrite(&input, 1, 1, src);
                 /* Close  inputfile[]  */
                 fclose(src);
                 /* Stopping the SDCard */
                 SDFatFS_close(sdfatfsHandle);
           }
            return (NULL);
    }
    }
    
    /*
     *  ======== fatfs_getFatTime ========
     */
    int32_t fatfs_getFatTime(void)
    {
        time_t seconds;
        uint32_t fatTime;
        struct tm *pTime;
    
        /*
         *  TI time() returns seconds elapsed since 1900, while other tools
         *  return seconds from 1970.  However, both TI and GNU localtime()
         *  sets tm tm_year to number of years since 1900.
         */
        seconds = time(NULL);
    
        pTime = localtime(&seconds);
    
        /*
         *  localtime() sets pTime->tm_year to number of years
         *  since 1900, so subtract 80 from tm_year to get FAT time
         *  offset from 1980.
         */
        fatTime = ((uint32_t)(pTime->tm_year - 80) << 25) |
            ((uint32_t)(pTime->tm_mon) << 21) |
            ((uint32_t)(pTime->tm_mday) << 16) |
            ((uint32_t)(pTime->tm_hour) << 11) |
            ((uint32_t)(pTime->tm_min) << 5) |
            ((uint32_t)(pTime->tm_sec) >> 1);
    
        return ((int32_t)fatTime);
    }