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.
Dependents: UsbHostMAX3421E_Hello
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 //wait_ms(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 wait_ms(1000); 00449 00450 // Set Configuration Value 00451 rcode = pUsb->setConf(bAddress, 0, bConfNum); 00452 00453 if(rcode) 00454 goto FailSetConfDescr; 00455 00456 wait_ms(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 wait_ms(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__
Generated on Tue Jul 12 2022 18:12:04 by
