I am converting an existing Stellaris product into one using the TM4C1294KCPDT chip. The USB OTG Device side works correctly, but the Host side does not.
I have traced the problem to the events being sent to my USBHCDEvents function -- it is receiving USB_EVENT_DISCONNECTED events every two seconds when a gamepad-like device is attached but it never receives a USB_EVENT_CONNECTED event. (The OTG polling is set for two seconds.)
My USB_OTGModeCallback function, which is called from the TIVAWARE at an interrupt level, does report that it is oscillating between the eUSBModeHost and the eUSBModeNone modes at the two second rate.
I also notice that my USBHHandpadCallback never seems to be called. Is suspect this is a consequence of the never fulling connecting....
Suggestions?
Tom
Code bit 1:
// Declare the USB Events driver interface.
DECLARE_EVENT_DRIVER(g_sUSBEventDriver, 0, 0, USBHCDEvents);
void USBHCDEvents(void *pvData);
// The global that holds all of the host drivers in use in the application.
// Two class drivers are supported -- HID and USBEvents
static const tUSBHostClassDriver * const g_ppHostClassDrivers[] =
{
&g_sUSBHIDClassDriver,
&g_sUSBEventDriver
};
// This global holds the number of class drivers in the g_ppHostClassDrivers list.
static const uint32_t g_ui32NumHostClassDrivers =
sizeof(g_ppHostClassDrivers) / sizeof(tUSBHostClassDriver *);
Code bit 2:
//*****************************************************************************
//
// USB initialization
//
// Hint: Unlike the rest of usb.c, this function runs prior to starting
// multi-tasking.
//
//*****************************************************************************
void USB_USBOTGinit(void)
{
uint32_t ui32PLLFreqHz;
bool bResult;
Error_Block eb;
//------------------------------------------------------------------------------------------------------
// Set up the chip hardware
//------------------------------------------------------------------------------------------------------
// Enable the USB peripheral and PLL (if required)
SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
// SysCtlUSBPLLEnable(); // Required for TM4C123, must not be present for TM4C129.....
// Tell the USB library the PLL frequency
ui32PLLFreqHz = 480000000;
bResult = USBOTGFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLFreqHz);
if (!bResult)
{
System_printf("USBLIB_FEATURE_USBPLL failed!\n");
System_flush();
}
// Setup USB host power control signal pins
// (Hint: USB TIVAWARE manual states other pins are handled by OTG init See Section 4.2.1)
GPIOPinConfigure(GPIO_PA6_USB0EPEN);
GPIOPinConfigure(GPIO_PA7_USB0PFLT);
GPIOPinTypeUSBDigital(NEWP_GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
USBHCDPowerConfigInit(0, USBHCD_FAULT_LOW | USBHCD_FAULT_VBUS_DIS | USBHCD_VBUS_FILTER | USBHCD_VBUS_AUTO_HIGH);
// Setup VBUS, ID, D+ and D- pins for USB operation
GPIOPinTypeUSBAnalog(NEWP_GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinTypeUSBAnalog(NEWP_GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
//------------------------------------------------------------------------------------------------------
// Initialize the USB OTG state
//------------------------------------------------------------------------------------------------------
USBStackModeSet(0, eUSBModeOTG, USB_OTGModeCallback); // set up the stack and OTG mode change callback function
g_eUSBState = STATE_NO_DEVICE; // Indicate, initially, that we are waiting for a device to be connected
g_eUSBDeviceState = DEVICE_STATE_NOT_CONFIGURED; // Indicate, initially, that we are not configured
//------------------------------------------------------------------------------------------------------
// Initialize the device stacks
//------------------------------------------------------------------------------------------------------
//
// Initialize the transmit and receive buffers.
//
USBBufferInit(&g_sTxBuffer);
USBBufferInit(&g_sRxBuffer);
// Only Bulk Transfer type of device is supported
USBDBulkInit(0, &g_sBulkDevice);
//------------------------------------------------------------------------------------------------------
// Initialize the host stacks
//------------------------------------------------------------------------------------------------------
// Register the host class drivers.
USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ui32NumHostClassDrivers); // Hint: only driver registered is HID
// Initialize the handpad driver. As part of that process, open an instance of the handpad driver.
USBHHandpadOpen(pui8InBuffer, pui8OutBuffer);
// Initialize the host control stack
USBHCDInit(0, g_pui8HCDPool, HCD_MEMORY_SIZE);
//------------------------------------------------------------------------------------------------------
// Set up the HAL to deal with USBOTG interrupts
//------------------------------------------------------------------------------------------------------
Error_init(&eb);
Hwi_Params_init(&USBOTG_Hwi_Params);
USBOTG_Hwi_Params.priority = USB0_Priority;
USBOTG_Hwi_Params.enableInt = true;
USBOTG_Hwi_Handle = Hwi_create(INT_USB0, USB0OTGModeIntHandler_wrapper, &USBOTG_Hwi_Params, &eb);
if (NULL == USBOTG_Hwi_Handle)
{
System_abort("USBOTG Hwi create failed");
}
//------------------------------------------------------------------------------------------------------
// Initialize and Enable the USB controller
//------------------------------------------------------------------------------------------------------
// Initialize the loop timer reference time
ui32LastPassTicks = Clock_getTicks();
// Initialize and Enable the USB controller
USBOTGModeInit(0, ui32MillisecToTicks(0, USBOTG_POLLING_RATE_MS), g_pui8HCDPool, HCD_MEMORY_SIZE);
Code bit 3 (from my handpad driver file):
void
USBHHandpadOpen(uint8_t *pui8InBuffer, uint8_t *pui8OutBuffer)
{
// Save the callback and data pointers.
g_sUSBHHandpad.pfnCallback = USBHHandpadCallback;
// Save the instance pointer for the HID device that was opened.
g_sUSBHHandpad.psHIDInstance = USBHHIDOpen(eUSBHHIDClassVendor, USBHHandpadCallback, (void *)&g_sUSBHHandpad);
// Save the buffer memory locations and the buffer size
g_sUSBHHandpad.pui8InBuffer = pui8InBuffer;
g_sUSBHHandpad.pui8OutBuffer = pui8OutBuffer;
g_sUSBHHandpad.ui32HIDFlags = ~USBHHANDPAD_DEVICE_PRESENT; // Initialize with device not connected
}
.