1 | /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
---|
2 |
|
---|
3 | This software may be distributed and modified under the terms of the GNU
|
---|
4 | General Public License version 2 (GPL2) as published by the Free Software
|
---|
5 | Foundation and appearing in the file GPL2.TXT included in the packaging of
|
---|
6 | this file. Please note that GPL2 Section 2[b] requires that all works based
|
---|
7 | on this software must also be made publicly available under the terms of
|
---|
8 | the GPL2 ("Copyleft").
|
---|
9 |
|
---|
10 | Contact information
|
---|
11 | -------------------
|
---|
12 |
|
---|
13 | Circuits At Home, LTD
|
---|
14 | Web : http://www.circuitsathome.com
|
---|
15 | e-mail : support@circuitsathome.com
|
---|
16 | */
|
---|
17 |
|
---|
18 | #ifndef HIDBOOT_H_INCLUDED
|
---|
19 | #define HIDBOOT_H_INCLUDED
|
---|
20 |
|
---|
21 | #include <stdint.h>
|
---|
22 | #include "usb_ch9.h"
|
---|
23 | #include "Usb.h"
|
---|
24 | #include "hid.h"
|
---|
25 | #include "Arduino.h"
|
---|
26 | #include "confdescparser.h"
|
---|
27 |
|
---|
28 | #define KEY_SPACE 0x2c
|
---|
29 | #define KEY_ZERO 0x27
|
---|
30 | #define KEY_ZERO2 0x62
|
---|
31 | #define KEY_ENTER 0x28
|
---|
32 | #define KEY_PERIOD 0x63
|
---|
33 |
|
---|
34 | /**
|
---|
35 | * \brief MOUSEINFO definition.
|
---|
36 | */
|
---|
37 | struct MOUSEINFO
|
---|
38 | {
|
---|
39 | struct
|
---|
40 | {
|
---|
41 | uint8_t bmLeftButton : 1;
|
---|
42 | uint8_t bmRightButton : 1;
|
---|
43 | uint8_t bmMiddleButton : 1;
|
---|
44 | uint8_t bmDummy : 1;
|
---|
45 | };
|
---|
46 | int8_t dX;
|
---|
47 | int8_t dY;
|
---|
48 | };
|
---|
49 |
|
---|
50 | /**
|
---|
51 | * \class MouseReportParser definition.
|
---|
52 | */
|
---|
53 | class MouseReportParser : public HIDReportParser
|
---|
54 | {
|
---|
55 | union
|
---|
56 | {
|
---|
57 | MOUSEINFO mouseInfo;
|
---|
58 | uint8_t bInfo[3];
|
---|
59 | } prevState;
|
---|
60 |
|
---|
61 | public:
|
---|
62 | virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf);
|
---|
63 |
|
---|
64 | protected:
|
---|
65 | virtual void OnMouseMove (MOUSEINFO *mi) {};
|
---|
66 | virtual void OnLeftButtonUp (MOUSEINFO *mi) {};
|
---|
67 | virtual void OnLeftButtonDown (MOUSEINFO *mi) {};
|
---|
68 | virtual void OnRightButtonUp (MOUSEINFO *mi) {};
|
---|
69 | virtual void OnRightButtonDown (MOUSEINFO *mi) {};
|
---|
70 | virtual void OnMiddleButtonUp (MOUSEINFO *mi) {};
|
---|
71 | virtual void OnMiddleButtonDown (MOUSEINFO *mi) {};
|
---|
72 | };
|
---|
73 |
|
---|
74 | /**
|
---|
75 | * \brief MODIFIERKEYS definition.
|
---|
76 | */
|
---|
77 | struct MODIFIERKEYS
|
---|
78 | {
|
---|
79 | uint8_t bmLeftCtrl : 1;
|
---|
80 | uint8_t bmLeftShift : 1;
|
---|
81 | uint8_t bmLeftAlt : 1;
|
---|
82 | uint8_t bmLeftGUI : 1;
|
---|
83 | uint8_t bmRightCtrl : 1;
|
---|
84 | uint8_t bmRightShift : 1;
|
---|
85 | uint8_t bmRightAlt : 1;
|
---|
86 | uint8_t bmRightGUI : 1;
|
---|
87 | };
|
---|
88 |
|
---|
89 | /**
|
---|
90 | * \brief KBDINFO definition.
|
---|
91 | */
|
---|
92 | struct KBDINFO
|
---|
93 | {
|
---|
94 | struct
|
---|
95 | {
|
---|
96 | uint8_t bmLeftCtrl : 1;
|
---|
97 | uint8_t bmLeftShift : 1;
|
---|
98 | uint8_t bmLeftAlt : 1;
|
---|
99 | uint8_t bmLeftGUI : 1;
|
---|
100 | uint8_t bmRightCtrl : 1;
|
---|
101 | uint8_t bmRightShift : 1;
|
---|
102 | uint8_t bmRightAlt : 1;
|
---|
103 | uint8_t bmRightGUI : 1;
|
---|
104 | };
|
---|
105 | uint8_t bReserved;
|
---|
106 | uint8_t Keys[6];
|
---|
107 | };
|
---|
108 |
|
---|
109 | /**
|
---|
110 | * \brief KBDLEDS definition.
|
---|
111 | */
|
---|
112 | struct KBDLEDS
|
---|
113 | {
|
---|
114 | uint8_t bmNumLock : 1;
|
---|
115 | uint8_t bmCapsLock : 1;
|
---|
116 | uint8_t bmScrollLock : 1;
|
---|
117 | uint8_t bmCompose : 1;
|
---|
118 | uint8_t bmKana : 1;
|
---|
119 | uint8_t bmReserved : 3;
|
---|
120 | };
|
---|
121 |
|
---|
122 | #define KEY_NUM_LOCK 0x53
|
---|
123 |
|
---|
124 | // Clear compiler warning
|
---|
125 | #ifdef KEY_CAPS_LOCK
|
---|
126 | #undef KEY_CAPS_LOCK
|
---|
127 | #endif
|
---|
128 |
|
---|
129 | #define KEY_CAPS_LOCK 0x39
|
---|
130 | #define KEY_SCROLL_LOCK 0x47
|
---|
131 |
|
---|
132 | /**
|
---|
133 | * \class KeyboardReportParser definition.
|
---|
134 | */
|
---|
135 | class KeyboardReportParser : public HIDReportParser
|
---|
136 | {
|
---|
137 | static const uint8_t numKeys[];
|
---|
138 | static const uint8_t symKeysUp[];
|
---|
139 | static const uint8_t symKeysLo[];
|
---|
140 | static const uint8_t padKeys[];
|
---|
141 |
|
---|
142 | protected:
|
---|
143 | union
|
---|
144 | {
|
---|
145 | KBDINFO kbdInfo;
|
---|
146 | uint8_t bInfo[sizeof(KBDINFO)];
|
---|
147 | } prevState;
|
---|
148 |
|
---|
149 | union
|
---|
150 | {
|
---|
151 | KBDLEDS kbdLeds;
|
---|
152 | uint8_t bLeds;
|
---|
153 | } kbdLockingKeys;
|
---|
154 |
|
---|
155 | uint8_t OemToAscii(uint8_t mod, uint8_t key);
|
---|
156 |
|
---|
157 | public:
|
---|
158 | KeyboardReportParser() { kbdLockingKeys.bLeds = 0; };
|
---|
159 |
|
---|
160 | virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf);
|
---|
161 |
|
---|
162 | protected:
|
---|
163 | uint8_t HandleLockingKeys(HID* hid, uint8_t key);
|
---|
164 |
|
---|
165 | virtual void OnKeyDown (uint8_t mod, uint8_t key) {};
|
---|
166 | virtual void OnKeyUp (uint8_t mod, uint8_t key) {};
|
---|
167 | };
|
---|
168 |
|
---|
169 | #define totalEndpoints 2
|
---|
170 |
|
---|
171 | #define HID_MAX_HID_CLASS_DESCRIPTORS 5
|
---|
172 |
|
---|
173 | /**
|
---|
174 | * \class HIDBoot definition.
|
---|
175 | */
|
---|
176 | template <const uint8_t BOOT_PROTOCOL>
|
---|
177 | class HIDBoot : public HID
|
---|
178 | {
|
---|
179 | EpInfo epInfo[totalEndpoints];
|
---|
180 |
|
---|
181 | HIDReportParser *pRptParser;
|
---|
182 |
|
---|
183 | uint32_t bConfNum; // configuration number
|
---|
184 | uint32_t bIfaceNum; // Interface Number
|
---|
185 | uint32_t bNumIface; // number of interfaces in the configuration
|
---|
186 | uint32_t bNumEP; // total number of EP in the configuration
|
---|
187 | uint32_t qNextPollTime; // next poll time
|
---|
188 | bool bPollEnable; // poll enable flag
|
---|
189 |
|
---|
190 | void Initialize();
|
---|
191 |
|
---|
192 | virtual HIDReportParser* GetReportParser(uint32_t id) { return pRptParser; };
|
---|
193 |
|
---|
194 | public:
|
---|
195 | HIDBoot(USBHost *p);
|
---|
196 |
|
---|
197 | virtual bool SetReportParser(uint32_t id, HIDReportParser *prs) { pRptParser = prs; return true; };
|
---|
198 |
|
---|
199 | // USBDeviceConfig implementation
|
---|
200 | virtual uint32_t Init(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
---|
201 | virtual uint32_t Release();
|
---|
202 | virtual uint32_t Poll();
|
---|
203 | virtual uint32_t GetAddress() { return bAddress; };
|
---|
204 |
|
---|
205 | // UsbConfigXtracter implementation
|
---|
206 | virtual void EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
---|
207 | };
|
---|
208 |
|
---|
209 | /**
|
---|
210 | * \brief HIDBoot class constructor.
|
---|
211 | */
|
---|
212 | template <const uint8_t BOOT_PROTOCOL>
|
---|
213 | HIDBoot<BOOT_PROTOCOL>::HIDBoot(USBHost *p) :
|
---|
214 | HID(p),
|
---|
215 | pRptParser(NULL),
|
---|
216 | qNextPollTime(0),
|
---|
217 | bPollEnable(false)
|
---|
218 | {
|
---|
219 | Initialize();
|
---|
220 |
|
---|
221 | if (pUsb)
|
---|
222 | pUsb->RegisterDeviceClass(this);
|
---|
223 | }
|
---|
224 |
|
---|
225 | /**
|
---|
226 | * \brief Initialize HIDBoot class.
|
---|
227 | */
|
---|
228 | template <const uint8_t BOOT_PROTOCOL>
|
---|
229 | void HIDBoot<BOOT_PROTOCOL>::Initialize()
|
---|
230 | {
|
---|
231 | for (uint32_t i = 0; i < totalEndpoints; ++i)
|
---|
232 | {
|
---|
233 | epInfo[i].deviceEpNum = 0;
|
---|
234 | epInfo[i].hostPipeNum = 0;
|
---|
235 | epInfo[i].maxPktSize = (i) ? 0 : 8;
|
---|
236 | epInfo[i].epAttribs = 0;
|
---|
237 | epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
---|
238 | }
|
---|
239 |
|
---|
240 | bNumEP = 1;
|
---|
241 | bNumIface = 0;
|
---|
242 | bConfNum = 0;
|
---|
243 | }
|
---|
244 |
|
---|
245 | /**
|
---|
246 | * \brief Initialize connection to an HID device.
|
---|
247 | *
|
---|
248 | * \param parent USB device address of the Parent device.
|
---|
249 | * \param port USB device base address.
|
---|
250 | * \param lowspeed USB device speed.
|
---|
251 | *
|
---|
252 | * \return 0 on success, error code otherwise.
|
---|
253 | */
|
---|
254 | template <const uint8_t BOOT_PROTOCOL>
|
---|
255 | uint32_t HIDBoot<BOOT_PROTOCOL>::Init(uint32_t parent, uint32_t port, uint32_t lowspeed)
|
---|
256 | {
|
---|
257 | const uint32_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);
|
---|
258 |
|
---|
259 | uint8_t buf[constBufSize];
|
---|
260 | uint32_t rcode = 0;
|
---|
261 | UsbDevice *p = 0;
|
---|
262 | EpInfo *oldep_ptr = 0;
|
---|
263 | uint32_t len = 0;
|
---|
264 |
|
---|
265 | uint32_t num_of_conf = 0; // number of configurations
|
---|
266 |
|
---|
267 | AddressPool &addrPool = pUsb->GetAddressPool();
|
---|
268 |
|
---|
269 | TRACE_USBHOST(printf("HIDBoot::Init\r\n");)
|
---|
270 |
|
---|
271 | if (bAddress)
|
---|
272 | return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
---|
273 |
|
---|
274 | // Get pointer to pseudo device with address 0 assigned
|
---|
275 | p = addrPool.GetUsbDevicePtr(0);
|
---|
276 |
|
---|
277 | if (!p)
|
---|
278 | return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
---|
279 |
|
---|
280 | if (!p->epinfo)
|
---|
281 | {
|
---|
282 | TRACE_USBHOST(printf("HIDBoot::Init : epinfo is null!\r\n");)
|
---|
283 | return USB_ERROR_EPINFO_IS_NULL;
|
---|
284 | }
|
---|
285 |
|
---|
286 | // Save old pointer to EP_RECORD of address 0
|
---|
287 | oldep_ptr = p->epinfo;
|
---|
288 |
|
---|
289 | // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
---|
290 | p->epinfo = epInfo;
|
---|
291 |
|
---|
292 | p->lowspeed = lowspeed;
|
---|
293 |
|
---|
294 | // Get device descriptor
|
---|
295 | rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
|
---|
296 |
|
---|
297 | if (!rcode)
|
---|
298 | len = (buf[0] > constBufSize) ? constBufSize : buf[0];
|
---|
299 |
|
---|
300 | if (rcode)
|
---|
301 | {
|
---|
302 | // Restore p->epinfo
|
---|
303 | p->epinfo = oldep_ptr;
|
---|
304 |
|
---|
305 | goto FailGetDevDescr;
|
---|
306 | }
|
---|
307 |
|
---|
308 | // Restore p->epinfo
|
---|
309 | p->epinfo = oldep_ptr;
|
---|
310 |
|
---|
311 | // Allocate new address according to device class
|
---|
312 | bAddress = addrPool.AllocAddress(parent, false, port);
|
---|
313 |
|
---|
314 | if (!bAddress)
|
---|
315 | return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
---|
316 |
|
---|
317 | // Extract Max Packet Size from the device descriptor
|
---|
318 | epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
---|
319 |
|
---|
320 | // Assign new address to the device
|
---|
321 | rcode = pUsb->setAddr(0, 0, bAddress);
|
---|
322 |
|
---|
323 | if (rcode)
|
---|
324 | {
|
---|
325 | p->lowspeed = false;
|
---|
326 | addrPool.FreeAddress(bAddress);
|
---|
327 | bAddress = 0;
|
---|
328 | TRACE_USBHOST(printf("HIDBoot::Init : setAddr failed with rcode %lu\r\n", rcode);)
|
---|
329 | return rcode;
|
---|
330 | }
|
---|
331 |
|
---|
332 | TRACE_USBHOST(printf("HIDBoot::Init : device address is now %lu\r\n", bAddress);)
|
---|
333 |
|
---|
334 | p->lowspeed = false;
|
---|
335 |
|
---|
336 | p = addrPool.GetUsbDevicePtr(bAddress);
|
---|
337 |
|
---|
338 | if (!p)
|
---|
339 | return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
---|
340 |
|
---|
341 | p->lowspeed = lowspeed;
|
---|
342 |
|
---|
343 | if (len)
|
---|
344 | rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
---|
345 |
|
---|
346 | if(rcode)
|
---|
347 | goto FailGetDevDescr;
|
---|
348 |
|
---|
349 | num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
|
---|
350 |
|
---|
351 | // Assign epInfo to epinfo pointer
|
---|
352 | rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
---|
353 |
|
---|
354 | if (rcode)
|
---|
355 | goto FailSetDevTblEntry;
|
---|
356 |
|
---|
357 | TRACE_USBHOST(printf("HIDBoot::Init : number of configuration is %lu\r\n", num_of_conf);)
|
---|
358 |
|
---|
359 | for (uint32_t i = 0; i < num_of_conf; ++i)
|
---|
360 | {
|
---|
361 | ConfigDescParser<
|
---|
362 | USB_CLASS_HID,
|
---|
363 | HID_BOOT_INTF_SUBCLASS,
|
---|
364 | BOOT_PROTOCOL,
|
---|
365 | CP_MASK_COMPARE_ALL> confDescrParser(this);
|
---|
366 |
|
---|
367 | rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
---|
368 |
|
---|
369 | if (bNumEP > 1)
|
---|
370 | break;
|
---|
371 | }
|
---|
372 |
|
---|
373 | if (bNumEP < 2)
|
---|
374 | return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
---|
375 |
|
---|
376 | TRACE_USBHOST(printf("HIDBoot::Init : bAddress: %lu\r\n", bAddress);)
|
---|
377 | TRACE_USBHOST(printf("HIDBoot::Init : bNumEP: %lu\r\n", bNumEP);)
|
---|
378 |
|
---|
379 | // Assign epInfo to epinfo pointer
|
---|
380 | rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
---|
381 |
|
---|
382 | TRACE_USBHOST(printf("HIDBoot::Init : bConfNum: %lu\r\n", bConfNum);)
|
---|
383 |
|
---|
384 | // Set Configuration Value
|
---|
385 | rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
---|
386 |
|
---|
387 | if (rcode)
|
---|
388 | goto FailSetConfDescr;
|
---|
389 |
|
---|
390 | TRACE_USBHOST(printf("HIDBoot::Init : bIfaceNum: %lu\r\n", bIfaceNum);)
|
---|
391 |
|
---|
392 | rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
|
---|
393 |
|
---|
394 | if (rcode)
|
---|
395 | goto FailSetProtocol;
|
---|
396 |
|
---|
397 | if (BOOT_PROTOCOL == 1)
|
---|
398 | {
|
---|
399 | rcode = SetIdle(bIfaceNum, 0, 0);
|
---|
400 |
|
---|
401 | if (rcode)
|
---|
402 | goto FailSetIdle;
|
---|
403 | }
|
---|
404 |
|
---|
405 | TRACE_USBHOST(printf("HIDBoot::Init : HID device configured successfully\r\n");)
|
---|
406 |
|
---|
407 | bPollEnable = true;
|
---|
408 | return 0;
|
---|
409 |
|
---|
410 | FailGetDevDescr:
|
---|
411 | TRACE_USBHOST(printf("HIDBoot::Init getDevDescr : ");)
|
---|
412 | goto Fail;
|
---|
413 |
|
---|
414 | FailSetDevTblEntry:
|
---|
415 | TRACE_USBHOST(printf("HIDBoot::Init setDevTblEn : ");)
|
---|
416 | goto Fail;
|
---|
417 |
|
---|
418 | FailSetProtocol:
|
---|
419 | TRACE_USBHOST(printf("HIDBoot::Init SetProto : ");)
|
---|
420 | goto Fail;
|
---|
421 |
|
---|
422 | FailSetIdle:
|
---|
423 | TRACE_USBHOST(printf("HIDBoot::Init SetIdle : ");)
|
---|
424 | goto Fail;
|
---|
425 |
|
---|
426 | FailSetConfDescr:
|
---|
427 | TRACE_USBHOST(printf("HIDBoot::Init setConf : ");)
|
---|
428 | goto Fail;
|
---|
429 |
|
---|
430 | Fail:
|
---|
431 | TRACE_USBHOST(printf("error code: %lu\r\n", rcode);)
|
---|
432 | Release();
|
---|
433 | return rcode;
|
---|
434 | }
|
---|
435 |
|
---|
436 | /**
|
---|
437 | * \brief Extract interrupt-IN endpoint information from configuration
|
---|
438 | * descriptor.
|
---|
439 | *
|
---|
440 | * \param conf Configuration number.
|
---|
441 | * \param iface Interface number.
|
---|
442 | * \param alt Alternate setting.
|
---|
443 | * \param proto Protocol version used.
|
---|
444 | * \param pep Pointer to endpoint descriptor.
|
---|
445 | */
|
---|
446 | template <const uint8_t BOOT_PROTOCOL>
|
---|
447 | void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *pep)
|
---|
448 | {
|
---|
449 | // If the first configuration satisfies, the others are not considered.
|
---|
450 | if (bNumEP > 1 && conf != bConfNum)
|
---|
451 | return;
|
---|
452 |
|
---|
453 | bConfNum = conf;
|
---|
454 | bIfaceNum = iface;
|
---|
455 |
|
---|
456 | uint32_t index = 0;
|
---|
457 | uint32_t pipe = 0;
|
---|
458 |
|
---|
459 | if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
---|
460 | {
|
---|
461 | index = epInterruptInIndex;
|
---|
462 |
|
---|
463 | // Fill in the endpoint info structure
|
---|
464 | epInfo[index].deviceEpNum = (pep->bEndpointAddress & 0x0F);
|
---|
465 | epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
---|
466 | epInfo[index].epAttribs = 0;
|
---|
467 |
|
---|
468 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : Found new endpoint\r\n");)
|
---|
469 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : deviceEpNum: %lu\r\n", epInfo[index].deviceEpNum);)
|
---|
470 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : maxPktSize: %lu\r\n", epInfo[index].maxPktSize);)
|
---|
471 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : index: %lu\r\n", index);)
|
---|
472 |
|
---|
473 | // Ensure pipe allocation is okay
|
---|
474 | pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].deviceEpNum, UOTGHS_HSTPIPCFG_PTYPE_INTRPT, UOTGHS_HSTPIPCFG_PTOKEN_IN, epInfo[index].maxPktSize, 10, UOTGHS_HSTPIPCFG_PBK_1_BANK);
|
---|
475 | if (pipe == 0)
|
---|
476 | {
|
---|
477 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : Pipe allocation failure\r\n");)
|
---|
478 | // Enumeration failed
|
---|
479 | return;
|
---|
480 | }
|
---|
481 |
|
---|
482 | epInfo[index].hostPipeNum = pipe;
|
---|
483 |
|
---|
484 | bNumEP++;
|
---|
485 | }
|
---|
486 | }
|
---|
487 |
|
---|
488 | /**
|
---|
489 | * \brief Release USB allocated resources (pipes and address).
|
---|
490 | *
|
---|
491 | * \note Release call is made from USBHost.task() on disconnection events.
|
---|
492 | * \note Release call is made from Init() on enumeration failure.
|
---|
493 | *
|
---|
494 | * \return Always 0.
|
---|
495 | */
|
---|
496 | template <const uint8_t BOOT_PROTOCOL>
|
---|
497 | uint32_t HIDBoot<BOOT_PROTOCOL>::Release()
|
---|
498 | {
|
---|
499 | // Free allocated host pipes
|
---|
500 | UHD_Pipe_Free(epInfo[epInterruptInIndex].hostPipeNum);
|
---|
501 |
|
---|
502 | // Free allocated USB address
|
---|
503 | pUsb->GetAddressPool().FreeAddress(bAddress);
|
---|
504 |
|
---|
505 | bConfNum = 0;
|
---|
506 | bIfaceNum = 0;
|
---|
507 | bNumEP = 1;
|
---|
508 | bAddress = 0;
|
---|
509 | qNextPollTime = 0;
|
---|
510 | bPollEnable = false;
|
---|
511 |
|
---|
512 | return 0;
|
---|
513 | }
|
---|
514 |
|
---|
515 | /**
|
---|
516 | * \brief Poll USB device activity.
|
---|
517 | *
|
---|
518 | * \note Poll call is periodically made from USBHost.task().
|
---|
519 | *
|
---|
520 | * \return 0 on success, error code otherwise.
|
---|
521 | */
|
---|
522 | template <const uint8_t BOOT_PROTOCOL>
|
---|
523 | uint32_t HIDBoot<BOOT_PROTOCOL>::Poll()
|
---|
524 | {
|
---|
525 | uint32_t rcode = 0;
|
---|
526 |
|
---|
527 | if (!bPollEnable)
|
---|
528 | return 0;
|
---|
529 |
|
---|
530 | if (qNextPollTime <= millis())
|
---|
531 | {
|
---|
532 | qNextPollTime = millis() + 10;
|
---|
533 |
|
---|
534 | const uint32_t const_buff_len = 16;
|
---|
535 | uint8_t buf[const_buff_len];
|
---|
536 |
|
---|
537 | uint32_t read = epInfo[epInterruptInIndex].maxPktSize;
|
---|
538 |
|
---|
539 | rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].deviceEpNum, &read, buf);
|
---|
540 |
|
---|
541 | if (rcode)
|
---|
542 | {
|
---|
543 | return rcode;
|
---|
544 | }
|
---|
545 |
|
---|
546 | if (pRptParser)
|
---|
547 | pRptParser->Parse((HID*)this, 0, (uint32_t)read, buf);
|
---|
548 | }
|
---|
549 |
|
---|
550 | return rcode;
|
---|
551 | }
|
---|
552 |
|
---|
553 | #endif /* HIDBOOT_H_INCLUDED */
|
---|