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");
}
}