PageRenderTime 32ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/robotica/elua/elua_stm32f4/src/platform/lm3s/usblib/host/usbhhidkeyboard.c

https://bitbucket.org/cicamargoba/stamp
C | 719 lines | 228 code | 69 blank | 422 comment | 35 complexity | ef239bb0f5af42e93477a53a30cd44dc MD5 | raw file
Possible License(s): 0BSD, GPL-3.0, BSD-3-Clause, MIT
  1. //*****************************************************************************
  2. //
  3. // usbhhidkeyboard.c - This file holds the application interfaces for USB
  4. // keyboard devices.
  5. //
  6. // Copyright (c) 2008-2011 Texas Instruments Incorporated. All rights reserved.
  7. // Software License Agreement
  8. //
  9. // Texas Instruments (TI) is supplying this software for use solely and
  10. // exclusively on TI's microcontroller products. The software is owned by
  11. // TI and/or its suppliers, and is protected under applicable copyright
  12. // laws. You may not combine this software with "viral" open-source
  13. // software in order to form a larger program.
  14. //
  15. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  16. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  17. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  18. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  19. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  20. // DAMAGES, FOR ANY REASON WHATSOEVER.
  21. //
  22. // This is part of revision 7611 of the Stellaris USB Library.
  23. //
  24. //*****************************************************************************
  25. #include "inc/hw_types.h"
  26. #include "usblib/usblib.h"
  27. #include "usblib/host/usbhost.h"
  28. #include "usblib/usbhid.h"
  29. #include "usblib/host/usbhhid.h"
  30. #include "usblib/host/usbhhidkeyboard.h"
  31. //*****************************************************************************
  32. //
  33. //! \addtogroup usblib_host_device
  34. //! @{
  35. //
  36. //*****************************************************************************
  37. //*****************************************************************************
  38. //
  39. // Prototypes for local functions.
  40. //
  41. //*****************************************************************************
  42. static unsigned long USBHKeyboardCallback(void *pvCBData,
  43. unsigned long ulEvent,
  44. unsigned long ulMsgParam,
  45. void *pvMsgData);
  46. //*****************************************************************************
  47. //
  48. // The size of a USB keyboard report.
  49. //
  50. //*****************************************************************************
  51. #define USBHKEYB_REPORT_SIZE 8
  52. //*****************************************************************************
  53. //
  54. // These are the flags for the tUSBHKeyboard.ulHIDFlags member variable.
  55. //
  56. //*****************************************************************************
  57. #define USBHKEYB_DEVICE_PRESENT 0x00000001
  58. //*****************************************************************************
  59. //
  60. // This is the structure definition for a keyboard device instance.
  61. //
  62. //*****************************************************************************
  63. typedef struct
  64. {
  65. //
  66. // Global flags for an instance of a keyboard.
  67. //
  68. unsigned long ulHIDFlags;
  69. //
  70. // The applications registered callback.
  71. //
  72. tUSBCallback pfnCallback;
  73. //
  74. // The HID instance pointer for this keyboard instance.
  75. //
  76. unsigned long ulHIDInstance;
  77. //
  78. // NUM_LOCK, CAPS_LOCK, SCROLL_LOCK, COMPOSE or KANA keys.
  79. //
  80. unsigned char ucKeyModSticky;
  81. //
  82. // This is the current state of the keyboard modifier keys.
  83. //
  84. unsigned char ucKeyModState;
  85. //
  86. // This holds the keyboard usage codes for keys that are being held down.
  87. //
  88. unsigned char pucKeyState[6];
  89. //
  90. // This is a local buffer to hold the current HID report that comes up
  91. // from the HID driver layer.
  92. //
  93. unsigned char pucBuffer[USBHKEYB_REPORT_SIZE];
  94. }
  95. tUSBHKeyboard;
  96. //*****************************************************************************
  97. //
  98. // This is the per instance information for a keyboard device.
  99. //
  100. //*****************************************************************************
  101. static tUSBHKeyboard g_sUSBHKeyboard =
  102. {
  103. 0
  104. };
  105. //*****************************************************************************
  106. //
  107. //! This function is used open an instance of a keyboard.
  108. //!
  109. //! \param pfnCallback is the callback function to call when new events occur
  110. //! with the keyboard returned.
  111. //! \param pucBuffer is the memory used by the keyboard to interact with the
  112. //! USB keyboard.
  113. //! \param ulSize is the size of the buffer provided by \e pucBuffer.
  114. //!
  115. //! This function is used to open an instance of the keyboard. The value
  116. //! returned from this function should be used as the instance identifier for
  117. //! all other USBHKeyboard calls. The \e pucBuffer memory buffer is used to
  118. //! access the keyboard. The buffer size required is at least enough to hold
  119. //! a normal report descriptor for the device. If there is not enough space
  120. //! only a partial report descriptor will be read out.
  121. //!
  122. //! \return Returns the instance identifier for the keyboard that is attached.
  123. //! If there is no keyboard present this will return 0.
  124. //
  125. //*****************************************************************************
  126. unsigned long
  127. USBHKeyboardOpen(tUSBCallback pfnCallback, unsigned char *pucBuffer,
  128. unsigned long ulSize)
  129. {
  130. //
  131. // Save the callback and data pointers.
  132. //
  133. g_sUSBHKeyboard.pfnCallback = pfnCallback;
  134. //
  135. // Save the instance pointer for the HID device that was opened.
  136. //
  137. g_sUSBHKeyboard.ulHIDInstance =
  138. USBHHIDOpen(USBH_HID_DEV_KEYBOARD, USBHKeyboardCallback,
  139. (unsigned long)&g_sUSBHKeyboard);
  140. return((unsigned long)&g_sUSBHKeyboard);
  141. }
  142. //*****************************************************************************
  143. //
  144. //! This function is used close an instance of a keyboard.
  145. //!
  146. //! \param ulInstance is the instance value for this keyboard.
  147. //!
  148. //! This function is used to close an instance of the keyboard that was opened
  149. //! with a call to USBHKeyboardOpen(). The \e ulInstance value is the value
  150. //! that was returned when the application called USBHKeyboardOpen().
  151. //!
  152. //! \return This function returns 0 to indicate success any non-zero value
  153. //! indicates an error condition.
  154. //
  155. //*****************************************************************************
  156. unsigned long
  157. USBHKeyboardClose(unsigned long ulInstance)
  158. {
  159. tUSBHKeyboard *pUSBHKeyboard;
  160. //
  161. // Recover the pointer to the instance data.
  162. //
  163. pUSBHKeyboard = (tUSBHKeyboard *)ulInstance;
  164. //
  165. // Reset the callback to null.
  166. //
  167. pUSBHKeyboard->pfnCallback = 0;
  168. //
  169. // Call the HID driver layer to close out this instance.
  170. //
  171. USBHHIDClose(pUSBHKeyboard->ulHIDInstance);
  172. return(0);
  173. }
  174. //*****************************************************************************
  175. //
  176. //! This function is used to map a USB usage ID to a printable character.
  177. //!
  178. //! \param ulInstance is the instance value for this keyboard.
  179. //! \param pTable is the table to use to map the usage ID to characters.
  180. //! \param ucUsageID is the USB usage ID to map to a character.
  181. //!
  182. //! This function is used to map a USB usage ID to a character. The provided
  183. //! \e pTable is used to perform the mapping and is described by the
  184. //! tHIDKeyboardUsageTable type defined structure. See the documentation on
  185. //! the tHIDKeyboardUsageTable structure for more details on the internals of
  186. //! this structure. This function uses the current state of the shift keys
  187. //! and the Caps Lock key to modify the data returned by this function. The
  188. //! pTable structure has values indicating which keys are modified by Caps Lock
  189. //! and alternate values for shifted cases. The number of bytes returned from
  190. //! this function depends on the \e pTable structure passed in as it holds the
  191. //! number of bytes per character in the table.
  192. //!
  193. //! \return Returns the character value for the given usage id.
  194. //
  195. //*****************************************************************************
  196. unsigned long
  197. USBHKeyboardUsageToChar(unsigned long ulInstance,
  198. const tHIDKeyboardUsageTable *pTable,
  199. unsigned char ucUsageID)
  200. {
  201. unsigned long ulValue;
  202. const unsigned char *pucKeyBoardMap;
  203. const unsigned short *pusKeyBoardMap;
  204. unsigned long ulOffset;
  205. unsigned long ulShift;
  206. tUSBHKeyboard *pUSBHKeyboard;
  207. //
  208. // Recover the pointer to the instance data.
  209. //
  210. pUSBHKeyboard = (tUSBHKeyboard *)ulInstance;
  211. //
  212. // The added offset for the shifted character value.
  213. //
  214. ulShift = 0;
  215. //
  216. // Offset in the table for the character.
  217. //
  218. ulOffset = (ucUsageID * pTable->ucBytesPerChar * 2);
  219. //
  220. // Handle the case where CAPS lock has been set.
  221. //
  222. if(pUSBHKeyboard->ucKeyModSticky &= HID_KEYB_CAPS_LOCK)
  223. {
  224. //
  225. // See if this usage ID is modified by Caps Lock by checking the packed
  226. // bit array in the pulShiftState member of the pTable array.
  227. //
  228. if((pTable->pulCapsLock[ucUsageID >> 5]) >> (ucUsageID & 0x1f) & 1)
  229. {
  230. ulShift = pTable->ucBytesPerChar;
  231. }
  232. }
  233. //
  234. // Now handle if a shift key is being held.
  235. //
  236. if((pUSBHKeyboard->ucKeyModState & 0x22) != 0)
  237. {
  238. //
  239. // Not shifted yet so we need to shift.
  240. //
  241. if(ulShift == 0)
  242. {
  243. ulShift = pTable->ucBytesPerChar;
  244. }
  245. else
  246. {
  247. //
  248. // Unshift because CAPS LOCK and shift were presed.
  249. //
  250. ulShift = 0;
  251. }
  252. }
  253. //
  254. // One byte per character.
  255. //
  256. if(pTable->ucBytesPerChar == 1)
  257. {
  258. //
  259. // Get the base address of the table.
  260. //
  261. pucKeyBoardMap = pTable->pCharMapping;
  262. ulValue = pucKeyBoardMap[ulOffset + ulShift];
  263. }
  264. //
  265. // Two bytes per character.
  266. //
  267. else if(pTable->ucBytesPerChar == 2)
  268. {
  269. //
  270. // Get the base address of the table.
  271. //
  272. pusKeyBoardMap = (unsigned short *)pTable->pCharMapping;
  273. ulValue = pusKeyBoardMap[ulOffset + ulShift];
  274. }
  275. //
  276. // All other sizes are unsupported for now.
  277. //
  278. else
  279. {
  280. ulValue = 0;
  281. }
  282. return(ulValue);
  283. }
  284. //*****************************************************************************
  285. //
  286. //! This function is used to set one of the fixed modifier keys on a keyboard.
  287. //!
  288. //! \param ulInstance is the instance value for this keyboard.
  289. //! \param ulModifiers is a bit mask of the modifiers to set on the keyboard.
  290. //!
  291. //! This function is used to set the modifier key states on a keyboard. The
  292. //! \e ulModifiers value is a bitmask of the following set of values:
  293. //! - HID_KEYB_NUM_LOCK
  294. //! - HID_KEYB_CAPS_LOCK
  295. //! - HID_KEYB_SCROLL_LOCK
  296. //! - HID_KEYB_COMPOSE
  297. //! - HID_KEYB_KANA
  298. //!
  299. //! Not all of these will be supported on all keyboards however setting values
  300. //! on a keyboard that does not have them should have no effect. The
  301. //! \e ulInstance value is the value that was returned when the application
  302. //! called USBHKeyboardOpen(). If the value \b HID_KEYB_CAPS_LOCK is used it
  303. //! will modify the values returned from the USBHKeyboardUsageToChar()
  304. //! function.
  305. //!
  306. //! \return This function returns 0 to indicate success any non-zero value
  307. //! indicates an error condition.
  308. //
  309. //*****************************************************************************
  310. unsigned long
  311. USBHKeyboardModifierSet(unsigned long ulInstance, unsigned long ulModifiers)
  312. {
  313. tUSBHKeyboard *pUSBHKeyboard;
  314. //
  315. // Recover the pointer to the instance data.
  316. //
  317. pUSBHKeyboard = (tUSBHKeyboard *)ulInstance;
  318. //
  319. // Remeber the fact that this is set.
  320. //
  321. pUSBHKeyboard->ucKeyModSticky = (unsigned char)ulModifiers;
  322. //
  323. // Set the LEDs on the keyboard.
  324. //
  325. USBHHIDSetReport(pUSBHKeyboard->ulHIDInstance, 0,
  326. (unsigned char *)&ulModifiers, 1);
  327. return(0);
  328. }
  329. //*****************************************************************************
  330. //
  331. //! This function is used to initialize a keyboard interface after a keyboard
  332. //! has been detected.
  333. //!
  334. //! \param ulInstance is the instance value for this keyboard.
  335. //!
  336. //! This function should be called after receiving a \b USB_EVENT_CONNECTED
  337. //! event in the callback function provided by USBHKeyboardOpen(), however this
  338. //! function should only be called outside the callback function. This will
  339. //! initialize the keyboard interface and determine the keyboard's
  340. //! layout and how it reports keys to the USB host controller. The
  341. //! \e ulInstance value is the value that was returned when the application
  342. //! called USBHKeyboardOpen(). This function only needs to be called once
  343. //! per connection event but it should be called every time a
  344. //! \b USB_EVENT_CONNECTED event occurs.
  345. //!
  346. //! \return This function returns 0 to indicate success any non-zero value
  347. //! indicates an error condition.
  348. //
  349. //*****************************************************************************
  350. unsigned long
  351. USBHKeyboardInit(unsigned long ulInstance)
  352. {
  353. unsigned char ucModData;
  354. tUSBHKeyboard *pUSBHKeyboard;
  355. //
  356. // Recover the pointer to the instance data.
  357. //
  358. pUSBHKeyboard = (tUSBHKeyboard *)ulInstance;
  359. //
  360. // Set the initial rate to only update on keyboard state changes.
  361. //
  362. USBHHIDSetIdle(pUSBHKeyboard->ulHIDInstance, 0, 0);
  363. //
  364. // Read out the Report Descriptor from the keyboard and parse it for
  365. // the format of the reports coming back from the keyboard.
  366. //
  367. USBHHIDGetReportDescriptor(pUSBHKeyboard->ulHIDInstance,
  368. pUSBHKeyboard->pucBuffer,
  369. USBHKEYB_REPORT_SIZE);
  370. //
  371. // Set the keyboard to boot protocol.
  372. //
  373. USBHHIDSetProtocol(pUSBHKeyboard->ulHIDInstance, 1);
  374. //
  375. // Used to clear the initial state of all on keyboard modifiers.
  376. //
  377. ucModData = 0;
  378. //
  379. // Update the keyboard LED state.
  380. //
  381. USBHHIDSetReport(pUSBHKeyboard->ulHIDInstance, 0, &ucModData, 1);
  382. return(0);
  383. }
  384. //*****************************************************************************
  385. //
  386. //! This function is used to set the automatic poll rate of the keyboard.
  387. //!
  388. //! \param ulInstance is the instance value for this keyboard.
  389. //! \param ulPollRate is the rate in ms to cause the keyboard to update the
  390. //! host regardless of no change in key state.
  391. //!
  392. //! This function will allow an application to tell the keyboard how often it
  393. //! should send updates to the USB host controller regardless of any changes
  394. //! in keyboard state. The \e ulInstance value is the value that was returned
  395. //! when the application called USBHKeyboardOpen(). The \e ulPollRate is the
  396. //! new value in ms for the update rate on the keyboard. This value is
  397. //! initially set to 0 which indicates that the keyboard should only to update
  398. //! when the keyboard state changes. Any value other than 0 can be used to
  399. //! force the keyboard to generate auto-repeat sequences for the application.
  400. //!
  401. //! \return This function returns 0 to indicate success any non-zero value
  402. //! indicates an error condition.
  403. //
  404. //*****************************************************************************
  405. unsigned long
  406. USBHKeyboardPollRateSet(unsigned long ulInstance, unsigned long ulPollRate)
  407. {
  408. tUSBHKeyboard *pUSBHKeyboard;
  409. //
  410. // Recover the pointer to the instance data.
  411. //
  412. pUSBHKeyboard = (tUSBHKeyboard *)ulInstance;
  413. //
  414. // Send the Set Idle command to the USB keyboard.
  415. //
  416. USBHHIDSetIdle(pUSBHKeyboard->ulHIDInstance, ulPollRate, 0);
  417. return(0);
  418. }
  419. //*****************************************************************************
  420. //
  421. // This is an internal function used to modify the current keyboard state.
  422. //
  423. // This function checks for changes in the keyboard state due to a new report
  424. // being received from the device. It first checks if this is a "roll-over"
  425. // case by seeing if 0x01 is in the first position of the new keyboard report.
  426. // This indicates that too many keys were pressed to handle and to ignore this
  427. // report. Next the keyboard modifier state is stored and if any changes are
  428. // detected a \b USBH_EVENT_HID_KB_MOD event is sent back to the application.
  429. // Then this function will check for any keys that have been released and send
  430. // a \b USBH_EVENT_HID_KB_REL even for each of these keys. The last check is
  431. // for any new keys that are pressed and a \b USBH_EVENT_HID_KB_PRESS event
  432. // will be sent for each new key pressed.
  433. //
  434. // \return None.
  435. //
  436. //*****************************************************************************
  437. static void
  438. UpdateKeyboardState(tUSBHKeyboard *pUSBHKeyboard)
  439. {
  440. long lNewKey, lOldKey;
  441. //
  442. // rollover code so ignore this buffer.
  443. //
  444. if(pUSBHKeyboard->pucBuffer[2] == 0x01)
  445. {
  446. return;
  447. }
  448. //
  449. // Handle the keyboard modifier states.
  450. //
  451. if(pUSBHKeyboard->ucKeyModState != pUSBHKeyboard->pucBuffer[0])
  452. {
  453. //
  454. // Notify the application of the event.
  455. //
  456. pUSBHKeyboard->pfnCallback(0, USBH_EVENT_HID_KB_MOD,
  457. pUSBHKeyboard->pucBuffer[0], 0);
  458. //
  459. // Save the new state of the modifier keys.
  460. //
  461. pUSBHKeyboard->ucKeyModState = pUSBHKeyboard->pucBuffer[0];
  462. }
  463. //
  464. // This loop checks for keys that have been released to make room for new
  465. // ones that may have been pressed.
  466. //
  467. for(lOldKey = 2; lOldKey < 8; lOldKey++)
  468. {
  469. //
  470. // If there is no old key pressed in this entry go to the next one.
  471. //
  472. if(pUSBHKeyboard->pucKeyState[lOldKey] == 0)
  473. {
  474. continue;
  475. }
  476. //
  477. // Check if this old key is still in the list of currently pressed
  478. // keys.
  479. //
  480. for(lNewKey = 2; lNewKey < 8; lNewKey++)
  481. {
  482. //
  483. // Break out if the key is still present.
  484. //
  485. if(pUSBHKeyboard->pucBuffer[lNewKey]
  486. == pUSBHKeyboard->pucKeyState[lOldKey])
  487. {
  488. break;
  489. }
  490. }
  491. //
  492. // If the old key was no longer in the list of pressed keys then
  493. // notify the application of the key release.
  494. //
  495. if(lNewKey == 8)
  496. {
  497. //
  498. // Send the key release notification to the application.
  499. //
  500. pUSBHKeyboard->pfnCallback(0,
  501. USBH_EVENT_HID_KB_REL,
  502. pUSBHKeyboard->pucKeyState[lOldKey],
  503. 0);
  504. //
  505. // Remove the old key from the currently held key list.
  506. //
  507. pUSBHKeyboard->pucKeyState[lOldKey] = 0;
  508. }
  509. }
  510. //
  511. // This loop checks for new keys that have been pressed.
  512. //
  513. for(lNewKey = 2; lNewKey < 8; lNewKey++)
  514. {
  515. //
  516. // The new list is empty so no new keys are pressed.
  517. //
  518. if(pUSBHKeyboard->pucBuffer[lNewKey] == 0)
  519. {
  520. break;
  521. }
  522. //
  523. // This loop checks if the current key was already pressed.
  524. //
  525. for(lOldKey = 2; lOldKey < 8; lOldKey++)
  526. {
  527. //
  528. // If it is in both lists then it was already pressed so ignore it.
  529. //
  530. if(pUSBHKeyboard->pucBuffer[lNewKey]
  531. == pUSBHKeyboard->pucKeyState[lOldKey])
  532. {
  533. break;
  534. }
  535. }
  536. //
  537. // The key in the new list was not found so it is new.
  538. //
  539. if(lOldKey == 8)
  540. {
  541. //
  542. // Look for a free location to store this key usage code.
  543. //
  544. for(lOldKey = 2; lOldKey < 8; lOldKey++)
  545. {
  546. //
  547. // If an empty location is found, store it and notify the
  548. // application.
  549. //
  550. if(pUSBHKeyboard->pucKeyState[lOldKey] == 0)
  551. {
  552. //
  553. // Save the newly pressed key.
  554. //
  555. pUSBHKeyboard->pucKeyState[lOldKey]
  556. = pUSBHKeyboard->pucBuffer[lNewKey];
  557. //
  558. // Notify the application of the new key that has been
  559. // pressed.
  560. //
  561. pUSBHKeyboard->pfnCallback(
  562. 0,
  563. USBH_EVENT_HID_KB_PRESS,
  564. pUSBHKeyboard->pucBuffer[lNewKey],
  565. 0);
  566. break;
  567. }
  568. }
  569. }
  570. }
  571. }
  572. //*****************************************************************************
  573. //
  574. //! This function handles event callbacks from the USB HID driver layer.
  575. //!
  576. //! \param pvCBData is the pointer that was passed in to the USBHHIDOpen()
  577. //! call.
  578. //! \param ulEvent is the event that has been passed up from the HID driver.
  579. //! \param ulMsgParam has meaning related to the \e ulEvent that occurred.
  580. //! \param pvMsgData has meaning related to the \e ulEvent that occurred.
  581. //!
  582. //! This function will receive all event updates from the HID driver layer.
  583. //! The keyboard driver itself will mostly be concerned with report callbacks
  584. //! from the HID driver layer and parsing them into keystrokes for the
  585. //! application that has registered for callbacks with the USBHKeyboardOpen()
  586. //! call.
  587. //!
  588. //! \return Non-zero values should be assumed to indicate an error condition.
  589. //
  590. //*****************************************************************************
  591. unsigned long
  592. USBHKeyboardCallback(void *pvCBData, unsigned long ulEvent,
  593. unsigned long ulMsgParam, void *pvMsgData)
  594. {
  595. tUSBHKeyboard *pUSBHKeyboard;
  596. //
  597. // Recover the pointer to the instance data.
  598. //
  599. pUSBHKeyboard = (tUSBHKeyboard *)pvCBData;
  600. switch (ulEvent)
  601. {
  602. //
  603. // New keyboard has been connected so notify the application.
  604. //
  605. case USB_EVENT_CONNECTED:
  606. {
  607. //
  608. // Remember that a keyboard is present.
  609. //
  610. pUSBHKeyboard->ulHIDFlags |= USBHKEYB_DEVICE_PRESENT;
  611. //
  612. // Notify the application that a new keyboard was connected.
  613. //
  614. pUSBHKeyboard->pfnCallback(0, ulEvent, ulMsgParam, pvMsgData);
  615. break;
  616. }
  617. case USB_EVENT_DISCONNECTED:
  618. {
  619. //
  620. // No keyboard is present.
  621. //
  622. pUSBHKeyboard->ulHIDFlags &= ~USBHKEYB_DEVICE_PRESENT;
  623. //
  624. // Notify the application that the keyboard was disconnected.
  625. //
  626. pUSBHKeyboard->pfnCallback(0, ulEvent, ulMsgParam, pvMsgData);
  627. break;
  628. }
  629. case USB_EVENT_RX_AVAILABLE:
  630. {
  631. //
  632. // New keyboard report structure was received.
  633. //
  634. USBHHIDGetReport(pUSBHKeyboard->ulHIDInstance, 0,
  635. pUSBHKeyboard->pucBuffer,
  636. USBHKEYB_REPORT_SIZE);
  637. //
  638. // Update the application on the changes in the keyboard state.
  639. //
  640. UpdateKeyboardState(pUSBHKeyboard);
  641. break;
  642. }
  643. }
  644. return(0);
  645. }
  646. //*****************************************************************************
  647. //
  648. //! @}
  649. //
  650. //*****************************************************************************