| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677 |
- //*****************************************************************************
- //
- // usbhhid.c - This file contains the host HID driver.
- //
- // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved.
- // Software License Agreement
- //
- // Texas Instruments (TI) is supplying this software for use solely and
- // exclusively on TI's microcontroller products. The software is owned by
- // TI and/or its suppliers, and is protected under applicable copyright
- // laws. You may not combine this software with "viral" open-source
- // software in order to form a larger program.
- //
- // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
- // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
- // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
- // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
- // DAMAGES, FOR ANY REASON WHATSOEVER.
- //
- // This is part of AM1808 StarterWare USB Library, resused from revision 6288 of the
- // stellaris USB Library
- //
- //*****************************************************************************
- #include "hw_types.h"
- #include "usb.h"
- #include "usblib.h"
- #include "usbhid.h"
- #include "usbhost.h"
- #include "usbhhid.h"
- extern tUSBHCD g_sUSBHCD[];
- static void * HIDDriverOpen(tUSBHostDevice *pDevice, unsigned int ulDeviceInst);
- static void HIDDriverClose(void *pvInstance);
- //*****************************************************************************
- //
- //! \addtogroup usblib_host_class
- //! @{
- //
- //*****************************************************************************
- //*****************************************************************************
- //
- // The instance data storage for attached hid devices.
- //
- //*****************************************************************************
- tHIDInstance g_HIDDevice[] =
- {
- {
- 0,
- 0,
- 0,
- USBH_HID_DEV_NONE,
- 0,
- 0
- },
- {
- 0,
- 0,
- 0,
- USBH_HID_DEV_NONE,
- 0,
- 1
- }
- };
- //*****************************************************************************
- //
- //! This constant global structure defines the HID Class Driver that is
- //! provided with the USB library.
- //
- //*****************************************************************************
- const tUSBHostClassDriver g_USBHIDClassDriver =
- {
- USB_CLASS_HID,
- HIDDriverOpen,
- HIDDriverClose,
- 0
- };
- //*****************************************************************************
- //
- //! This function is used to open an instance of a HID device.
- //!
- //! \param eDeviceType is the type of device that should be loaded for this
- //! instance of the HID device.
- //! \param pfnCallback is the function that will be called whenever changes
- //! are detected for this device.
- //! \param ulCBData is the data that will be returned in when the pfnCallback
- //! function is called.
- //!
- //! This function creates an instance of an specific type of HID device. The
- //! \e eDeviceType parameter is one subclass/protocol values of the types
- //! specified in enumerated types tHIDSubClassProtocol. Only devices that
- //! enumerate with this type will be called back via the \e pfnCallback
- //! function. The \e pfnCallback parameter is the callback function for any
- //! events that occur for this device type. The \e pfnCallback function must
- //! point to a valid function of type \e tUSBCallback for this call to complete
- //! successfully. To release this device instance the caller of USBHHIDOpen()
- //! should call USBHHIDClose() and pass in the value returned from the
- //! USBHHIDOpen() call.
- //!
- //! \return This function returns and instance value that should be used with
- //! any other APIs that require an instance value. If a value of 0 is returned
- //! then the device instance could not be created.
- //
- //*****************************************************************************
- unsigned int
- USBHHIDOpen(unsigned int ulIndex,tHIDSubClassProtocol eDeviceType,
- tUSBCallback pfnCallback, unsigned int ulCBData)
- {
- //
- // Only one callback is supported.
- //
- if(g_HIDDevice[ulIndex].pfnCallback)
- {
- return (0);
- }
- //
- // Save the instance data for this device.
- //
- g_HIDDevice[ulIndex].ulIndex = ulIndex;
- g_HIDDevice[ulIndex].pfnCallback = pfnCallback;
- g_HIDDevice[ulIndex].eDeviceType = eDeviceType;
- g_HIDDevice[ulIndex].ulCBData = ulCBData;
- //
- // Return the device instance pointer.
- //
- return((unsigned int)&g_HIDDevice[ulIndex]);
- }
- //*****************************************************************************
- //
- //! This function is used to release an instance of a HID device.
- //!
- //! \param ulHIDInstance is the instance value for a HID device to release.
- //!
- //! This function releases an instance of a HID device that was created by a
- //! call to USBHHIDOpen(). This call is required to allow other HID devices
- //! to be enumerated after another HID device has been disconnected. The
- //! \e ulHIDInstance parameter should hold the value that was returned from the
- //! previous call to USBHHIDOpen().
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- USBHHIDClose(unsigned int ulHIDInstance)
- {
- tHIDInstance *pHIDInstance;
- pHIDInstance = (tHIDInstance *)ulHIDInstance;
- //
- // Disable any more notification from the HID layer.
- //
- pHIDInstance->pfnCallback = 0;
- pHIDInstance->eDeviceType = USBH_HID_DEV_NONE;
- }
- //*****************************************************************************
- //
- // This function handles callbacks for the interrupt IN endpoint.
- //
- //*****************************************************************************
- static void
- HIDIntINCallback(unsigned int ulIndex, unsigned int ulPipe, unsigned int ulEvent)
- {
- switch (ulEvent)
- {
- //
- // Handles a request to schedule a new request on the interrupt IN
- // pipe.
- //
- case USB_EVENT_SCHEDULER:
- {
- USBHCDPipeSchedule(ulIndex, ulPipe, 0, 1);
- break;
- }
- //
- // Called when new data is available on the interrupt IN pipe.
- //
- case USB_EVENT_RX_AVAILABLE:
- {
- //
- // Send the report data to the USB host HID device class driver.
- //
- g_HIDDevice[ulIndex].pfnCallback((void *)g_HIDDevice[ulIndex].ulCBData,
- USB_EVENT_RX_AVAILABLE,
- ulPipe,
- 0);
- break;
- }
- }
- }
- //*****************************************************************************
- //
- //! This function is used to open an instance of the HID driver.
- //!
- //! \param pDevice is a pointer to the device information structure.
- //!
- //! This function will attempt to open an instance of the HID driver based on
- //! the information contained in the pDevice structure. This call can fail if
- //! there are not sufficient resources to open the device. The function will
- //! return a value that should be passed back into USBHIDClose() when the
- //! driver is no longer needed.
- //!
- //! \return The function will return a pointer to a HID driver instance.
- //
- //*****************************************************************************
- static void *
- HIDDriverOpen(tUSBHostDevice *pDevice, unsigned int ulInstance)
- {
- int iIdx;
- tEndpointDescriptor *pEndpointDescriptor;
- tInterfaceDescriptor *pInterface;
- tHIDInstance *pHIDInstance;
- pHIDInstance = (tHIDInstance *)ulInstance;
-
- unsigned int ulIndex = pHIDInstance->ulIndex;
- //
- // Don't allow the device to be opened without closing first.
- //
- if(pHIDInstance->pDevice)
- {
- return (0);
- }
- //
- // Get the interface descriptor.
- //
- pInterface = USBDescGetInterface(pDevice->pConfigDescriptor, 0, 0);
- if((pInterface->bInterfaceSubClass != USB_HID_SCLASS_BOOT) ||
- (pInterface->bInterfaceProtocol != pHIDInstance->eDeviceType))
- {
- return(0);
- }
- //
- // Save the device pointer.
- //
- pHIDInstance->pDevice = pDevice;
- for(iIdx = 0; iIdx < 3; iIdx++)
- {
- //
- // Get the first endpoint descriptor.
- //
- pEndpointDescriptor = USBDescGetInterfaceEndpoint(pInterface, iIdx,
- 256);
- //
- // If no more endpoints then break out.
- //
- if(pEndpointDescriptor == 0)
- {
- break;
- }
- //
- // Interrupt
- //
- if((pEndpointDescriptor->bmAttributes & USB_EP_ATTR_TYPE_M) ==
- USB_EP_ATTR_INT)
- {
- //
- // Interrupt IN.
- //
- if(pEndpointDescriptor->bEndpointAddress & USB_EP_DESC_IN)
- {
- pHIDInstance->ulIntInPipe = USBHCDPipeAlloc(ulIndex,
- USBHCD_PIPE_INTR_IN,
- pDevice->ulAddress,
- HIDIntINCallback);
- USBHCDPipeConfig(ulIndex, pHIDInstance->ulIntInPipe,
- pEndpointDescriptor->wMaxPacketSize,
- pEndpointDescriptor->bInterval,
- (pEndpointDescriptor->bEndpointAddress &
- USB_EP_DESC_NUM_M));
- }
- }
- }
- //
- // If there is a callback function call it to inform the application that
- // the device has been enumerated.
- //
- if(pHIDInstance->pfnCallback != 0)
- {
- pHIDInstance->pfnCallback((void *)pHIDInstance->ulCBData,
- USB_EVENT_CONNECTED,
- (unsigned int)pHIDInstance, 0);
- }
- //
- // Save the device pointer.
- //
- pHIDInstance->pDevice = pDevice;
- return (pHIDInstance);
- }
- //*****************************************************************************
- //
- //! This function is used to release an instance of the HID driver.
- //!
- //! \param pvInstance is an instance pointer that needs to be released.
- //!
- //! This function will free up any resources in use by the HID driver instance
- //! that is passed in. The \e pvInstance pointer should be a valid value that
- //! was returned from a call to USBHIDOpen().
- //!
- //! \return None.
- //
- //*****************************************************************************
- static void
- HIDDriverClose(void *pvInstance)
- {
- tHIDInstance *pHIDInstance;
- pHIDInstance = (tHIDInstance *)pvInstance;
-
- //
- // No device so just exit.
- //
- if(pHIDInstance->pDevice == 0)
- {
- return;
- }
- //
- // Reset the device pointer.
- //
- pHIDInstance->pDevice = 0;
- //
- // Free the Interrupt IN pipe.
- //
- if(pHIDInstance->ulIntInPipe != 0)
- {
- USBHCDPipeFree(pHIDInstance->ulIndex, pHIDInstance->ulIntInPipe);
- }
- //
- // If the callback exists, call it with an Open event.
- //
- if(pHIDInstance->pfnCallback != 0)
- {
- pHIDInstance->pfnCallback((void *)pHIDInstance->ulCBData,
- USB_EVENT_DISCONNECTED,
- (unsigned int)&pHIDInstance, 0);
- }
- }
- //*****************************************************************************
- //
- //! This function is used to set the idle timeout for a HID device.
- //!
- //! \param ulInstance is the value that was returned from the call to
- //! USBHHIDOpen().
- //! \param ucDuration is the duration of the timeout in milliseconds.
- //! \param ucReportID is the report identifier to set the timeout on.
- //!
- //! This function will send the Set Idle command to a HID device to set the
- //! idle timeout for a given report. The length of the timeout is specified
- //! by the \e ucDuration parameter and the report the timeout for is in the
- //! \e ucReportID value.
- //!
- //! \return Always returns 0.
- //
- //*****************************************************************************
- unsigned int
- USBHHIDSetIdle(unsigned int ulInstance, unsigned char ucDuration,
- unsigned char ucReportID)
- {
- tUSBRequest SetupPacket;
- tHIDInstance *pHIDInstance;
-
- pHIDInstance = (tHIDInstance *)ulInstance;
- //
- // This is a Class specific interface OUT request.
- //
- SetupPacket.bmRequestType = USB_RTYPE_DIR_OUT | USB_RTYPE_CLASS
- | USB_RTYPE_INTERFACE;
- //
- // Request a Device Descriptor.
- //
- SetupPacket.bRequest = USBREQ_SET_IDLE;
- SetupPacket.wValue = (ucDuration << 8) | ucReportID;
- //
- // Set this on interface 1.
- //
- SetupPacket.wIndex = 0;
- //
- // This is always 0 for this request.
- //
- SetupPacket.wLength = 0;
- //
- // Put the setup packet in the buffer.
- //
- USBHCDControlTransfer(pHIDInstance->ulIndex,
- &SetupPacket,
- pHIDInstance->pDevice->ulAddress,
- 0,
- 0,
- MAX_PACKET_SIZE_EP0);
- return (0);
- }
- //*****************************************************************************
- //
- //! This function can be used to retrieve the report descriptor for a given
- //! device instance.
- //!
- //! \param ulInstance is the value that was returned from the call to
- //! USBHHIDOpen().
- //! \param pucBuffer is the memory buffer to use to store the report
- //! descriptor.
- //! \param ulSize is the size in bytes of the buffer pointed to by
- //! \e pucBuffer.
- //!
- //! This function is used to return a report descriptor from a HID device
- //! instance so that it can determine how to interpret reports that are
- //! returned from the device indicated by the \e ulInstance parameter.
- //! This call is blocking and will return the number of bytes read into the
- //! \e pucBuffer.
- //!
- //! \return Returns the number of bytes read into the \e pucBuffer.
- //
- //*****************************************************************************
- unsigned int
- USBHHIDGetReportDescriptor(unsigned int ulInstance, unsigned char *pucBuffer,
- unsigned int ulSize)
- {
- tUSBRequest SetupPacket;
- unsigned int ulBytes;
- tHIDInstance *pHIDInstance;
- pHIDInstance = (tHIDInstance *)ulInstance;
- //
- // This is a Standard Device IN request.
- //
- SetupPacket.bmRequestType = USB_RTYPE_DIR_IN | USB_RTYPE_STANDARD
- | USB_RTYPE_INTERFACE;
- //
- // Request a Report Descriptor.
- //
- SetupPacket.bRequest = USBREQ_GET_DESCRIPTOR;
- SetupPacket.wValue = USB_HID_DTYPE_REPORT << 8;
- //
- // Index is always 0 for device requests.
- //
- SetupPacket.wIndex = 0;
- //
- // All devices must have at least an 8 byte max packet size so just ask
- // for 8 bytes to start with.
- //
- SetupPacket.wLength = ulSize;
- //
- // Now get the full descriptor now that the actual maximum packet size
- // is known.
- //
- ulBytes = USBHCDControlTransfer(
- pHIDInstance->ulIndex,
- &SetupPacket,
- pHIDInstance->pDevice->ulAddress,
- pucBuffer,
- ulSize,
- pHIDInstance->pDevice->DeviceDescriptor.bMaxPacketSize0);
- return (ulBytes);
- }
- //*****************************************************************************
- //
- //! This function is used to set or clear the boot protocol state of a device.
- //!
- //! \param ulInstance is the value that was returned from the call to
- //! USBHHIDOpen().
- //! \param ulBootProtocol is either zero or non-zero to indicate which protocol
- //! to use for the device.
- //!
- //! A USB host device can use this function to set the protocol for a connected
- //! HID device. This is commonly used to set keyboards and mice into their
- //! simplified boot protocol modes to fix the report structure to a know
- //! state.
- //!
- //! \return This function returns 0.
- //
- //*****************************************************************************
- unsigned int
- USBHHIDSetProtocol(unsigned int ulInstance, unsigned int ulBootProtocol)
- {
- tUSBRequest SetupPacket;
- tHIDInstance *pHIDInstance;
- pHIDInstance = (tHIDInstance *)ulInstance;
- //
- // This is a Standard Device IN request.
- //
- SetupPacket.bmRequestType = USB_RTYPE_DIR_OUT | USB_RTYPE_CLASS
- | USB_RTYPE_INTERFACE;
- //
- // Request a Report Descriptor.
- //
- SetupPacket.bRequest = USBREQ_SET_PROTOCOL;
- if(ulBootProtocol)
- {
- //
- // Boot Protocol.
- //
- SetupPacket.wValue = 0;
- }
- else
- {
- //
- // Report Protocol.
- //
- SetupPacket.wValue = 1;
- }
- //
- // Index is always 0 for device requests.
- //
- SetupPacket.wIndex = 0;
- //
- // Always 0.
- //
- SetupPacket.wLength = 0;
- //
- // Now get the full descriptor now that the actual maximum packet size
- // is known.
- //
- USBHCDControlTransfer(
- pHIDInstance->ulIndex,
- &SetupPacket,
- pHIDInstance->pDevice->ulAddress,
- 0,
- 0,
- pHIDInstance->pDevice->DeviceDescriptor.bMaxPacketSize0);
- return (0);
- }
- //*****************************************************************************
- //
- //! This function is used to retrieve a report from a HID device.
- //!
- //! \param ulInstance is the value that was returned from the call to
- //! USBHHIDOpen().
- //! \param ulInterface is the interface to retrieve the report from.
- //! \param pucData is the memory buffer to use to store the report.
- //! \param ulSize is the size in bytes of the buffer pointed to by
- //! \e pucBuffer.
- //!
- //! This function is used to retrieve a report from a USB pipe. It is usually
- //! called when the USB HID layer has detected a new data available in a USB
- //! pipe. The USB HID host device code will receive a
- //! \b USB_EVENT_RX_AVAILABLE event when data is available, allowing the
- //! callback function to retrieve the data.
- //!
- //! \return Returns the number of bytes read from report.
- //
- //*****************************************************************************
- unsigned int
- USBHHIDGetReport(unsigned int ulInstance,
- unsigned int ulInterface,
- unsigned char *pucData,
- unsigned int ulSize)
- {
- tHIDInstance *pHIDInstance;
- //
- // Cast the instance pointer to the correct type for ease of use.
- //
- pHIDInstance = (tHIDInstance *)ulInstance;
- //
- // Read the Data out.
- //
- ulSize = USBHCDPipeReadNonBlocking(pHIDInstance->ulIndex, pHIDInstance
- ->ulIntInPipe, pucData, ulSize);
- //
- // Return the number of bytes read from the interrupt in pipe.
- //
- return(ulSize);
- }
- //*****************************************************************************
- //
- //! This function is used to send a report to a HID device.
- //!
- //! \param ulInstance is the value that was returned from the call to
- //! USBHHIDOpen().
- //! \param ulInterface is the interface to send the report to.
- //! \param pucData is the memory buffer to use to store the report.
- //! \param ulSize is the size in bytes of the buffer pointed to by
- //! \e pucBuffer.
- //!
- //! This function is used to send a report to a USB HID device. It can be
- //! only be called from outside the callback context as this function will not
- //! return from the call until the data has been sent successfully.
- //!
- //! \return Returns the number of bytes sent to the device.
- //
- //*****************************************************************************
- unsigned int
- USBHHIDSetReport(unsigned int ulInstance, unsigned int ulInterface,
- unsigned char *pucData, unsigned int ulSize)
- {
- tUSBRequest SetupPacket;
- tHIDInstance *pHIDInstance;
- pHIDInstance = (tHIDInstance *)ulInstance;
- //
- // This is a Standard Device IN request.
- //
- SetupPacket.bmRequestType = USB_RTYPE_DIR_OUT | USB_RTYPE_CLASS
- | USB_RTYPE_INTERFACE;
- //
- // Request a Report Descriptor.
- //
- SetupPacket.bRequest = USBREQ_SET_REPORT;
- SetupPacket.wValue = USB_HID_REPORT_OUTPUT << 8;
- //
- // Index is always 0 for device requests.
- //
- SetupPacket.wIndex = (unsigned short)ulInterface;
- //
- // Always 0.
- //
- SetupPacket.wLength = ulSize;
- //
- // Now get the full descriptor now that the actual maximum packet size
- // is known.
- //
- USBHCDControlTransfer(pHIDInstance->ulIndex, &SetupPacket, pHIDInstance
- ->pDevice->ulAddress, pucData, ulSize, pHIDInstance
- ->pDevice->DeviceDescriptor.bMaxPacketSize0);
- return (ulSize);
- }
- //*****************************************************************************
- //
- //! @}
- //
- //*****************************************************************************
|