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.

RTOS/TM4C1294NCPDT: Recovering after USBMSCHFatFs_waitForConnect

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Tool/software: TI-RTOS

Hello

I have application that performs usbstick operation with TM4c1294 using TI-RTOS which can write and read file from usb flash drive. I am using USBMSCHFatFs drivers to perform operation.

Program check for USB is connected (using USBMSCHFatFs_waitForConnect) before executing any read write operation. It has 10 second delay in USBMSCHFatFs_waitForConnect.

if USB flashdrive is not connected and delay expires, it quits the operation.

The problem is once that happens next time when I connect USB flash drive and try to read or write  it receives NULL from USBMSCHFatFs_open.

I tried re-initializing USB driver but did not work. Also tried closing USBMSCHFatFs (USBMSCHFatFs_close) did not helped.  Only way I can make that work is using Power reset.

Thanks

  • Hi,

    Tushar Patel40 said:
    It has 10 second delay in USBMSCHFatFs_waitForConnect. if USB flashdrive is not connected and delay expires, it quits the operation.

    What happens when you remove delay or make it infinite loop task?

  • Tushar,

    Can you give the actual code you are using? If that's not possible, can you reproduce it with modifying the fatsdusbcopy example? Also, what version of TI-RTOS are you using?

    Todd
  • I am using TI-RTOS 2.16.1.14. Here is the routine which checks for USB connection.

    uint8_t CheckUSBConnected(void)
    {
        USBMSCHFatFs_Handle usbmschfatfsHandle;
        USBMSCHFatFs_Params usbmschfatfsParams;

        /* Mount and register the USB Drive */
        USBMSCHFatFs_Params_init(&usbmschfatfsParams);
        usbmschfatfsParams.serviceTaskStackPtr = usbServiceTaskStack;
        usbmschfatfsParams.serviceTaskStackSize = sizeof(usbServiceTaskStack);
        usbmschfatfsHandle = USBMSCHFatFs_open(Board_USBMSCHFatFs0,
                                               USB_DRIVE_NUM,
                                              &usbmschfatfsParams);
        if (usbmschfatfsHandle == NULL) {
            //System_abort("Error starting the USB Drive\n");
            LCD_DisplayMessageFullScreen("Error starting the USB   Drive");
            //USB_Init();

    //USBMSCHFatFs_close(usbmschfatfsHandle);


            return 0;
        }

         /* Need to block until a USB Drive has been enumerated */
        if (!USBMSCHFatFs_waitForConnect(usbmschfatfsHandle, 10000)) {
            //System_abort("No USB drive present, aborting...\n");
            LCD_DisplayMessageFullScreen("No USB drive present,   aborting...");
           // USB_Init();

    //USBMSCHFatFs_close(usbmschfatfsHandle);
            return 0;

    }

        /* Stopping the USB Drive */
        USBMSCHFatFs_close(usbmschfatfsHandle);
        System_printf("Drive %u unmounted\n", USB_DRIVE_NUM);

        return 1;
    }

  • If I increase delay to make it infinite loop, it just wait forever and whenever flash is connected it performs the task. That's what I have done for now but I want to quit operation if flashdrive is not connected and so user can perform operation later again.

  • Perhaps create a task to invoke a GPTM timer interval where interrupt handler polls [uint8_t CheckUSBConnected(void)] and remove blocking code(WaitForConnect) & delay directives.
  • I was able to call USBMSCHFatFs_close after a falled USBMSCHFatFs_open() and then later call USBMSCHFatFs_open and then USBMSCHFatFs_waitForConnect again (after I plugged in the USB drive) and have it work. I did notice that the LP reset sometimes with certain USB sticks when I plugged it in. It was running a slightly modified fatsdusbcopy_EK_TM4C1294XL_TI_TivaTM4C1294NCPDT example (attached).

    fatsdusbcopy.c
    /*
     * Copyright (c) 2015, 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.
     */
    
    /*
     *  ======== fatsdusbcopy.c ========
     */
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SDSPI.h>
    #include <ti/drivers/USBMSCHFatFs.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    /* Buffer size used for the file copy process */
    #define CPY_BUFF_SIZE       2048
    
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define SD_DRIVE_NUM           0
    #define USB_DRIVE_NUM          1
    
    #define TASKSTACKSIZE          1024
    /*
     * Static task stack for the USBMSCHFatFs USB driver
     * This allows the application to reduce the required system Heap.
     */
    static uint8_t usbServiceTaskStack[1024];
    
    const char  inputfilesd[]  = "fat:"STR(SD_DRIVE_NUM)":input.txt";
    const char outputfileusb[] = "fat:"STR(USB_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";
    
    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];
    
    unsigned char cpy_buff[CPY_BUFF_SIZE];
    
    /*
     *  ======== taskFxn ========
     *  Task to perform a file copy
     *
     *  Task 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).
     *
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void taskFxn(UArg arg0, UArg arg1)
    {
        SDSPI_Handle sdspiHandle;
        SDSPI_Params sdspiParams;
        USBMSCHFatFs_Handle usbmschfatfsHandle;
        USBMSCHFatFs_Params usbmschfatfsParams;
    
        /* 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;
    
        /* Mount and register the USB Drive */
        SDSPI_Params_init(&sdspiParams);
        sdspiHandle = SDSPI_open(Board_SDSPI0, SD_DRIVE_NUM, &sdspiParams);
        if (sdspiHandle == NULL) {
            System_abort("Error starting the SD card\n");
        }
        else {
            System_printf("Drive %u is mounted\n", SD_DRIVE_NUM);
        }
    
        Task_sleep(1000);
        while (1) {
            /* Mount and register the USB Drive */
            USBMSCHFatFs_Params_init(&usbmschfatfsParams);
            usbmschfatfsParams.serviceTaskStackPtr = usbServiceTaskStack;
            usbmschfatfsParams.serviceTaskStackSize = sizeof(usbServiceTaskStack);
            usbmschfatfsHandle = USBMSCHFatFs_open(Board_USBMSCHFatFs0,
                                                   USB_DRIVE_NUM,
                                                  &usbmschfatfsParams);
            if (usbmschfatfsHandle == NULL) {
                System_abort("Error starting the USB Drive\n");
            }
            else {
                System_printf("Drive %u is mounted\n", USB_DRIVE_NUM);
            }
    
    
            GPIO_write(Board_LED0, Board_LED_OFF);
            GPIO_toggle(Board_LED1);
            /* Need to block until a USB Drive has been enumerated */
            if (USBMSCHFatFs_waitForConnect(usbmschfatfsHandle, 5000)) {
                break;
            }
            USBMSCHFatFs_close(usbmschfatfsHandle);
        }
    
        GPIO_write(Board_LED0, Board_LED_ON);
        /* Try to open the source file */
        src = fopen(inputfilesd, "r");
        if (!src) {
            System_printf("Creating a new file \"%s\"...", inputfilesd);
    
            /* Open file for both reading and writing */
            src = fopen(inputfilesd, "w+");
            if ( !src ) {
                System_printf("Error: \"%s\" could not be created.\n"
                              "Please check the Getting Started Guide "
                              "if additional jumpers are necessary.\n",
                              inputfilesd);
                System_abort("Aborting...\n");
            }
    
            fwrite(textarray, 1, strlen(textarray), src);
            fflush(src);
    
            /* Reset the internal file pointer */
            rewind(src);
    
            System_printf("done\n");
        }
        else {
            System_printf("Using existing copy of \"%s\"\n", inputfilesd);
        }
    
        /* Create a new file object for the file copy */
        dst = fopen(outputfileusb, "w");
        if (!dst) {
            System_printf("Error opening \"%s\"\n", outputfileusb);
            System_abort("Aborting...\n");
        }
        else {
            System_printf("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) {
                System_printf("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);
    
        System_printf("File \"%s\" (%u B) copied to \"%s\" (Wrote %u B)\n",
                      inputfilesd, filesize, outputfileusb, totalBytesCopied);
    
        /* Now output the outputfile[] contents onto the console */
        dst = fopen(outputfileusb, "r");
        if (!dst) {
            System_printf("Error opening \"%s\"\n", outputfileusb);
            System_abort("Aborting...\n");
        }
    
        /* 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 */
            }
            /* Write output */
            System_printf("%s", cpy_buff);
        }
    
        /* Close the file */
        fclose(dst);
    
        /* Stopping the SDCard */
        SDSPI_close(sdspiHandle);
        System_printf("Drive %u unmounted\n", SD_DRIVE_NUM);
    
        /* Stopping the USB Drive */
        USBMSCHFatFs_close(usbmschfatfsHandle);
        System_printf("Drive %u unmounted\n", USB_DRIVE_NUM);
    
        while (1) {
            Task_sleep(200);
            GPIO_toggle(Board_LED0);
            GPIO_toggle(Board_LED1);
        }
        BIOS_exit(0);
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        Task_Params taskParams;
    
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initSDSPI();
        Board_initUSBMSCHFatFs();
    
        /* Construct file copy Task thread */
        Task_Params_init(&taskParams);
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = &task0Stack;
        taskParams.instance->name = "fatsdUSBCopyTask";
        Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL);
    
        /* Turn on user LED */
        GPIO_write(Board_LED0, Board_LED_ON);
        GPIO_write(Board_LED1, Board_LED_ON);
    
        System_printf("Starting the FatSD USB Copy example\n");
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

    I'm not sure what's going on with the reset with some of the USB drives. If you are seeing it also, we should ping the TM4C engineers. I'm using the EK-TM4C1294XL LaunchPad.

    Todd

  • Cal you elaborate what is LP reset mean?

  • Sorry for the poor grammar.

    I did notice that the LaunchPad would reset sometimes with certain USB sticks when I plugged it in.
  • Problem you are seeing could be extension of issue I have. I am not using LuanchPad but it is same micro-controller (TM4C1294). My USB driver are originally based on fatsdusbcopy with modification as I am not using PD6,PD7 and PQ4 (which are optional for external power control) and but I have similar task in subroutine which I called based on user input. System_abort is replaced with return status.  Here is my current code for initialization and USB connection check.

    void USB_Init(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        uDMAEnable();
        uDMAControlBaseSet(dmaControlTable);

        /* Enable the USB peripheral and PLL */
        SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
        SysCtlUSBPLLEnable();

        /* Setup pins for USB operation */
        GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);

        USBMSCHFatFs_init();
    }

    uint8_t CheckUSBConnected(void)
    {
        USBMSCHFatFs_Handle usbmschfatfsHandle;
        USBMSCHFatFs_Params usbmschfatfsParams;
        uint8_t status = 0;
        /* Mount and register the USB Drive */
        USBMSCHFatFs_Params_init(&usbmschfatfsParams);
        usbmschfatfsParams.serviceTaskStackPtr = usbServiceTaskStack;
        usbmschfatfsParams.serviceTaskStackSize = sizeof(usbServiceTaskStack);
        usbmschfatfsHandle = USBMSCHFatFs_open(Board_USBMSCHFatFs0,
                                               USB_DRIVE_NUM,
                                              &usbmschfatfsParams);
        if (usbmschfatfsHandle == NULL)
        {
            LCD_DisplayMessageFullScreen("Error starting the USB   Drive");
            status = 0;
        }
        else
        {
            LCD_DisplayMessage("Connecting to USB flash drive.....");

            /* Need to block until a USB Drive has been enumerated */
            if (!USBMSCHFatFs_waitForConnect(usbmschfatfsHandle, 10000))
            {
                LCD_DisplayMessageFullScreen("No USB drive present,   aborting...");
                status = 0;
            }
            else
            {
                status = 1;
            }
        }
        /* Stopping the USB Drive */
        USBMSCHFatFs_close(usbmschfatfsHandle);
        return status;
    }

    The major issue for me right now is over longer period(10 to 15 days) of time, USB driver stops working. When my code try to check for USB stick is connected and get stuck in 

    if (!USBMSCHFatFs_waitForConnect(usbmschfatfsHandle, 10000))  and never quit until I remove stick.

    Also, I was checking signals USBD_N and USBD_P.   USBD_P stays high during normal working operation but drops to low when I have this problem.

    We try to look for more detail about these two signal but seems like data sheet for TM4C1294NCDPT requires NDA for full information about USB section.