UVC host library

Dependents:   LifeCam WebcamServer

usb/UsbDevice2.cpp

Committer:
va009039
Date:
2012-08-15
Revision:
3:3eb41d749f9a
Parent:
0:b0f04c137829

File content as of revision 3:3eb41d749f9a:

#include "UsbDevice.h"
//#define __DEBUG
#include "mydbg.h"
#include "Utils.h"

#define PORT_RESET         4
#define PORT_POWER         8
#define C_PORT_CONNECTION 16
#define C_PORT_RESET      20

UsbErr UsbDevice::hub_init()
{
    UsbErr rc;
    uint8_t buf[9];
    rc = controlReceive(
          USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE, // 0xa0 
          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, // 0xa0 
          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("%p m_hub=%d m_port=%d m_addr=%d\n", this, m_hub, m_port, m_addr);
    // check status
    for(int port = 1; port <= m_hub_ports; port++) {
        uint32_t status;
        UsbErr rc = GetPortStatus(port, &status);
        DBG_ASSERT(rc == USBERR_OK);
        DBG("port: %d status: %08X\n", port, status);
        if (status & 0x010000) { // Connect Status Change, has changed
            DBG_ASSERT(status & 0x000001);
            ClearPortFeature(C_PORT_CONNECTION, port);
            bool low_speed = false;
            if (status & 0x0200) {
                low_speed = true;
            }
            DBG_ASSERT(m_pMgr);
            m_pMgr->onUsbDeviceConnected(m_addr, port, low_speed);
            return USBERR_PROCESSING;
        }
    }
    return USBERR_OK;
}

UsbErr UsbDevice::hub_PortReset(int port)
{
    DBG("%p port=%d\n", this, port);
    DBG_ASSERT(port >= 1);
    SetPortReset(port);
    // wait reset
    for(int i = 0; i < 100; i++) {
        uint32_t status;    
        UsbErr rc = GetPortStatus(port, &status);
        DBG_ASSERT(rc == USBERR_OK);
        DBG("RESET port: %d status: %08X\n", port, status);
        if (status & 0x100000) { // Reset change , Reset complete
            return USBERR_OK;
        }
        wait_ms(5);
     }
     return USBERR_ERROR;
}

UsbErr UsbDevice::SetPortFeature(int feature, int index)
{
    //DBG("feature=%d index=%d\n", feature, index);
    UsbErr rc;
    rc = controlSend(
          USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_OTHER, 
          SET_FEATURE, feature, index, 0, 0);
    return rc;
}

UsbErr UsbDevice::ClearPortFeature(int feature, int index)
{
    UsbErr rc;
    rc = controlSend(
          USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_OTHER, 
          CLEAR_FEATURE, feature, index, 0, 0);
    return rc;
}

UsbErr UsbDevice::SetPortReset(int port)
{
    //DBG("port=%d\n", port);
    UsbErr rc = SetPortFeature(PORT_RESET, port);
    DBG_ASSERT(rc == USBERR_OK);
    return rc;
}

UsbErr UsbDevice::GetPortStatus(int port, uint8_t* buf, int size)
{
    DBG_ASSERT(size == 4);
    UsbErr rc;
    rc = controlReceive(
          USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_OTHER, 
          GET_STATUS, 0, port, buf, sizeof(buf));
    return rc;
}

UsbErr UsbDevice::GetPortStatus(int port, uint32_t* status)
{
    uint8_t buf[4];
    UsbErr rc = GetPortStatus(port, buf, sizeof(buf));
    *status = LE32(buf);
    return rc;
}