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.

Initializing USB to recognize a USB Stick

Other Parts Discussed in Thread: SYSBIOS, EK-TM4C123GXL

I am using the Tiva C Series dk-TM4C123G and I can't get it to consistantly recognize that I have a USB stick attached. If I run the example usb_host_msc first my code work after this. I think it is because USBHMSCDriveOpen(0,MSCCallback); is not registering the callback properly. If I power cycle and run my code it never gets to the MSCCallback code. If I run usb_host_msc first and then my code the callback starts happening.

#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/gates/GateMutex.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Task.h>

#include <stdbool.h>

/* driverlib Header files */
#include <inc/hw_ints.h>
#include <inc/hw_types.h>

/* usblib Header files */
#include <usblib/usb-ids.h>
#include <usblib/usblib.h>
#include <usblib/usbhid.h>
#include <usblib/host/usbhost.h>
#include <usblib/host/usbhhid.h>
#include <usblib/host/usbhhidmouse.h>
#include <usblib/host/usbhmsc.h>
#include <driverlib/rom_map.h>
#include <driverlib/sysctl.h>
#include <driverlib/udma.h>
#include <driverlib/rom.h>
/* Example/Board Header files */
#include "USBMH.h"

#if defined(TIVAWARE)
typedef tUSBHMouse             *USBMHType;
typedef UInt                    USBMHEventType;
typedef Void                    USBMHHandleType;
#else /* MWARE */
#define g_sUSBHIDClassDriver    g_USBHIDClassDriver
#define ui32Event               ulEvent
#define eUSBModeHost            USB_MODE_HOST
typedef ULong                   USBMHType;
typedef ULong                   USBMHEventType;
typedef ULong                   USBMHHandleType;
#endif

/* Defines */
#define HCDMEMORYPOOLSIZE   128 /* Memory for the Host Class Driver */
#define MMEMORYPOOLSIZE     128 /* Memory for the mouse host driver */

 

/* Static variables and handles */
//static volatile USBMH_USBState state;
static UChar            memPoolHCD[HCDMEMORYPOOLSIZE];

static volatile Char    xPosition;
static volatile Char    yPosition;
static volatile UChar   mouseButtons;

static GateMutex_Handle gateUSBWait;
static GateMutex_Handle gateUSBLibAccess;
static Semaphore_Handle semUSBConnected;
tDMAControlTable g_psDMAControlTable[6];


//*****************************************************************************
//
// The instance data for the MSC driver.
//
//*****************************************************************************
tUSBHMSCInstance *g_psMSCInstance = 0;

 

static Void USBMH_hwiHandler(UArg arg0);
static Void serviceUSBHost(UArg arg0, UArg arg1);
static Void usbHCDEvents(Void *cbData);
Void USBMH_getState(USBMH_State *mouseState);
Void USBMH_init(Void);
Bool USBMH_waitForConnect(UInt timeout);

/* MACRO to create a generic USB event host driver */
DECLARE_EVENT_DRIVER(USBMH_eventDriver, 0, 0, usbHCDEvents);

//*****************************************************************************
//
// Holds global flags for the system.
//
//*****************************************************************************
static volatile uint32_t g_ui32Flags = 0;

//*****************************************************************************
//
// Flag indicating that some USB device is connected.
//
//*****************************************************************************
#define FLAGS_DEVICE_PRESENT    0x00000001
#define FLAGS_FILE_OPENED       0x00000002

typedef volatile enum
{
    //
    // No device is present.
    //
    STATE_NO_DEVICE,

    //
    // Mass storage device is being enumerated.
    //
    STATE_DEVICE_ENUM,

    //
    // Mass storage device is ready.
    //
    STATE_DEVICE_READY,

    //
    // An unsupported device has been attached.
    //
    STATE_UNKNOWN_DEVICE,

    //
    // A mass storage device was connected but failed to ever report ready.
    //
    STATE_TIMEOUT_DEVICE,

    //
    // A power fault has occurred.
    //
    STATE_POWER_FAULT
}
USBState;
USBState g_eState;

/* A list of available Host Class Drivers */
static tUSBHostClassDriver const * const usbHCDDriverList[] = {
    &g_sUSBHostMSCClassDriver,
    &USBMH_eventDriver
};

/* Variable containing the number of HCDs in usbHCDDriverList */
const ULong numHostClassDrivers =
    sizeof(usbHCDDriverList) / sizeof(tUSBHostClassDriver *);

 

/*
 *  ======== USBMH_hwiHandler ========
 *  This function calls the USB library's device interrupt handler.
 */
static Void USBMH_hwiHandler(UArg arg0)
{
    USB0HostIntHandler();
}

static void
MSCCallback(tUSBHMSCInstance *ps32Instance, uint32_t ui32Event, void *pvData)
{
    //
    // Determine the event.
    //
    switch(ui32Event)
    {
        //
        // Called when the device driver has successfully enumerated an MSC
        // device.
        //
        case MSC_EVENT_OPEN:
        {
            //
            // Proceed to the enumeration state.
            //
            g_eState = STATE_DEVICE_ENUM;

            break;
        }

        //
        // Called when the device driver has been unloaded due to error or
        // the device is no longer present.
        //
        case MSC_EVENT_CLOSE:
        {
            //
            // Go back to the "no device" state and wait for a new connection.
            //
            g_eState = STATE_NO_DEVICE;

            //
            // Re-initialize the file system.
            //
          //  FileInit();

            break;
        }

        default:
        {
            break;
        }
    }
    System_printf("Callback \n");
    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

}


/*
 *  ======== serviceUSBHost ========
 *  Task to periodically service the USB Stack
 *
 *  USBHCDMain handles the USB Stack's state machine. For example it handles the
 *  enumeration process when a device connects.
 *  Future USB library improvement goal is to remove this polling requirement..
 */
static Void serviceUSBHost(UArg arg0, UArg arg1)
{
    UInt key;

    while (TRUE) {

        key = GateMutex_enter(gateUSBLibAccess);
       USBHCDMain();

          switch(g_eState)
             {
                  //
                  // A device has enumerated.
                  //
              //
              // A device has enumerated.
              //
              case STATE_DEVICE_ENUM:
              {
                  //
                  // Check to see if the device is ready.  If not then stay
                  // in this state and we will check it again on the next pass.
                  //
                  if(USBHMSCDriveReady(g_psMSCInstance) != 0)
                  {
                      //
                      // Wait about 500ms before attempting to check if the
                      // device is ready again.
                      //
                      SysCtlDelay(MAP_SysCtlClockGet()/3);
                      break;

                  }
                  //
                   // If there were no errors reported, we are ready for
                   // MSC operation.
                   //
                   g_eState = STATE_DEVICE_READY;

                   //
                   // Set the Device Present flag.
                   //
                   g_ui32Flags = FLAGS_DEVICE_PRESENT;

                   break;
              }
              case STATE_NO_DEVICE:
              {
                  if(g_ui32Flags == FLAGS_DEVICE_PRESENT)
                  {
                      //
                      // Clear the Device Present flag.
                      //
                      g_ui32Flags &= ~(FLAGS_DEVICE_PRESENT | FLAGS_FILE_OPENED);
                  }
                  break;
              }
              //
              // An unknown device was connected.
              //
              case STATE_UNKNOWN_DEVICE:
              {
                  //
                  // If this is a new device then change the status.
                  //
                  if((g_ui32Flags & FLAGS_DEVICE_PRESENT) == 0)
                  {
                      //
                      // Unknown device is present
                      //
                  }

                  //
                  // Set the Device Present flag even though the unknown device
                  // is not useful to us.
                  //
                  g_ui32Flags = FLAGS_DEVICE_PRESENT;
                  break;
              }

              //
              // The device is ready and in use.
              //
              case STATE_DEVICE_READY:
              {
                  break;
              }

              default:
              {
                  g_eState = STATE_NO_DEVICE;
                  g_ui32Flags &= ~(FLAGS_DEVICE_PRESENT | FLAGS_FILE_OPENED);
                  break;
              }
          }

        GateMutex_leave(gateUSBLibAccess, key);

        /* Future enhancement to remove the Task_sleep */
        Task_sleep(10);
    }
}
/*
 *  ======== usbHCDEvents ========
 *  Generic USB Host Class Driver event callback.
 *
 *  This callback is called to notify the application that a unknown device was
 *  connected. (e.g. It wasn't a mouse)
 */
static Void usbHCDEvents(Void *cbData)
{
    tEventInfo *pEventInfo;

    /* Cast this pointer to its actual type. */
    pEventInfo = (tEventInfo *)cbData;

    switch (pEventInfo->ui32Event) {

        case USB_EVENT_UNKNOWN_CONNECTED:
            /* An unknown device was detected. */
            g_eState = STATE_UNKNOWN_DEVICE;
            break;

        case USB_EVENT_DISCONNECTED:
            /* Unknown device has been removed. */
            g_eState = STATE_NO_DEVICE;
            break;

        case USB_EVENT_POWER_FAULT:
            /* No power means no device is present. */
            g_eState = STATE_POWER_FAULT;
            break;

        default:
            break;
    }
}


/*
 *  ======== USBMH_init ========
 */
Error_Block eb;
void USBMH_init(void)
{
    Hwi_Handle hwi;
    Task_Handle task;
    Task_Params taskParams;

    Semaphore_Params semParams;

    Error_init(&eb);
    // Enable the uDMA controller and set up the control table base.
     // The uDMA controller is used by the USB library.
     //
     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
     ROM_uDMAEnable();
     ROM_uDMAControlBaseSet(g_psDMAControlTable);

    /* Initialize the USB stack for host mode. */
    USBStackModeSet(0, eUSBModeHost, NULL);


    /* Register host class drivers */
    USBHCDRegisterDrivers(0, usbHCDDriverList, numHostClassDrivers);

    /* Open an instance of the mouse host driver
    mouseInstance = USBHMouseOpen(cbMouseHandler, memPoolM, MMEMORYPOOLSIZE);
    if(!mouseInstance) {
        System_abort("Error initializing the Mouse Host");
    }
*/

    /* Install interrupt handler */
    hwi = Hwi_create(INT_USB0, USBMH_hwiHandler, NULL, &eb);
    if (hwi == NULL) {
        System_abort("Can't create USB Hwi");
    }
    g_psMSCInstance = USBHMSCDriveOpen(0,MSCCallback);

    /* Initialize USB power configuration */
    USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);

    /* Enable the USB stack */
    USBHCDInit(0, memPoolHCD, HCDMEMORYPOOLSIZE);


    /* RTOS primitives */
    Semaphore_Params_init(&semParams);
    semParams.mode = Semaphore_Mode_BINARY;
    semUSBConnected = Semaphore_create(0, &semParams, &eb);
    if (semUSBConnected == NULL) {
        System_abort("Could not create USB Connect semaphore");
    }

    gateUSBLibAccess = GateMutex_create(NULL, &eb);
    if (gateUSBLibAccess == NULL) {
        System_abort("Could not create USB Wait gate");
    }

    gateUSBWait = GateMutex_create(NULL, &eb);
    if (gateUSBWait == NULL) {
        System_abort("Could not create USB Wait gate");
    }

   /*
    * Note that serviceUSBHost() should not be run until the USB Stack has been
    * initialized!!
   */
    Task_Params_init(&taskParams);
    taskParams.priority = 15;
    task = Task_create(serviceUSBHost, &taskParams, &eb);
    if (task == NULL) {
            System_abort("Can't create USB service task");
    }

 

}

  • Hi Teresa,

    What version of TI-RTOS are you using?

    I think you might be pulling code in from two different examples. Half of it seems to come from the USB Host mouse and other half from TivaWare's MSC Host driver.

    Are you trying to use both USB Host HID mouse and USB Host MSC?

    If you want to just use MSC host (no Host HID mouse) I'd take a look at the USBMSCHFatFs driver in TI-RTOS.

    (C:\ti\tirtos_1_20_00_28\packages\ti\drivers\usbmschfatfs\USBMSCHFatFsTiva.c)
  • I am using version 1_10_00_23 that is what the eval board came with. I was pulling code from two examples. The mouse application was using the RTOS and the USB Host MSC example was not using the RTOS so I was trying to pull the code that was required for the MSC into the example that used the RTOS. My version of RTOS does the USBMSCHfatFs driver so I will look at that.  I have to use an RTOS for application that I am writing for -  I can't have it all sitting in a while(1) in the main function.

  • Is there an example  that uses the USBMSCHFatFSTiva.c and Ti BIOS

  • FatSD USB Copy

    The USBMSCHFatFs driver is integrated into SYS/BIOS' FatFS module. The only driver APIs are the _open, _close, and _waitForConnect APIs.

  • There is no FatSD USB Copy for dk-TM4C123G. When I tried TI-RTOS it was missing a couple key parts in the EK_TM4C123GXL.c and EK_TM4C123GXL.h files. Specificly Board_initUSBMSCHFatFs(); and it associated config information.
    When I tried to insert them into the example I got an error informing me "USB host not supported".
    Is there something I can do to get the autocreated files to include the init functions? or a a TI-RTOS example?
    Thanks, I've wasted way too many hours today.
    T-Rex
    SSI-Racing
    Making green sexy since 2006
  • Hi Michael,

    The FatSD USB Copy example is not supported on the TM4C123GXL board, as this board does not support USB host mode. Please refer to section "3.5 Summary of Example Peripheral Use and Target Support" of the TI-RTOS Getting Started Guide for a table which displays example support for various hardware platforms.

    Steve
  • Thank you Steve for your reply,

    I read the Tiva™ C Series TM4C123G LaunchPad Evaluation Board pdf and -

    1.3 Features
    Your Tiva C Series LaunchPad includes the following features:
    • Tiva TM4C123GH6PMI microcontroller
    • Motion control PWM
    • USB micro-A and micro-B connector for USB device, host, and on-the-go (OTG) connectivity

    Am I missing something or is it not supported by the TI-RTOS? Not supported by TI-RTOS is fine, not supported is an issue that would require me to make some unplanned changes.

    I have a product that I would like to put a USB stick logging feature on. One of the clients had an emergency and needs a prototype this week. The daughter board done, tested, works for months. I have been using the SD FatFS since december so I shouldn't have a problem implementing if I could find a TIVAware compatible USB FatFS example.

    Is there somewhere I can find a USB Stick writing example that works on the EK-TM4C123GXL?

    Thank you
  • Michael,

    Sorry, I think I was confused on which board you are using.  We do have the USB example for the DK-TM4C123GH6PGE:

    Steve

  • Actually the excerpt is from the EK-TM4C123GXL PDF which, as you noted, does not have any OTG / Host examples and the TI-RTOS file does not support HostMode.