diff --git a/src/BTD.cpp b/src/BTD.cpp index 9eecf6e..85201a7 100644 --- a/src/BTD.cpp +++ b/src/BTD.cpp @@ -49,7 +49,7 @@ uint32_t BTD::ConfigureDevice(uint32_t parent, uint32_t port, uint32_t lowspeed) const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; @@ -129,12 +129,27 @@ uint32_t BTD::ConfigureDevice(uint32_t parent, uint32_t port, uint32_t lowspeed) if(rcode != hrJERR) rcode = USB_ERROR_FailGetDevDescr; #endif + +//Fail: + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nBTD Config Failed, error code: "), 0x80); + NotifyFail(rcode); +#endif Release(); return rcode; }; uint32_t BTD::Init(uint32_t parent __attribute__((unused)), uint32_t port __attribute__((unused)), uint32_t lowspeed) { - uint8_t rcode; + uint32_t rcode; uint8_t num_of_conf = epInfo[1].epAddr; // Number of configurations epInfo[1].epAddr = 0; @@ -401,7 +416,7 @@ void BTD::disconnect() { void BTD::HCI_event_task() { uint16_t length = BULK_MAXPKTSIZE; // Request more than 16 bytes anyway, the inTransfer routine will take care of this - uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf, pollInterval); // Input on endpoint 1 + uint32_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf, pollInterval); // Input on endpoint 1 if(!rcode || rcode == USB_ERRORFLOW) { // Check for errors switch(hcibuf[0]) { // Switch on event type @@ -922,7 +937,7 @@ void BTD::HCI_task() { void BTD::ACL_event_task() { uint16_t length = BULK_MAXPKTSIZE; - uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &length, l2capinbuf, pollInterval); // Input on endpoint 2 + uint32_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &length, l2capinbuf, pollInterval); // Input on endpoint 2 if(!rcode) { // Check for errors if(length > 0) { // Check if any data was read @@ -1232,7 +1247,7 @@ void BTD::L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t for(uint16_t i = 0; i < nbytes; i++) // L2CAP C-frame buf[8 + i] = data[i]; - uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf); + uint32_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf); if(rcode) { delay(100); // This small delay prevents it from overflowing if it fails #ifdef DEBUG_USB_HOST diff --git a/src/PS3USB.cpp b/src/PS3USB.cpp index 11187bd..eaa469a 100644 --- a/src/PS3USB.cpp +++ b/src/PS3USB.cpp @@ -48,7 +48,7 @@ bPollEnable(false) // don't start polling before dongle is connected uint32_t PS3USB::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint16_t PID; @@ -251,6 +251,15 @@ uint32_t PS3USB::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; Fail: + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80); NotifyFail(rcode); diff --git a/src/Usb.cpp b/src/Usb.cpp index 9265f6e..2b8773c 100644 --- a/src/Usb.cpp +++ b/src/Usb.cpp @@ -635,7 +635,7 @@ uint32_t USBHost::DefaultAddressing(uint32_t parent, uint32_t port, uint32_t low p0->lowspeed = (lowspeed) ? 1 : 0; // Allocate new address according to device class - uint32_t bAddress = addrPool.AllocAddress(parent, 0, port); + uint8_t bAddress = addrPool.AllocAddress(parent, 0, port); if(!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; @@ -665,41 +665,51 @@ uint32_t USBHost::AttemptConfig(uint32_t driver, uint32_t parent, uint32_t port, again: uint32_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed); if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) { - if(parent == 0) { - // Send a bus reset on the root interface. - //regWr(rHCTL, bmBUSRST); //issue bus reset - UHD_BusReset(); - delay(102); // delay 102ms, compensate for clock inaccuracy. - } else { - // reset parent port - devConfig[parent]->ResetHubPort(port); - } - } else if(rcode != 0x00/*hrJERR*/ && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works + ResetPort(parent, port); + } else if(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED) { + goto failed; + } else if(rcode == USB_ERROR_TRANSFER_TIMEOUT || rcode == USB_ERRORTIMEOUT) { + goto failed; + } else if(rcode != 0x00/*hrJERR*/ && retries < USB_RETRY_LIMIT) { // Some devices returns this when plugged in - trying to initialize the device again usually works delay(100); retries++; goto again; } else if(rcode) - return rcode; + goto failed; rcode = devConfig[driver]->Init(parent, port, lowspeed); - if(rcode != 0x00/*hrJERR*/ && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works + if(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED) { + goto failed; + } else if(rcode == USB_ERROR_TRANSFER_TIMEOUT || rcode == USB_ERRORTIMEOUT) { + goto failed; + } else if(rcode != 0x00/*hrJERR*/ && retries < USB_RETRY_LIMIT) { // Some devices returns this when plugged in - trying to initialize the device again usually works delay(100); retries++; goto again; } +failed: if(rcode) { // Issue a bus reset, because the device may be in a limbo state + ResetPort(parent, port); + } + return rcode; +} + +void USBHost::ResetPort(uint32_t parent, uint32_t port) { if(parent == 0) { // Send a bus reset on the root interface. - //regWr(rHCTL, bmBUSRST); //issue bus reset UHD_BusReset(); - delay(102); // delay 102ms, compensate for clock inaccuracy. + while( !Is_uhd_reset_sent() ) {} + uhd_ack_reset_sent(); // Clear Bus Reset flag } else { - // reset parent port - devConfig[parent]->ResetHubPort(port); + for (uint8_t i = 0; i < USB_NUMDEVICES; i++) { + if (devConfig[i] && devConfig[i]->GetAddress() == parent) { + devConfig[i]->ResetHubPort(port); + return; + } } } - return rcode; + delay(102); // delay 102ms, compensate for clock inaccuracy. } /* @@ -743,7 +753,6 @@ uint32_t USBHost::AttemptConfig(uint32_t driver, uint32_t parent, uint32_t port, * */ uint32_t USBHost::Configuring(uint32_t parent, uint32_t port, uint32_t lowspeed) { - //uint32_t bAddress = 0; //printf("Configuring: parent = %i, port = %i\r\n", parent, port); uint32_t devConfigIndex; uint32_t rcode = 0; diff --git a/src/UsbCore.h b/src/UsbCore.h index abc06f8..2e5972f 100644 --- a/src/UsbCore.h +++ b/src/UsbCore.h @@ -89,12 +89,12 @@ typedef MAX3421e MAX3421E; // Balanduino #define USB_ERROR_FailGetConfDescr 0xE3 #define USB_ERROR_TRANSFER_TIMEOUT 0xFF -#define USB_XFER_TIMEOUT 10000 //30000 // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec -//#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. 0 means NAKs are not counted -#define USB_RETRY_LIMIT 3 // 3 retry limit for a transfer -#define USB_SETTLE_DELAY 200 //settle delay in milliseconds +#define USB_XFER_TIMEOUT 1000 // USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec +//#define USB_NAK_LIMIT 32000 // NAK limit for a transfer. 0 means NAKs are not counted +#define USB_RETRY_LIMIT 3 // retry limit for a transfer +#define USB_SETTLE_DELAY 200 // settle delay in milliseconds -#define USB_NUMDEVICES 16 //number of USB devices +#define USB_NUMDEVICES 16 // number of USB devices //#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller #define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms @@ -258,6 +258,7 @@ class USBHost { uint32_t OutTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t nbytes, uint8_t *data); uint32_t InTransfer(EpInfo *pep, uint32_t nak_limit, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval = 0); uint32_t AttemptConfig(uint32_t driver, uint32_t parent, uint32_t port, uint32_t lowspeed); + void ResetPort(uint32_t parent, uint32_t port); }; #if 0 //defined(USB_METHODS_INLINE) diff --git a/src/XBOXOLD.cpp b/src/XBOXOLD.cpp index cf4a693..9093b8a 100644 --- a/src/XBOXOLD.cpp +++ b/src/XBOXOLD.cpp @@ -63,7 +63,7 @@ bPollEnable(false) { // don't start polling before dongle is connected uint32_t XBOXOLD::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint16_t PID; @@ -225,6 +225,15 @@ uint32_t XBOXOLD::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; Fail: + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nXbox Init Failed, error code: "), 0x80); NotifyFail(rcode); diff --git a/src/XBOXONE.cpp b/src/XBOXONE.cpp index c17c609..7201348 100644 --- a/src/XBOXONE.cpp +++ b/src/XBOXONE.cpp @@ -47,7 +47,7 @@ bPollEnable(false) { // don't start polling before dongle is connected uint32_t XBOXONE::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint16_t PID, VID; @@ -228,6 +228,15 @@ uint32_t XBOXONE::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; Fail: + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nXbox One Init Failed, error code: "), 0x80); NotifyFail(rcode); @@ -292,7 +301,7 @@ uint32_t XBOXONE::Release() { } uint32_t XBOXONE::Poll() { - uint8_t rcode = 0; + uint32_t rcode = 0; if(!bPollEnable) return 0; @@ -300,7 +309,7 @@ uint32_t XBOXONE::Poll() { if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) { // Do not poll if shorter than polling interval qNextPollTime = (uint32_t)millis() + pollInterval; // Set new poll time uint16_t length = (uint16_t)epInfo[ XBOX_ONE_INPUT_PIPE ].maxPktSize; // Read the maximum packet size from the endpoint - uint8_t rcode = pUsb->inTransfer((uint32_t)bAddress, epInfo[ XBOX_ONE_INPUT_PIPE ].epAddr, &length, readBuf, pollInterval); + uint32_t rcode = pUsb->inTransfer((uint32_t)bAddress, epInfo[ XBOX_ONE_INPUT_PIPE ].epAddr, &length, readBuf, pollInterval); if(!rcode) { readReport(); #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller @@ -406,7 +415,7 @@ int16_t XBOXONE::getAnalogHat(AnalogHatEnum a) { /* Xbox Controller commands */ uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) { data[2] = cmdCounter++; // Increment the output command counter - uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_ONE_OUTPUT_PIPE ].epAddr, nbytes, data); + uint32_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_ONE_OUTPUT_PIPE ].epAddr, nbytes, data); #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nXboxCommand, Return: "), 0x80); D_PrintHex (rcode, 0x80); diff --git a/src/XBOXRECV.cpp b/src/XBOXRECV.cpp index f29bade..30dae4d 100644 --- a/src/XBOXRECV.cpp +++ b/src/XBOXRECV.cpp @@ -42,7 +42,7 @@ uint32_t XBOXRECV::ConfigureDevice(uint32_t parent, uint32_t port, uint32_t lows const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint16_t PID, VID; @@ -136,7 +136,7 @@ uint32_t XBOXRECV::ConfigureDevice(uint32_t parent, uint32_t port, uint32_t lows }; uint32_t XBOXRECV::Init(uint32_t parent __attribute__((unused)), uint32_t port __attribute__((unused)), uint32_t lowspeed) { - uint8_t rcode; + uint32_t rcode; AddressPool &addrPool = pUsb->GetAddressPool(); #ifdef EXTRADEBUG @@ -470,7 +470,7 @@ uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) { void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) { #ifdef EXTRADEBUG - uint8_t rcode; + uint32_t rcode; #endif uint8_t outputPipe; switch(controller) { diff --git a/src/XBOXUSB.cpp b/src/XBOXUSB.cpp index a1e2124..1b1b16d 100644 --- a/src/XBOXUSB.cpp +++ b/src/XBOXUSB.cpp @@ -40,7 +40,7 @@ bPollEnable(false) { // don't start polling before dongle is connected uint32_t XBOXUSB::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint16_t PID; @@ -213,6 +213,15 @@ uint32_t XBOXUSB::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; Fail: + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80); NotifyFail(rcode); diff --git a/src/adk.h b/src/adk.h index 8811795..3d60fd9 100644 --- a/src/adk.h +++ b/src/adk.h @@ -116,7 +116,7 @@ class ADK : public USBDeviceConfig, public UsbConfigXtracter { return bAddress; }; - virtual uint32_t isReady() { + virtual bool isReady() { return ready; }; diff --git a/src/cdc_XR21B1411.cpp b/src/cdc_XR21B1411.cpp index 66d5557..b798045 100644 --- a/src/cdc_XR21B1411.cpp +++ b/src/cdc_XR21B1411.cpp @@ -28,7 +28,7 @@ uint32_t XR21B1411::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t num_of_conf; // number of configurations @@ -200,10 +200,20 @@ uint32_t XR21B1411::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); + goto Fail; +Fail: #endif - + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST -Fail: + Notify(PSTR("\r\nXR21B1411 Init Failed, error code: "), 0x80); NotifyFail(rcode); #endif Release(); diff --git a/src/cdcacm.cpp b/src/cdcacm.cpp index ea02f79..3442181 100644 --- a/src/cdcacm.cpp +++ b/src/cdcacm.cpp @@ -51,7 +51,7 @@ uint32_t ACM::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t num_of_conf; // number of configurations @@ -218,10 +218,20 @@ uint32_t ACM::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); + goto Fail; +Fail: #endif - + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST -Fail: + Notify(PSTR("\r\nACM Init Failed, error code: "), 0x80); NotifyFail(rcode); #endif Release(); @@ -271,7 +281,7 @@ uint32_t ACM::Release() { } uint32_t ACM::Poll() { - //uint8_t rcode = 0; + //uint32_t rcode = 0; //if(!bPollEnable) // return 0; //return rcode; diff --git a/src/cdcftdi.cpp b/src/cdcftdi.cpp index 51fb811..085a063 100644 --- a/src/cdcftdi.cpp +++ b/src/cdcftdi.cpp @@ -43,7 +43,7 @@ uint32_t FTDI::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; @@ -213,8 +213,20 @@ uint32_t FTDI::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); - + goto Fail; Fail: +#endif + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nFTDI Init Failed, error code: "), 0x80); NotifyFail(rcode); #endif Release(); @@ -260,7 +272,7 @@ uint32_t FTDI::Release() { } uint32_t FTDI::Poll() { - uint8_t rcode = 0; + uint32_t rcode = 0; //if (!bPollEnable) // return 0; diff --git a/src/cdcprolific.cpp b/src/cdcprolific.cpp index 1c72757..86c8594 100644 --- a/src/cdcprolific.cpp +++ b/src/cdcprolific.cpp @@ -26,7 +26,7 @@ uint32_t PL2303::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t num_of_conf; // number of configurations @@ -220,10 +220,20 @@ uint32_t PL2303::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); + goto Fail; +Fail: #endif - + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST -Fail: + Notify(PSTR("\r\nPL2303 Init Failed, error code: "), 0x80); NotifyFail(rcode); #endif Release(); @@ -232,7 +242,7 @@ uint32_t PL2303::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { //uint8_t PL::Poll() //{ -// uint8_t rcode = 0; +// uint32_t rcode = 0; // // //if (!bPollEnable) // // return 0; diff --git a/src/hid.cpp b/src/hid.cpp index 40b08dd..bfe12a9 100644 --- a/src/hid.cpp +++ b/src/hid.cpp @@ -24,7 +24,7 @@ uint32_t HID::GetReportDescr(uint32_t ep, USBReadParser *parser) { const uint8_t constBufLen = 64; uint8_t buf[constBufLen]; - uint8_t rcode = pUsb->ctrlReq(bAddress, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, + uint32_t rcode = pUsb->ctrlReq(bAddress, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, 128, constBufLen, buf, (USBReadParser*)parser); //return ((rcode != hrSTALL) ? rcode : 0); @@ -35,7 +35,7 @@ uint32_t HID::GetReportDescr(uint32_t wIndex, USBReadParser *parser) { const uint8_t constBufLen = 128; uint8_t buf[constBufLen]; - uint8_t rcode = pUsb->ctrlReq(bAddress, 0x00, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, + uint32_t rcode = pUsb->ctrlReq(bAddress, 0x00, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, wIndex, 128, constBufLen, buf, (USBReadParser*)parser); //return ((rcode != hrSTALL) ? rcode : 0); diff --git a/src/hid.h b/src/hid.h index cc376d8..8634e3e 100644 --- a/src/hid.h +++ b/src/hid.h @@ -167,6 +167,7 @@ class HID : public USBDeviceConfig, public UsbConfigXtracter { return pUsb; }; virtual uint32_t SetReportParser(uint32_t id, HIDReportParser *prs); + virtual bool isReady(); uint32_t SetProtocol(uint32_t iface, uint32_t protocol); uint32_t GetProtocol(uint32_t iface, uint8_t* dataptr); diff --git a/src/hidboot.h b/src/hidboot.h index 21e0860..680b1fc 100644 --- a/src/hidboot.h +++ b/src/hidboot.h @@ -221,6 +221,10 @@ class HIDBoot : public HID //public USBDeviceConfig, public UsbConfigXtracter return bAddress; }; + virtual bool isReady() { + return bPollEnable; + }; + // UsbConfigXtracter implementation virtual void EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); }; @@ -431,7 +435,7 @@ uint32_t HIDBoot::Init(uint32_t parent, uint32_t port, uint32_t l //USBTRACE2("setEpInfoEntry returned ", rcode); USBTRACE2("Cnf:", bConfNum); - delay(1000); + delay(200); // Give time for address change // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); @@ -439,7 +443,7 @@ uint32_t HIDBoot::Init(uint32_t parent, uint32_t port, uint32_t l if(rcode) goto FailSetConfDescr; - delay(1000); + delay(200); // let things settle USBTRACE2("bIfaceNum:", bIfaceNum); USBTRACE2("bNumIface:", bNumIface); @@ -513,6 +517,15 @@ uint32_t HIDBoot::Init(uint32_t parent, uint32_t port, uint32_t l //#endif Fail: + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST NotifyFail(rcode); #endif diff --git a/src/hidcomposite.cpp b/src/hidcomposite.cpp index eca5640..666568d 100644 --- a/src/hidcomposite.cpp +++ b/src/hidcomposite.cpp @@ -97,7 +97,7 @@ uint32_t HIDComposite::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t len = 0; @@ -239,7 +239,7 @@ uint32_t HIDComposite::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0); // if(rcode && rcode != hrSTALL) -// goto FailSetIdle; +// goto Fail; } USBTRACE("HU configured\r\n"); @@ -271,16 +271,18 @@ uint32_t HIDComposite::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { #ifdef DEBUG_USB_HOST NotifyFailSetConfDescr(); goto Fail; +Fail: #endif - - -FailSetIdle: -#ifdef DEBUG_USB_HOST - USBTRACE("SetIdle:"); -#endif - + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST -Fail: NotifyFail(rcode); #endif Release(); @@ -355,7 +357,7 @@ void HIDComposite::ZeroMemory(uint8_t len, uint8_t *buf) { } uint32_t HIDComposite::Poll() { - uint8_t rcode = 0; + uint32_t rcode = 0; if(!bPollEnable) return 0; @@ -375,7 +377,7 @@ uint32_t HIDComposite::Poll() { ZeroMemory(constBuffLen, buf); - uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf); + uint32_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf); if(rcode) { if(rcode != USB_ERRORFLOW) diff --git a/src/hiduniversal.cpp b/src/hiduniversal.cpp index 21d833e..103abd1 100644 --- a/src/hiduniversal.cpp +++ b/src/hiduniversal.cpp @@ -99,7 +99,7 @@ uint32_t HIDUniversal::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { uint8_t buf[constBufSize]; USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); - uint8_t rcode; + uint32_t rcode; UsbDeviceDefinition *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t len = 0; @@ -278,10 +278,19 @@ uint32_t HIDUniversal::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { FailSetIdle: #ifdef DEBUG_USB_HOST USBTRACE("SetIdle:"); + goto Fail; +Fail: #endif - + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; #ifdef DEBUG_USB_HOST -Fail: NotifyFail(rcode); #endif Release(); @@ -385,7 +394,7 @@ uint32_t HIDUniversal::Poll() { ZeroMemory(constBuffLen, buf); - uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf); + uint32_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf); if(rcode) { if(rcode != USB_ERRORFLOW/*hrNAK*/) diff --git a/src/hiduniversal.h b/src/hiduniversal.h index 7d6afc8..a30718d 100644 --- a/src/hiduniversal.h +++ b/src/hiduniversal.h @@ -94,7 +94,7 @@ class HIDUniversal : public HID { return bAddress; }; - virtual uint32_t isReady() { + virtual bool isReady() { return bPollEnable; }; diff --git a/src/parsetools.h b/src/parsetools.h index d463358..d7d603e 100644 --- a/src/parsetools.h +++ b/src/parsetools.h @@ -24,7 +24,7 @@ e-mail : support@circuitsathome.com //#include "Arduino.h" struct MultiValueBuffer { - uint8_t valueSize; + uint8_t valueSize = 0; void *pValue; }; diff --git a/src/usbhub.cpp b/src/usbhub.cpp index 0131725..7a0eaba 100644 --- a/src/usbhub.cpp +++ b/src/usbhub.cpp @@ -212,11 +212,29 @@ uint32_t USBHub::Init(uint32_t parent, uint32_t port, uint32_t lowspeed) { goto Fail; Fail: + // Reset address + if (bAddress) { + pUsb->setAddr(bAddress, 0, 0); + } + // Reset endpoint info + p->epinfo->epAddr = 0; + p->epinfo->maxPktSize = 8; + p->epinfo->epAttribs = 0; + p->epinfo->bmNakPower = USB_NAK_MAX_POWER; USBTRACE("...FAIL\r\n"); return rcode; } uint32_t USBHub::Release() { + UsbDeviceAddress a; + a.devAddress = 0; + a.bmHub = 0; + a.bmParent = bAddress; + for (uint8_t j = 1; j <= bNbrPorts; j++) { + a.bmAddress = j; + pUsb->ReleaseDevice(a.devAddress); + } + pUsb->GetAddressPool().FreeAddress(bAddress); if(bAddress == 0x41) @@ -312,21 +330,25 @@ uint32_t USBHub::CheckHubStatus() { void USBHub::ResetHubPort(uint32_t port) { HubEvent evt; evt.bmEvent = 0; - uint8_t rcode; + uint32_t rcode; ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0); ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0); SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0); - - for(int i = 0; i < 3; i++) { + for(int i = 0; i < USB_RETRY_LIMIT; i++) { rcode = GetPortStatus(port, 4, evt.evtBuff); - if(rcode) break; // Some kind of error, bail. + if(rcode) { // Some kind of error, bail. + USBTRACE2("Hub port reset failed, rcode: ", rcode); + break; + } if(evt.bmEvent == bmHUB_PORT_EVENT_RESET_COMPLETE || evt.bmEvent == bmHUB_PORT_EVENT_LS_RESET_COMPLETE) { + USBTRACE("Hub port reset complete\r\n"); break; } delay(100); // simulate polling. } + ClearPortFeature(HUB_FEATURE_C_PORT_RESET, port, 0); ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0); delay(20); @@ -340,6 +362,8 @@ uint32_t USBHub::PortStatusChange(uint32_t port, HubEvent &evt) { if(bResetInitiated) return 0; + USBTRACE("Hub device connected\r\n"); + ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0); ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0); SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0); @@ -352,6 +376,8 @@ uint32_t USBHub::PortStatusChange(uint32_t port, HubEvent &evt) { ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0); bResetInitiated = false; + USBTRACE("Hub device disconnected\r\n"); + UsbDeviceAddress a; a.devAddress = 0; a.bmHub = 0; @@ -368,9 +394,9 @@ uint32_t USBHub::PortStatusChange(uint32_t port, HubEvent &evt) { delay(20); - a.devAddress = bAddress; + USBTRACE("Hub port reset complete\r\n"); - pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED)); + pUsb->Configuring(bAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED)); bResetInitiated = false; break; @@ -379,7 +405,7 @@ uint32_t USBHub::PortStatusChange(uint32_t port, HubEvent &evt) { } void PrintHubPortStatus(USBHub *hubptr, uint32_t /* addr */, uint32_t port, uint32_t print_changes) { - uint8_t rcode = 0; + uint32_t rcode = 0; HubEvent evt; rcode = hubptr->GetPortStatus(port, 4, evt.evtBuff);