mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
fix some HUB related issues
This commit is contained in:
parent
d4ea5892c8
commit
ea63a6b537
4 changed files with 60 additions and 20 deletions
48
Usb.cpp
48
Usb.cpp
|
@ -581,6 +581,25 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
return 0;
|
||||
};
|
||||
|
||||
void USB::ResetHubPort(uint8_t parent, uint8_t port) {
|
||||
if (parent == 0) {
|
||||
// Send a bus reset on the root interface.
|
||||
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
||||
} else {
|
||||
for (uint8_t i = 0; i < USB_NUMDEVICES; i++) {
|
||||
if (devConfig[i]) {
|
||||
UsbDeviceAddress addr;
|
||||
addr.devAddress = devConfig[i]->GetAddress();
|
||||
if (addr.bmHub && addr.bmAddress == parent) {
|
||||
devConfig[i]->ResetHubPort(port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) {
|
||||
//printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
|
||||
uint8_t retries = 0;
|
||||
|
@ -588,14 +607,7 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo
|
|||
again:
|
||||
uint8_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
|
||||
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
||||
} else {
|
||||
// reset parent port
|
||||
devConfig[parent]->ResetHubPort(port);
|
||||
}
|
||||
ResetHubPort(parent, port);
|
||||
} else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
|
||||
delay(100);
|
||||
retries++;
|
||||
|
@ -611,14 +623,7 @@ again:
|
|||
}
|
||||
if(rcode) {
|
||||
// Issue a bus reset, because the device may be in a limbo state
|
||||
if(parent == 0) {
|
||||
// Send a bus reset on the root interface.
|
||||
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
||||
} else {
|
||||
// reset parent port
|
||||
devConfig[parent]->ResetHubPort(port);
|
||||
}
|
||||
ResetHubPort(parent, port);
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
@ -762,14 +767,23 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
}
|
||||
|
||||
uint8_t USB::ReleaseDevice(uint8_t addr) {
|
||||
UsbDeviceAddress a;
|
||||
if(!addr)
|
||||
return 0;
|
||||
|
||||
a.devAddress = addr;
|
||||
if(a.bmHub) {
|
||||
for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
|
||||
if(!devConfig[i]) continue;
|
||||
if(devConfig[i]->GetAddress() == addr)
|
||||
return devConfig[i]->Release();
|
||||
}
|
||||
} else {
|
||||
for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
|
||||
if(!devConfig[i]) continue;
|
||||
if(devConfig[i]->GetPortAddress() == addr)
|
||||
return devConfig[i]->Release();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,10 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
virtual uint8_t GetPortAddress() {
|
||||
return GetAddress();
|
||||
}
|
||||
|
||||
virtual void ResetHubPort(uint8_t port __attribute__((unused))) {
|
||||
return;
|
||||
} // Note used for hubs only!
|
||||
|
@ -274,6 +278,7 @@ private:
|
|||
uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit);
|
||||
uint8_t OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data);
|
||||
uint8_t InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval = 0);
|
||||
void ResetHubPort(uint8_t parent, uint8_t port);
|
||||
uint8_t AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed);
|
||||
};
|
||||
|
||||
|
|
20
usbhub.cpp
20
usbhub.cpp
|
@ -21,6 +21,7 @@ bool USBHub::bResetInitiated = false;
|
|||
USBHub::USBHub(USB *p) :
|
||||
pUsb(p),
|
||||
bAddress(0),
|
||||
bPortAddress(0),
|
||||
bNbrPorts(0),
|
||||
//bInitState(0),
|
||||
qNextPollTime(0),
|
||||
|
@ -104,6 +105,14 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
if(!bAddress)
|
||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||
|
||||
{
|
||||
UsbDeviceAddress a;
|
||||
a.devAddress = bAddress;
|
||||
a.bmHub = 0;
|
||||
a.bmAddress = port ? : 1;
|
||||
bPortAddress = a.devAddress;
|
||||
}
|
||||
|
||||
// Extract Max Packet Size from the device descriptor
|
||||
epInfo[0].maxPktSize = udd->bMaxPacketSize0;
|
||||
|
||||
|
@ -115,6 +124,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
p->epinfo = oldep_ptr;
|
||||
addrPool.FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
bPortAddress = 0;
|
||||
return rcode;
|
||||
}
|
||||
|
||||
|
@ -214,12 +224,22 @@ Fail:
|
|||
}
|
||||
|
||||
uint8_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)
|
||||
pUsb->SetHubPreMask();
|
||||
|
||||
bAddress = 0;
|
||||
bPortAddress = 0;
|
||||
bNbrPorts = 0;
|
||||
qNextPollTime = 0;
|
||||
bPollEnable = false;
|
||||
|
|
1
usbhub.h
1
usbhub.h
|
@ -169,6 +169,7 @@ class USBHub : USBDeviceConfig {
|
|||
EpInfo epInfo[2]; // interrupt endpoint info structure
|
||||
|
||||
uint8_t bAddress; // address
|
||||
uint8_t bPortAddress; // port address
|
||||
uint8_t bNbrPorts; // number of ports
|
||||
// uint8_t bInitState; // initialization state variable
|
||||
uint32_t qNextPollTime; // next poll time
|
||||
|
|
Loading…
Reference in a new issue