usbdhid.c 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665
  1. //*****************************************************************************
  2. //
  3. // usbdhid.c - USB HID device class 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 and reused from revision 6288
  22. // of the Stellaris USB Library.
  23. //
  24. //*****************************************************************************
  25. #include "hw_usb.h"
  26. #include "hw_types.h"
  27. #include "debug.h"
  28. #include "usb.h"
  29. #include "interrupt.h"
  30. #include "usblib.h"
  31. #include "usbhid.h"
  32. #include "usbdevice.h"
  33. #include "usbdhid.h"
  34. #include "usblibpriv.h"
  35. //*****************************************************************************
  36. //
  37. //! \addtogroup hid_device_class_api
  38. //! @{
  39. //
  40. //*****************************************************************************
  41. //*****************************************************************************
  42. //This macro is used to diable the bit band operartion. Need to undefine this macro to use the
  43. // bit band operation.
  44. //***************************************************************************
  45. #define DISABLE_BIT_BAND
  46. //*****************************************************************************
  47. //
  48. // The subset of endpoint status flags that we consider to be reception
  49. // errors. These are passed to the client via USB_EVENT_ERROR if seen.
  50. //
  51. //*****************************************************************************
  52. #define USB_RX_ERROR_FLAGS (USBERR_DEV_RX_DATA_ERROR | \
  53. USBERR_DEV_RX_OVERRUN | \
  54. USBERR_DEV_RX_FIFO_FULL)
  55. //*****************************************************************************
  56. //
  57. // Marker used to indicate that a given HID descriptor cannot be found in the
  58. // client-supplied list.
  59. //
  60. //*****************************************************************************
  61. #define HID_NOT_FOUND 0xFFFFFFFF
  62. //*****************************************************************************
  63. //
  64. // Flags that may appear in usDeferredOpFlags to indicate some operation that
  65. // has been requested but could not be processed at the time it was received.
  66. // Each deferred operation is defined as the bit number that should be set in
  67. // tHIDInstance->usDeferredOpFlags to indicate that the operation is pending.
  68. //
  69. //*****************************************************************************
  70. #define HID_DO_PACKET_RX 5
  71. #define HID_DO_SEND_IDLE_REPORT 6
  72. //*****************************************************************************
  73. //
  74. // Macros to convert between USB controller base address and an index. These
  75. // are currently trivial but are included to allow for the possibility of
  76. // supporting more than one controller in the future.
  77. //
  78. //*****************************************************************************
  79. #if (USB_NUM_INSTANCE == 2)
  80. #define USB_BASE_TO_INDEX(BaseAddr, index) do{ \
  81. if(USB0_BASE==BaseAddr) \
  82. index = 0; \
  83. else if(USB1_BASE==BaseAddr) \
  84. index = 1; \
  85. else \
  86. index = -1; \
  87. }while(0)
  88. #define USB_INDEX_TO_BASE(Index, BaseAddr) ( \
  89. if(0==Index) \
  90. BaseAddr = USB0_BASE; \
  91. else if(1==Index) \
  92. BaseAddr = USB1_BASE; \
  93. else \
  94. BaseAddr = -1; \
  95. )
  96. #else
  97. #define USB_BASE_TO_INDEX(BaseAddr, index) do{ \
  98. if(USB0_BASE==BaseAddr) \
  99. index = 0; \
  100. else \
  101. index = -1; \
  102. }while(0)
  103. #define USB_INDEX_TO_BASE(Index, BaseAddr) ( \
  104. if(0==Index) \
  105. BaseAddr = USB0_BASE; \
  106. else \
  107. BaseAddr = -1; \
  108. )
  109. #endif
  110. //*****************************************************************************
  111. //
  112. // Endpoints to use for each of the required endpoints in the driver.
  113. //
  114. //*****************************************************************************
  115. #define INT_IN_ENDPOINT USB_EP_3
  116. #define INT_OUT_ENDPOINT USB_EP_3
  117. //*****************************************************************************
  118. //
  119. // Maximum packet size for the interrupt endpoints used for report transmission
  120. // and reception and the associated FIFO sizes to set aside for each endpoint.
  121. //
  122. //*****************************************************************************
  123. #define INT_IN_EP_FIFO_SIZE USB_FIFO_SZ_64
  124. #define INT_OUT_EP_FIFO_SIZE USB_FIFO_SZ_64
  125. #define INT_IN_EP_MAX_SIZE USB_FIFO_SZ_TO_BYTES(INT_IN_EP_FIFO_SIZE)
  126. #define INT_OUT_EP_MAX_SIZE USB_FIFO_SZ_TO_BYTES(INT_IN_EP_FIFO_SIZE)
  127. //*****************************************************************************
  128. //
  129. // USB instance Object
  130. //
  131. //*****************************************************************************
  132. extern tUSBInstanceObject g_USBInstance[];
  133. //*****************************************************************************
  134. //
  135. // Device Descriptor. This is stored in RAM to allow several fields to be
  136. // changed at runtime based on the client's requirements.
  137. //
  138. //*****************************************************************************
  139. unsigned char g_pHIDDeviceDescriptor[] =
  140. {
  141. 18, // Size of this structure.
  142. USB_DTYPE_DEVICE, // Type of this structure.
  143. USBShort(0x200), // USB version 1.1 (if we say 2.0, hosts assume
  144. // high-speed - see USB 2.0 spec 9.2.6.6)
  145. USB_CLASS_DEVICE, // USB Device Class
  146. 0, // USB Device Sub-class
  147. USB_HID_PROTOCOL_NONE, // USB Device protocol
  148. 64, // Maximum packet size for default pipe.
  149. USBShort(0), // Vendor ID (VID).
  150. USBShort(0), // Product ID (PID).
  151. USBShort(0x100), // Device Version BCD.
  152. 1, // Manufacturer string identifier.
  153. 2, // Product string identifier.
  154. 3, // Product serial number.
  155. 1 // Number of configurations.
  156. };
  157. //*****************************************************************************
  158. //
  159. // HID device configuration descriptor.
  160. //
  161. // It is vital that the configuration descriptor bConfigurationValue field
  162. // (byte 6) is 1 for the first configuration and increments by 1 for each
  163. // additional configuration defined here. This relationship is assumed in the
  164. // device stack for simplicity even though the USB 2.0 specification imposes
  165. // no such restriction on the bConfigurationValue values.
  166. //
  167. // Note that this structure is deliberately located in RAM since we need to
  168. // be able to patch some values in it based on client requirements.
  169. //
  170. //*****************************************************************************
  171. unsigned char g_pHIDDescriptor[] =
  172. {
  173. //
  174. // Configuration descriptor header.
  175. //
  176. 9, // Size of the configuration descriptor.
  177. USB_DTYPE_CONFIGURATION, // Type of this descriptor.
  178. USBShort(34), // The total size of this full structure.
  179. 1, // The number of interfaces in this
  180. // configuration.
  181. 1, // The unique value for this configuration.
  182. 5, // The string identifier that describes this
  183. // configuration.
  184. USB_CONF_ATTR_SELF_PWR, // Bus Powered, Self Powered, remote wake up.
  185. 250, // The maximum power in 2mA increments.
  186. };
  187. //*****************************************************************************
  188. //
  189. // The remainder of the configuration descriptor is stored in flash since we
  190. // don't need to modify anything in it at runtime.
  191. //
  192. //*****************************************************************************
  193. unsigned char g_pHIDInterface[] =
  194. {
  195. //
  196. // HID Device Class Interface Descriptor.
  197. //
  198. 9, // Size of the interface descriptor.
  199. USB_DTYPE_INTERFACE, // Type of this descriptor.
  200. 0, // The index for this interface.
  201. 0, // The alternate setting for this interface.
  202. 2, // The number of endpoints used by this
  203. // interface.
  204. USB_CLASS_HID, // The interface class
  205. 0, // The interface sub-class.
  206. 0, // The interface protocol for the sub-class
  207. // specified above.
  208. 4, // The string index for this interface.
  209. };
  210. const unsigned char g_pHIDInEndpoint[] =
  211. {
  212. //
  213. // Interrupt IN endpoint descriptor
  214. //
  215. 7, // The size of the endpoint descriptor.
  216. USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint.
  217. USB_EP_DESC_IN | USB_EP_TO_INDEX(INT_IN_ENDPOINT),
  218. USB_EP_ATTR_INT, // Endpoint is an interrupt endpoint.
  219. USBShort(INT_IN_EP_MAX_SIZE), // The maximum packet size.
  220. 16, // The polling interval for this endpoint.
  221. };
  222. const unsigned char g_pHIDOutEndpoint[] =
  223. {
  224. //
  225. // Interrupt OUT endpoint descriptor
  226. //
  227. 7, // The size of the endpoint descriptor.
  228. USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint.
  229. USB_EP_DESC_OUT | USB_EP_TO_INDEX(INT_OUT_ENDPOINT),
  230. USB_EP_ATTR_INT, // Endpoint is an interrupt endpoint.
  231. USBShort(INT_OUT_EP_MAX_SIZE), // The maximum packet size.
  232. 16, // The polling interval for this endpoint.
  233. };
  234. //*****************************************************************************
  235. //
  236. // The HID configuration descriptor is defined as four or five sections
  237. // depending upon the client's configuration choice. These sections are:
  238. //
  239. // 1. The 9 byte configuration descriptor (RAM).
  240. // 2. The interface descriptor (RAM).
  241. // 3. The HID report and physical descriptors (provided by the client)
  242. // (FLASH).
  243. // 4. The mandatory interrupt IN endpoint descriptor (FLASH).
  244. // 5. The optional interrupt OUT endpoint descriptor (FLASH).
  245. //
  246. //*****************************************************************************
  247. const tConfigSection g_sHIDConfigSection =
  248. {
  249. sizeof(g_pHIDDescriptor),
  250. g_pHIDDescriptor
  251. };
  252. const tConfigSection g_sHIDInterfaceSection =
  253. {
  254. sizeof(g_pHIDInterface),
  255. g_pHIDInterface
  256. };
  257. const tConfigSection g_sHIDInEndpointSection =
  258. {
  259. sizeof(g_pHIDInEndpoint),
  260. g_pHIDInEndpoint
  261. };
  262. const tConfigSection g_sHIDOutEndpointSection =
  263. {
  264. sizeof(g_pHIDOutEndpoint),
  265. g_pHIDOutEndpoint
  266. };
  267. //*****************************************************************************
  268. //
  269. // Place holder for the user's HID descriptor block.
  270. //
  271. //*****************************************************************************
  272. tConfigSection g_sHIDDescriptorSection =
  273. {
  274. 0, (void *)0
  275. };
  276. //*****************************************************************************
  277. //
  278. // This array lists all the sections that must be concatenated to make a
  279. // single, complete HID configuration descriptor.
  280. //
  281. //*****************************************************************************
  282. const tConfigSection *g_psHIDSections[] =
  283. {
  284. &g_sHIDConfigSection,
  285. &g_sHIDInterfaceSection,
  286. &g_sHIDDescriptorSection,
  287. &g_sHIDInEndpointSection,
  288. &g_sHIDOutEndpointSection
  289. };
  290. #define NUM_HID_SECTIONS (sizeof(g_psHIDSections) / \
  291. sizeof(tConfigSection *))
  292. //*****************************************************************************
  293. //
  294. // The header for the single configuration we support. This is the root of
  295. // the data structure that defines all the bits and pieces that are pulled
  296. // together to generate the configuration descriptor. Note that this must be
  297. // in RAM since we need to include or exclude the final section based on
  298. // client supplied initialization parameters.
  299. //
  300. //*****************************************************************************
  301. tConfigHeader g_sHIDConfigHeader =
  302. {
  303. NUM_HID_SECTIONS,
  304. g_psHIDSections
  305. };
  306. //*****************************************************************************
  307. //
  308. // Configuration Descriptor.
  309. //
  310. //*****************************************************************************
  311. const tConfigHeader * const g_pHIDConfigDescriptors[] =
  312. {
  313. &g_sHIDConfigHeader
  314. };
  315. //*****************************************************************************
  316. //
  317. // Forward references for device handler callbacks
  318. //
  319. //*****************************************************************************
  320. static void HandleGetDescriptor(void *pvInstance, tUSBRequest *pUSBRequest,
  321. unsigned int ulIndex);
  322. static void HandleRequest(void *pvInstance, tUSBRequest *pUSBRequest,
  323. unsigned int ulIndex);
  324. static void HandleConfigChange(void *pvInstance, unsigned int ulInfo,
  325. unsigned int ulIndex);
  326. static void HandleEP0DataReceived(void *pvInstance, unsigned int ulInfo,
  327. unsigned int ulIndex);
  328. static void HandleEP0DataSent(void *pvInstance, unsigned int ulInfo,
  329. unsigned int ulIndex);
  330. static void HandleReset(void *pvInstance);
  331. static void HandleSuspend(void *pvInstance);
  332. static void HandleResume(void *pvInstance);
  333. static void HandleDisconnect(void *pvInstance);
  334. static void HandleEndpoints(void *pvInstance, unsigned int ulStatus,
  335. unsigned int ulIndex);
  336. static void HandleDevice(void *pvInstance, unsigned int ulRequest,
  337. void *pvRequestData);
  338. //*****************************************************************************
  339. //
  340. // The device information structure for the USB HID devices.
  341. //
  342. //*****************************************************************************
  343. tDeviceInfo g_sHIDDeviceInfo =
  344. {
  345. //
  346. // Device event handler callbacks.
  347. //
  348. {
  349. HandleGetDescriptor, // GetDescriptor
  350. HandleRequest, // RequestHandler
  351. 0, // InterfaceChange
  352. HandleConfigChange, // ConfigChange
  353. HandleEP0DataReceived, // DataReceived
  354. HandleEP0DataSent, // DataSentCallback
  355. HandleReset, // ResetHandler
  356. HandleSuspend, // SuspendHandler
  357. HandleResume, // ResumeHandler
  358. HandleDisconnect, // DisconnectHandler
  359. HandleEndpoints, // EndpointHandler
  360. HandleDevice // Device handler.
  361. },
  362. g_pHIDDeviceDescriptor,
  363. g_pHIDConfigDescriptors,
  364. 0, // Will be completed during USBDHIDInit().
  365. 0, // Will be completed during USBDHIDInit().
  366. &g_sUSBDefaultFIFOConfig
  367. };
  368. //*****************************************************************************
  369. //
  370. // Set or clear deferred operation flags in an "atomic" manner.
  371. //
  372. // \param pusDeferredOp points to the flags variable which is to be modified.
  373. // \param usBit indicates which bit number is to be set or cleared.
  374. // \param bSet indicates the state that the flag must be set to. If \b true,
  375. // the flag is set, if \b false, the flag is cleared.
  376. //
  377. // This function safely sets or clears a bit in a flag variable. The operation
  378. // makes use of bitbanding to ensure that the operation is atomic (no read-
  379. // modify-write is required).
  380. //
  381. // \return None.
  382. //
  383. //*****************************************************************************
  384. static void
  385. SetDeferredOpFlag(volatile unsigned short *pusDeferredOp,
  386. unsigned short usBit, tBoolean bSet)
  387. {
  388. #ifdef DISABLE_BIT_BAND
  389. if(bSet)
  390. {
  391. HWREG(pusDeferredOp) |= (1<<usBit);
  392. }
  393. else
  394. {
  395. HWREG(pusDeferredOp) &= ~(1<<usBit);
  396. }
  397. #else
  398. //
  399. // Set the flag bit to 1 or 0 using a bitband access.
  400. //
  401. HWREGBITH(pusDeferredOp, usBit) = bSet ? 1 : 0;
  402. #endif
  403. }
  404. //*****************************************************************************
  405. //
  406. // This function is called to clear the counter used to keep track of the time
  407. // elapsed since a given report was last sent.
  408. //
  409. // \param psDevice points to the HID device structure whose report timer is to
  410. // be cleared.
  411. // \param ucReportID is the first byte of the report to be sent. If this
  412. // device offers more than one input report, this value is used to find the
  413. // relevant report timer structure in the psDevice structure.
  414. //
  415. // \return None.
  416. //
  417. //*****************************************************************************
  418. static void
  419. ClearReportTimer(const tUSBDHIDDevice *psDevice, unsigned char ucReportID)
  420. {
  421. unsigned int ulLoop;
  422. if(psDevice->ucNumInputReports > 1)
  423. {
  424. //
  425. // We have more than 1 input report so the report must begin with a
  426. // byte containing the report ID. Scan the table we were provided
  427. // when the device was initialized to find the entry for this report.
  428. //
  429. for(ulLoop = 0; ulLoop < psDevice->ucNumInputReports; ulLoop++)
  430. {
  431. if(psDevice->psReportIdle[ulLoop].ucReportID == ucReportID)
  432. {
  433. break;
  434. }
  435. }
  436. }
  437. else
  438. {
  439. ulLoop = 0;
  440. }
  441. //
  442. // If we drop out of the loop with an index less than ucNumInputReports,
  443. // we found the relevant report so clear its timer.
  444. //
  445. if(ulLoop < psDevice->ucNumInputReports)
  446. {
  447. psDevice->psReportIdle[ulLoop].ulTimeSinceReportmS = 0;
  448. }
  449. }
  450. //*****************************************************************************
  451. //
  452. // This function is called to clear the idle period timers for each input
  453. // report supported by the device.
  454. //
  455. // \param psDevice points to the HID device structure whose timers are to be
  456. // cleared.
  457. // \param ulTimemS is the elapsed time in milliseconds since the last call
  458. // to this function.
  459. //
  460. // \return None.
  461. //
  462. //*****************************************************************************
  463. static void
  464. ClearIdleTimers(const tUSBDHIDDevice *psDevice)
  465. {
  466. unsigned int ulLoop;
  467. //
  468. // Clear the "time till next report" counters for each input report.
  469. //
  470. for(ulLoop = 0; ulLoop < psDevice->ucNumInputReports; ulLoop++)
  471. {
  472. psDevice->psReportIdle[ulLoop].usTimeTillNextmS =
  473. psDevice->psReportIdle[ulLoop].ucDuration4mS * 4;
  474. }
  475. }
  476. //*****************************************************************************
  477. //
  478. // This function is called periodically to allow us to process the report idle
  479. // timers.
  480. //
  481. // \param psDevice points to the HID device structure whose timers are to be
  482. // updated.
  483. // \param ulElapsedmS indicates the number of milliseconds that have elapsed
  484. // since the last call to this function.
  485. //
  486. // \return None.
  487. //
  488. //*****************************************************************************
  489. static void
  490. ProcessIdleTimers(const tUSBDHIDDevice *psDevice, unsigned int ulElapsedmS)
  491. {
  492. unsigned int ulLoop;
  493. unsigned int ulSizeReport;
  494. void *pvReport;
  495. tHIDInstance *psInst;
  496. tBoolean bDeferred;
  497. //
  498. // Get our instance data pointer
  499. //
  500. psInst = ((tUSBDHIDDevice *)psDevice)->psPrivateHIDData;
  501. //
  502. // We have not had to defer any report transmissions yet.
  503. //
  504. bDeferred = false;
  505. //
  506. // Look at each of the input report idle timers in turn.
  507. //
  508. for(ulLoop = 0; ulLoop < psDevice->ucNumInputReports; ulLoop++)
  509. {
  510. //
  511. // Update the time since the last report was sent.
  512. //
  513. psDevice->psReportIdle[ulLoop].ulTimeSinceReportmS += ulElapsedmS;
  514. //
  515. // Is this timer running?
  516. //
  517. if(psDevice->psReportIdle[ulLoop].ucDuration4mS)
  518. {
  519. //
  520. // Yes - is it about to expire?
  521. //
  522. if(psDevice->psReportIdle[ulLoop].usTimeTillNextmS <= ulElapsedmS)
  523. {
  524. //
  525. // The timer is about to expire. Can we send a report right
  526. // now?
  527. //
  528. if((psInst->eHIDTxState == HID_STATE_IDLE) &&
  529. (psInst->bSendInProgress == false))
  530. {
  531. //
  532. // We can send a report so send a message to the
  533. // application to retrieve its latest report for
  534. // transmission to the host.
  535. //
  536. ulSizeReport = psDevice->pfnRxCallback(
  537. psDevice->pvRxCBData,
  538. USBD_HID_EVENT_IDLE_TIMEOUT,
  539. psDevice->psReportIdle[ulLoop].ucReportID,
  540. &pvReport);
  541. //
  542. // Schedule the report for transmission.
  543. //
  544. USBDHIDReportWrite((void *)psDevice, pvReport,
  545. ulSizeReport, true);
  546. //
  547. // Reload the timer for the next period.
  548. //
  549. psDevice->psReportIdle[ulLoop].usTimeTillNextmS =
  550. psDevice->psReportIdle[ulLoop].ucDuration4mS * 4;
  551. }
  552. else
  553. {
  554. //
  555. // We can't send the report straight away so flag it for
  556. // transmission as soon as the previous transmission ends.
  557. //
  558. psDevice->psReportIdle[ulLoop].usTimeTillNextmS = 0;
  559. bDeferred = true;
  560. }
  561. }
  562. else
  563. {
  564. //
  565. // The timer is not about to expire. Update the time till the
  566. // next report transmission.
  567. //
  568. psDevice->psReportIdle[ulLoop].usTimeTillNextmS -= ulElapsedmS;
  569. }
  570. }
  571. }
  572. //
  573. // If we had to defer transmission of any report, remember this so that we
  574. // will process it as soon as possible.
  575. //
  576. SetDeferredOpFlag(&psInst->usDeferredOpFlags,
  577. HID_DO_SEND_IDLE_REPORT, bDeferred);
  578. }
  579. static void
  580. SetIdleTimeout(const tUSBDHIDDevice *psDevice, unsigned char ucReportID,
  581. unsigned char ucTimeout4mS)
  582. {
  583. unsigned int ulLoop;
  584. tBoolean bReportNeeded;
  585. tHIDReportIdle *psIdle;
  586. //
  587. // Remember that we have not found any report that needs to be sent
  588. // immediately.
  589. //
  590. bReportNeeded = false;
  591. //
  592. // Search through all the input reports looking for ones that fit the
  593. // requirements.
  594. //
  595. for(ulLoop = 0; ulLoop < psDevice->ucNumInputReports; ulLoop++)
  596. {
  597. psIdle = &psDevice->psReportIdle[ulLoop];
  598. //
  599. // If the report ID passed matches the report ID in the idle timer
  600. // control structure or we were passed a report ID of zero, which
  601. // indicates that all timers are to be set...
  602. //
  603. if(!ucReportID || (ucReportID == psIdle->ucReportID))
  604. {
  605. //
  606. // Save the new duration for the idle timer.
  607. //
  608. psIdle->ucDuration4mS = ucTimeout4mS;
  609. //
  610. // Are we enabling the idle timer? If so, fix up the time until it
  611. // needs to fire.
  612. //
  613. if(ucTimeout4mS)
  614. {
  615. //
  616. // Determine what the timeout is for this report given the time
  617. // since the last report of this type was sent.
  618. //
  619. if(psIdle->ulTimeSinceReportmS >=
  620. ((unsigned int)ucTimeout4mS * 4))
  621. {
  622. psIdle->usTimeTillNextmS = 0;
  623. bReportNeeded = true;
  624. }
  625. else
  626. {
  627. psIdle->usTimeTillNextmS =
  628. (((unsigned short)ucTimeout4mS * 4) -
  629. psIdle->ulTimeSinceReportmS);
  630. }
  631. }
  632. }
  633. }
  634. //
  635. // If we get to here and bReportNeeded is true, this means we need to
  636. // send back at least one of the input reports as soon as possible. Try
  637. // to do this immediately.
  638. //
  639. if(bReportNeeded)
  640. {
  641. ProcessIdleTimers(psDevice, 0);
  642. }
  643. }
  644. //*****************************************************************************
  645. //
  646. // Find the idle timeout for a given HID input report.
  647. //
  648. // \param psDevice points to the HID device whose report idle timeout is to be
  649. // found.
  650. // \param ucReportID identifies the report whose timeout is requested. If 0,
  651. // the timeout for the first report is returns, regardless of its ID (or
  652. // whether it has one).
  653. //
  654. // This function returns the current idle timeout for a given HID input report.
  655. // The value returned is expressed in terms of 4mS intervals. Convert to
  656. // milliseconds by multiplying by 4. If the return value is 0, this indicates
  657. // that an infinite timeout is currently set and the device will not send the
  658. // report unless a state change occurs.
  659. //
  660. // \return Returns the current idle timeout for the given report.
  661. //
  662. //*****************************************************************************
  663. static unsigned int
  664. GetIdleTimeout(const tUSBDHIDDevice *psDevice, unsigned char ucReportID)
  665. {
  666. unsigned int ulLoop;
  667. tHIDReportIdle *psIdle;
  668. //
  669. // Search through all the input reports looking for ones that fit the
  670. // requirements.
  671. //
  672. for(ulLoop = 0; ulLoop < psDevice->ucNumInputReports; ulLoop++)
  673. {
  674. psIdle = &psDevice->psReportIdle[ulLoop];
  675. //
  676. // If the report ID passed matches the report ID in the idle timer
  677. // control structure or we were passed a report ID of zero, which
  678. // indicates that all timers are to be set...
  679. //
  680. if(!ucReportID || (ucReportID == psIdle->ucReportID))
  681. {
  682. //
  683. // We found a report matching the required ID or we were not passed
  684. // an ID and we are looking at the first report information.
  685. //
  686. return((unsigned int)psIdle->ucDuration4mS);
  687. }
  688. }
  689. //
  690. // If we drop out, the report couldn't be found so we need to indicate
  691. // an error.
  692. //
  693. return(HID_NOT_FOUND);
  694. }
  695. //*****************************************************************************
  696. //
  697. // Find the n-th HID class descriptor of a given type in the client-provided
  698. // descriptor table.
  699. //
  700. // \param psDevice points to the HID device which is to be searched for the
  701. // required class descriptor.
  702. // \param ucType is the type of class descriptor being requested. This will
  703. // be either USB_HID_DTYPE_REPORT or USB_HID_DTYPE_PHYSICAL.
  704. // \param ulIndex is the zero-based index of the descriptor that is being
  705. // requested.
  706. //
  707. // This function parses the supplied HID descriptor to find the index into the
  708. // sClassDescriptor array that corresponds to the requested descriptor. If
  709. // a descriptor with the requested index does not exist, HID_NOT_FOUND will be
  710. // returned unless the request is for a physical descriptor and at least one
  711. // such descriptor exists. In this case, the index returned will be for the
  712. // last physical descriptor (as required by the HID spec 7.1.1).
  713. //
  714. // \return Returns the index of the descriptor within the sClassDescriptor
  715. // of the tHIDDevice structure if found or HID_NOT_FOUND otherwise.
  716. //
  717. //*****************************************************************************
  718. static unsigned int
  719. FindHIDDescriptor(const tUSBDHIDDevice *psDevice, unsigned char ucType,
  720. unsigned int ulIndex, unsigned int *pulLen)
  721. {
  722. tBoolean bFoundType;
  723. unsigned int ulLoop;
  724. unsigned int ulCount;
  725. unsigned int ulLastFound;
  726. const tHIDClassDescriptorInfo *psDesc;
  727. //
  728. // Remember that we have not found any descriptor with a matching type yet.
  729. //
  730. bFoundType = false;
  731. ulCount = 0;
  732. ulLastFound = 0;
  733. //
  734. // Walk through all the class descriptors looking for the one which
  735. // matches the requested index and type.
  736. //
  737. for(ulLoop = 0; ulLoop < psDevice->psHIDDescriptor->bNumDescriptors;
  738. ulLoop++)
  739. {
  740. psDesc = &(psDevice->psHIDDescriptor->sClassDescriptor[ulLoop]);
  741. if(psDesc->bDescriptorType == ucType)
  742. {
  743. //
  744. // We found a descriptor of the correct type. Is this the
  745. // correct index?
  746. //
  747. bFoundType = true;
  748. //
  749. // Is this the descriptor we are looking for?
  750. //
  751. if(ulCount == ulIndex)
  752. {
  753. //
  754. // Yes - we found it so return the index and size to the
  755. // caller.
  756. //
  757. *pulLen = (unsigned int)psDesc->wDescriptorLength;
  758. return(ulLoop);
  759. }
  760. else
  761. {
  762. //
  763. // Update our count and keep looking. Remember where we were
  764. // when we found this descriptor in case we need to return the
  765. // last physical descriptor.
  766. //
  767. ulCount++;
  768. ulLastFound = ulLoop;
  769. }
  770. }
  771. }
  772. //
  773. // If we drop out, we didn't find the requested descriptor. Now handle
  774. // the special case of a physical descriptor - if we found any physical
  775. // descriptors, return the last one.
  776. //
  777. if((ucType == USB_HID_DTYPE_PHYSICAL) && bFoundType)
  778. {
  779. //
  780. // Get the length of the last descriptor we found.
  781. //
  782. psDesc = &(psDevice->psHIDDescriptor->sClassDescriptor[ulLastFound]);
  783. *pulLen = (unsigned int)psDesc->wDescriptorLength;
  784. //
  785. // Return the index to the caller.
  786. //
  787. return(ulLastFound);
  788. }
  789. else
  790. {
  791. //
  792. // We couldn't find the descriptor so return an appropriate error.
  793. //
  794. return(HID_NOT_FOUND);
  795. }
  796. }
  797. //*****************************************************************************
  798. //
  799. // Schedule transmission of the next packet forming part of an input report.
  800. //
  801. // \param psInst points to the device instance whose input report is to be
  802. // sent.
  803. //
  804. // This function is called to transmit the next packet of an input report
  805. // passed to the driver via a call to USBDHIDReportWrite. If any data remains
  806. // to be sent, a USB packet is written to the FIFO and scheduled for
  807. // transmission to the host. The function ensures that reports are sent as
  808. // a sequence of full packets followed by either a single short packet or a
  809. // packet with no data to indicate the end of the transaction.
  810. //
  811. //*****************************************************************************
  812. static int
  813. ScheduleReportTransmission(tHIDInstance *psInst)
  814. {
  815. unsigned int ulNumBytes;
  816. unsigned char *pucData;
  817. int iRetcode;
  818. //
  819. // Set the number of bytes to send this iteration.
  820. //
  821. ulNumBytes = (unsigned int)(psInst->usInReportSize -
  822. psInst->usInReportIndex);
  823. //
  824. // Limit individual transfers to the maximum packet size for the endpoint.
  825. //
  826. if(ulNumBytes > INT_IN_EP_MAX_SIZE)
  827. {
  828. ulNumBytes = INT_IN_EP_MAX_SIZE;
  829. }
  830. //
  831. // Where are we sending this data from?
  832. //
  833. pucData = psInst->pucInReportData + psInst->usInReportIndex;
  834. //
  835. // Put the data in the correct FIFO.
  836. //
  837. iRetcode = USBEndpointDataPut(psInst->ulUSBBase, psInst->ucINEndpoint,
  838. pucData, ulNumBytes);
  839. if(iRetcode != -1)
  840. {
  841. //
  842. // Update the count and index ready for the next time round.
  843. //
  844. psInst->usInReportIndex += ulNumBytes;
  845. //
  846. // Send out the current data.
  847. //
  848. iRetcode = USBEndpointDataSend(psInst->ulUSBBase, psInst->ucINEndpoint,
  849. USB_TRANS_IN);
  850. }
  851. //
  852. // Tell the caller how we got on.
  853. //
  854. return(iRetcode);
  855. }
  856. //*****************************************************************************
  857. //
  858. // Receives notifications related to data received from the host.
  859. //
  860. // \param psDevice is the device instance whose endpoint is to be processed.
  861. // \param ulStatus is the USB interrupt status that caused this function to
  862. // be called.
  863. //
  864. // This function is called from HandleEndpoints for all interrupts signaling
  865. // the arrival of data on the interrupt OUT endpoint (in other words, whenever
  866. // the host has sent us a packet of data). We inform the client that a packet
  867. // is available and, on return, check to see if the packet has been read. If
  868. // not, we schedule another notification to the client for a later time.
  869. //
  870. // \return Returns \b true on success or \b false on failure.
  871. //
  872. //*****************************************************************************
  873. static tBoolean
  874. ProcessDataFromHost(const tUSBDHIDDevice *psDevice, unsigned int ulStatus,
  875. unsigned int ulIndex)
  876. {
  877. unsigned int ulEPStatus;
  878. unsigned int ulSize;
  879. tHIDInstance *psInst;
  880. //
  881. // Get a pointer to our instance data.
  882. //
  883. psInst = psDevice->psPrivateHIDData;
  884. //
  885. // Get the endpoint status to see why we were called.
  886. //
  887. ulEPStatus = USBEndpointStatus(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint);
  888. //
  889. // Clear the status bits.
  890. //
  891. USBDevEndpointStatusClear(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint, ulEPStatus);
  892. //
  893. // Has a packet been received?
  894. //
  895. if(ulEPStatus & USB_DEV_RX_PKT_RDY)
  896. {
  897. //
  898. // Set the flag we use to indicate that a packet read is pending. This
  899. // will be cleared if the packet is read. If the client doesn't read
  900. // the packet in the context of the USB_EVENT_RX_AVAILABLE callback,
  901. // the event will be signaled later during tick processing.
  902. //
  903. SetDeferredOpFlag(&psInst->usDeferredOpFlags, HID_DO_PACKET_RX, true);
  904. //
  905. // How big is the packet we've just been sent?
  906. //
  907. ulSize = USBEndpointDataAvail(psInst->ulUSBBase,
  908. psInst->ucOUTEndpoint);
  909. //
  910. // The receive channel is not blocked so let the caller know
  911. // that a packet is waiting. The parameters are set to indicate
  912. // that the packet has not been read from the hardware FIFO yet.
  913. //
  914. psDevice->pfnRxCallback(psDevice->pvRxCBData,
  915. USB_EVENT_RX_AVAILABLE, ulSize,
  916. (void *)0);
  917. }
  918. else
  919. {
  920. //
  921. // No packet was received. Some error must have been reported. Check
  922. // and pass this on to the client if necessary.
  923. //
  924. if(ulEPStatus & USB_RX_ERROR_FLAGS)
  925. {
  926. //
  927. // This is an error we report to the client so...
  928. //
  929. psDevice->pfnRxCallback(psDevice->pvRxCBData,
  930. USB_EVENT_ERROR,
  931. (ulEPStatus & USB_RX_ERROR_FLAGS),
  932. (void *)0);
  933. }
  934. return (false);
  935. }
  936. return (true);
  937. }
  938. //*****************************************************************************
  939. //
  940. // Receives notifications related to data sent to the host.
  941. //
  942. // \param psDevice is the device instance whose endpoint is to be processed.
  943. // \param ulStatus is the USB interrupt status that caused this function to
  944. // be called.
  945. //
  946. // This function is called from HandleEndpoints for all interrupts originating
  947. // from the interrupt IN endpoint (in other words, whenever data has been
  948. // transmitted to the USB host). We examine the cause of the interrupt and,
  949. // if due to completion of a transmission, notify the client.
  950. //
  951. // \return Returns \b true on success or \b false on failure.
  952. //
  953. //*****************************************************************************
  954. static tBoolean
  955. ProcessDataToHost(const tUSBDHIDDevice *psDevice, unsigned int ulStatus,
  956. unsigned int ulIndex)
  957. {
  958. tHIDInstance *psInst;
  959. unsigned int ulEPStatus;
  960. //
  961. // Get a pointer to our instance data.
  962. //
  963. psInst = psDevice->psPrivateHIDData;
  964. //
  965. // Get the endpoint status to see why we were called.
  966. //
  967. ulEPStatus = USBEndpointStatus(psInst->ulUSBBase, psInst->ucINEndpoint);
  968. //
  969. // Clear the status bits.
  970. //
  971. USBDevEndpointStatusClear(psInst->ulUSBBase, psInst->ucINEndpoint,
  972. ulEPStatus);
  973. //
  974. // Our last packet was transmitted successfully. Is there any more data to
  975. // send or have we finished sending the whole report? We know we finished
  976. // if the usInReportIndex has reached the usInReportSize value.
  977. //
  978. if(psInst->usInReportSize == psInst->usInReportIndex)
  979. {
  980. //
  981. // We finished sending the last report so are idle once again.
  982. //
  983. psInst->eHIDTxState = HID_STATE_IDLE;
  984. //
  985. // Notify the client that the report transmission completed.
  986. //
  987. psDevice->pfnTxCallback(psDevice->pvTxCBData, USB_EVENT_TX_COMPLETE,
  988. psInst->usInReportSize, (void *)0);
  989. //
  990. // Do we have any reports to send as a result of idle timer timeouts?
  991. //
  992. if(psInst->usDeferredOpFlags & (1 << HID_DO_SEND_IDLE_REPORT))
  993. {
  994. //
  995. // Yes - send reports for any timers that expired recently.
  996. //
  997. ProcessIdleTimers(psDevice, 0);
  998. }
  999. }
  1000. else
  1001. {
  1002. //
  1003. // There must be more data or a zero length packet waiting to be sent
  1004. // so go ahead and do this.
  1005. //
  1006. ScheduleReportTransmission(psInst);
  1007. }
  1008. return (true);
  1009. }
  1010. //*****************************************************************************
  1011. //
  1012. // Called by the USB stack for any activity involving one of our endpoints
  1013. // other than EP0. This function is a fan out that merely directs the call to
  1014. // the correct handler depending upon the endpoint and transaction direction
  1015. // signaled in ulStatus.
  1016. //
  1017. //*****************************************************************************
  1018. static void
  1019. HandleEndpoints(void *pvInstance, unsigned int ulStatus, unsigned int ulIndex)
  1020. {
  1021. const tUSBDHIDDevice *psHIDInst;
  1022. tHIDInstance *psInst;
  1023. ASSERT(pvInstance != 0);
  1024. //
  1025. // Determine if the serial device is in single or composite mode because
  1026. // the meaning of ulIndex is different in both cases.
  1027. //
  1028. psHIDInst = (const tUSBDHIDDevice *)pvInstance;
  1029. psInst = psHIDInst->psPrivateHIDData;
  1030. //
  1031. // Handler for the interrupt OUT data endpoint.
  1032. //
  1033. if(ulStatus & (0x10000 << USB_EP_TO_INDEX(psInst->ucOUTEndpoint)))
  1034. {
  1035. //
  1036. // Data is being sent to us from the host.
  1037. //
  1038. ProcessDataFromHost(pvInstance, ulStatus, ulIndex);
  1039. }
  1040. //
  1041. // Handler for the interrupt IN data endpoint.
  1042. //
  1043. if(ulStatus & (1 << USB_EP_TO_INDEX(psInst->ucINEndpoint)))
  1044. {
  1045. ProcessDataToHost(pvInstance, ulStatus, ulIndex);
  1046. }
  1047. }
  1048. //*****************************************************************************
  1049. //
  1050. // Called by the USB stack whenever a configuration change occurs.
  1051. //
  1052. //*****************************************************************************
  1053. static void
  1054. HandleConfigChange(void *pvInstance, unsigned int ulInfo,
  1055. unsigned int ulIndex)
  1056. {
  1057. tHIDInstance *psInst;
  1058. const tUSBDHIDDevice *psDevice;
  1059. ASSERT(pvInstance != 0);
  1060. //
  1061. // Create the instance pointer.
  1062. //
  1063. psDevice = pvInstance;
  1064. //
  1065. // Get a pointer to our instance data.
  1066. //
  1067. psInst = psDevice->psPrivateHIDData;
  1068. //
  1069. // Set all our endpoints to idle state.
  1070. //
  1071. psInst->eHIDRxState = HID_STATE_IDLE;
  1072. psInst->eHIDTxState = HID_STATE_IDLE;
  1073. //
  1074. // If we are not currently connected let the client know we are open for
  1075. // business.
  1076. //
  1077. if(!psInst->bConnected)
  1078. {
  1079. //
  1080. // Pass the connected event to the client.
  1081. //
  1082. psDevice->pfnRxCallback(psDevice->pvRxCBData, USB_EVENT_CONNECTED, 0,
  1083. (void *)0);
  1084. }
  1085. //
  1086. // Clear the idle timers for each input report.
  1087. //
  1088. ClearIdleTimers(psDevice);
  1089. //
  1090. // Remember that we are connected.
  1091. //
  1092. psInst->bConnected = true;
  1093. }
  1094. //*****************************************************************************
  1095. //
  1096. // Device instance specific handler.
  1097. //
  1098. //*****************************************************************************
  1099. static void
  1100. HandleDevice(void *pvInstance, unsigned int ulRequest, void *pvRequestData)
  1101. {
  1102. tHIDInstance *psInst;
  1103. unsigned char *pucData;
  1104. //
  1105. // Create the serial instance data.
  1106. //
  1107. psInst = ((tUSBDHIDDevice *)pvInstance)->psPrivateHIDData;
  1108. //
  1109. // Create the char array used by the events supported by the USB CDC
  1110. // serial class.
  1111. //
  1112. pucData = (unsigned char *)pvRequestData;
  1113. switch(ulRequest)
  1114. {
  1115. //
  1116. // This was an interface change event.
  1117. //
  1118. case USB_EVENT_COMP_IFACE_CHANGE:
  1119. {
  1120. psInst->ucInterface = pucData[1];
  1121. break;
  1122. }
  1123. //
  1124. // This was an endpoint change event.
  1125. //
  1126. case USB_EVENT_COMP_EP_CHANGE:
  1127. {
  1128. //
  1129. // Determine if this is an IN or OUT endpoint that has changed.
  1130. //
  1131. if(pucData[0] & USB_EP_DESC_IN)
  1132. {
  1133. psInst->ucINEndpoint =
  1134. INDEX_TO_USB_EP((pucData[1] & 0x7f));
  1135. }
  1136. else
  1137. {
  1138. //
  1139. // Extract the new endpoint number.
  1140. //
  1141. psInst->ucOUTEndpoint =
  1142. INDEX_TO_USB_EP(pucData[1] & 0x7f);
  1143. }
  1144. break;
  1145. }
  1146. default:
  1147. {
  1148. break;
  1149. }
  1150. }
  1151. }
  1152. //*****************************************************************************
  1153. //
  1154. // This function is called by the USB device stack whenever the device is
  1155. // disconnected from the host.
  1156. //
  1157. //*****************************************************************************
  1158. static void
  1159. HandleDisconnect(void *pvInstance)
  1160. {
  1161. const tUSBDHIDDevice *psDevice;
  1162. ASSERT(pvInstance != 0);
  1163. //
  1164. // Create the instance pointer.
  1165. //
  1166. psDevice = (const tUSBDHIDDevice *)pvInstance;
  1167. //
  1168. // If we are not currently connected so let the client know we are open
  1169. // for business.
  1170. //
  1171. if(psDevice->psPrivateHIDData->bConnected)
  1172. {
  1173. //
  1174. // Pass the disconnected event to the client.
  1175. //
  1176. psDevice->pfnRxCallback(psDevice->pvRxCBData, USB_EVENT_DISCONNECTED,
  1177. 0, (void *)0);
  1178. }
  1179. //
  1180. // Remember that we are no longer connected.
  1181. //
  1182. psDevice->psPrivateHIDData->bConnected = false;
  1183. }
  1184. //*****************************************************************************
  1185. //
  1186. // This function is called by the USB device stack whenever a request for a
  1187. // non-standard descriptor is received.
  1188. //
  1189. // \param pvInstance is the instance data for this request.
  1190. // \param pUSBRequest points to the request received.
  1191. //
  1192. // This call parses the provided request structure and determines which
  1193. // descriptor is being requested. Assuming the descriptor can be found, it is
  1194. // scheduled for transmission via endpoint zero. If the descriptor cannot be
  1195. // found, the endpoint is stalled to indicate an error to the host.
  1196. //
  1197. //*****************************************************************************
  1198. static void
  1199. HandleGetDescriptor(void *pvInstance, tUSBRequest *pUSBRequest,
  1200. unsigned int ulIndex)
  1201. {
  1202. unsigned int ulSize;
  1203. unsigned int ulDesc;
  1204. const tUSBDHIDDevice *psDevice;
  1205. ASSERT(pvInstance != 0);
  1206. //
  1207. // Which device are we dealing with?
  1208. //
  1209. psDevice = pvInstance;
  1210. //
  1211. // Which type of class descriptor are we being asked for?
  1212. //
  1213. switch(pUSBRequest->wValue >> 8)
  1214. {
  1215. //
  1216. // This is a request for a HID report or physical descriptor.
  1217. //
  1218. case USB_HID_DTYPE_REPORT:
  1219. case USB_HID_DTYPE_PHYSICAL:
  1220. {
  1221. //
  1222. // Find the index to the descriptor that is being queried.
  1223. //
  1224. ulSize = 0;
  1225. ulDesc = FindHIDDescriptor(psDevice, pUSBRequest->wValue >> 8,
  1226. pUSBRequest->wValue & 0xFF,
  1227. &ulSize);
  1228. //
  1229. // Did we find the descriptor?
  1230. //
  1231. if(ulDesc == HID_NOT_FOUND)
  1232. {
  1233. //
  1234. // No - stall the endpoint and return.
  1235. //
  1236. USBDCDStallEP0(ulIndex);
  1237. return;
  1238. }
  1239. //
  1240. // If there is more data to send than the host requested then just
  1241. // send the requested amount of data.
  1242. //
  1243. if(ulSize > pUSBRequest->wLength)
  1244. {
  1245. ulSize = pUSBRequest->wLength;
  1246. }
  1247. //
  1248. // Send the data via endpoint 0.
  1249. //
  1250. USBDCDSendDataEP0(0,
  1251. (unsigned char *)psDevice->ppClassDescriptors[ulDesc], ulSize);
  1252. break;
  1253. }
  1254. //
  1255. // This is a request for the HID descriptor (as found in the
  1256. // configuration descriptor following the relevant interface).
  1257. //
  1258. case USB_HID_DTYPE_HID:
  1259. {
  1260. //
  1261. // How big is the HID descriptor?
  1262. //
  1263. ulSize = (unsigned int)psDevice->psHIDDescriptor->bLength;
  1264. //
  1265. // If there is more data to send than the host requested then just
  1266. // send the requested amount of data.
  1267. //
  1268. if(ulSize > pUSBRequest->wLength)
  1269. {
  1270. ulSize = pUSBRequest->wLength;
  1271. }
  1272. //
  1273. // Send the data via endpoint 0.
  1274. //
  1275. USBDCDSendDataEP0(0, (unsigned char *)psDevice->psHIDDescriptor,
  1276. ulSize);
  1277. break;
  1278. }
  1279. //
  1280. // This was an unknown request so stall.
  1281. //
  1282. default:
  1283. {
  1284. USBDCDStallEP0(ulIndex);
  1285. break;
  1286. }
  1287. }
  1288. }
  1289. //*****************************************************************************
  1290. //
  1291. // This function is called by the USB device stack whenever a non-standard
  1292. // request is received.
  1293. //
  1294. // \param pvInstance is the instance data for this HID device.
  1295. // \param pUSBRequest points to the request received.
  1296. //
  1297. // This call parses the provided request structure. Assuming the request is
  1298. // understood, it is handled and any required response generated. If the
  1299. // request cannot be handled by this device class, endpoint zero is stalled to
  1300. // indicate an error to the host.
  1301. //
  1302. //*****************************************************************************
  1303. static void
  1304. HandleRequest(void *pvInstance, tUSBRequest *pUSBRequest,
  1305. unsigned int ulIndex)
  1306. {
  1307. tHIDInstance *psInst;
  1308. unsigned char ucProtocol;
  1309. const tUSBDHIDDevice *psDevice;
  1310. ASSERT(pvInstance != 0);
  1311. //
  1312. // Which device are we dealing with?
  1313. //
  1314. psDevice = pvInstance;
  1315. //
  1316. // Get a pointer to our instance data.
  1317. //
  1318. psInst = psDevice->psPrivateHIDData;
  1319. //
  1320. // Make sure the request was for this interface.
  1321. //
  1322. if(pUSBRequest->wIndex != psInst->ucInterface)
  1323. {
  1324. return;
  1325. }
  1326. //
  1327. // Determine the type of request.
  1328. //
  1329. switch(pUSBRequest->bRequest)
  1330. {
  1331. //
  1332. // A Set Report request is received from the host when it sends an
  1333. // Output report via endpoint 0.
  1334. //
  1335. case USBREQ_SET_REPORT:
  1336. {
  1337. //
  1338. // Ask the application for a buffer large enough to hold the
  1339. // report we are to be sent.
  1340. //
  1341. psInst->usOutReportSize = pUSBRequest->wLength;
  1342. psInst->pucOutReportData =
  1343. (unsigned char *)psDevice->pfnRxCallback(
  1344. psDevice->pvRxCBData,
  1345. USBD_HID_EVENT_GET_REPORT_BUFFER,
  1346. pUSBRequest->wValue,
  1347. (void *)(unsigned int)(pUSBRequest->wLength));
  1348. //
  1349. // Did the client provide us a buffer?
  1350. //
  1351. if(!psInst->pucOutReportData)
  1352. {
  1353. //
  1354. // The application couldn't provide us a buffer so stall the
  1355. // request.
  1356. //
  1357. USBDCDStallEP0(ulIndex);
  1358. }
  1359. else
  1360. {
  1361. //
  1362. // The client provided us a buffer to read the report into
  1363. // so request the data from the host.
  1364. //
  1365. //
  1366. // Set the state to indicate we are waiting for data.
  1367. //
  1368. psInst->eHIDRxState = HID_STATE_WAIT_DATA;
  1369. //
  1370. // Now read the payload of the request. We handle the actual
  1371. // operation in the data callback once this data is received.
  1372. //
  1373. USBDCDRequestDataEP0(0, psInst->pucOutReportData,
  1374. (unsigned int)pUSBRequest->wLength);
  1375. //
  1376. // Need to ACK the data on end point 0 in this case. Do this
  1377. // after requesting the data to prevent race conditions that
  1378. // occur if you acknowledge before setting up to receive the
  1379. // request data.
  1380. //
  1381. USBDevEndpointDataAck(psInst->ulUSBBase, USB_EP_0, true);
  1382. }
  1383. break;
  1384. }
  1385. //
  1386. // A Get Report request is used by the host to poll a device for its
  1387. // current state.
  1388. //
  1389. case USBREQ_GET_REPORT:
  1390. {
  1391. unsigned int ulSize;
  1392. unsigned char *pucReport;
  1393. //
  1394. // Get the latest report from the application.
  1395. //
  1396. ulSize = psDevice->pfnRxCallback(psDevice->pvRxCBData,
  1397. USBD_HID_EVENT_GET_REPORT,
  1398. pUSBRequest->wValue, &pucReport);
  1399. //
  1400. // Need to ACK the data on end point 0 in this case.
  1401. //
  1402. USBDevEndpointDataAck(psInst->ulUSBBase, USB_EP_0, true);
  1403. //
  1404. // ..then send back the requested report.
  1405. //
  1406. psInst->bGetRequestPending = true;
  1407. USBDCDSendDataEP0(0, pucReport, ulSize);
  1408. break;
  1409. }
  1410. //
  1411. // A set IDLE request has been made. This indicates to us how often a
  1412. // given report should be sent back to the host in the absence of any
  1413. // change in state of the device.
  1414. //
  1415. case USBREQ_SET_IDLE:
  1416. {
  1417. //
  1418. // Set the idle timeout for the requested report(s).
  1419. //
  1420. SetIdleTimeout(psDevice, pUSBRequest->wValue & 0xFF,
  1421. (pUSBRequest->wValue >> 8) & 0xFF);
  1422. //
  1423. // Need to ACK the data on end point 0 in this case.
  1424. //
  1425. USBDevEndpointDataAck(psInst->ulUSBBase, USB_EP_0, true);
  1426. break;
  1427. }
  1428. //
  1429. // A get IDLE request has been made. This request queries the current
  1430. // idle timeout for a given report.
  1431. //
  1432. case USBREQ_GET_IDLE:
  1433. {
  1434. unsigned int ulTimeout;
  1435. //
  1436. // Determine the timeout for the requested report.
  1437. //
  1438. ulTimeout = GetIdleTimeout(psDevice, pUSBRequest->wValue);
  1439. if(ulTimeout != HID_NOT_FOUND)
  1440. {
  1441. //
  1442. // Need to ACK the data on end point 0 in this case.
  1443. //
  1444. USBDevEndpointDataAck(psInst->ulUSBBase, USB_EP_0, true);
  1445. //
  1446. // Send our response to the host.
  1447. //
  1448. USBDCDSendDataEP0(0, (unsigned char *)&ulTimeout, 1);
  1449. }
  1450. else
  1451. {
  1452. //
  1453. // The report ID was not found so stall the endpoint.
  1454. //
  1455. USBDCDStallEP0(ulIndex);
  1456. }
  1457. break;
  1458. }
  1459. //
  1460. // Set either boot or report protocol for reports sent from the device.
  1461. // This is only supported by devices in the boot subclass.
  1462. //
  1463. case USBREQ_SET_PROTOCOL:
  1464. {
  1465. if(psDevice->ucSubclass == USB_HID_SCLASS_BOOT)
  1466. {
  1467. //
  1468. // We need to ACK the data on end point 0 in this case.
  1469. //
  1470. USBDevEndpointDataAck(psInst->ulUSBBase, USB_EP_0, true);
  1471. //
  1472. // We are a boot subclass device so pass this on to the
  1473. // application.
  1474. //
  1475. psDevice->pfnRxCallback(psDevice->pvRxCBData,
  1476. USBD_HID_EVENT_SET_PROTOCOL,
  1477. pUSBRequest->wValue,
  1478. (void *)0);
  1479. }
  1480. else
  1481. {
  1482. //
  1483. // This is not a boot subclass device so stall the endpoint to
  1484. // show that we don't support this request.
  1485. //
  1486. USBDCDStallEP0(ulIndex);
  1487. }
  1488. break;
  1489. }
  1490. //
  1491. // Inform the host of the protocol, boot or report, that is currently
  1492. // in use. This is only supported by devices in the boot subclass.
  1493. //
  1494. case USBREQ_GET_PROTOCOL:
  1495. {
  1496. if(psDevice->ucSubclass == USB_HID_SCLASS_BOOT)
  1497. {
  1498. //
  1499. // We need to ACK the data on end point 0 in this case.
  1500. //
  1501. USBDevEndpointDataAck(psInst->ulUSBBase, USB_EP_0, true);
  1502. //
  1503. // We are a boot subclass device so pass this on to the
  1504. // application callback to get the answer.
  1505. //
  1506. ucProtocol = (unsigned char)psDevice->pfnRxCallback(
  1507. psDevice->pvRxCBData, USBD_HID_EVENT_GET_PROTOCOL, 0,
  1508. (void *)0);
  1509. //
  1510. // Send our response to the host.
  1511. //
  1512. USBDCDSendDataEP0(0, (unsigned char *)&ucProtocol, 1);
  1513. }
  1514. else
  1515. {
  1516. //
  1517. // This is not a boot subclass device so stall the endpoint to
  1518. // show that we don't support this request.
  1519. //
  1520. USBDCDStallEP0(ulIndex);
  1521. }
  1522. break;
  1523. }
  1524. //
  1525. // This request was not recognized so stall.
  1526. //
  1527. default:
  1528. {
  1529. USBDCDStallEP0(ulIndex);
  1530. break;
  1531. }
  1532. }
  1533. }
  1534. //*****************************************************************************
  1535. //
  1536. // This function is called by the USB device stack whenever the data requested
  1537. // on endpoint zero is received.
  1538. //
  1539. //*****************************************************************************
  1540. static void
  1541. HandleEP0DataReceived(void *pvInstance, unsigned int ulDataSize,
  1542. unsigned int ulIndex)
  1543. {
  1544. tHIDInstance *psInst;
  1545. const tUSBDHIDDevice *psDevice;
  1546. ASSERT(pvInstance != 0);
  1547. //
  1548. // Which device are we dealing with?
  1549. //
  1550. psDevice = pvInstance;
  1551. //
  1552. // If we were not passed any data, just return.
  1553. //
  1554. if(ulDataSize == 0)
  1555. {
  1556. return;
  1557. }
  1558. //
  1559. // Get our instance data pointer.
  1560. //
  1561. psInst = psDevice->psPrivateHIDData;
  1562. //
  1563. // Make sure we are actually expecting something.
  1564. //
  1565. if(psInst->eHIDRxState != HID_STATE_WAIT_DATA)
  1566. {
  1567. return;
  1568. }
  1569. //
  1570. // Change the endpoint state back to idle now that we have been passed
  1571. // the data we were waiting for.
  1572. //
  1573. psInst->eHIDRxState = HID_STATE_IDLE;
  1574. //
  1575. // The only things we ever request via endpoint zero are reports sent to
  1576. // us via a Set_Report request. Pass the newly received report on to
  1577. // the client.
  1578. //
  1579. psDevice->pfnRxCallback(psDevice->pvRxCBData, USBD_HID_EVENT_SET_REPORT,
  1580. psInst->usOutReportSize,
  1581. psInst->pucOutReportData);
  1582. }
  1583. //*****************************************************************************
  1584. //
  1585. // This function is called by the USB device stack whenever the data sent on
  1586. // endpoint zero is received and acknowledged by the host.
  1587. //
  1588. //*****************************************************************************
  1589. static void
  1590. HandleEP0DataSent(void *pvInstance, unsigned int ulInfo,
  1591. unsigned int ulIndex)
  1592. {
  1593. tHIDInstance *psInst;
  1594. const tUSBDHIDDevice *psDevice;
  1595. ASSERT(pvInstance != 0);
  1596. //
  1597. // Which device are we dealing with?
  1598. //
  1599. psDevice = pvInstance;
  1600. //
  1601. // Get our instance data pointer.
  1602. //
  1603. psInst = psDevice->psPrivateHIDData;
  1604. //
  1605. // If we just sent a report in response to a Get_Report request, send an
  1606. // event to the application telling it that the transmission completed.
  1607. //
  1608. if(psInst->bGetRequestPending)
  1609. {
  1610. //
  1611. // Clear the flag now that we are sending the application callback.
  1612. //
  1613. psInst->bGetRequestPending = false;
  1614. psDevice->pfnRxCallback(psDevice->pvRxCBData,
  1615. USBD_HID_EVENT_REPORT_SENT, 0, (void *)0);
  1616. }
  1617. return;
  1618. }
  1619. //*****************************************************************************
  1620. //
  1621. // This function is called by the USB device stack whenever the device is
  1622. // reset. If we are currently connected, send a disconnect event at this
  1623. // point.
  1624. //
  1625. //*****************************************************************************
  1626. static void
  1627. HandleReset(void *pvInstance)
  1628. {
  1629. ASSERT(pvInstance != 0);
  1630. //
  1631. // Merely call the disconnect handler. This causes a disconnect message to
  1632. // be sent to the client if we think we are currently connected.
  1633. //
  1634. HandleDisconnect(pvInstance);
  1635. }
  1636. //*****************************************************************************
  1637. //
  1638. // This function is called by the USB device stack whenever the bus is put into
  1639. // suspend state.
  1640. //
  1641. //*****************************************************************************
  1642. static void
  1643. HandleSuspend(void *pvInstance)
  1644. {
  1645. const tUSBDHIDDevice *psDevice;
  1646. ASSERT(pvInstance != 0);
  1647. //
  1648. // Create the instance pointer.
  1649. //
  1650. psDevice = (const tUSBDHIDDevice *)pvInstance;
  1651. //
  1652. // Pass the event on to the client.
  1653. //
  1654. psDevice->pfnRxCallback(psDevice->pvRxCBData, USB_EVENT_SUSPEND, 0,
  1655. (void *)0);
  1656. }
  1657. //*****************************************************************************
  1658. //
  1659. // This function is called by the USB device stack whenever the bus is taken
  1660. // out of suspend state.
  1661. //
  1662. //*****************************************************************************
  1663. static void
  1664. HandleResume(void *pvInstance)
  1665. {
  1666. const tUSBDHIDDevice *psDevice;
  1667. ASSERT(pvInstance != 0);
  1668. //
  1669. // Create the instance pointer.
  1670. //
  1671. psDevice = (const tUSBDHIDDevice *)pvInstance;
  1672. //
  1673. // Pass the event on to the client.
  1674. //
  1675. psDevice->pfnRxCallback(psDevice->pvRxCBData,
  1676. USB_EVENT_RESUME, 0, (void *)0);
  1677. }
  1678. //*****************************************************************************
  1679. //
  1680. // This function is called periodically and provides us with a time reference
  1681. // and method of implementing delayed or time-dependent operations.
  1682. //
  1683. // \param pvInstance is the instance data for this request.
  1684. // \param ulTimemS is the elapsed time in milliseconds since the last call
  1685. // to this function.
  1686. //
  1687. // \return None.
  1688. //
  1689. //*****************************************************************************
  1690. static void
  1691. HIDTickHandler(void *pvInstance, unsigned int ulTimemS, unsigned int ulIndex)
  1692. {
  1693. tHIDInstance *psInst;
  1694. unsigned int ulSize;
  1695. const tUSBDHIDDevice *psDevice;
  1696. ASSERT(pvInstance != 0);
  1697. //
  1698. // Create the instance pointer.
  1699. //
  1700. psDevice = (const tUSBDHIDDevice *)pvInstance;
  1701. //
  1702. // Get our instance data pointer.
  1703. //
  1704. psInst = psDevice->psPrivateHIDData;
  1705. //
  1706. // If we are connected, process our idle timers.
  1707. //
  1708. if(psInst->bConnected)
  1709. {
  1710. ProcessIdleTimers(psDevice, ulTimemS);
  1711. }
  1712. //
  1713. // Do we have a deferred receive waiting
  1714. //
  1715. if(psInst->usDeferredOpFlags & (1 << HID_DO_PACKET_RX))
  1716. {
  1717. //
  1718. // Yes - how big is the waiting packet?
  1719. //
  1720. ulSize = USBEndpointDataAvail(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint);
  1721. //
  1722. // Tell the client that there is a packet waiting for it.
  1723. //
  1724. psDevice->pfnRxCallback(psDevice->pvRxCBData,
  1725. USB_EVENT_RX_AVAILABLE, ulSize, (void *)0);
  1726. }
  1727. return;
  1728. }
  1729. //*****************************************************************************
  1730. //
  1731. //! Initializes HID device operation for a given USB controller.
  1732. //!
  1733. //! \param ulIndex is the index of the USB controller which is to be
  1734. //! initialized for HID device operation.
  1735. //! \param psDevice points to a structure containing parameters customizing
  1736. //! the operation of the HID device.
  1737. //!
  1738. //! An application wishing to offer a USB HID interface to a host system
  1739. //! must call this function to initialize the USB controller and attach the
  1740. //! device to the USB bus. This function performs all required USB
  1741. //! initialization.
  1742. //!
  1743. //! On successful completion, this function will return the \e psDevice pointer
  1744. //! passed to it. This must be passed on all future calls from the application
  1745. //! to the HID device class driver.
  1746. //!
  1747. //! The USB HID device class API offers the application a report-based transmit
  1748. //! interface for Input reports. Output reports may be received via the
  1749. //! control endpoint or via a dedicated Interrupt OUT endpoint. If using the
  1750. //! dedicated endpoint, report data is delivered to the application packet-by-
  1751. //! packet. If the application uses reports longer than 64 bytes and would
  1752. //! rather receive full reports, it may use a USB buffer above the receive
  1753. //! channel to allow full reports to be read.
  1754. //!
  1755. //! Transmit Operation:
  1756. //!
  1757. //! Calls to USBDHIDReportWrite() pass complete reports to the driver for
  1758. //! transmission. These will be transmitted to the host using as many USB
  1759. //! packets as are necessary to complete the transmission.
  1760. //!
  1761. //! Once a full Input report has been acknowledged by the USB host, a
  1762. //! USB_EVENT_TX_COMPLETE event is sent to the application transmit callback to
  1763. //! inform it that another report may be transmitted.
  1764. //!
  1765. //! Receive Operation (when using a dedicated interrupt OUT endpoint):
  1766. //!
  1767. //! An incoming USB data packet will result in a call to the application
  1768. //! callback with event USB_EVENT_RX_AVAILABLE. The application must then
  1769. //! call USBDHIDPacketRead(), passing a buffer capable of holding the received
  1770. //! packet. The size of the packet may be determined by calling function
  1771. //! USBDHIDRxPacketAvailable() prior to reading the packet.
  1772. //!
  1773. //! Receive Operation (when not using a dedicated OUT endpoint):
  1774. //!
  1775. //! If no dedicated OUT endpoint is used, Output and Feature reports are sent
  1776. //! from the host using the control endpoint, endpoint zero. When such a
  1777. //! report is received, USBD_HID_EVENT_GET_REPORT_BUFFER is sent to the
  1778. //! application which must respond with a buffer large enough to hold the
  1779. //! report. The device class driver will then copy the received report into
  1780. //! the supplied buffer before sending USBD_HID_EVENT_SET_REPORT to indicate
  1781. //! that the report is now available.
  1782. //!
  1783. //! \note The application must not make any calls to the low level USB device
  1784. //! interface if interacting with USB via the USB HID device class API. Doing
  1785. //! so will cause unpredictable (though almost certainly unpleasant) behavior.
  1786. //!
  1787. //! \return Returns NULL on failure or the \e psDevice pointer on success.
  1788. //
  1789. //*****************************************************************************
  1790. void *
  1791. USBDHIDInit(unsigned int ulIndex, const tUSBDHIDDevice *psDevice)
  1792. {
  1793. //
  1794. // Check parameter validity.
  1795. //
  1796. ASSERT(ulIndex == 0);
  1797. ASSERT(psDevice);
  1798. ASSERT(psDevice->ppStringDescriptors);
  1799. ASSERT(psDevice->psPrivateHIDData);
  1800. ASSERT(psDevice->pfnRxCallback);
  1801. ASSERT(psDevice->pfnTxCallback);
  1802. ASSERT(psDevice->ppClassDescriptors);
  1803. ASSERT(psDevice->psHIDDescriptor);
  1804. ASSERT((psDevice->ucNumInputReports == 0) || psDevice->psReportIdle);
  1805. USBDHIDCompositeInit(ulIndex, psDevice);
  1806. //
  1807. // All is well so now pass the descriptors to the lower layer and put
  1808. // the HID device on the bus.
  1809. //
  1810. USBDCDInit(ulIndex, psDevice->psPrivateHIDData->psDevInfo);
  1811. //
  1812. // Return the pointer to the instance indicating that everything went well.
  1813. //
  1814. return((void *)psDevice);
  1815. }
  1816. //*****************************************************************************
  1817. //
  1818. //! Initializes HID device operation for a given USB controller.
  1819. //!
  1820. //! This function is used for initializing an instance related information of the
  1821. //! HID device.
  1822. //!
  1823. //! \param ulIndex is the index of the USB controller which is to be
  1824. //! initialized for HID device operation.
  1825. //! \param psDevice points to a structure containing parameters customizing
  1826. //! the operation of the HID device.
  1827. //!
  1828. //! \return Returns NULL on failure or the \e psDevice pointer on success.
  1829. //
  1830. //*****************************************************************************
  1831. void *
  1832. USBDHIDCompositeInit(unsigned int ulIndex, const tUSBDHIDDevice *psDevice)
  1833. {
  1834. tHIDInstance *psInst;
  1835. tDeviceDescriptor *psDevDesc;
  1836. tInterfaceDescriptor *psDevIf;
  1837. //
  1838. // Check parameter validity.
  1839. //
  1840. ASSERT(ulIndex == 0);
  1841. ASSERT(psDevice);
  1842. ASSERT(psDevice->ppStringDescriptors);
  1843. ASSERT(psDevice->psPrivateHIDData);
  1844. ASSERT(psDevice->pfnRxCallback);
  1845. ASSERT(psDevice->pfnTxCallback);
  1846. ASSERT(psDevice->ppClassDescriptors);
  1847. ASSERT(psDevice->psHIDDescriptor);
  1848. ASSERT((psDevice->ucNumInputReports == 0) || psDevice->psReportIdle);
  1849. if(ulIndex == 0)
  1850. {
  1851. g_USBInstance[ulIndex].uiUSBInstance = ulIndex;
  1852. g_USBInstance[ulIndex].uiBaseAddr = USB0_BASE;
  1853. g_USBInstance[ulIndex].uiSubBaseAddr = USB_0_OTGBASE;
  1854. g_USBInstance[ulIndex].uiInterruptNum = SYS_INT_USB0;
  1855. g_USBInstance[ulIndex].uiSubInterruptNum = SYS_INT_USBSSINT;
  1856. g_USBInstance[ulIndex].uiPHYConfigRegAddr = CFGCHIP2_USBPHYCTRL;
  1857. }
  1858. #if (USB_NUM_INSTANCE == 2)
  1859. else if(ulIndex == 1)
  1860. {
  1861. g_USBInstance[ulIndex].uiUSBInstance = ulIndex;
  1862. g_USBInstance[ulIndex].uiBaseAddr = USB1_BASE;
  1863. g_USBInstance[ulIndex].uiSubBaseAddr = USB_1_OTGBASE;
  1864. g_USBInstance[ulIndex].uiInterruptNum = SYS_INT_USB1;
  1865. g_USBInstance[ulIndex].uiSubInterruptNum = SYS_INT_USBSSINT;
  1866. g_USBInstance[ulIndex].uiPHYConfigRegAddr = CFGCHIP2_USB1PHYCTRL;
  1867. }
  1868. #endif
  1869. //
  1870. // Initialize the workspace in the passed instance structure.
  1871. //
  1872. psInst = psDevice->psPrivateHIDData;
  1873. psInst->psConfDescriptor = (tConfigDescriptor *)g_pHIDDescriptor;
  1874. psInst->psDevInfo = &g_sHIDDeviceInfo;
  1875. psInst->ulUSBBase = g_USBInstance[ulIndex].uiBaseAddr;
  1876. psInst->eHIDRxState = HID_STATE_UNCONFIGURED;
  1877. psInst->eHIDTxState = HID_STATE_UNCONFIGURED;
  1878. psInst->usDeferredOpFlags = 0;
  1879. psInst->bConnected = false;
  1880. psInst->bGetRequestPending = false;
  1881. psInst->bSendInProgress = false;
  1882. psInst->usInReportIndex = 0;
  1883. psInst->usInReportSize = 0;
  1884. psInst->pucInReportData = (unsigned char *)0;
  1885. psInst->usOutReportSize = 0;
  1886. psInst->pucOutReportData = (unsigned char *)0;
  1887. //
  1888. // Set the default endpoint and interface assignments.
  1889. //
  1890. psInst->ucINEndpoint = INT_IN_ENDPOINT;
  1891. psInst->ucOUTEndpoint = INT_OUT_ENDPOINT;
  1892. psInst->ucInterface = 0;
  1893. //
  1894. // Fix up the device descriptor with the client-supplied values.
  1895. //
  1896. psDevDesc = (tDeviceDescriptor *)psInst->psDevInfo->pDeviceDescriptor;
  1897. psDevDesc->idVendor = psDevice->usVID;
  1898. psDevDesc->idProduct = psDevice->usPID;
  1899. //
  1900. // Fix up the configuration descriptor with client-supplied values.
  1901. //
  1902. psInst->psConfDescriptor->bmAttributes = psDevice->ucPwrAttributes;
  1903. psInst->psConfDescriptor->bMaxPower =
  1904. (unsigned char)(psDevice->usMaxPowermA / 2);
  1905. //
  1906. // Slot the client's HID descriptor into our standard configuration
  1907. // descriptor.
  1908. //
  1909. g_sHIDDescriptorSection.ucSize = psDevice->psHIDDescriptor->bLength;
  1910. g_sHIDDescriptorSection.pucData =
  1911. (unsigned char *)psDevice->psHIDDescriptor;
  1912. //
  1913. // Fix up the interface and endpoint descriptors depending upon client
  1914. // choices.
  1915. //
  1916. psDevIf = (tInterfaceDescriptor *)g_pHIDInterface;
  1917. psDevIf->bNumEndpoints = psDevice->bUseOutEndpoint ? 2 : 1;
  1918. psDevIf->bInterfaceSubClass = psDevice->ucSubclass;
  1919. psDevIf->bInterfaceProtocol = psDevice->ucProtocol;
  1920. //
  1921. // If necessary, remove the interrupt OUT endpoint from the configuration
  1922. // descriptor.
  1923. //
  1924. if(psDevice->bUseOutEndpoint == false)
  1925. {
  1926. g_sHIDConfigHeader.ucNumSections = (NUM_HID_SECTIONS - 1);
  1927. }
  1928. else
  1929. {
  1930. g_sHIDConfigHeader.ucNumSections = NUM_HID_SECTIONS;
  1931. }
  1932. //
  1933. // Plug in the client's string table to the device information
  1934. // structure.
  1935. //
  1936. psInst->psDevInfo->ppStringDescriptors = psDevice->ppStringDescriptors;
  1937. psInst->psDevInfo->ulNumStringDescriptors
  1938. = psDevice->ulNumStringDescriptors;
  1939. psInst->psDevInfo->pvInstance = (void *)psDevice;
  1940. //
  1941. // Initialize the input report idle timers if any input reports exist.
  1942. //
  1943. ClearIdleTimers(psDevice);
  1944. //
  1945. // Register our tick handler (this must be done after USBDCDInit).
  1946. //
  1947. InternalUSBRegisterTickHandler(USB_TICK_HANDLER_DEVICE,
  1948. HIDTickHandler,
  1949. (void *)psDevice);
  1950. //
  1951. // Return the pointer to the instance indicating that everything went well.
  1952. //
  1953. return((void *)psDevice);
  1954. }
  1955. //*****************************************************************************
  1956. //
  1957. //! Shuts down the HID device.
  1958. //!
  1959. //! \param pvInstance is the pointer to the device instance structure as
  1960. //! returned by USBDHIDInit().
  1961. //!
  1962. //! This function terminates HID operation for the instance supplied and
  1963. //! removes the device from the USB bus. This function should not be called
  1964. //! if the HID device is part of a composite device and instead the
  1965. //! USBDCompositeTerm() function should be called for the full composite
  1966. //! device.
  1967. //!
  1968. //! Following this call, the \e pvInstance instance should not me used in any
  1969. //! other calls.
  1970. //!
  1971. //! \return None.
  1972. //
  1973. //*****************************************************************************
  1974. void
  1975. USBDHIDTerm(void *pvInstance)
  1976. {
  1977. tHIDInstance *psInst;
  1978. int index;
  1979. ASSERT(pvInstance);
  1980. //
  1981. // Get a pointer to our instance data.
  1982. //
  1983. psInst = ((tUSBDHIDDevice *)pvInstance)->psPrivateHIDData;
  1984. //
  1985. // Terminate the requested instance.
  1986. //
  1987. USB_BASE_TO_INDEX(psInst->ulUSBBase, index);
  1988. USBDCDTerm(index);
  1989. psInst->ulUSBBase = 0;
  1990. psInst->psDevInfo = (tDeviceInfo *)0;
  1991. psInst->psConfDescriptor = (tConfigDescriptor *)0;
  1992. }
  1993. //*****************************************************************************
  1994. //
  1995. //! Sets the client-specific pointer parameter for the receive channel
  1996. //! callback.
  1997. //!
  1998. //! \param pvInstance is the pointer to the device instance structure as
  1999. //! returned by USBDHIDInit().
  2000. //! \param pvCBData is the pointer that client wishes to be provided on each
  2001. //! event sent to the receive channel callback function.
  2002. //!
  2003. //! The client uses this function to change the callback pointer passed in
  2004. //! the first parameter on all callbacks to the \e pfnRxCallback function
  2005. //! passed on USBDHIDInit().
  2006. //!
  2007. //! If a client wants to make runtime changes in the callback pointer, it must
  2008. //! ensure that the pvInstance structure passed to USBDHIDInit() resides in
  2009. //! RAM. If this structure is in flash, callback data changes will not be
  2010. //! possible.
  2011. //!
  2012. //! \return Returns the previous callback pointer that was being used for
  2013. //! this instance's receive callback.
  2014. //
  2015. //*****************************************************************************
  2016. void *
  2017. USBDHIDSetRxCBData(void *pvInstance, void *pvCBData)
  2018. {
  2019. void *pvOldValue;
  2020. ASSERT(pvInstance);
  2021. //
  2022. // Set the callback data for the receive channel after remembering the
  2023. // previous value.
  2024. //
  2025. pvOldValue = ((tUSBDHIDDevice *)pvInstance)->pvRxCBData;
  2026. ((tUSBDHIDDevice *)pvInstance)->pvRxCBData = pvCBData;
  2027. //
  2028. // Return the previous callback data value.
  2029. //
  2030. return (pvOldValue);
  2031. }
  2032. //*****************************************************************************
  2033. //
  2034. //! Sets the client-specific data pointer for the transmit callback.
  2035. //!
  2036. //! \param pvInstance is the pointer to the device instance structure as
  2037. //! returned by USBDHIDInit().
  2038. //! \param pvCBData is the pointer that client wishes to be provided on each
  2039. //! event sent to the transmit channel callback function.
  2040. //!
  2041. //! The client uses this function to change the callback data pointer passed in
  2042. //! the first parameter on all callbacks to the \e pfnTxCallback function
  2043. //! passed on USBDHIDInit().
  2044. //!
  2045. //! If a client wants to make runtime changes in the callback data, it must
  2046. //! ensure that the pvInstance structure passed to USBDHIDInit() resides in
  2047. //! RAM. If this structure is in flash, callback data changes will not be
  2048. //! possible.
  2049. //!
  2050. //! \return Returns the previous callback data pointer that was being used for
  2051. //! this instance's transmit callback.
  2052. //
  2053. //*****************************************************************************
  2054. void *
  2055. USBDHIDSetTxCBData(void *pvInstance, void *pvCBData)
  2056. {
  2057. void *pvOldValue;
  2058. ASSERT(pvInstance);
  2059. //
  2060. // Set the callback data for the transmit channel after remembering the
  2061. // previous value.
  2062. //
  2063. pvOldValue = ((tUSBDHIDDevice *)pvInstance)->pvTxCBData;
  2064. ((tUSBDHIDDevice *)pvInstance)->pvTxCBData = pvCBData;
  2065. //
  2066. // Return the previous callback data value.
  2067. //
  2068. return (pvOldValue);
  2069. }
  2070. //*****************************************************************************
  2071. //
  2072. //! Transmits a HID device report to the USB host via the HID interrupt IN
  2073. //! endpoint.
  2074. //!
  2075. //! \param pvInstance is the pointer to the device instance structure as
  2076. //! returned by USBDHIDInit().
  2077. //! \param pcData points to the first byte of data which is to be transmitted.
  2078. //! \param ulLength is the number of bytes of data to transmit.
  2079. //! \param bLast is ignored in this implementation. This parameter is required
  2080. //! to ensure compatibility with other device class drivers and USB buffers.
  2081. //!
  2082. //! This function schedules the supplied data for transmission to the USB
  2083. //! host in a single USB transaction using as many packets as it takes to send
  2084. //! all the data in the report. If no transmission is currently ongoing,
  2085. //! the first packet of data is immediately copied to the relevant USB endpoint
  2086. //! FIFO for transmission. Whenever all the report data has been acknowledged
  2087. //! by the host, a \b USB_EVENT_TX_COMPLETE event will be sent to the
  2088. //! application transmit callback indicating that another report can now be
  2089. //! transmitted.
  2090. //!
  2091. //! The caller must ensure that the data pointed to by pucData remains
  2092. //! accessible and unaltered until the \b USB_EVENT_TX_COMPLETE is received.
  2093. //!
  2094. //! \return Returns the number of bytes actually scheduled for transmission.
  2095. //! At this level, this will either be the number of bytes passed or 0 to
  2096. //! indicate a failure.
  2097. //
  2098. //*****************************************************************************
  2099. unsigned int
  2100. USBDHIDReportWrite(void *pvInstance, unsigned char *pcData,
  2101. unsigned int ulLength, tBoolean bLast)
  2102. {
  2103. tHIDInstance *psInst;
  2104. int iRetcode;
  2105. ASSERT(pvInstance);
  2106. //
  2107. // Get our instance data pointer
  2108. //
  2109. psInst = ((tUSBDHIDDevice *)pvInstance)->psPrivateHIDData;
  2110. //
  2111. // Set a flag indicating that we are currently in the process of sending
  2112. // a packet.
  2113. //
  2114. psInst->bSendInProgress = true;
  2115. //
  2116. // Can we send the data provided?
  2117. //
  2118. if(psInst->eHIDTxState != HID_STATE_IDLE)
  2119. {
  2120. //
  2121. // We are in the middle of sending another report. Return 0 to
  2122. // indicate that we can't send this report until the previous one
  2123. // finishes.
  2124. //
  2125. psInst->bSendInProgress = false;
  2126. return (0);
  2127. }
  2128. //
  2129. // Clear the elapsed time since this report was last sent.
  2130. //
  2131. if(ulLength)
  2132. {
  2133. ClearReportTimer(pvInstance, *pcData);
  2134. }
  2135. //
  2136. // Keep track of the whereabouts of the report so that we can send it in
  2137. // multiple packets if necessary.
  2138. //
  2139. psInst->pucInReportData = pcData;
  2140. psInst->usInReportIndex = 0;
  2141. psInst->usInReportSize = ulLength;
  2142. //
  2143. // Schedule transmission of the first packet of the report.
  2144. //
  2145. psInst->eHIDTxState = HID_STATE_WAIT_DATA;
  2146. iRetcode = ScheduleReportTransmission(psInst);
  2147. //
  2148. // Clear the flag we use to indicate that we are in the midst of sending
  2149. // a packet.
  2150. //
  2151. psInst->bSendInProgress = false;
  2152. //
  2153. // Did an error occur while trying to send the data?
  2154. //
  2155. if(iRetcode != -1)
  2156. {
  2157. //
  2158. // No - tell the caller we sent all the bytes provided.
  2159. //
  2160. return (ulLength);
  2161. }
  2162. else
  2163. {
  2164. //
  2165. // Yes - tell the caller we couldn't send the data.
  2166. //
  2167. return (0);
  2168. }
  2169. }
  2170. //*****************************************************************************
  2171. //
  2172. //! Reads a packet of data received from the USB host via the interrupt OUT
  2173. //! endpoint (if in use).
  2174. //!
  2175. //! \param pvInstance is the pointer to the device instance structure as
  2176. //! returned by USBDHIDInit().
  2177. //! \param pcData points to a buffer into which the received data will be
  2178. //! written.
  2179. //! \param ulLength is the size of the buffer pointed to by pcData.
  2180. //! \param bLast indicates whether the client will make a further call to
  2181. //! read additional data from the packet.
  2182. //!
  2183. //! This function reads up to ulLength bytes of data received from the USB
  2184. //! host into the supplied application buffer. If the driver detects that the
  2185. //! entire packet has been read, it is acknowledged to the host.
  2186. //!
  2187. //! The \e bLast parameter is ignored in this implementation since the end of
  2188. //! a packet can be determined without relying upon the client to provide
  2189. //! this information.
  2190. //!
  2191. //! \return Returns the number of bytes of data read.
  2192. //
  2193. //*****************************************************************************
  2194. unsigned int
  2195. USBDHIDPacketRead(void *pvInstance, unsigned char *pcData,
  2196. unsigned int ulLength, tBoolean bLast)
  2197. {
  2198. unsigned int ulEPStatus, ulPkt;
  2199. unsigned int ulCount;
  2200. tHIDInstance *psInst;
  2201. int iRetcode;
  2202. ASSERT(pvInstance);
  2203. //
  2204. // Get our instance data pointer
  2205. //
  2206. psInst = ((tUSBDHIDDevice *)pvInstance)->psPrivateHIDData;
  2207. //
  2208. // Does the relevant endpoint FIFO have a packet waiting for us?
  2209. //
  2210. ulEPStatus = USBEndpointStatus(psInst->ulUSBBase, psInst->ucOUTEndpoint);
  2211. if(ulEPStatus & USB_DEV_RX_PKT_RDY)
  2212. {
  2213. //
  2214. // How many bytes are available for us to receive?
  2215. //
  2216. ulPkt = USBEndpointDataAvail(psInst->ulUSBBase, psInst->ucOUTEndpoint);
  2217. //
  2218. // Get as much data as we can.
  2219. //
  2220. ulCount = ulLength;
  2221. iRetcode = USBEndpointDataGet(psInst->ulUSBBase, psInst->ucOUTEndpoint,
  2222. pcData, &ulCount);
  2223. //
  2224. // Did we read the last of the packet data?
  2225. //
  2226. if(ulCount == ulPkt)
  2227. {
  2228. //
  2229. // Clear the endpoint status so that we know no packet is
  2230. // waiting.
  2231. //
  2232. USBDevEndpointStatusClear(psInst->ulUSBBase, psInst->ucOUTEndpoint,
  2233. ulEPStatus);
  2234. //
  2235. // Acknowledge the data, thus freeing the host to send the
  2236. // next packet.
  2237. //
  2238. USBDevEndpointDataAck(psInst->ulUSBBase, psInst->ucOUTEndpoint,
  2239. true);
  2240. //
  2241. // Clear the flag we set to indicate that a packet read is
  2242. // pending.
  2243. //
  2244. SetDeferredOpFlag(&psInst->usDeferredOpFlags,
  2245. HID_DO_PACKET_RX, false);
  2246. }
  2247. //
  2248. // If all went well, tell the caller how many bytes they got.
  2249. //
  2250. if(iRetcode != -1)
  2251. {
  2252. return (ulCount);
  2253. }
  2254. }
  2255. //
  2256. // No packet was available or an error occurred while reading so tell
  2257. // the caller no bytes were returned.
  2258. //
  2259. return (0);
  2260. }
  2261. //*****************************************************************************
  2262. //
  2263. //! Returns the number of free bytes in the transmit buffer.
  2264. //!
  2265. //! \param pvInstance is the pointer to the device instance structure as
  2266. //! returned by USBDHIDInit().
  2267. //!
  2268. //! This function indicates to the caller whether or not it is safe to send a
  2269. //! new report using a call to USBDHIDReportWrite(). The value returned will
  2270. //! be the maximum USB packet size (64) if no transmission is currently
  2271. //! outstanding or 0 if a transmission is in progress. Since the function
  2272. //! USBDHIDReportWrite() can accept full reports longer than a single USB
  2273. //! packet, the caller should be aware that the returned value from this
  2274. //! class driver, unlike others, does not indicate the maximum size of report
  2275. //! that can be written but is merely an indication that another report can be
  2276. //! written.
  2277. //!
  2278. //! \return Returns 0 if an outgoing report is still being transmitted or 64
  2279. //! if no transmission is currently in progress.
  2280. //
  2281. //*****************************************************************************
  2282. unsigned int
  2283. USBDHIDTxPacketAvailable(void *pvInstance)
  2284. {
  2285. tHIDInstance *psInst;
  2286. ASSERT(pvInstance);
  2287. //
  2288. // Get our instance data pointer.
  2289. //
  2290. psInst = ((tUSBDHIDDevice *)pvInstance)->psPrivateHIDData;
  2291. //
  2292. // Do we have a packet transmission currently ongoing?
  2293. //
  2294. if(psInst->eHIDTxState != HID_STATE_IDLE)
  2295. {
  2296. //
  2297. // We are not ready to receive a new packet so return 0.
  2298. //
  2299. return (0);
  2300. }
  2301. else
  2302. {
  2303. //
  2304. // We can receive a packet so return the max packet size for the
  2305. // relevant endpoint.
  2306. //
  2307. return (INT_IN_EP_MAX_SIZE);
  2308. }
  2309. }
  2310. //*****************************************************************************
  2311. //
  2312. //! Determines whether a packet is available and, if so, the size of the
  2313. //! buffer required to read it.
  2314. //!
  2315. //! \param pvInstance is the pointer to the device instance structure as
  2316. //! returned by USBDHIDInit().
  2317. //!
  2318. //! This function may be used to determine if a received packet remains to be
  2319. //! read and allows the application to determine the buffer size needed to
  2320. //! read the data.
  2321. //!
  2322. //! \return Returns 0 if no received packet remains unprocessed or the
  2323. //! size of the packet if a packet is waiting to be read.
  2324. //
  2325. //*****************************************************************************
  2326. unsigned int
  2327. USBDHIDRxPacketAvailable(void *pvInstance)
  2328. {
  2329. unsigned int ulEPStatus;
  2330. unsigned int ulSize;
  2331. tHIDInstance *psInst;
  2332. ASSERT(pvInstance);
  2333. //
  2334. // Get our instance data pointer
  2335. //
  2336. psInst = ((tUSBDHIDDevice *)pvInstance)->psPrivateHIDData;
  2337. //
  2338. // Does the relevant endpoint FIFO have a packet waiting for us?
  2339. //
  2340. ulEPStatus = USBEndpointStatus(psInst->ulUSBBase, psInst->ucOUTEndpoint);
  2341. if(ulEPStatus & USB_DEV_RX_PKT_RDY)
  2342. {
  2343. //
  2344. // Yes - a packet is waiting. How big is it?
  2345. //
  2346. ulSize = USBEndpointDataAvail(psInst->ulUSBBase, psInst->ucOUTEndpoint);
  2347. return (ulSize);
  2348. }
  2349. else
  2350. {
  2351. //
  2352. // There is no packet waiting to be received.
  2353. //
  2354. return (0);
  2355. }
  2356. }
  2357. //*****************************************************************************
  2358. //
  2359. //! Reports the device power status (bus- or self-powered) to the USB library.
  2360. //!
  2361. //! \param pvInstance is the pointer to the HID device instance structure.
  2362. //! \param ucPower indicates the current power status, either \b
  2363. //! USB_STATUS_SELF_PWR or \b USB_STATUS_BUS_PWR.
  2364. //!
  2365. //! Applications which support switching between bus- or self-powered
  2366. //! operation should call this function whenever the power source changes
  2367. //! to indicate the current power status to the USB library. This information
  2368. //! is required by the USB library to allow correct responses to be provided
  2369. //! when the host requests status from the device.
  2370. //!
  2371. //! \return None.
  2372. //
  2373. //*****************************************************************************
  2374. void
  2375. USBDHIDPowerStatusSet(void *pvInstance, unsigned char ucPower)
  2376. {
  2377. ASSERT(pvInstance);
  2378. //
  2379. // Pass the request through to the lower layer.
  2380. //
  2381. USBDCDPowerStatusSet(0, ucPower);
  2382. }
  2383. //*****************************************************************************
  2384. //
  2385. //! Requests a remote wake up to resume communication when in suspended state.
  2386. //!
  2387. //! \param pvInstance is the pointer to the HID device instance structure.
  2388. //!
  2389. //! When the bus is suspended, an application which supports remote wake up
  2390. //! (advertised to the host via the configuration descriptor) may call this
  2391. //! function to initiate remote wake up signaling to the host. If the remote
  2392. //! wake up feature has not been disabled by the host, this will cause the bus
  2393. //! to resume operation within 20mS. If the host has disabled remote wake up,
  2394. //! \b false will be returned to indicate that the wake up request was not
  2395. //! successful.
  2396. //!
  2397. //! \return Returns \b true if the remote wake up is not disabled and the
  2398. //! signaling was started or \b false if remote wake up is disabled or if
  2399. //! signaling is currently ongoing following a previous call to this function.
  2400. //
  2401. //*****************************************************************************
  2402. tBoolean
  2403. USBDHIDRemoteWakeupRequest(void *pvInstance)
  2404. {
  2405. ASSERT(pvInstance);
  2406. //
  2407. // Pass the request through to the lower layer.
  2408. //
  2409. return(USBDCDRemoteWakeupRequest(0));
  2410. }
  2411. //*****************************************************************************
  2412. //
  2413. // Close the Doxygen group.
  2414. //! @}
  2415. //
  2416. //*****************************************************************************