UsbErr UsbDevice::hub_init()
{
UsbErr rc;
uint8_t buf[9];
rc = controlReceive(
USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE,
GET_DESCRIPTOR,
(USB_DESCRIPTOR_TYPE_HUB << 8), 0, buf, sizeof(buf));
DBG_ASSERT(rc == USBERR_OK);
DBG_ASSERT(buf[0] == 9);
DBG_ASSERT(buf[1] == 0x29);
DBG_BYTES("HUB DESCRIPTOR", buf, sizeof(buf));
m_hub_ports = buf[2];
VERBOSE("NbrPorts: %d\n", m_hub_ports);
int PwrOn2PwrGood = buf[5];
VERBOSE("PwrOn2PwrGood: %d %d ms\n", PwrOn2PwrGood, PwrOn2PwrGood*2);
VERBOSE("HubContrCurrent: %d\n", buf[6]);
rc = setConfiguration(1);
DBG_ASSERT(rc == USBERR_OK);
uint8_t status[4];
rc = controlReceive(
USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE,
GET_STATUS,
0, 0, status, sizeof(status));
DBG_ASSERT(rc == USBERR_OK);
DBG_BYTES("HUB STATUS", status, sizeof(status));
for(int i = 1; i <= m_hub_ports; i++) {
rc = SetPortFeature(PORT_POWER, i);
DBG("PORT_POWER port=%d rc=%d\n", i, rc);
DBG_ASSERT(rc == USBERR_OK);
if (rc != USBERR_OK) {
return rc;
}
}
wait_ms(PwrOn2PwrGood*2);
m_enumerated = true;
return USBERR_OK;
}
UsbErr UsbDevice::hub_poll()
{
DBG("m_hub=%d m_port=%d\n", m_hub, m_port);
UsbErr rc;
for(int port = 1; port <= m_hub_ports; port++) {
uint8_t status[4];
rc = GetPortStatus(port, status, sizeof(status));
DBG_ASSERT(rc == USBERR_OK);
DBG("port=%d\n", port);
DBG_BYTES("STATUS", status, sizeof(status));
if (status[2] & 0x01) {
DBG_ASSERT(status[0] & 0x01);
ClearPortFeature(C_PORT_CONNECTION, port);
SetPortReset(port);
DBG_ASSERT((status[2] & 0x10) == 0x00);
bool reset = false;
for(int i = 0; i < 100; i++) {
rc = GetPortStatus(port, status, sizeof(status));
DBG_ASSERT(rc == USBERR_OK);
DBG_BYTES("RESET", status, sizeof(status));
if (status[2] & 0x10) {
reset = true;
break;
}
wait_ms(5);
}
DBG_ASSERT(reset);
if (!reset) {
break;
}
DBG_ASSERT(m_pMgr);
wait_ms(200);
m_pMgr->onUsbDeviceConnected(m_port, port);
break;
}
}
rc = USBERR_OK;
return rc;
}