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: Function to receive characters till '\n'.

Part Number: LP-CC2652RB
Other Parts Discussed in Thread: SYSCONFIG

Tool/software: Code Composer Studio

Hi i am reading characters from uart into cc2652. I am using UART_read(uart, &input, 1) to receive characters one byte at a time. Is there any function that can receive a string until a specific character such as '\n'. please suggest if there is something equivalent to readstringuntil("\n").

Thanks,

shivam 

  • Hi,

    To do so you need to use the CC26X2 version of the UART driver and chose the option "return on new line". The selection of the CC26X2 version of the driver has to be done through SysConfig. The return behavior of the driver is selected through the parameters used to call UART_open.

    Regards,

  • Hi,

    You need to implement it in code. 

    -kel

  • You can do this with the following pseudo code.

    uint8_t idx=0;
    char buf[256];
    
    UART_read(uart, &input, 1, NULL);
    if (input!='\n'){
        //Collect input into buf[]
        buf[idx]=input;
        idx++;
    } else {
        //Input character is "\n", you can do whatever you have collect in buf[]
    }
    
    
    

  • Okay thanks, i am using uartecho code from cc26x2 sdk, so still i have to use something else to implement cc2652 version uart driver.
    Thanks,

    shivam

  • Hi YK thanks for your reply.
    I am trying to write the buf string into the sd card but there is nothing written in the sd card when i am using the code.
    Please refer the code below. I am using a separate thread for writing text into the sd card file. One thing i doubt is that whether the file object can access the buf array in its code as i am collecting the uart data in buf array in uart thread. Though i am declaring the buff array globally as extern char buf [256].

    This is the code where i am passing message to switch between threads:

     while (1) {
    
            uint8_t idx=0;
    
    
            UART_read(uart, &input, 1);
            if (input =='\n')
            {
                msg = 5;
                mq_send(*mqdes , (char *)&msg, sizeof(msg), 0);
                //Collect input into buf[]
    
            }
            else
            {
                //Input character is "\n", you can do whatever you have collect in buf[]
                buf[idx]=input;
                idx++;
            }
    
            GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
            UART_write(uart, &input, 1);
        }

    This is the code where i am trying to write text into file by receiving message.

    while (mq_receive(*mqdes, (char *)&msg, sizeof(msg), NULL) != -1) 
    {
            /* Turn on user LED */
            GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
            Task_sleep(sleepTickCount);
            SDFatFS_Handle sdfatfsHandle;
                                FILE *src;
                                SDFatFS_init();
                                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);
                                sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
                                                 /* Open file for both reading and writing */
                                                 src = fopen(inputfile, "w+");
                                                 fseek(src,0,SEEK_END);
                                                 //fwrite(&input, 1, 1, src);
                                                 fwrite(buf, 256, strlen(buf), src);
                                             /* Close  inputfile[]  */
                                             fclose(src);
                                             /* Stopping the SDCard */
                                             SDFatFS_close(sdfatfsHandle);
        }
    

    Note: Both these codes i have written in separate c files in the project. I have declared buf array as extern char buf[256] to use it in the separate c file for writing it into sd card file.

  • I can only suggest you to use CCS to trace and debug your own application code.

  • Okay thanks YK, but its a debug case only. I have implemented ecerything as you suggested in earlier posts. I am just one step away from my end goal i.e. to write the incoming characters into sd card.
    Rest everything is done. And its a ccs functionality only. Please give my reply above a look once.

  • 1. Where do you put those two while loop? in different thread/task or in the same one?

    2. Why do you keep calling SDFatFS_init, SDFatFS_open, and SDFatFS_close in a while loop? You should only call them once.

  • 1. Where do you put those two while loop? in different thread/task or in the same one?

    These two while loops are in different tasks as shown in the attached image below. 1st while loop "while(1)" is in fatsd.c & another while loop is in alarm.c.
    In fatsd i am receiving uart data from another microcontroller and passing a message to another task in alarm.c file to write buf array data in sd card.

    2. Why do you keep calling SDFatFS_init, SDFatFS_open, and SDFatFS_close in a while loop? You should only call them once.

    Okay but won't that cause problems in writing data if the file is left open after writing once? I am just trying to open , write and close the file. As i have not implemented any time limit on when i will close the file. Its just that it should continue writing till the board is powered on.

    Thanks,

    shivam

  • Hi,

    As I mentioned in my first message, the CC26X2 UART driver is able to return on new line.

    1- Activate the proper driver using SysConfig:

    2- Set up the UART driver as following:

        UART_Handle uart;
        UART_Params uartParams;
    
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_TEXT;
        uartParams.readDataMode = UART_DATA_TEXT;
        uartParams.readReturnMode = UART_RETURN_NEWLINE;
    
        uart = UART_open(CONFIG_UART_0, &uartParams);

    Best regards,

  • Anyway, you might need to trace and debug if your application get correct sdfatfsHandle and src before you start write data to the file.

  • Hi , please look at my sysconfig screenshot, i think its already in CC26x2 driver mode. I am also not getting this option of use cc26x2 driver instead of cc26xx as in your case.

      

  • I dont think that is the case as i am able to write some dummy data into the file when i am receiving the "\n" character.

  • If you are able to write some dummy data into the file when you receive the "\n" character, there must be something wrong in your message queue processing. This is out of scope of this forum and you are on your own.

  • Okay okay. I will try but can you just tell that whether my approach is correct or i need to change it. So that i can move forward in the same line?

  • Have a brief look on your codes, I see no reason why you put “ uint8_t idx=0;” in while(1) loop of UART read.

  • I have taken this part from the pseudo code you have suggested earlier shown below. I am trying to write one line of string into the buff array after receiving "\n". If i dont use uint8_t idx = 0 in while loop then the buf array will overflow when idx crosses a value of 256.

    uint8_t idx=0;
    char buf[256];
    
    UART_read(uart, &input, 1, NULL);
    if (input!='\n'){
        //Collect input into buf[]
        buf[idx]=input;
        idx++;
    } else {
        //Input character is "\n", you can do whatever you have collect in buf[]
    }
    

  • Then, you should do limitation not to allow more than 256 bytes before you send it to write to SD card. I had do the same thing in my test and I am sure there’s no problem.

  • How i can do that?

  • Add an if condition to check how many bytes you have collected. When it reach 256 bytes, suspend collecting and do write buffer to SD card first. After SD writing, clear buffer and do collecting from scratch again.

  • Thanks , i will try this. 
    Now i think i have mostly solved the problem. Now one thing is remaining i.e. sd card file is getting written by last 256 bytes received. I think the problem is in usage of fseek to move the file pointer at the last written location. I am using the fseek command as below:

    fseek(src,0,SEEK_END);

    Is it right?

    I have also tried fputs(buf,src) but the data is just getting written once to sd card file. 

  • fseek usage looks no problem to me.

  • Okay so now as you suggested earlier i didn't use sdfatfs_open, sdfatfs_close in while loop and rather wrote it outside the while loop. Now only the last set of 256 bytes received from uart is getting written in the sd card. It means that the functionality is okay of the code as i am continuously receiving uart data and on receive of "\n", blinking the Onboard LED.  As i understand the file content is getting overwritten on the same location every time.  To be more clear i will say that every time i receive the "\n" character, i am blinking on board led after file write code lines, so it means it is successfully writing the content in file in the sd card. But the visible content is the last set of bytes received before disconnecting the board. Is it something i have to do append the content in the file or since i am opening the file every time in while loop that is why the problem is happening? When i am putting fopen outside the while loop then nothing gets written. So fopen is not a problem. Please refer my while loop code thread after receiving message queue.

    SDFatFS_Handle sdfatfsHandle;
        FILE *src;
        SDFatFS_init();
        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);
         sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
    
        while (mq_receive(*mqdes, (char *)&msg, sizeof(msg), NULL) != -1) {
            /* Turn on user LED */
            /* Open file for both reading and writing */
            src = fopen(inputfile, "w+");
           fseek(src,0,SEEK_END);
           //fwrite(&input, 1, 1, src);
           fwrite(textarray, 1, strlen(textarray), src);
           fwrite(buf, 1, strlen(buf), src);
            /* Close  inputfile[]  */
            //fclose(src);
            /* Stopping the SDCard */
            fclose(src);
            GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
            Task_sleep(sleepTickCount);
        }
    
        SDFatFS_close(sdfatfsHandle);

    I am very close YK and it is because of you thanks a lot to you and i apologize for my rude behavior before.

  • I suggest you to do fopen/fclose outside while loop to avoid fseek every time you want to write buffer.

  • I have tried that YK, in that case the file is left blank that is nothing gets written into it. Do you think i need to do fflush(buf) to clear the buffer after writing it into the file. I dont think that may be the case as i verify that the data gets overwritten so nothing from the buf side.

    Thanks,

    shivam

  • Yes, I would suggest you to call fflush to flush data to file and you also need to check if you close the file before to remove SD card to check file on your PC.

  • I tried fflush still it didn't work.  Yes i am closing the file everytime after writing the data. The issue is that the every new string overwrites the earlier written string in the file. Please take a look at my code below. One more thing that i have noticed is when i am using  fwrite(buf, 2,strlen(buf), src); instead of fwrite(buf, 1, strlen(buf), src); i am getting my cursor (file pointer) after 2 strings but one string is empty as shown in image.

    void *alarmThread(void *arg0)
    {
        mqd_t *mqdes = arg0;
        int msg;
        UInt32 sleepTickCount;
        sleepTickCount = 100000 / Clock_tickPeriod;
        SDFatFS_Handle sdfatfsHandle;
        FILE *src;
        SDFatFS_init();
        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);
         sdfatfsHandle = SDFatFS_open(CONFIG_SDFatFS_0, DRIVE_NUM);
    
    
        while (mq_receive(*mqdes, (char *)&msg, sizeof(msg), NULL) != -1)
        {
            src = fopen(inputfile, "w+");
            fseek(src,0,SEEK_END);
           //fwrite(&input, 1, 1, src);
           fwrite(textarray, 1, strlen(textarray), src);
           fwrite(buf, 1, strlen(buf), src);
           fflush(stdin);
           fclose(src);
           GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
           Task_sleep(sleepTickCount);
        }
    
        SDFatFS_close(sdfatfsHandle);
    
        return(0);
    }

  • I had suggested you to do fopen/fclose outside while loop to avoid fseek every time you want to write buffer but it seems that you don't take it.

  • No no i tried that i have told this here: Please see the image below. When i do fopen/fclose outside while loop nothing is written into the file.

  • I don't think you put fopen/fclose would cause this issue. You must not close file properly before you remove SD card from card holder.

  • can you suggest me file read write driver documentation for cc26xx?

  • As I know, there’s no dedicated document for this.

  • Hi i found this in tirtos documentation in the fatfs usage section is it something related to this that fatsfs api is able to write in a particular sector location only because of which the string is getting overwritten?
    Please see the attached image.

  • I don't see relation between the descriptions and your problem.

  • okay, please see this as well do you think this will affect as i am using both CIO Apis and FATFs apis in my code.

  • In fatsd example, you can see "const char outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";" which already fulfill this.

  • No i was talking about the highlighted text in the image. 

  • I don't see you use other mixing API, right?

  • But i am using fflush and fwrite both from stdio.h & Fatfs.

    Anyways i will study more and check.

  • The original fatsd example uses fflush and fwrite so it should have problem.

  • Okay but original fatsd example is not writing large data in the sd card. Is the example suited to write large amount of data in to the sd card?

  • Why not? I have no problem to write large data into SD card with my example code.

  • Okay i don't know then what's stopping me.

  • There must be something wrong in your application login when you open file, write data, and close the file. You have be patient to trace and debug your application.

  • Ok do you think i need to open the file in append mode?

  • It depends on if you want to overwrite it.

  • But append mode is used for appending data at the end of the file not overwriting it. Am i right?

    Is the following usage of fopen in append mode correct?

    fopen(inputfile, "a");

  • I think you need to use w+ attribute and fseek to end of file to continue writing.

  • Thanks yikai, it got solved by using fwrite in append mode.

    Many thanks for all your help.