Fix hidboot not allocating or checking properly on mouse.

Removal of duplicate code: Force all drivers to delay after setting address.
This commit is contained in:
Andrew J. Kroll 2013-12-18 21:58:24 -05:00
parent fcaef6f5a2
commit 77efe42a71
7 changed files with 68 additions and 44 deletions

View file

@ -129,7 +129,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nAddr: "), 0x80); Notify(PSTR("\r\nAddr: "), 0x80);
D_PrintHex<uint8_t > (bAddress, 0x80); D_PrintHex<uint8_t > (bAddress, 0x80);
#endif #endif
delay(300); // Spec says you should wait at least 200ms //delay(300); // Spec says you should wait at least 200ms
p->lowspeed = false; p->lowspeed = false;

16
Usb.cpp
View file

@ -447,7 +447,7 @@ void USB::Task(void) //USB state machine
case LSHOST: case LSHOST:
lowspeed = true; lowspeed = true;
//intentional fallthrough //intentional fallthrough
case FSHOST: //attached case FSHOST: //attached
if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
delay = millis() + USB_SETTLE_DELAY; delay = millis() + USB_SETTLE_DELAY;
@ -503,11 +503,11 @@ void USB::Task(void) //USB state machine
break; break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET: case USB_ATTACHED_SUBSTATE_WAIT_RESET:
if (delay < millis()) usb_task_state = USB_STATE_CONFIGURING; 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: case USB_STATE_CONFIGURING:
//Serial.print("\r\nConf.LS: "); //Serial.print("\r\nConf.LS: ");
//Serial.println(lowspeed, HEX); //Serial.println(lowspeed, HEX);
rcode = Configuring(0, 0, lowspeed); rcode = Configuring(0, 0, lowspeed);
@ -748,7 +748,7 @@ uint8_t USB::ReleaseDevice(uint8_t addr) {
return 0; return 0;
for (uint8_t i = 0; i < USB_NUMDEVICES; i++) { for (uint8_t i = 0; i < USB_NUMDEVICES; i++) {
if(!devConfig[i]) continue; if (!devConfig[i]) continue;
if (devConfig[i]->GetAddress() == addr) if (devConfig[i]->GetAddress() == addr)
return devConfig[i]->Release(); 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 //set address
uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) { 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 //set configuration

View file

@ -145,7 +145,7 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nAddr: "), 0x80); Notify(PSTR("\r\nAddr: "), 0x80);
D_PrintHex<uint8_t > (bAddress, 0x80); D_PrintHex<uint8_t > (bAddress, 0x80);
#endif #endif
delay(300); // Spec says you should wait at least 200ms //delay(300); // Spec says you should wait at least 200ms
p->lowspeed = false; p->lowspeed = false;

View file

@ -133,7 +133,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nAddr: "), 0x80); Notify(PSTR("\r\nAddr: "), 0x80);
D_PrintHex<uint8_t > (bAddress, 0x80); D_PrintHex<uint8_t > (bAddress, 0x80);
#endif #endif
delay(300); // Spec says you should wait at least 200ms //delay(300); // Spec says you should wait at least 200ms
p->lowspeed = false; p->lowspeed = false;

View file

@ -128,7 +128,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//USBTRACE2("\r\nAddr:", bAddress); //USBTRACE2("\r\nAddr:", bAddress);
// Spec says you should wait at least 200ms. // Spec says you should wait at least 200ms.
delay(300); //delay(300);
p->lowspeed = false; p->lowspeed = false;

View file

@ -28,7 +28,6 @@ e-mail : support@circuitsathome.com
#define UHS_HID_BOOT_KEY_ZERO2 0x62 #define UHS_HID_BOOT_KEY_ZERO2 0x62
#define UHS_HID_BOOT_KEY_PERIOD 0x63 #define UHS_HID_BOOT_KEY_PERIOD 0x63
struct MOUSEINFO { struct MOUSEINFO {
struct { struct {
@ -168,15 +167,16 @@ protected:
}; };
}; };
#define totalEndpoints (((BOOT_PROTOCOL & HID_PROTOCOL_KEYBOARD)? 2 : 0)+((BOOT_PROTOCOL & HID_PROTOCOL_MOUSE)? 1 : 0)) #define bitsEndpoints(p) (((p & HID_PROTOCOL_KEYBOARD)? 2 : 0)+((p & HID_PROTOCOL_MOUSE)? 1 : 0))
#define epMUL (((BOOT_PROTOCOL & HID_PROTOCOL_KEYBOARD)? 1 : 0)+((BOOT_PROTOCOL & 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 #define HID_MAX_HID_CLASS_DESCRIPTORS 5
template <const uint8_t BOOT_PROTOCOL> template <const uint8_t BOOT_PROTOCOL>
class HIDBoot : public HID //public USBDeviceConfig, public UsbConfigXtracter class HIDBoot : public HID //public USBDeviceConfig, public UsbConfigXtracter
{ {
EpInfo epInfo[totalEndpoints]; EpInfo epInfo[totalEndpoints(BOOT_PROTOCOL)];
HIDReportParser *pRptParser[epMUL]; HIDReportParser *pRptParser[epMUL(BOOT_PROTOCOL)];
uint8_t bConfNum; // configuration number uint8_t bConfNum; // configuration number
uint8_t bIfaceNum; // Interface Number uint8_t bIfaceNum; // Interface Number
@ -219,7 +219,7 @@ qNextPollTime(0),
bPollEnable(false) { bPollEnable(false) {
Initialize(); Initialize();
for(uint8_t i = 0; i < epMUL; i++) { for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) {
pRptParser[i] = NULL; pRptParser[i] = NULL;
} }
if(pUsb) if(pUsb)
@ -228,7 +228,7 @@ bPollEnable(false) {
template <const uint8_t BOOT_PROTOCOL> template <const uint8_t BOOT_PROTOCOL>
void HIDBoot<BOOT_PROTOCOL>::Initialize() { void HIDBoot<BOOT_PROTOCOL>::Initialize() {
for(uint8_t i = 0; i < totalEndpoints; i++) { for(int i = 0; i < totalEndpoints(BOOT_PROTOCOL); i++) {
epInfo[i].epAddr = 0; epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8; epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0; epInfo[i].epAttribs = 0;
@ -314,6 +314,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
USBTRACE2("setAddr:", rcode); USBTRACE2("setAddr:", rcode);
return rcode; return rcode;
} }
delay(2); //per USB 2.0 sect.9.2.6.3
USBTRACE2("Addr:", bAddress); USBTRACE2("Addr:", bAddress);
@ -335,15 +336,22 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); //rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if(rcode) //if(rcode)
goto FailSetDevTblEntry; // goto FailSetDevTblEntry;
//USBTRACE2("NC:", num_of_conf); //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. // GCC will optimize unused stuff away.
if(BOOT_PROTOCOL & HID_PROTOCOL_KEYBOARD) { if(BOOT_PROTOCOL & HID_PROTOCOL_KEYBOARD) {
USBTRACE("HID_PROTOCOL_KEYBOARD\r\n");
for(uint8_t i = 0; i < num_of_conf; i++) { for(uint8_t i = 0; i < num_of_conf; i++) {
ConfigDescParser< ConfigDescParser<
USB_CLASS_HID, USB_CLASS_HID,
@ -351,46 +359,55 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
HID_PROTOCOL_KEYBOARD, HID_PROTOCOL_KEYBOARD,
CP_MASK_COMPARE_ALL> confDescrParserA(this); CP_MASK_COMPARE_ALL> confDescrParserA(this);
if(bNumEP == totalEndpoints)
break;
pUsb->getConfDescr(bAddress, 0, i, &confDescrParserA); pUsb->getConfDescr(bAddress, 0, i, &confDescrParserA);
if(bNumEP == (uint8_t) (bitsEndpoints(BOOT_PROTOCOL)))
break;
} }
} }
// GCC will optimize unused stuff away. // GCC will optimize unused stuff away.
if(BOOT_PROTOCOL & HID_PROTOCOL_MOUSE) { if(BOOT_PROTOCOL & HID_PROTOCOL_MOUSE) {
USBTRACE("HID_PROTOCOL_MOUSE\r\n");
for(uint8_t i = 0; i < num_of_conf; i++) { for(uint8_t i = 0; i < num_of_conf; i++) {
ConfigDescParser< ConfigDescParser<
USB_CLASS_HID, USB_CLASS_HID,
HID_BOOT_INTF_SUBCLASS, HID_BOOT_INTF_SUBCLASS,
HID_PROTOCOL_MOUSE, HID_PROTOCOL_MOUSE,
CP_MASK_COMPARE_ALL> confDescrParserB(this); CP_MASK_COMPARE_ALL> confDescrParserB(this);
if(bNumEP == totalEndpoints)
break;
pUsb->getConfDescr(bAddress, 0, i, &confDescrParserB); pUsb->getConfDescr(bAddress, 0, i, &confDescrParserB);
if(bNumEP > 1 /* (uint8_t) (totalEndpoints(BOOT_PROTOCOL))*/)
break;
} }
} }
USBTRACE2("bAddr:", bAddress); USBTRACE2("bAddr:", bAddress);
USBTRACE2("bNumEP:", bNumEP); USBTRACE2("bNumEP:", bNumEP);
USBTRACE2("totalEndpoints:", totalEndpoints); USBTRACE2("totalEndpoints:", (uint8_t) (bitsEndpoints(BOOT_PROTOCOL)));
if(bNumEP != totalEndpoints) { USBTRACE2("epMUL:", epMUL(BOOT_PROTOCOL));
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail; if(bNumEP != (uint8_t)(totalEndpoints(BOOT_PROTOCOL))) {
} rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail;
}
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
USBTRACE2("setEpInfoEntry returned ", rcode); USBTRACE2("setEpInfoEntry returned ", rcode);
USBTRACE2("Cnf:", bConfNum); USBTRACE2("Cnf:", bConfNum);
delay(1000);
// Set Configuration Value // Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum); rcode = pUsb->setConf(bAddress, 0, bConfNum);
if(rcode) if(rcode)
goto FailSetConfDescr; goto FailSetConfDescr;
delay(1000);
USBTRACE2("If:", bIfaceNum); USBTRACE2("If:", bIfaceNum);
rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL); rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
@ -416,17 +433,17 @@ FailGetDevDescr:
goto Fail; goto Fail;
#endif #endif
FailSetDevTblEntry: //FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST //#ifdef DEBUG_USB_HOST
NotifyFailSetDevTblEntry(); // NotifyFailSetDevTblEntry();
goto Fail; // goto Fail;
#endif //#endif
//FailGetConfDescr: //FailGetConfDescr:
//#ifdef DEBUG_USB_HOST //#ifdef DEBUG_USB_HOST
// NotifyFailGetConfDescr(); // NotifyFailGetConfDescr();
// goto Fail; // goto Fail;
//#endif //#endif
FailSetConfDescr: FailSetConfDescr:
#ifdef DEBUG_USB_HOST #ifdef DEBUG_USB_HOST
@ -450,6 +467,7 @@ Fail:
NotifyFail(rcode); NotifyFail(rcode);
#endif #endif
Release(); Release();
return rcode; return rcode;
} }
@ -463,7 +481,8 @@ void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t
bIfaceNum = iface; bIfaceNum = iface;
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) { 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 // Fill in the endpoint info structure
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
@ -485,6 +504,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Release() {
bAddress = 0; bAddress = 0;
qNextPollTime = 0; qNextPollTime = 0;
bPollEnable = false; bPollEnable = false;
return 0; return 0;
} }
@ -499,7 +519,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
qNextPollTime = millis() + 10; qNextPollTime = millis() + 10;
// To-do: optimize manually, getting rid of the loop // 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; const uint8_t const_buff_len = 16;
uint8_t buf[const_buff_len]; uint8_t buf[const_buff_len];
@ -514,11 +534,11 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
pRptParser[i]->Parse((HID*)this, 0, (uint8_t) read, buf); pRptParser[i]->Parse((HID*)this, 0, (uint8_t) read, buf);
#if 0 // Set this to 1 to print the incoming data #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<uint8_t > (buf[i], 0x80); PrintHex<uint8_t > (buf[i], 0x80);
USB_HOST_SERIAL.write(' '); USB_HOST_SERIAL.write(' ');
} }
if (read) if(read)
USB_HOST_SERIAL.println(); USB_HOST_SERIAL.println();
#endif #endif
} else { } else {

View file

@ -148,7 +148,7 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
return rcode; 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); USBTRACE2("Addr:", bAddress);