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
54
Usb.cpp
54
Usb.cpp
|
@ -581,6 +581,25 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
return 0;
|
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) {
|
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);
|
//printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
|
||||||
uint8_t retries = 0;
|
uint8_t retries = 0;
|
||||||
|
@ -588,14 +607,7 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo
|
||||||
again:
|
again:
|
||||||
uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
|
uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
|
||||||
if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
|
if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
|
||||||
if(parent == 0) {
|
ResetHubPort(parent, port);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
} else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
|
} else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
|
||||||
delay(100);
|
delay(100);
|
||||||
retries++;
|
retries++;
|
||||||
|
@ -611,14 +623,7 @@ again:
|
||||||
}
|
}
|
||||||
if(rcode) {
|
if(rcode) {
|
||||||
// Issue a bus reset, because the device may be in a limbo state
|
// Issue a bus reset, because the device may be in a limbo state
|
||||||
if(parent == 0) {
|
ResetHubPort(parent, port);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
@ -762,13 +767,22 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USB::ReleaseDevice(uint8_t addr) {
|
uint8_t USB::ReleaseDevice(uint8_t addr) {
|
||||||
|
UsbDeviceAddress a;
|
||||||
if(!addr)
|
if(!addr)
|
||||||
return 0;
|
return 0;
|
||||||
|
a.devAddress = addr;
|
||||||
for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
|
if(a.bmHub) {
|
||||||
if(!devConfig[i]) continue;
|
for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
|
||||||
if(devConfig[i]->GetAddress() == addr)
|
if(!devConfig[i]) continue;
|
||||||
|
if(devConfig[i]->GetAddress() == addr)
|
||||||
return devConfig[i]->Release();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,10 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual uint8_t GetPortAddress() {
|
||||||
|
return GetAddress();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void ResetHubPort(uint8_t port __attribute__((unused))) {
|
virtual void ResetHubPort(uint8_t port __attribute__((unused))) {
|
||||||
return;
|
return;
|
||||||
} // Note used for hubs only!
|
} // 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 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 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);
|
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);
|
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) :
|
USBHub::USBHub(USB *p) :
|
||||||
pUsb(p),
|
pUsb(p),
|
||||||
bAddress(0),
|
bAddress(0),
|
||||||
|
bPortAddress(0),
|
||||||
bNbrPorts(0),
|
bNbrPorts(0),
|
||||||
//bInitState(0),
|
//bInitState(0),
|
||||||
qNextPollTime(0),
|
qNextPollTime(0),
|
||||||
|
@ -104,6 +105,14 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
if(!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
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
|
// Extract Max Packet Size from the device descriptor
|
||||||
epInfo[0].maxPktSize = udd->bMaxPacketSize0;
|
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;
|
p->epinfo = oldep_ptr;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
bPortAddress = 0;
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,12 +224,22 @@ Fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USBHub::Release() {
|
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);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
|
|
||||||
if(bAddress == 0x41)
|
if(bAddress == 0x41)
|
||||||
pUsb->SetHubPreMask();
|
pUsb->SetHubPreMask();
|
||||||
|
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
bPortAddress = 0;
|
||||||
bNbrPorts = 0;
|
bNbrPorts = 0;
|
||||||
qNextPollTime = 0;
|
qNextPollTime = 0;
|
||||||
bPollEnable = false;
|
bPollEnable = false;
|
||||||
|
|
1
usbhub.h
1
usbhub.h
|
@ -169,6 +169,7 @@ class USBHub : USBDeviceConfig {
|
||||||
EpInfo epInfo[2]; // interrupt endpoint info structure
|
EpInfo epInfo[2]; // interrupt endpoint info structure
|
||||||
|
|
||||||
uint8_t bAddress; // address
|
uint8_t bAddress; // address
|
||||||
|
uint8_t bPortAddress; // port address
|
||||||
uint8_t bNbrPorts; // number of ports
|
uint8_t bNbrPorts; // number of ports
|
||||||
// uint8_t bInitState; // initialization state variable
|
// uint8_t bInitState; // initialization state variable
|
||||||
uint32_t qNextPollTime; // next poll time
|
uint32_t qNextPollTime; // next poll time
|
||||||
|
|
Loading…
Reference in a new issue