Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
hidboot.h
00001 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. 00002 00003 This software may be distributed and modified under the terms of the GNU 00004 General Public License version 2 (GPL2) as published by the Free Software 00005 Foundation and appearing in the file GPL2.TXT included in the packaging of 00006 this file. Please note that GPL2 Section 2[b] requires that all works based 00007 on this software must also be made publicly available under the terms of 00008 the GPL2 ("Copyleft"). 00009 00010 Contact information 00011 ------------------- 00012 00013 Circuits At Home, LTD 00014 Web : http://www.circuitsathome.com 00015 e-mail : support@circuitsathome.com 00016 */ 00017 #if !defined(__HIDBOOT_H__) 00018 #define __HIDBOOT_H__ 00019 00020 #include "usbhid.h" 00021 00022 #define UHS_HID_BOOT_KEY_ZERO 0x27 00023 #define UHS_HID_BOOT_KEY_ENTER 0x28 00024 #define UHS_HID_BOOT_KEY_SPACE 0x2c 00025 #define UHS_HID_BOOT_KEY_CAPS_LOCK 0x39 00026 #define UHS_HID_BOOT_KEY_SCROLL_LOCK 0x47 00027 #define UHS_HID_BOOT_KEY_NUM_LOCK 0x53 00028 #define UHS_HID_BOOT_KEY_ZERO2 0x62 00029 #define UHS_HID_BOOT_KEY_PERIOD 0x63 00030 00031 // Don't worry, GCC will optimize the result to a final value. 00032 #define bitsEndpoints(p) ((((p) & USB_HID_PROTOCOL_KEYBOARD)? 2 : 0) | (((p) & USB_HID_PROTOCOL_MOUSE)? 1 : 0)) 00033 #define totalEndpoints(p) ((bitsEndpoints(p) == 3) ? 3 : 2) 00034 #define epMUL(p) ((((p) & USB_HID_PROTOCOL_KEYBOARD)? 1 : 0) + (((p) & USB_HID_PROTOCOL_MOUSE)? 1 : 0)) 00035 00036 // Already defined in hid.h 00037 // #define HID_MAX_HID_CLASS_DESCRIPTORS 5 00038 00039 struct MOUSEINFO { 00040 00041 struct { 00042 uint8_t bmLeftButton : 1; 00043 uint8_t bmRightButton : 1; 00044 uint8_t bmMiddleButton : 1; 00045 uint8_t bmDummy : 5; 00046 }; 00047 int8_t dX; 00048 int8_t dY; 00049 }; 00050 00051 class MouseReportParser : public HIDReportParser { 00052 00053 union { 00054 MOUSEINFO mouseInfo; 00055 uint8_t bInfo[sizeof (MOUSEINFO)]; 00056 } prevState; 00057 00058 public: 00059 void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); 00060 00061 protected: 00062 00063 virtual void OnMouseMove(MOUSEINFO *mi __attribute__((unused))) { 00064 }; 00065 00066 virtual void OnLeftButtonUp(MOUSEINFO *mi __attribute__((unused))) { 00067 }; 00068 00069 virtual void OnLeftButtonDown(MOUSEINFO *mi __attribute__((unused))) { 00070 }; 00071 00072 virtual void OnRightButtonUp(MOUSEINFO *mi __attribute__((unused))) { 00073 }; 00074 00075 virtual void OnRightButtonDown(MOUSEINFO *mi __attribute__((unused))) { 00076 }; 00077 00078 virtual void OnMiddleButtonUp(MOUSEINFO *mi __attribute__((unused))) { 00079 }; 00080 00081 virtual void OnMiddleButtonDown(MOUSEINFO *mi __attribute__((unused))) { 00082 }; 00083 }; 00084 00085 struct MODIFIERKEYS { 00086 uint8_t bmLeftCtrl : 1; 00087 uint8_t bmLeftShift : 1; 00088 uint8_t bmLeftAlt : 1; 00089 uint8_t bmLeftGUI : 1; 00090 uint8_t bmRightCtrl : 1; 00091 uint8_t bmRightShift : 1; 00092 uint8_t bmRightAlt : 1; 00093 uint8_t bmRightGUI : 1; 00094 }; 00095 00096 struct KBDINFO { 00097 00098 struct { 00099 uint8_t bmLeftCtrl : 1; 00100 uint8_t bmLeftShift : 1; 00101 uint8_t bmLeftAlt : 1; 00102 uint8_t bmLeftGUI : 1; 00103 uint8_t bmRightCtrl : 1; 00104 uint8_t bmRightShift : 1; 00105 uint8_t bmRightAlt : 1; 00106 uint8_t bmRightGUI : 1; 00107 }; 00108 uint8_t bReserved; 00109 uint8_t Keys[6]; 00110 }; 00111 00112 struct KBDLEDS { 00113 uint8_t bmNumLock : 1; 00114 uint8_t bmCapsLock : 1; 00115 uint8_t bmScrollLock : 1; 00116 uint8_t bmCompose : 1; 00117 uint8_t bmKana : 1; 00118 uint8_t bmReserved : 3; 00119 }; 00120 00121 class KeyboardReportParser : public HIDReportParser { 00122 static const uint8_t numKeys[10]; 00123 static const uint8_t symKeysUp[12]; 00124 static const uint8_t symKeysLo[12]; 00125 static const uint8_t padKeys[5]; 00126 00127 protected: 00128 00129 union { 00130 KBDINFO kbdInfo; 00131 uint8_t bInfo[sizeof (KBDINFO)]; 00132 } prevState; 00133 00134 union { 00135 KBDLEDS kbdLeds; 00136 uint8_t bLeds; 00137 } kbdLockingKeys; 00138 00139 uint8_t OemToAscii(uint8_t mod, uint8_t key); 00140 00141 public: 00142 00143 KeyboardReportParser() { 00144 kbdLockingKeys.bLeds = 0; 00145 }; 00146 00147 void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); 00148 00149 protected: 00150 00151 virtual uint8_t HandleLockingKeys(USBHID* hid, uint8_t key) { 00152 uint8_t old_keys = kbdLockingKeys.bLeds; 00153 00154 switch(key) { 00155 case UHS_HID_BOOT_KEY_NUM_LOCK: 00156 kbdLockingKeys.kbdLeds.bmNumLock = ~kbdLockingKeys.kbdLeds.bmNumLock; 00157 break; 00158 case UHS_HID_BOOT_KEY_CAPS_LOCK: 00159 kbdLockingKeys.kbdLeds.bmCapsLock = ~kbdLockingKeys.kbdLeds.bmCapsLock; 00160 break; 00161 case UHS_HID_BOOT_KEY_SCROLL_LOCK: 00162 kbdLockingKeys.kbdLeds.bmScrollLock = ~kbdLockingKeys.kbdLeds.bmScrollLock; 00163 break; 00164 } 00165 00166 if(old_keys != kbdLockingKeys.bLeds && hid) { 00167 uint8_t lockLeds = kbdLockingKeys.bLeds; 00168 return (hid->SetReport(0, 0/*hid->GetIface()*/, 2, 0, 1, &lockLeds)); 00169 } 00170 00171 return 0; 00172 }; 00173 00174 virtual void OnControlKeysChanged(uint8_t before __attribute__((unused)), uint8_t after __attribute__((unused))) { 00175 }; 00176 00177 virtual void OnKeyDown(uint8_t mod __attribute__((unused)), uint8_t key __attribute__((unused))) { 00178 }; 00179 00180 virtual void OnKeyUp(uint8_t mod __attribute__((unused)), uint8_t key __attribute__((unused))) { 00181 }; 00182 00183 virtual const uint8_t *getNumKeys() { 00184 return numKeys; 00185 }; 00186 00187 virtual const uint8_t *getSymKeysUp() { 00188 return symKeysUp; 00189 }; 00190 00191 virtual const uint8_t *getSymKeysLo() { 00192 return symKeysLo; 00193 }; 00194 00195 virtual const uint8_t *getPadKeys() { 00196 return padKeys; 00197 }; 00198 }; 00199 00200 template <const uint8_t BOOT_PROTOCOL> 00201 class HIDBoot : public USBHID //public USBDeviceConfig, public UsbConfigXtracter 00202 { 00203 EpInfo epInfo[totalEndpoints(BOOT_PROTOCOL)]; 00204 HIDReportParser *pRptParser[epMUL(BOOT_PROTOCOL)]; 00205 00206 uint8_t bConfNum; // configuration number 00207 uint8_t bIfaceNum; // Interface Number 00208 uint8_t bNumIface; // number of interfaces in the configuration 00209 uint8_t bNumEP; // total number of EP in the configuration 00210 uint32_t qNextPollTime; // next poll time 00211 bool bPollEnable; // poll enable flag 00212 uint8_t bInterval; // largest interval 00213 bool bRptProtoEnable; // Report Protocol enable flag 00214 00215 void Initialize(); 00216 00217 virtual HIDReportParser* GetReportParser(uint8_t id) { 00218 return pRptParser[id]; 00219 }; 00220 00221 public: 00222 HIDBoot(USB *p, bool bRptProtoEnable = false); 00223 00224 virtual bool SetReportParser(uint8_t id, HIDReportParser *prs) { 00225 pRptParser[id] = prs; 00226 return true; 00227 }; 00228 00229 // USBDeviceConfig implementation 00230 uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed); 00231 uint8_t Release(); 00232 uint8_t Poll(); 00233 00234 virtual uint8_t GetAddress() { 00235 return bAddress; 00236 }; 00237 00238 virtual bool isReady() { 00239 return bPollEnable; 00240 }; 00241 00242 // UsbConfigXtracter implementation 00243 // Method should be defined here if virtual. 00244 virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); 00245 00246 virtual bool DEVCLASSOK(uint8_t klass) { 00247 return (klass == USB_CLASS_HID); 00248 } 00249 00250 virtual bool DEVSUBCLASSOK(uint8_t subklass) { 00251 return (subklass == BOOT_PROTOCOL); 00252 } 00253 }; 00254 00255 template <const uint8_t BOOT_PROTOCOL> 00256 HIDBoot<BOOT_PROTOCOL>::HIDBoot(USB *p, bool bRptProtoEnable/* = false*/) : 00257 USBHID(p), 00258 qNextPollTime(0), 00259 bPollEnable(false), 00260 bRptProtoEnable(bRptProtoEnable) { 00261 Initialize(); 00262 00263 for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) { 00264 pRptParser[i] = NULL; 00265 } 00266 if(pUsb) 00267 pUsb->RegisterDeviceClass(this); 00268 } 00269 00270 template <const uint8_t BOOT_PROTOCOL> 00271 void HIDBoot<BOOT_PROTOCOL>::Initialize() { 00272 for(int i = 0; i < totalEndpoints(BOOT_PROTOCOL); i++) { 00273 epInfo[i].epAddr = 0; 00274 epInfo[i].maxPktSize = (i) ? 0 : 8; 00275 epInfo[i].bmSndToggle = 0; 00276 epInfo[i].bmRcvToggle = 0; 00277 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER; 00278 } 00279 bNumEP = 1; 00280 bNumIface = 0; 00281 bConfNum = 0; 00282 } 00283 00284 template <const uint8_t BOOT_PROTOCOL> 00285 uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed) { 00286 const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); 00287 00288 uint8_t buf[constBufSize]; 00289 USB_DEVICE_DESCRIPTOR* device; 00290 uint8_t rcode; 00291 UsbDevice *p = NULL; 00292 EpInfo *oldep_ptr = NULL; 00293 uint8_t len = 0; 00294 //uint16_t cd_len = 0; 00295 00296 uint8_t num_of_conf; // number of configurations 00297 //uint8_t num_of_intf; // number of interfaces 00298 00299 AddressPool &addrPool = pUsb->GetAddressPool(); 00300 00301 USBTRACE("BM Init\r\n"); 00302 //USBTRACE2("totalEndpoints:", (uint8_t) (totalEndpoints(BOOT_PROTOCOL))); 00303 //USBTRACE2("epMUL:", epMUL(BOOT_PROTOCOL)); 00304 00305 if(bAddress) 00306 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; 00307 00308 bInterval = 0; 00309 // Get pointer to pseudo device with address 0 assigned 00310 p = addrPool.GetUsbDevicePtr(0); 00311 00312 if(!p) 00313 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; 00314 00315 if(!p->epinfo) { 00316 USBTRACE("epinfo\r\n"); 00317 return USB_ERROR_EPINFO_IS_NULL; 00318 } 00319 00320 // Save old pointer to EP_RECORD of address 0 00321 oldep_ptr = p->epinfo; 00322 00323 // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence 00324 p->epinfo = epInfo; 00325 00326 p->lowspeed = lowspeed; 00327 00328 // Get device descriptor 00329 rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf); 00330 00331 if(!rcode) 00332 len = (buf[0] > constBufSize) ? constBufSize : buf[0]; 00333 00334 device = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf); 00335 00336 if(rcode) { 00337 // Restore p->epinfo 00338 p->epinfo = oldep_ptr; 00339 00340 goto FailGetDevDescr; 00341 } 00342 00343 // Restore p->epinfo 00344 p->epinfo = oldep_ptr; 00345 00346 // Allocate new address according to device class 00347 bAddress = addrPool.AllocAddress(parent, false, port); 00348 00349 if(!bAddress) 00350 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; 00351 00352 // Extract Max Packet Size from the device descriptor 00353 epInfo[0].maxPktSize = (uint8_t)(device->bMaxPacketSize0); 00354 00355 // Assign new address to the device 00356 rcode = pUsb->setAddr(0, 0, bAddress); 00357 00358 if(rcode) { 00359 p->lowspeed = false; 00360 addrPool.FreeAddress(bAddress); 00361 bAddress = 0; 00362 USBTRACE2("setAddr:", rcode); 00363 return rcode; 00364 } 00365 //delay(2); //per USB 2.0 sect.9.2.6.3 00366 00367 USBTRACE2("Addr:", bAddress); 00368 00369 p->lowspeed = false; 00370 00371 p = addrPool.GetUsbDevicePtr(bAddress); 00372 00373 if(!p) 00374 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; 00375 00376 p->lowspeed = lowspeed; 00377 00378 if(len) 00379 rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf); 00380 00381 if(rcode) 00382 goto FailGetDevDescr; 00383 00384 num_of_conf = device->bNumConfigurations; 00385 00386 USBTRACE2("NC:", num_of_conf); 00387 00388 // GCC will optimize unused stuff away. 00389 if((BOOT_PROTOCOL & (USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE)) == (USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE)) { 00390 USBTRACE("HID_PROTOCOL_KEYBOARD AND MOUSE\r\n"); 00391 ConfigDescParser< 00392 USB_CLASS_HID, 00393 HID_BOOT_INTF_SUBCLASS, 00394 USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE, 00395 CP_MASK_COMPARE_ALL > confDescrParser(this); 00396 confDescrParser.SetOR(); // Use the OR variant. 00397 for(uint8_t i = 0; i < num_of_conf; i++) { 00398 pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); 00399 if(bNumEP == (uint8_t)(totalEndpoints(BOOT_PROTOCOL))) 00400 break; 00401 } 00402 } else { 00403 // GCC will optimize unused stuff away. 00404 if(BOOT_PROTOCOL & USB_HID_PROTOCOL_KEYBOARD) { 00405 USBTRACE("HID_PROTOCOL_KEYBOARD\r\n"); 00406 for(uint8_t i = 0; i < num_of_conf; i++) { 00407 ConfigDescParser< 00408 USB_CLASS_HID, 00409 HID_BOOT_INTF_SUBCLASS, 00410 USB_HID_PROTOCOL_KEYBOARD, 00411 CP_MASK_COMPARE_ALL> confDescrParserA(this); 00412 00413 pUsb->getConfDescr(bAddress, 0, i, &confDescrParserA); 00414 if(bNumEP == (uint8_t)(totalEndpoints(BOOT_PROTOCOL))) 00415 break; 00416 } 00417 } 00418 00419 // GCC will optimize unused stuff away. 00420 if(BOOT_PROTOCOL & USB_HID_PROTOCOL_MOUSE) { 00421 USBTRACE("HID_PROTOCOL_MOUSE\r\n"); 00422 for(uint8_t i = 0; i < num_of_conf; i++) { 00423 ConfigDescParser< 00424 USB_CLASS_HID, 00425 HID_BOOT_INTF_SUBCLASS, 00426 USB_HID_PROTOCOL_MOUSE, 00427 CP_MASK_COMPARE_ALL> confDescrParserB(this); 00428 00429 pUsb->getConfDescr(bAddress, 0, i, &confDescrParserB); 00430 if(bNumEP == ((uint8_t)(totalEndpoints(BOOT_PROTOCOL)))) 00431 break; 00432 00433 } 00434 } 00435 } 00436 USBTRACE2("bNumEP:", bNumEP); 00437 00438 if(bNumEP != (uint8_t)(totalEndpoints(BOOT_PROTOCOL))) { 00439 rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; 00440 goto Fail; 00441 } 00442 00443 // Assign epInfo to epinfo pointer 00444 rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); 00445 //USBTRACE2("setEpInfoEntry returned ", rcode); 00446 USBTRACE2("Cnf:", bConfNum); 00447 00448 delay(1000); 00449 00450 // Set Configuration Value 00451 rcode = pUsb->setConf(bAddress, 0, bConfNum); 00452 00453 if(rcode) 00454 goto FailSetConfDescr; 00455 00456 delay(1000); 00457 00458 USBTRACE2("bIfaceNum:", bIfaceNum); 00459 USBTRACE2("bNumIface:", bNumIface); 00460 00461 // Yes, mouse wants SetProtocol and SetIdle too! 00462 for(uint8_t i = 0; i < epMUL(BOOT_PROTOCOL); i++) { 00463 USBTRACE2("\r\nInterface:", i); 00464 rcode = SetProtocol(i, bRptProtoEnable ? HID_RPT_PROTOCOL : USB_HID_BOOT_PROTOCOL); 00465 if(rcode) goto FailSetProtocol; 00466 USBTRACE2("PROTOCOL SET HID_BOOT rcode:", rcode); 00467 rcode = SetIdle(i, 0, 0); 00468 USBTRACE2("SET_IDLE rcode:", rcode); 00469 // if(rcode) goto FailSetIdle; This can fail. 00470 // Get the RPIPE and just throw it away. 00471 SinkParser<USBReadParser, uint16_t, uint16_t> sink; 00472 rcode = GetReportDescr(i, &sink); 00473 USBTRACE2("RPIPE rcode:", rcode); 00474 } 00475 00476 // Get RPIPE and throw it away. 00477 00478 if(BOOT_PROTOCOL & USB_HID_PROTOCOL_KEYBOARD) { 00479 // Wake keyboard interface by twinkling up to 5 LEDs that are in the spec. 00480 // kana, compose, scroll, caps, num 00481 rcode = 0x20; // Reuse rcode. 00482 while(rcode) { 00483 rcode >>= 1; 00484 // Ignore any error returned, we don't care if LED is not supported 00485 SetReport(0, 0, 2, 0, 1, &rcode); // Eventually becomes zero (All off) 00486 delay(25); 00487 } 00488 } 00489 USBTRACE("BM configured\r\n"); 00490 00491 bPollEnable = true; 00492 return 0; 00493 00494 FailGetDevDescr: 00495 #ifdef DEBUG_USB_HOST 00496 NotifyFailGetDevDescr(); 00497 goto Fail; 00498 #endif 00499 00500 //FailSetDevTblEntry: 00501 //#ifdef DEBUG_USB_HOST 00502 // NotifyFailSetDevTblEntry(); 00503 // goto Fail; 00504 //#endif 00505 00506 //FailGetConfDescr: 00507 //#ifdef DEBUG_USB_HOST 00508 // NotifyFailGetConfDescr(); 00509 // goto Fail; 00510 //#endif 00511 00512 FailSetConfDescr: 00513 #ifdef DEBUG_USB_HOST 00514 NotifyFailSetConfDescr(); 00515 goto Fail; 00516 #endif 00517 00518 FailSetProtocol: 00519 #ifdef DEBUG_USB_HOST 00520 USBTRACE("SetProto:"); 00521 goto Fail; 00522 #endif 00523 00524 //FailSetIdle: 00525 //#ifdef DEBUG_USB_HOST 00526 // USBTRACE("SetIdle:"); 00527 //#endif 00528 00529 Fail: 00530 #ifdef DEBUG_USB_HOST 00531 NotifyFail(rcode); 00532 #endif 00533 Release(); 00534 00535 return rcode; 00536 } 00537 00538 template <const uint8_t BOOT_PROTOCOL> 00539 void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) { 00540 00541 // If the first configuration satisfies, the others are not considered. 00542 //if(bNumEP > 1 && conf != bConfNum) 00543 if(bNumEP == totalEndpoints(BOOT_PROTOCOL)) 00544 return; 00545 00546 bConfNum = conf; 00547 bIfaceNum = iface; 00548 00549 if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT && (pep->bEndpointAddress & 0x80) == 0x80) { 00550 if(pep->bInterval > bInterval) bInterval = pep->bInterval; 00551 00552 // Fill in the endpoint info structure 00553 epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F); 00554 epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize; 00555 epInfo[bNumEP].bmSndToggle = 0; 00556 epInfo[bNumEP].bmRcvToggle = 0; 00557 epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT; 00558 bNumEP++; 00559 00560 } 00561 } 00562 00563 template <const uint8_t BOOT_PROTOCOL> 00564 uint8_t HIDBoot<BOOT_PROTOCOL>::Release() { 00565 pUsb->GetAddressPool().FreeAddress(bAddress); 00566 00567 bConfNum = 0; 00568 bIfaceNum = 0; 00569 bNumEP = 1; 00570 bAddress = 0; 00571 qNextPollTime = 0; 00572 bPollEnable = false; 00573 00574 return 0; 00575 } 00576 00577 template <const uint8_t BOOT_PROTOCOL> 00578 uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() { 00579 uint8_t rcode = 0; 00580 00581 if(bPollEnable && ((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L)) { 00582 00583 // To-do: optimize manually, using the for loop only if needed. 00584 for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) { 00585 const uint16_t const_buff_len = 16; 00586 uint8_t buf[const_buff_len]; 00587 00588 USBTRACE3("(hidboot.h) i=", i, 0x81); 00589 USBTRACE3("(hidboot.h) epInfo[epInterruptInIndex + i].epAddr=", epInfo[epInterruptInIndex + i].epAddr, 0x81); 00590 USBTRACE3("(hidboot.h) epInfo[epInterruptInIndex + i].maxPktSize=", epInfo[epInterruptInIndex + i].maxPktSize, 0x81); 00591 uint16_t read = (uint16_t)epInfo[epInterruptInIndex + i].maxPktSize; 00592 00593 rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex + i].epAddr, &read, buf); 00594 // SOME buggy dongles report extra keys (like sleep) using a 2 byte packet on the wrong endpoint. 00595 // Since keyboard and mice must report at least 3 bytes, we ignore the extra data. 00596 if(!rcode && read > 2) { 00597 if(pRptParser[i]) 00598 pRptParser[i]->Parse((USBHID*)this, 0, (uint8_t)read, buf); 00599 #ifdef DEBUG_USB_HOST 00600 // We really don't care about errors and anomalies unless we are debugging. 00601 } else { 00602 if(rcode != hrNAK) { 00603 USBTRACE3("(hidboot.h) Poll:", rcode, 0x81); 00604 } 00605 if(!rcode && read) { 00606 USBTRACE3("(hidboot.h) Strange read count: ", read, 0x80); 00607 USBTRACE3("(hidboot.h) Interface:", i, 0x80); 00608 } 00609 } 00610 00611 if(!rcode && read && (UsbDEBUGlvl > 0x7f)) { 00612 for(uint8_t i = 0; i < read; i++) { 00613 PrintHex<uint8_t > (buf[i], 0x80); 00614 USBTRACE1(" ", 0x80); 00615 } 00616 if(read) 00617 USBTRACE1("\r\n", 0x80); 00618 #endif 00619 } 00620 00621 } 00622 qNextPollTime = (uint32_t)millis() + bInterval; 00623 } 00624 return rcode; 00625 } 00626 00627 #endif // __HIDBOOTMOUSE_H__ 00628
Generated on Thu Jul 14 2022 08:33:41 by
1.7.2