usbhhid.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. //*****************************************************************************
  2. //
  3. // usbhhid.c - This file contains the host HID driver.
  4. //
  5. // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of AM1808 StarterWare USB Library, resused from revision 6288 of the
  22. // stellaris USB Library
  23. //
  24. //*****************************************************************************
  25. #include "hw_types.h"
  26. #include "usb.h"
  27. #include "usblib.h"
  28. #include "usbhid.h"
  29. #include "usbhost.h"
  30. #include "usbhhid.h"
  31. extern tUSBHCD g_sUSBHCD[];
  32. static void * HIDDriverOpen(tUSBHostDevice *pDevice, unsigned int ulDeviceInst);
  33. static void HIDDriverClose(void *pvInstance);
  34. //*****************************************************************************
  35. //
  36. //! \addtogroup usblib_host_class
  37. //! @{
  38. //
  39. //*****************************************************************************
  40. //*****************************************************************************
  41. //
  42. // The instance data storage for attached hid devices.
  43. //
  44. //*****************************************************************************
  45. tHIDInstance g_HIDDevice[] =
  46. {
  47. {
  48. 0,
  49. 0,
  50. 0,
  51. USBH_HID_DEV_NONE,
  52. 0,
  53. 0
  54. },
  55. {
  56. 0,
  57. 0,
  58. 0,
  59. USBH_HID_DEV_NONE,
  60. 0,
  61. 1
  62. }
  63. };
  64. //*****************************************************************************
  65. //
  66. //! This constant global structure defines the HID Class Driver that is
  67. //! provided with the USB library.
  68. //
  69. //*****************************************************************************
  70. const tUSBHostClassDriver g_USBHIDClassDriver =
  71. {
  72. USB_CLASS_HID,
  73. HIDDriverOpen,
  74. HIDDriverClose,
  75. 0
  76. };
  77. //*****************************************************************************
  78. //
  79. //! This function is used to open an instance of a HID device.
  80. //!
  81. //! \param eDeviceType is the type of device that should be loaded for this
  82. //! instance of the HID device.
  83. //! \param pfnCallback is the function that will be called whenever changes
  84. //! are detected for this device.
  85. //! \param ulCBData is the data that will be returned in when the pfnCallback
  86. //! function is called.
  87. //!
  88. //! This function creates an instance of an specific type of HID device. The
  89. //! \e eDeviceType parameter is one subclass/protocol values of the types
  90. //! specified in enumerated types tHIDSubClassProtocol. Only devices that
  91. //! enumerate with this type will be called back via the \e pfnCallback
  92. //! function. The \e pfnCallback parameter is the callback function for any
  93. //! events that occur for this device type. The \e pfnCallback function must
  94. //! point to a valid function of type \e tUSBCallback for this call to complete
  95. //! successfully. To release this device instance the caller of USBHHIDOpen()
  96. //! should call USBHHIDClose() and pass in the value returned from the
  97. //! USBHHIDOpen() call.
  98. //!
  99. //! \return This function returns and instance value that should be used with
  100. //! any other APIs that require an instance value. If a value of 0 is returned
  101. //! then the device instance could not be created.
  102. //
  103. //*****************************************************************************
  104. unsigned int
  105. USBHHIDOpen(unsigned int ulIndex,tHIDSubClassProtocol eDeviceType,
  106. tUSBCallback pfnCallback, unsigned int ulCBData)
  107. {
  108. //
  109. // Only one callback is supported.
  110. //
  111. if(g_HIDDevice[ulIndex].pfnCallback)
  112. {
  113. return (0);
  114. }
  115. //
  116. // Save the instance data for this device.
  117. //
  118. g_HIDDevice[ulIndex].ulIndex = ulIndex;
  119. g_HIDDevice[ulIndex].pfnCallback = pfnCallback;
  120. g_HIDDevice[ulIndex].eDeviceType = eDeviceType;
  121. g_HIDDevice[ulIndex].ulCBData = ulCBData;
  122. //
  123. // Return the device instance pointer.
  124. //
  125. return((unsigned int)&g_HIDDevice[ulIndex]);
  126. }
  127. //*****************************************************************************
  128. //
  129. //! This function is used to release an instance of a HID device.
  130. //!
  131. //! \param ulHIDInstance is the instance value for a HID device to release.
  132. //!
  133. //! This function releases an instance of a HID device that was created by a
  134. //! call to USBHHIDOpen(). This call is required to allow other HID devices
  135. //! to be enumerated after another HID device has been disconnected. The
  136. //! \e ulHIDInstance parameter should hold the value that was returned from the
  137. //! previous call to USBHHIDOpen().
  138. //!
  139. //! \return None.
  140. //
  141. //*****************************************************************************
  142. void
  143. USBHHIDClose(unsigned int ulHIDInstance)
  144. {
  145. tHIDInstance *pHIDInstance;
  146. pHIDInstance = (tHIDInstance *)ulHIDInstance;
  147. //
  148. // Disable any more notification from the HID layer.
  149. //
  150. pHIDInstance->pfnCallback = 0;
  151. pHIDInstance->eDeviceType = USBH_HID_DEV_NONE;
  152. }
  153. //*****************************************************************************
  154. //
  155. // This function handles callbacks for the interrupt IN endpoint.
  156. //
  157. //*****************************************************************************
  158. static void
  159. HIDIntINCallback(unsigned int ulIndex, unsigned int ulPipe, unsigned int ulEvent)
  160. {
  161. switch (ulEvent)
  162. {
  163. //
  164. // Handles a request to schedule a new request on the interrupt IN
  165. // pipe.
  166. //
  167. case USB_EVENT_SCHEDULER:
  168. {
  169. USBHCDPipeSchedule(ulIndex, ulPipe, 0, 1);
  170. break;
  171. }
  172. //
  173. // Called when new data is available on the interrupt IN pipe.
  174. //
  175. case USB_EVENT_RX_AVAILABLE:
  176. {
  177. //
  178. // Send the report data to the USB host HID device class driver.
  179. //
  180. g_HIDDevice[ulIndex].pfnCallback((void *)g_HIDDevice[ulIndex].ulCBData,
  181. USB_EVENT_RX_AVAILABLE,
  182. ulPipe,
  183. 0);
  184. break;
  185. }
  186. }
  187. }
  188. //*****************************************************************************
  189. //
  190. //! This function is used to open an instance of the HID driver.
  191. //!
  192. //! \param pDevice is a pointer to the device information structure.
  193. //!
  194. //! This function will attempt to open an instance of the HID driver based on
  195. //! the information contained in the pDevice structure. This call can fail if
  196. //! there are not sufficient resources to open the device. The function will
  197. //! return a value that should be passed back into USBHIDClose() when the
  198. //! driver is no longer needed.
  199. //!
  200. //! \return The function will return a pointer to a HID driver instance.
  201. //
  202. //*****************************************************************************
  203. static void *
  204. HIDDriverOpen(tUSBHostDevice *pDevice, unsigned int ulInstance)
  205. {
  206. int iIdx;
  207. tEndpointDescriptor *pEndpointDescriptor;
  208. tInterfaceDescriptor *pInterface;
  209. tHIDInstance *pHIDInstance;
  210. pHIDInstance = (tHIDInstance *)ulInstance;
  211. unsigned int ulIndex = pHIDInstance->ulIndex;
  212. //
  213. // Don't allow the device to be opened without closing first.
  214. //
  215. if(pHIDInstance->pDevice)
  216. {
  217. return (0);
  218. }
  219. //
  220. // Get the interface descriptor.
  221. //
  222. pInterface = USBDescGetInterface(pDevice->pConfigDescriptor, 0, 0);
  223. if((pInterface->bInterfaceSubClass != USB_HID_SCLASS_BOOT) ||
  224. (pInterface->bInterfaceProtocol != pHIDInstance->eDeviceType))
  225. {
  226. return(0);
  227. }
  228. //
  229. // Save the device pointer.
  230. //
  231. pHIDInstance->pDevice = pDevice;
  232. for(iIdx = 0; iIdx < 3; iIdx++)
  233. {
  234. //
  235. // Get the first endpoint descriptor.
  236. //
  237. pEndpointDescriptor = USBDescGetInterfaceEndpoint(pInterface, iIdx,
  238. 256);
  239. //
  240. // If no more endpoints then break out.
  241. //
  242. if(pEndpointDescriptor == 0)
  243. {
  244. break;
  245. }
  246. //
  247. // Interrupt
  248. //
  249. if((pEndpointDescriptor->bmAttributes & USB_EP_ATTR_TYPE_M) ==
  250. USB_EP_ATTR_INT)
  251. {
  252. //
  253. // Interrupt IN.
  254. //
  255. if(pEndpointDescriptor->bEndpointAddress & USB_EP_DESC_IN)
  256. {
  257. pHIDInstance->ulIntInPipe = USBHCDPipeAlloc(ulIndex,
  258. USBHCD_PIPE_INTR_IN,
  259. pDevice->ulAddress,
  260. HIDIntINCallback);
  261. USBHCDPipeConfig(ulIndex, pHIDInstance->ulIntInPipe,
  262. pEndpointDescriptor->wMaxPacketSize,
  263. pEndpointDescriptor->bInterval,
  264. (pEndpointDescriptor->bEndpointAddress &
  265. USB_EP_DESC_NUM_M));
  266. }
  267. }
  268. }
  269. //
  270. // If there is a callback function call it to inform the application that
  271. // the device has been enumerated.
  272. //
  273. if(pHIDInstance->pfnCallback != 0)
  274. {
  275. pHIDInstance->pfnCallback((void *)pHIDInstance->ulCBData,
  276. USB_EVENT_CONNECTED,
  277. (unsigned int)pHIDInstance, 0);
  278. }
  279. //
  280. // Save the device pointer.
  281. //
  282. pHIDInstance->pDevice = pDevice;
  283. return (pHIDInstance);
  284. }
  285. //*****************************************************************************
  286. //
  287. //! This function is used to release an instance of the HID driver.
  288. //!
  289. //! \param pvInstance is an instance pointer that needs to be released.
  290. //!
  291. //! This function will free up any resources in use by the HID driver instance
  292. //! that is passed in. The \e pvInstance pointer should be a valid value that
  293. //! was returned from a call to USBHIDOpen().
  294. //!
  295. //! \return None.
  296. //
  297. //*****************************************************************************
  298. static void
  299. HIDDriverClose(void *pvInstance)
  300. {
  301. tHIDInstance *pHIDInstance;
  302. pHIDInstance = (tHIDInstance *)pvInstance;
  303. //
  304. // No device so just exit.
  305. //
  306. if(pHIDInstance->pDevice == 0)
  307. {
  308. return;
  309. }
  310. //
  311. // Reset the device pointer.
  312. //
  313. pHIDInstance->pDevice = 0;
  314. //
  315. // Free the Interrupt IN pipe.
  316. //
  317. if(pHIDInstance->ulIntInPipe != 0)
  318. {
  319. USBHCDPipeFree(pHIDInstance->ulIndex, pHIDInstance->ulIntInPipe);
  320. }
  321. //
  322. // If the callback exists, call it with an Open event.
  323. //
  324. if(pHIDInstance->pfnCallback != 0)
  325. {
  326. pHIDInstance->pfnCallback((void *)pHIDInstance->ulCBData,
  327. USB_EVENT_DISCONNECTED,
  328. (unsigned int)&pHIDInstance, 0);
  329. }
  330. }
  331. //*****************************************************************************
  332. //
  333. //! This function is used to set the idle timeout for a HID device.
  334. //!
  335. //! \param ulInstance is the value that was returned from the call to
  336. //! USBHHIDOpen().
  337. //! \param ucDuration is the duration of the timeout in milliseconds.
  338. //! \param ucReportID is the report identifier to set the timeout on.
  339. //!
  340. //! This function will send the Set Idle command to a HID device to set the
  341. //! idle timeout for a given report. The length of the timeout is specified
  342. //! by the \e ucDuration parameter and the report the timeout for is in the
  343. //! \e ucReportID value.
  344. //!
  345. //! \return Always returns 0.
  346. //
  347. //*****************************************************************************
  348. unsigned int
  349. USBHHIDSetIdle(unsigned int ulInstance, unsigned char ucDuration,
  350. unsigned char ucReportID)
  351. {
  352. tUSBRequest SetupPacket;
  353. tHIDInstance *pHIDInstance;
  354. pHIDInstance = (tHIDInstance *)ulInstance;
  355. //
  356. // This is a Class specific interface OUT request.
  357. //
  358. SetupPacket.bmRequestType = USB_RTYPE_DIR_OUT | USB_RTYPE_CLASS
  359. | USB_RTYPE_INTERFACE;
  360. //
  361. // Request a Device Descriptor.
  362. //
  363. SetupPacket.bRequest = USBREQ_SET_IDLE;
  364. SetupPacket.wValue = (ucDuration << 8) | ucReportID;
  365. //
  366. // Set this on interface 1.
  367. //
  368. SetupPacket.wIndex = 0;
  369. //
  370. // This is always 0 for this request.
  371. //
  372. SetupPacket.wLength = 0;
  373. //
  374. // Put the setup packet in the buffer.
  375. //
  376. USBHCDControlTransfer(pHIDInstance->ulIndex,
  377. &SetupPacket,
  378. pHIDInstance->pDevice->ulAddress,
  379. 0,
  380. 0,
  381. MAX_PACKET_SIZE_EP0);
  382. return (0);
  383. }
  384. //*****************************************************************************
  385. //
  386. //! This function can be used to retrieve the report descriptor for a given
  387. //! device instance.
  388. //!
  389. //! \param ulInstance is the value that was returned from the call to
  390. //! USBHHIDOpen().
  391. //! \param pucBuffer is the memory buffer to use to store the report
  392. //! descriptor.
  393. //! \param ulSize is the size in bytes of the buffer pointed to by
  394. //! \e pucBuffer.
  395. //!
  396. //! This function is used to return a report descriptor from a HID device
  397. //! instance so that it can determine how to interpret reports that are
  398. //! returned from the device indicated by the \e ulInstance parameter.
  399. //! This call is blocking and will return the number of bytes read into the
  400. //! \e pucBuffer.
  401. //!
  402. //! \return Returns the number of bytes read into the \e pucBuffer.
  403. //
  404. //*****************************************************************************
  405. unsigned int
  406. USBHHIDGetReportDescriptor(unsigned int ulInstance, unsigned char *pucBuffer,
  407. unsigned int ulSize)
  408. {
  409. tUSBRequest SetupPacket;
  410. unsigned int ulBytes;
  411. tHIDInstance *pHIDInstance;
  412. pHIDInstance = (tHIDInstance *)ulInstance;
  413. //
  414. // This is a Standard Device IN request.
  415. //
  416. SetupPacket.bmRequestType = USB_RTYPE_DIR_IN | USB_RTYPE_STANDARD
  417. | USB_RTYPE_INTERFACE;
  418. //
  419. // Request a Report Descriptor.
  420. //
  421. SetupPacket.bRequest = USBREQ_GET_DESCRIPTOR;
  422. SetupPacket.wValue = USB_HID_DTYPE_REPORT << 8;
  423. //
  424. // Index is always 0 for device requests.
  425. //
  426. SetupPacket.wIndex = 0;
  427. //
  428. // All devices must have at least an 8 byte max packet size so just ask
  429. // for 8 bytes to start with.
  430. //
  431. SetupPacket.wLength = ulSize;
  432. //
  433. // Now get the full descriptor now that the actual maximum packet size
  434. // is known.
  435. //
  436. ulBytes = USBHCDControlTransfer(
  437. pHIDInstance->ulIndex,
  438. &SetupPacket,
  439. pHIDInstance->pDevice->ulAddress,
  440. pucBuffer,
  441. ulSize,
  442. pHIDInstance->pDevice->DeviceDescriptor.bMaxPacketSize0);
  443. return (ulBytes);
  444. }
  445. //*****************************************************************************
  446. //
  447. //! This function is used to set or clear the boot protocol state of a device.
  448. //!
  449. //! \param ulInstance is the value that was returned from the call to
  450. //! USBHHIDOpen().
  451. //! \param ulBootProtocol is either zero or non-zero to indicate which protocol
  452. //! to use for the device.
  453. //!
  454. //! A USB host device can use this function to set the protocol for a connected
  455. //! HID device. This is commonly used to set keyboards and mice into their
  456. //! simplified boot protocol modes to fix the report structure to a know
  457. //! state.
  458. //!
  459. //! \return This function returns 0.
  460. //
  461. //*****************************************************************************
  462. unsigned int
  463. USBHHIDSetProtocol(unsigned int ulInstance, unsigned int ulBootProtocol)
  464. {
  465. tUSBRequest SetupPacket;
  466. tHIDInstance *pHIDInstance;
  467. pHIDInstance = (tHIDInstance *)ulInstance;
  468. //
  469. // This is a Standard Device IN request.
  470. //
  471. SetupPacket.bmRequestType = USB_RTYPE_DIR_OUT | USB_RTYPE_CLASS
  472. | USB_RTYPE_INTERFACE;
  473. //
  474. // Request a Report Descriptor.
  475. //
  476. SetupPacket.bRequest = USBREQ_SET_PROTOCOL;
  477. if(ulBootProtocol)
  478. {
  479. //
  480. // Boot Protocol.
  481. //
  482. SetupPacket.wValue = 0;
  483. }
  484. else
  485. {
  486. //
  487. // Report Protocol.
  488. //
  489. SetupPacket.wValue = 1;
  490. }
  491. //
  492. // Index is always 0 for device requests.
  493. //
  494. SetupPacket.wIndex = 0;
  495. //
  496. // Always 0.
  497. //
  498. SetupPacket.wLength = 0;
  499. //
  500. // Now get the full descriptor now that the actual maximum packet size
  501. // is known.
  502. //
  503. USBHCDControlTransfer(
  504. pHIDInstance->ulIndex,
  505. &SetupPacket,
  506. pHIDInstance->pDevice->ulAddress,
  507. 0,
  508. 0,
  509. pHIDInstance->pDevice->DeviceDescriptor.bMaxPacketSize0);
  510. return (0);
  511. }
  512. //*****************************************************************************
  513. //
  514. //! This function is used to retrieve a report from a HID device.
  515. //!
  516. //! \param ulInstance is the value that was returned from the call to
  517. //! USBHHIDOpen().
  518. //! \param ulInterface is the interface to retrieve the report from.
  519. //! \param pucData is the memory buffer to use to store the report.
  520. //! \param ulSize is the size in bytes of the buffer pointed to by
  521. //! \e pucBuffer.
  522. //!
  523. //! This function is used to retrieve a report from a USB pipe. It is usually
  524. //! called when the USB HID layer has detected a new data available in a USB
  525. //! pipe. The USB HID host device code will receive a
  526. //! \b USB_EVENT_RX_AVAILABLE event when data is available, allowing the
  527. //! callback function to retrieve the data.
  528. //!
  529. //! \return Returns the number of bytes read from report.
  530. //
  531. //*****************************************************************************
  532. unsigned int
  533. USBHHIDGetReport(unsigned int ulInstance,
  534. unsigned int ulInterface,
  535. unsigned char *pucData,
  536. unsigned int ulSize)
  537. {
  538. tHIDInstance *pHIDInstance;
  539. //
  540. // Cast the instance pointer to the correct type for ease of use.
  541. //
  542. pHIDInstance = (tHIDInstance *)ulInstance;
  543. //
  544. // Read the Data out.
  545. //
  546. ulSize = USBHCDPipeReadNonBlocking(pHIDInstance->ulIndex, pHIDInstance
  547. ->ulIntInPipe, pucData, ulSize);
  548. //
  549. // Return the number of bytes read from the interrupt in pipe.
  550. //
  551. return(ulSize);
  552. }
  553. //*****************************************************************************
  554. //
  555. //! This function is used to send a report to a HID device.
  556. //!
  557. //! \param ulInstance is the value that was returned from the call to
  558. //! USBHHIDOpen().
  559. //! \param ulInterface is the interface to send the report to.
  560. //! \param pucData is the memory buffer to use to store the report.
  561. //! \param ulSize is the size in bytes of the buffer pointed to by
  562. //! \e pucBuffer.
  563. //!
  564. //! This function is used to send a report to a USB HID device. It can be
  565. //! only be called from outside the callback context as this function will not
  566. //! return from the call until the data has been sent successfully.
  567. //!
  568. //! \return Returns the number of bytes sent to the device.
  569. //
  570. //*****************************************************************************
  571. unsigned int
  572. USBHHIDSetReport(unsigned int ulInstance, unsigned int ulInterface,
  573. unsigned char *pucData, unsigned int ulSize)
  574. {
  575. tUSBRequest SetupPacket;
  576. tHIDInstance *pHIDInstance;
  577. pHIDInstance = (tHIDInstance *)ulInstance;
  578. //
  579. // This is a Standard Device IN request.
  580. //
  581. SetupPacket.bmRequestType = USB_RTYPE_DIR_OUT | USB_RTYPE_CLASS
  582. | USB_RTYPE_INTERFACE;
  583. //
  584. // Request a Report Descriptor.
  585. //
  586. SetupPacket.bRequest = USBREQ_SET_REPORT;
  587. SetupPacket.wValue = USB_HID_REPORT_OUTPUT << 8;
  588. //
  589. // Index is always 0 for device requests.
  590. //
  591. SetupPacket.wIndex = (unsigned short)ulInterface;
  592. //
  593. // Always 0.
  594. //
  595. SetupPacket.wLength = ulSize;
  596. //
  597. // Now get the full descriptor now that the actual maximum packet size
  598. // is known.
  599. //
  600. USBHCDControlTransfer(pHIDInstance->ulIndex, &SetupPacket, pHIDInstance
  601. ->pDevice->ulAddress, pucData, ulSize, pHIDInstance
  602. ->pDevice->DeviceDescriptor.bMaxPacketSize0);
  603. return (ulSize);
  604. }
  605. //*****************************************************************************
  606. //
  607. //! @}
  608. //
  609. //*****************************************************************************