Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix compatibility with hubs and HID devices #6

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions src/BTD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<USB_DEVICE_DESCRIPTOR*>(buf);
uint8_t rcode;
uint32_t rcode;
UsbDeviceDefinition *p = NULL;
EpInfo *oldep_ptr = NULL;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion src/PS3USB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<USB_DEVICE_DESCRIPTOR*>(buf);
uint8_t rcode;
uint32_t rcode;
UsbDeviceDefinition *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
Expand Down Expand Up @@ -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);
Expand Down
47 changes: 28 additions & 19 deletions src/Usb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
}

/*
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 6 additions & 5 deletions src/UsbCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ typedef MAX3421e<P20, P19> 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

Expand Down Expand Up @@ -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)
Expand Down
11 changes: 10 additions & 1 deletion src/XBOXOLD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<USB_DEVICE_DESCRIPTOR*>(buf);
uint8_t rcode;
uint32_t rcode;
UsbDeviceDefinition *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
Expand Down Expand Up @@ -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);
Expand Down
17 changes: 13 additions & 4 deletions src/XBOXONE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<USB_DEVICE_DESCRIPTOR*>(buf);
uint8_t rcode;
uint32_t rcode;
UsbDeviceDefinition *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID, VID;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -292,15 +301,15 @@ uint32_t XBOXONE::Release() {
}

uint32_t XBOXONE::Poll() {
uint8_t rcode = 0;
uint32_t rcode = 0;

if(!bPollEnable)
return 0;

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
Expand Down Expand Up @@ -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<uint8_t > (rcode, 0x80);
Expand Down
6 changes: 3 additions & 3 deletions src/XBOXRECV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<USB_DEVICE_DESCRIPTOR*>(buf);
uint8_t rcode;
uint32_t rcode;
UsbDeviceDefinition *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID, VID;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
11 changes: 10 additions & 1 deletion src/XBOXUSB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<USB_DEVICE_DESCRIPTOR*>(buf);
uint8_t rcode;
uint32_t rcode;
UsbDeviceDefinition *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/adk.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class ADK : public USBDeviceConfig, public UsbConfigXtracter {
return bAddress;
};

virtual uint32_t isReady() {
virtual bool isReady() {
return ready;
};

Expand Down
16 changes: 13 additions & 3 deletions src/cdc_XR21B1411.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<USB_DEVICE_DESCRIPTOR*>(buf);

uint8_t rcode;
uint32_t rcode;
UsbDeviceDefinition *p = NULL;
EpInfo *oldep_ptr = NULL;
uint8_t num_of_conf; // number of configurations
Expand Down Expand Up @@ -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();
Expand Down
Loading