From 77efe42a718472d1d649465b4d6a8bfeee145e30 Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Wed, 18 Dec 2013 21:58:24 -0500 Subject: [PATCH] Fix hidboot not allocating or checking properly on mouse. Removal of duplicate code: Force all drivers to delay after setting address. --- PS3USB.cpp | 2 +- Usb.cpp | 16 +++++---- XBOXOLD.cpp | 2 +- XBOXUSB.cpp | 2 +- adk.cpp | 2 +- hidboot.h | 86 +++++++++++++++++++++++++++++------------------- hiduniversal.cpp | 2 +- 7 files changed, 68 insertions(+), 44 deletions(-) diff --git a/PS3USB.cpp b/PS3USB.cpp index 1f6226eb..8cc4a40f 100644 --- a/PS3USB.cpp +++ b/PS3USB.cpp @@ -129,7 +129,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { Notify(PSTR("\r\nAddr: "), 0x80); D_PrintHex (bAddress, 0x80); #endif - delay(300); // Spec says you should wait at least 200ms + //delay(300); // Spec says you should wait at least 200ms p->lowspeed = false; diff --git a/Usb.cpp b/Usb.cpp index 8f498dba..3bcea447 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -447,7 +447,7 @@ void USB::Task(void) //USB state machine case LSHOST: lowspeed = true; - //intentional fallthrough + //intentional fallthrough case FSHOST: //attached if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { delay = millis() + USB_SETTLE_DELAY; @@ -503,11 +503,11 @@ void USB::Task(void) //USB state machine break; case USB_ATTACHED_SUBSTATE_WAIT_RESET: if (delay < millis()) usb_task_state = USB_STATE_CONFIGURING; - else break; // don't fall through + else break; // don't fall through case USB_STATE_CONFIGURING: - //Serial.print("\r\nConf.LS: "); - //Serial.println(lowspeed, HEX); + //Serial.print("\r\nConf.LS: "); + //Serial.println(lowspeed, HEX); rcode = Configuring(0, 0, lowspeed); @@ -748,7 +748,7 @@ uint8_t USB::ReleaseDevice(uint8_t addr) { return 0; for (uint8_t i = 0; i < USB_NUMDEVICES; i++) { - if(!devConfig[i]) continue; + if (!devConfig[i]) continue; if (devConfig[i]->GetAddress() == addr) return devConfig[i]->Release(); } @@ -794,7 +794,11 @@ uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, u //set address uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) { - return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL)); + uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL); + //delay(2); //per USB 2.0 sect.9.2.6.3 + delay(300); // Older spec says you should wait at least 200ms + return rcode; + //return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL)); } //set configuration diff --git a/XBOXOLD.cpp b/XBOXOLD.cpp index e60330c8..d615f83f 100644 --- a/XBOXOLD.cpp +++ b/XBOXOLD.cpp @@ -145,7 +145,7 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) { Notify(PSTR("\r\nAddr: "), 0x80); D_PrintHex (bAddress, 0x80); #endif - delay(300); // Spec says you should wait at least 200ms + //delay(300); // Spec says you should wait at least 200ms p->lowspeed = false; diff --git a/XBOXUSB.cpp b/XBOXUSB.cpp index a7900811..111c5c3e 100644 --- a/XBOXUSB.cpp +++ b/XBOXUSB.cpp @@ -133,7 +133,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) { Notify(PSTR("\r\nAddr: "), 0x80); D_PrintHex (bAddress, 0x80); #endif - delay(300); // Spec says you should wait at least 200ms + //delay(300); // Spec says you should wait at least 200ms p->lowspeed = false; diff --git a/adk.cpp b/adk.cpp index a3530d00..2d655b74 100644 --- a/adk.cpp +++ b/adk.cpp @@ -128,7 +128,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) { //USBTRACE2("\r\nAddr:", bAddress); // Spec says you should wait at least 200ms. - delay(300); + //delay(300); p->lowspeed = false; diff --git a/hidboot.h b/hidboot.h index 8f228a92..32430caa 100644 --- a/hidboot.h +++ b/hidboot.h @@ -28,7 +28,6 @@ e-mail : support@circuitsathome.com #define UHS_HID_BOOT_KEY_ZERO2 0x62 #define UHS_HID_BOOT_KEY_PERIOD 0x63 - struct MOUSEINFO { struct { @@ -168,15 +167,16 @@ protected: }; }; -#define totalEndpoints (((BOOT_PROTOCOL & HID_PROTOCOL_KEYBOARD)? 2 : 0)+((BOOT_PROTOCOL & HID_PROTOCOL_MOUSE)? 1 : 0)) -#define epMUL (((BOOT_PROTOCOL & HID_PROTOCOL_KEYBOARD)? 1 : 0)+((BOOT_PROTOCOL & HID_PROTOCOL_MOUSE)? 1 : 0)) +#define bitsEndpoints(p) (((p & HID_PROTOCOL_KEYBOARD)? 2 : 0)+((p & HID_PROTOCOL_MOUSE)? 1 : 0)) +#define totalEndpoints(p) ((bitsEndpoints(p) == 3) ? 3 : 2) +#define epMUL(p) (((p & HID_PROTOCOL_KEYBOARD)? 1 : 0)+((p & HID_PROTOCOL_MOUSE)? 1 : 0)) #define HID_MAX_HID_CLASS_DESCRIPTORS 5 template class HIDBoot : public HID //public USBDeviceConfig, public UsbConfigXtracter { - EpInfo epInfo[totalEndpoints]; - HIDReportParser *pRptParser[epMUL]; + EpInfo epInfo[totalEndpoints(BOOT_PROTOCOL)]; + HIDReportParser *pRptParser[epMUL(BOOT_PROTOCOL)]; uint8_t bConfNum; // configuration number uint8_t bIfaceNum; // Interface Number @@ -219,7 +219,7 @@ qNextPollTime(0), bPollEnable(false) { Initialize(); - for(uint8_t i = 0; i < epMUL; i++) { + for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) { pRptParser[i] = NULL; } if(pUsb) @@ -228,7 +228,7 @@ bPollEnable(false) { template void HIDBoot::Initialize() { - for(uint8_t i = 0; i < totalEndpoints; i++) { + for(int i = 0; i < totalEndpoints(BOOT_PROTOCOL); i++) { epInfo[i].epAddr = 0; epInfo[i].maxPktSize = (i) ? 0 : 8; epInfo[i].epAttribs = 0; @@ -314,6 +314,7 @@ uint8_t HIDBoot::Init(uint8_t parent, uint8_t port, bool lowspeed USBTRACE2("setAddr:", rcode); return rcode; } + delay(2); //per USB 2.0 sect.9.2.6.3 USBTRACE2("Addr:", bAddress); @@ -335,15 +336,22 @@ uint8_t HIDBoot::Init(uint8_t parent, uint8_t port, bool lowspeed num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; // Assign epInfo to epinfo pointer - rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + //rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); - if(rcode) - goto FailSetDevTblEntry; + //if(rcode) + // goto FailSetDevTblEntry; //USBTRACE2("NC:", num_of_conf); + // GCC will optimize unused stuff away. + //if((totalEndpoints(BOOT_PROTOCOL)) != 3) { + // bNumEP = 0; + //} + USBTRACE2("bNumEP:", bNumEP); + USBTRACE2("totalEndpoints:", (uint8_t) (bitsEndpoints(BOOT_PROTOCOL))); // GCC will optimize unused stuff away. if(BOOT_PROTOCOL & HID_PROTOCOL_KEYBOARD) { + USBTRACE("HID_PROTOCOL_KEYBOARD\r\n"); for(uint8_t i = 0; i < num_of_conf; i++) { ConfigDescParser< USB_CLASS_HID, @@ -351,46 +359,55 @@ uint8_t HIDBoot::Init(uint8_t parent, uint8_t port, bool lowspeed HID_PROTOCOL_KEYBOARD, CP_MASK_COMPARE_ALL> confDescrParserA(this); - if(bNumEP == totalEndpoints) - break; pUsb->getConfDescr(bAddress, 0, i, &confDescrParserA); + if(bNumEP == (uint8_t) (bitsEndpoints(BOOT_PROTOCOL))) + break; } } // GCC will optimize unused stuff away. if(BOOT_PROTOCOL & HID_PROTOCOL_MOUSE) { + USBTRACE("HID_PROTOCOL_MOUSE\r\n"); for(uint8_t i = 0; i < num_of_conf; i++) { ConfigDescParser< USB_CLASS_HID, HID_BOOT_INTF_SUBCLASS, HID_PROTOCOL_MOUSE, CP_MASK_COMPARE_ALL> confDescrParserB(this); - if(bNumEP == totalEndpoints) - break; pUsb->getConfDescr(bAddress, 0, i, &confDescrParserB); + if(bNumEP > 1 /* (uint8_t) (totalEndpoints(BOOT_PROTOCOL))*/) + break; + } } + USBTRACE2("bAddr:", bAddress); USBTRACE2("bNumEP:", bNumEP); - USBTRACE2("totalEndpoints:", totalEndpoints); - if(bNumEP != totalEndpoints) { - rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; - goto Fail; - } + USBTRACE2("totalEndpoints:", (uint8_t) (bitsEndpoints(BOOT_PROTOCOL))); + USBTRACE2("epMUL:", epMUL(BOOT_PROTOCOL)); + + if(bNumEP != (uint8_t)(totalEndpoints(BOOT_PROTOCOL))) { + rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + goto Fail; + } // Assign epInfo to epinfo pointer rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); USBTRACE2("setEpInfoEntry returned ", rcode); USBTRACE2("Cnf:", bConfNum); + delay(1000); + // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); if(rcode) goto FailSetConfDescr; + delay(1000); + USBTRACE2("If:", bIfaceNum); rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL); @@ -416,17 +433,17 @@ FailGetDevDescr: goto Fail; #endif -FailSetDevTblEntry: -#ifdef DEBUG_USB_HOST - NotifyFailSetDevTblEntry(); - goto Fail; -#endif + //FailSetDevTblEntry: + //#ifdef DEBUG_USB_HOST + // NotifyFailSetDevTblEntry(); + // goto Fail; + //#endif -//FailGetConfDescr: -//#ifdef DEBUG_USB_HOST -// NotifyFailGetConfDescr(); -// goto Fail; -//#endif + //FailGetConfDescr: + //#ifdef DEBUG_USB_HOST + // NotifyFailGetConfDescr(); + // goto Fail; + //#endif FailSetConfDescr: #ifdef DEBUG_USB_HOST @@ -450,6 +467,7 @@ Fail: NotifyFail(rcode); #endif Release(); + return rcode; } @@ -463,7 +481,8 @@ void HIDBoot::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t bIfaceNum = iface; if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) { - uint8_t index = bNumEP;//epInterruptInIndex; //+ bNumEP; + + uint8_t index = bNumEP; //epInterruptInIndex; //+ bNumEP; // Fill in the endpoint info structure epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); @@ -485,6 +504,7 @@ uint8_t HIDBoot::Release() { bAddress = 0; qNextPollTime = 0; bPollEnable = false; + return 0; } @@ -499,7 +519,7 @@ uint8_t HIDBoot::Poll() { qNextPollTime = millis() + 10; // To-do: optimize manually, getting rid of the loop - for(uint8_t i = 0; i < epMUL; i++) { + for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) { const uint8_t const_buff_len = 16; uint8_t buf[const_buff_len]; @@ -514,11 +534,11 @@ uint8_t HIDBoot::Poll() { pRptParser[i]->Parse((HID*)this, 0, (uint8_t) read, buf); #if 0 // Set this to 1 to print the incoming data - for (uint8_t i=0; i < read; i++) { + for(uint8_t i = 0; i < read; i++) { PrintHex (buf[i], 0x80); USB_HOST_SERIAL.write(' '); } - if (read) + if(read) USB_HOST_SERIAL.println(); #endif } else { diff --git a/hiduniversal.cpp b/hiduniversal.cpp index b669e6bf..9cbd09c4 100644 --- a/hiduniversal.cpp +++ b/hiduniversal.cpp @@ -148,7 +148,7 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) { return rcode; } - delay( 2 ); //per USB 2.0 sect.9.2.6.3 + //delay(2); //per USB 2.0 sect.9.2.6.3 USBTRACE2("Addr:", bAddress);