The code in USBHMouseInit() in the file host/usbhhidmouse.c looks like this:
uint32_t USBHMouseInit(tUSBHMouse *psMsInstance) { // Set the initial rate to only update on mouse state changes. USBHHIDSetIdle(psMsInstance->psHIDInstance, 0, 0); // Read out the Report Descriptor from the mouse and parse it for the format of the reports coming back from the mouse. USBHHIDGetReportDescriptor(psMsInstance->psHIDInstance, psMsInstance->pui8Heap, psMsInstance->ui32HeapSize); // Set the mouse to boot protocol. USBHHIDSetProtocol(psMsInstance->psHIDInstance, 1); return(0); }
Note that this code does not check the return value of the calls to USBHHIDSetIdle(), USBHHIDGetReportDescriptor() and USBHHIDSetProtocol().
To my surprise, when I did check the return values, each of these three function calls seemed to return 0xffffffff, which is an error code returned by USBHCDControlTransfer(), which is a function called by each of these three functions. In particular, I wanted to get the HID Report Descriptor returned by USBHHIDGetReportDescriptor(). But this function only returned 0xffffffff. Incidentally, the comment which states "... and parse it for the format of the reports ..." is a little bit misleading: the TivaWare USB Library does not seem to actually include code capable of parsing HID Report Descriptors.
The reason for USBHCDControlTransfer() returning 0xffffffff seems to be that the member psDevice of the struct tHIDInstance seems to be NULL. A pointer to the struct tHIDInstance is passed in as the first argument to each of these functions as psMsInstance->psHIDInstance.
Further investigation showed that the pointer to this struct is initialized by the return value of the function USBHHIDOpen() called in the function USBHMouseOpen(), which looks as follows:
tUSBHMouse *USBHMouseOpen(tUSBHIDMouseCallback pfnCallback, uint8_t *pui8Buffer, uint32_t ui32Size) { // Save the callback and data pointers. g_sUSBHMouse.pfnCallback = pfnCallback; // Save the instance pointer for the HID device that was opened. g_sUSBHMouse.psHIDInstance = USBHHIDOpen(eUSBHHIDClassMouse, USBHMouseCallback, (void *)&g_sUSBHMouse); // Save the heap buffer and size. g_sUSBHMouse.pui8Heap = pui8Buffer; g_sUSBHMouse.ui32HeapSize = ui32Size; return(&g_sUSBHMouse); }
However, since USBHMouseOpen() is called very early in the USB Host Stack initialization process, at the time USBHMouseOpen() initializes psHIDInstance, the member psDevice is still NULL. psDevice seems to get a value only later on in the process.
I solved this by adding the following in the USBHMouseCallback() callback function:
uint32_t USBHMouseCallback(void *pvMouse, uint32_t ui32Event, uint32_t ui32MsgParam, void *pvMsgData) { tUSBHMouse *psMsInstance; // Recover the pointer to the instance data psMsInstance = (tUSBHMouse *)pvMouse; switch(ui32Event) { // New mouse has been connected so notify the application. case USB_EVENT_CONNECTED: o_debug_print(3, "Mouse Connected\r\n"); // Remember that a mouse is present psMsInstance->ui32HIDFlags |= USBHMSWW_DEVICE_PRESENT; // ADDED: Save psHIDInstance tHIDInstance *lpHIDInstance = (tHIDInstance *) ui32MsgParam; psMsInstance->psHIDInstance = lpHIDInstance; // Notify the application that a new mouse was connected psMsInstance->pfnCallback(0, ui32Event, ui32MsgParam, pvMsgData); break;
By the time the callback function USBHMouseCallback() gets called with a ui32Event value of USB_EVENT_CONNECTED, the psDevice member in the instance of psHIDInstance passed in as ui32MsgParam, has gotten a value.
Please note that the same issue seems to occur in host/usbhhidkeyboard.c, and the above described solution works there as well.
I would like to know if the behavior I am observing, of psDevice being NULL when the function calls in USBHMouseInit() are taking place, is because of some error or misunderstanding on my end, or whether this seems to be an issue with these host drivers.
Thank you,
Ariel