Exemplo n.º 1
0
Arquivo: adk.cpp Projeto: THXC/Arduino
/* Connection initialization of an Android phone */
uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {

        uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
        uint8_t rcode;
        uint8_t num_of_conf; // number of configurations
        UsbDevice *p = NULL;
        EpInfo *oldep_ptr = NULL;

        // get memory address of USB device address pool
        AddressPool &addrPool = pUsb->GetAddressPool();

        USBTRACE("\r\nADK Init");

        // check if address has already been assigned to an instance
        if (bAddress) {
                USBTRACE("\r\nAddress in use");
                return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
        }

        // Get pointer to pseudo device with address 0 assigned
        p = addrPool.GetUsbDevicePtr(0);

        if (!p) {
                USBTRACE("\r\nAddress not found");
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
        }

        if (!p->epinfo) {
                USBTRACE("epinfo is null\r\n");
                return USB_ERROR_EPINFO_IS_NULL;
        }

        // Save old pointer to EP_RECORD of address 0
        oldep_ptr = p->epinfo;

        // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
        p->epinfo = epInfo;

        p->lowspeed = lowspeed;

        // Get device descriptor
        rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);

        // Restore p->epinfo
        p->epinfo = oldep_ptr;

        if (rcode) {
                goto FailGetDevDescr;
        }

        // Allocate new address according to device class
        bAddress = addrPool.AllocAddress(parent, false, port);

        // Extract Max Packet Size from device descriptor
        epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
        // Assign new address to the device
        rcode = pUsb->setAddr(0, 0, bAddress);
        if (rcode) {
                p->lowspeed = false;
                addrPool.FreeAddress(bAddress);
                bAddress = 0;
                //USBTRACE2("setAddr:",rcode);
                return rcode;
        }//if (rcode...

        //USBTRACE2("\r\nAddr:", bAddress);
        // Spec says you should wait at least 200ms.
        delay(300);

        p->lowspeed = false;

        //get pointer to assigned address record
        p = addrPool.GetUsbDevicePtr(bAddress);
        if (!p) {
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
        }

        p->lowspeed = lowspeed;

        // Assign epInfo to epinfo pointer - only EP0 is known
        rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
        if (rcode) {
                goto FailSetDevTblEntry;
        }

        //check if ADK device is already in accessory mode; if yes, configure and exit
        if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor == ADK_VID &&
                (((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)) {
                USBTRACE("\r\nAcc.mode device detected");
                /* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */
                num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;

                //USBTRACE2("\r\nNC:",num_of_conf);

                for (uint8_t i = 0; i < num_of_conf; i++) {
                        ConfigDescParser < 0, 0, 0, 0 > confDescrParser(this);
                        rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
                        if (rcode) {
                                goto FailGetConfDescr;
                        }
                        if (bNumEP > 2) {
                                break;
                        }
                } // for (uint8_t i=0; i<num_of_conf; i++...

                if (bNumEP == 3) {
                        // Assign epInfo to epinfo pointer - this time all 3 endpoins
                        rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
                        if (rcode) {
                                goto FailSetDevTblEntry;
                        }
                }



                // Set Configuration Value
                rcode = pUsb->setConf(bAddress, 0, bConfNum);
                if (rcode) {
                        goto FailSetConfDescr;
                }
                /* print endpoint structure */
                //		          USBTRACE("\r\nEndpoint Structure:");
                //		          USBTRACE("\r\nEP0:");
                //		          USBTRACE2("\r\nAddr: ", epInfo[0].epAddr );
                //	            USBTRACE2("\r\nMax.pkt.size: ", epInfo[0].maxPktSize );
                //	            USBTRACE2("\r\nAttr: ", epInfo[0].epAttribs );
                //	            USBTRACE("\r\nEpout:");
                //		          USBTRACE2("\r\nAddr: ", epInfo[epDataOutIndex].epAddr );
                //	            USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataOutIndex].maxPktSize );
                //	            USBTRACE2("\r\nAttr: ", epInfo[epDataOutIndex].epAttribs );
                //	            USBTRACE("\r\nEpin:");
                //		          USBTRACE2("\r\nAddr: ", epInfo[epDataInIndex].epAddr );
                //	            USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataInIndex].maxPktSize );
                //	            USBTRACE2("\r\nAttr: ", epInfo[epDataInIndex].epAttribs );

                USBTRACE("\r\nConfiguration successful");
                ready = true;
                return 0; //successful configuration
        }//if( buf->idVendor == ADK_VID...

        //probe device - get accessory protocol revision
        {
                uint16_t adkproto = -1;
                rcode = getProto((uint8_t*) & adkproto);
                if (rcode) {
                        goto FailGetProto; //init fails
                }
                USBTRACE2("\r\nADK protocol rev. ", adkproto);
        }

        //sending ID strings
        sendStr(ACCESSORY_STRING_MANUFACTURER, manufacturer);
        sendStr(ACCESSORY_STRING_MODEL, model);
        sendStr(ACCESSORY_STRING_DESCRIPTION, description);
        sendStr(ACCESSORY_STRING_VERSION, version);
        sendStr(ACCESSORY_STRING_URI, uri);
        sendStr(ACCESSORY_STRING_SERIAL, serial);

        //switch to accessory mode
        //the Android phone will reset
        rcode = switchAcc();
        if (rcode) {
                goto FailSwAcc; //init fails
        }
        rcode = USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
        delay(1000); // Give Android a chance to do its reset. This is a guess, and possibly could be lower.
        goto SwAttempt; //switch to accessory mode attempted

        /* diagnostic messages */
FailGetDevDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetDevDescr(rcode);
        goto Fail;
#endif

FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST
        NotifyFailSetDevTblEntry(rcode);
        goto Fail;
#endif

FailGetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetConfDescr(rcode);
        goto Fail;
#endif

FailSetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailSetConfDescr(rcode);
        goto Fail;
#endif

FailGetProto:
#ifdef DEBUG_USB_HOST
        USBTRACE("\r\ngetProto:");
        goto Fail;
#endif

FailSwAcc:
#ifdef DEBUG_USB_HOST
        USBTRACE("\r\nswAcc:");
        goto Fail;
#endif

SwAttempt:
#ifdef DEBUG_USB_HOST
        USBTRACE("\r\nAccessory mode switch attempt");
#endif
        //FailOnInit:
        //	USBTRACE("OnInit:");
        //	goto Fail;
        //
Fail:
        //USBTRACE2("\r\nADK Init Failed, error code: ", rcode);
        //NotifyFail(rcode);
        Release();
        return rcode;
}
Exemplo n.º 2
0
uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
        const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);

        uint8_t buf[constBufSize];
        uint8_t rcode;
        UsbDevice *p = NULL;
        EpInfo *oldep_ptr = NULL;
        //uint8_t		len = 0;
        //uint16_t	cd_len = 0;

        uint8_t num_of_conf; // number of configurations
        //uint8_t		num_of_intf;	// number of interfaces

        AddressPool &addrPool = pUsb->GetAddressPool();

        USBTRACE("FTDI Init\r\n");

        if (bAddress)
                return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;

        // Get pointer to pseudo device with address 0 assigned
        p = addrPool.GetUsbDevicePtr(0);

        if (!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        if (!p->epinfo) {
                USBTRACE("epinfo\r\n");
                return USB_ERROR_EPINFO_IS_NULL;
        }

        // Save old pointer to EP_RECORD of address 0
        oldep_ptr = p->epinfo;

        // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
        p->epinfo = epInfo;

        p->lowspeed = lowspeed;

        // Get device descriptor
        rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);

        // Restore p->epinfo
        p->epinfo = oldep_ptr;

        if (rcode)
                goto FailGetDevDescr;

        if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor != FTDI_VID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct != FTDI_PID)
                return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;

        // Save type of FTDI chip
        wFTDIType = ((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice;

        // Allocate new address according to device class
        bAddress = addrPool.AllocAddress(parent, false, port);

        if (!bAddress)
                return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;

        // Extract Max Packet Size from the device descriptor
        epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;

        // Assign new address to the device
        rcode = pUsb->setAddr(0, 0, bAddress);

        if (rcode) {
                p->lowspeed = false;
                addrPool.FreeAddress(bAddress);
                bAddress = 0;
                USBTRACE2("setAddr:", rcode);
                return rcode;
        }

        USBTRACE2("Addr:", bAddress);

        p->lowspeed = false;

        p = addrPool.GetUsbDevicePtr(bAddress);

        if (!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        p->lowspeed = lowspeed;

        num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;

        // Assign epInfo to epinfo pointer
        rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);

        if (rcode)
                goto FailSetDevTblEntry;

        USBTRACE2("NC:", num_of_conf);

        for (uint8_t i = 0; i < num_of_conf; i++) {
                HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
                ConfigDescParser < 0xFF, 0xFF, 0xFF, CP_MASK_COMPARE_ALL> confDescrParser(this);

                rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);

                if (rcode)
                        goto FailGetConfDescr;

                rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);

                if (rcode)
                        goto FailGetConfDescr;

                if (bNumEP > 1)
                        break;
        } // for

        if (bNumEP < 2)
                return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;

        USBTRACE2("NumEP:", bNumEP);

        // Assign epInfo to epinfo pointer
        rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);

        USBTRACE2("Conf:", bConfNum);

        // Set Configuration Value
        rcode = pUsb->setConf(bAddress, 0, bConfNum);

        if (rcode)
                goto FailSetConfDescr;

        rcode = pAsync->OnInit(this);

        if (rcode)
                goto FailOnInit;

        USBTRACE("FTDI configured\r\n");

        bPollEnable = true;
        return 0;

FailGetDevDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetDevDescr();
        goto Fail;
#endif

FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST
        NotifyFailSetDevTblEntry();
        goto Fail;
#endif

FailGetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetConfDescr();
        goto Fail;
#endif

FailSetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailSetConfDescr();
        goto Fail;
#endif

FailOnInit:
#ifdef DEBUG_USB_HOST
        USBTRACE("OnInit:");
#endif

Fail:
#ifdef DEBUG_USB_HOST
        NotifyFail(rcode);
#endif
        Release();
        return rcode;
}
Exemplo n.º 3
0
uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool 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;
        UsbDevice *p = NULL;
        EpInfo *oldep_ptr = NULL;
        uint8_t len = 0;

        uint8_t num_of_conf; // number of configurations
        //uint8_t num_of_intf; // number of interfaces

        AddressPool &addrPool = pUsb->GetAddressPool();

        USBTRACE("HU Init\r\n");

        if(bAddress)
                return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;

        // Get pointer to pseudo device with address 0 assigned
        p = addrPool.GetUsbDevicePtr(0);

        if(!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        if(!p->epinfo) {
                USBTRACE("epinfo\r\n");
                return USB_ERROR_EPINFO_IS_NULL;
        }

        // Save old pointer to EP_RECORD of address 0
        oldep_ptr = p->epinfo;

        // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
        p->epinfo = epInfo;

        p->lowspeed = lowspeed;

        // Get device descriptor
        rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);

        if(!rcode)
                len = (buf[0] > constBufSize) ? constBufSize : buf[0];

        if(rcode) {
                // Restore p->epinfo
                p->epinfo = oldep_ptr;

                goto FailGetDevDescr;
        }

        // Restore p->epinfo
        p->epinfo = oldep_ptr;

        // Allocate new address according to device class
        bAddress = addrPool.AllocAddress(parent, false, port);

        if(!bAddress)
                return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;

        // Extract Max Packet Size from the device descriptor
        epInfo[0].maxPktSize = udd->bMaxPacketSize0;

        // Assign new address to the device
        rcode = pUsb->setAddr(0, 0, bAddress);

        if(rcode) {
                p->lowspeed = false;
                addrPool.FreeAddress(bAddress);
                bAddress = 0;
                USBTRACE2("setAddr:", rcode);
                return rcode;
        }

        //delay(2); //per USB 2.0 sect.9.2.6.3

        USBTRACE2("Addr:", bAddress);

        p->lowspeed = false;

        p = addrPool.GetUsbDevicePtr(bAddress);

        if(!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        p->lowspeed = lowspeed;

        if(len)
                rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);

        if(rcode)
                goto FailGetDevDescr;

        VID = udd->idVendor; // Can be used by classes that inherits this class to check the VID and PID of the connected device
        PID = udd->idProduct;

        num_of_conf = udd->bNumConfigurations;

        // Assign epInfo to epinfo pointer
        rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);

        if(rcode)
                goto FailSetDevTblEntry;

        USBTRACE2("NC:", num_of_conf);

        for(uint8_t i = 0; i < num_of_conf; i++) {
                //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
                ConfigDescParser<USB_CLASS_HID, 0, 0,
                        CP_MASK_COMPARE_CLASS> confDescrParser(this);

                //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
                rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);

                if(rcode)
                        goto FailGetConfDescr;

                if(bNumEP > 1)
                        break;
        } // for

        if(bNumEP < 2)
                return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;

        // Assign epInfo to epinfo pointer
        rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);

        USBTRACE2("Cnf:", bConfNum);

        // Set Configuration Value
        rcode = pUsb->setConf(bAddress, 0, bConfNum);

        if(rcode)
                goto FailSetConfDescr;

        for(uint8_t i = 0; i < bNumIface; i++) {
                if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
                        continue;

                rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);

                if(rcode && rcode != hrSTALL)
                        goto FailSetIdle;
        }

        USBTRACE("HU configured\r\n");

        OnInitSuccessful();

        bPollEnable = true;
        return 0;

FailGetDevDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetDevDescr();
        goto Fail;
#endif

FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST
        NotifyFailSetDevTblEntry();
        goto Fail;
#endif

FailGetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetConfDescr();
        goto Fail;
#endif

FailSetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailSetConfDescr();
        goto Fail;
#endif


FailSetIdle:
#ifdef DEBUG_USB_HOST
        USBTRACE("SetIdle:");
#endif

#ifdef DEBUG_USB_HOST
Fail:
        NotifyFail(rcode);
#endif
        Release();
        return rcode;
}
Exemplo n.º 4
0
uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
    uint8_t	buf[sizeof(USB_DEVICE_DESCRIPTOR)];
	uint8_t	rcode;
	UsbDevice *p = NULL;
	EpInfo *oldep_ptr = NULL;  
    uint8_t	num_of_conf; // number of configurations
    uint16_t PID;
    uint16_t VID;
    
    // get memory address of USB device address pool
	AddressPool	&addrPool = pUsb->GetAddressPool();    
#ifdef EXTRADEBUG
	Notify(PSTR("\r\nBTD Init"));
#endif
    // check if address has already been assigned to an instance
    if (bAddress) {
#ifdef DEBUG
        Notify(PSTR("\r\nAddress in use"));
#endif
        return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
    }
    
    // Get pointer to pseudo device with address 0 assigned
    p = addrPool.GetUsbDevicePtr(0);
    
    if (!p) {        
#ifdef DEBUG
	    Notify(PSTR("\r\nAddress not found"));
#endif
        return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
    }
    
    if (!p->epinfo) {
#ifdef DEBUG
        Notify(PSTR("\r\nepinfo is null"));
#endif
        return USB_ERROR_EPINFO_IS_NULL;
    }
    
    // Save old pointer to EP_RECORD of address 0
    oldep_ptr = p->epinfo;
    
    // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
    p->epinfo = epInfo;
    
    p->lowspeed = lowspeed;
    
    // Get device descriptor
    rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data
    
    // Restore p->epinfo
    p->epinfo = oldep_ptr;
    
    if(rcode)
        goto FailGetDevDescr;
    
    // Allocate new address according to device class
    bAddress = addrPool.AllocAddress(parent, false, port);
    
    if (!bAddress)
		return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
    
    // Extract Max Packet Size from device descriptor
    epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; 
    
    // Assign new address to the device
    rcode = pUsb->setAddr( 0, 0, bAddress );
    if (rcode) {
        p->lowspeed = false;
        addrPool.FreeAddress(bAddress);
        bAddress = 0;
#ifdef DEBUG
        Notify(PSTR("\r\nsetAddr: "));
#endif
        PrintHex<uint8_t>(rcode);
        return rcode;
    }
#ifdef EXTRADEBUG
    Notify(PSTR("\r\nAddr: "));
    PrintHex<uint8_t>(bAddress);
#endif
    p->lowspeed = false;
    
    //get pointer to assigned address record
    p = addrPool.GetUsbDevicePtr(bAddress);
    if (!p) 
        return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
    
    p->lowspeed = lowspeed;        
    
    // Assign epInfo to epinfo pointer - only EP0 is known
    rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
    if (rcode)
        goto FailSetDevTblEntry;
    VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
    PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
    
    if(VID == PS3_VID && (PID == PS3_PID ||  PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
        /* We only need the Control endpoint, so we don't have to initialize the other endpoints of device */                
        rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 1);
        if( rcode )
            goto FailSetConf;
        
        if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
#ifdef DEBUG
            if(PID == PS3_PID)
                Notify(PSTR("\r\nDualshock 3 Controller Connected"));
            else // must be a navigation controller
                Notify(PSTR("\r\nNavigation Controller Connected"));
#endif
            /* Set internal bluetooth address */
            setBdaddr(my_bdaddr);
        }
        else { // must be a Motion controller
#ifdef DEBUG
            Notify(PSTR("\r\nMotion Controller Connected"));
#endif
            setMoveBdaddr(my_bdaddr);
        }
        rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 0); // Reset configuration value
        pUsb->setAddr(bAddress, 0, 0); // Reset address
        Release(); // Release device
        return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // return
    }
    else {
        num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;

        // check if attached device is a Bluetooth dongle and fill endpoint data structure
        // first interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
        // and 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT,
        // not necessarily in this order
        for (uint8_t i=0; i<num_of_conf; i++) {
            ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
            rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
            if(rcode)
                goto FailGetConfDescr;
            if(bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted
                break;
        }
    
        if (bNumEP < BTD_MAX_ENDPOINTS)
            goto FailUnknownDevice;
        
        // Assign epInfo to epinfo pointer - this time all 3 endpoins
        rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
        if(rcode)
            goto FailSetDevTblEntry;
        
        delay(200); // Give time for address change
    
        // Set Configuration Value
        rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
        if(rcode)
            goto FailSetConf;
    
        hci_num_reset_loops = 100; // only loop 100 times before trying to send the hci reset command
        hci_counter = 0;
        hci_state = HCI_INIT_STATE;
        watingForConnection = false;
        bPollEnable = true;

#ifdef DEBUG
        Notify(PSTR("\r\nBluetooth Dongle Initialized"));
#endif
    }
    return 0; // Successful configuration
    
    /* diagnostic messages */  
FailGetDevDescr:
#ifdef DEBUG
    Notify(PSTR("\r\ngetDevDescr"));
#endif
    goto Fail;    
FailSetDevTblEntry:
#ifdef DEBUG
    Notify(PSTR("\r\nsetDevTblEn"));
#endif
    goto Fail;
FailGetConfDescr:
#ifdef DEBUG
    Notify(PSTR("\r\ngetConf"));
#endif
    goto Fail;
FailSetConf:
#ifdef DEBUG
    Notify(PSTR("\r\nsetConf"));
#endif
    goto Fail;
FailUnknownDevice:
#ifdef DEBUG
    Notify(PSTR("\r\nUnknown Device Connected - VID: "));
    PrintHex<uint16_t>(VID);
    Notify(PSTR(" PID: "));
    PrintHex<uint16_t>(PID);
#endif
    pUsb->setAddr(bAddress, 0, 0); // Reset address
    rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
    goto Fail;
Fail:
#ifdef DEBUG
    Notify(PSTR("\r\nBTD Init Failed, error code: "));
    Serial.print(rcode);                     
#endif    
    Release();
    return rcode;
}
Exemplo n.º 5
0
uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed)
{
	const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);

	uint8_t		buf[constBufSize];
	uint8_t		rcode;
	UsbDevice	*p = NULL;
	EpInfo		*oldep_ptr = NULL;
	uint8_t		len = 0;
	uint16_t	cd_len = 0;

	uint8_t		num_of_conf;	// number of configurations
	uint8_t		num_of_intf;	// number of interfaces

	AddressPool	&addrPool = pUsb->GetAddressPool();

	USBTRACE("HU Init\r\n");

	if (bAddress)
		return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;

	// Get pointer to pseudo device with address 0 assigned
	p = addrPool.GetUsbDevicePtr(0);

	if (!p)
		return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

	if (!p->epinfo)
	{
		USBTRACE("epinfo\r\n");
		return USB_ERROR_EPINFO_IS_NULL;
	}

	// Save old pointer to EP_RECORD of address 0
	oldep_ptr = p->epinfo;

	// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
	p->epinfo = epInfo;

	p->lowspeed = lowspeed;

	// Get device descriptor
	rcode = pUsb->getDevDescr( 0, 0, 8, (uint8_t*)buf );

	if  (!rcode)
		len = (buf[0] > constBufSize) ? constBufSize : buf[0];

	if( rcode ) 
	{
		// Restore p->epinfo
		p->epinfo = oldep_ptr;

		goto FailGetDevDescr;
	}

	// Restore p->epinfo
	p->epinfo = oldep_ptr;

	// Allocate new address according to device class
	bAddress = addrPool.AllocAddress(parent, false, port);

	if (!bAddress)
		return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;

	// Extract Max Packet Size from the device descriptor
	epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; 

	// Assign new address to the device
	rcode = pUsb->setAddr( 0, 0, bAddress );

	if (rcode)
	{
		p->lowspeed = false;
		addrPool.FreeAddress(bAddress);
		bAddress = 0;
		USBTRACE2("setAddr:",rcode);
		return rcode;
	}

	USBTRACE2("Addr:", bAddress);

	p->lowspeed = false;

	p = addrPool.GetUsbDevicePtr(bAddress);

	if (!p)
		return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

	p->lowspeed = lowspeed;

	if (len)
		rcode = pUsb->getDevDescr( bAddress, 0, len, (uint8_t*)buf );

	if(rcode) 
		goto FailGetDevDescr;

	num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;

	// Assign epInfo to epinfo pointer
	rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);

	if (rcode)
		goto FailSetDevTblEntry;

	USBTRACE2("NC:", num_of_conf);

	for (uint8_t i=0; i<num_of_conf; i++)
	{
		HexDumper<USBReadParser, uint16_t, uint16_t>		HexDump;
		ConfigDescParser<USB_CLASS_HID, 0, 0, 
			CP_MASK_COMPARE_CLASS>							confDescrParser(this);

		rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
		rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
		
		if (bNumEP > 1)
			break;
	} // for
	
	if (bNumEP < 2)
		return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;

	// Assign epInfo to epinfo pointer
	rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);

	USBTRACE2("\r\nCnf:", bConfNum);

	// Set Configuration Value
	//rcode = pUsb->setConf(bAddress, 0, 0);
	rcode = pUsb->setConf(bAddress, 0, bConfNum);

	if (rcode)
		goto FailSetConfDescr;

	for (uint8_t i=0; i<bNumIface; i++)
	{
		if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
			continue;

		USBTRACE("Proto\r\n");

		//rcode = SetProtocol(hidInterfaces[i].bmInterface, HID_RPT_PROTOCOL);

		//if (rcode)
		//	goto FailSetProtocol;

		rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);

		if (rcode)
			goto FailSetIdle;
	}

	USBTRACE("HU configured\r\n");

	{
		HexDumper<USBReadParser, uint16_t, uint16_t>    Hex;
		ReportDescParser                                Rpt;

		if (rcode = GetReportDescr(0, &Hex))
			goto FailGetReportDescr;
	        
		if (rcode = GetReportDescr(0, &Rpt))
			goto FailGetReportDescr;
	}
	bPollEnable = true;
	return 0;

FailGetDevDescr:
	USBTRACE("getDevDescr:");
	goto Fail;

FailSetDevTblEntry:
	USBTRACE("setDevTblEn:");
	goto Fail;

FailGetConfDescr:
	USBTRACE("getConf:");
	goto Fail;

FailSetConfDescr:
	USBTRACE("setConf:");
	goto Fail;

FailSetProtocol:
	USBTRACE("SetProto:");
	goto Fail;

FailSetIdle:
	USBTRACE("SetIdle:");
	goto Fail;

FailGetReportDescr:
	USBTRACE("GetReportDescr:");
	goto Fail;

Fail:
	Serial.println(rcode, HEX);
	Release();
	return rcode;
}
Exemplo n.º 6
0
uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
    uint8_t rcode;
    uint8_t num_of_conf = epInfo[1].epAddr; // Number of configurations
    epInfo[1].epAddr = 0;

    AddressPool &addrPool = pUsb->GetAddressPool();
#ifdef EXTRADEBUG
    Notify(PSTR("\r\nBTD Init"), 0x80);
#endif
    UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record

    if(!p) {
#ifdef DEBUG_USB_HOST
        Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
        return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
    }

    delay(300); // Assign new address to the device

    rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device
    if(rcode) {
#ifdef DEBUG_USB_HOST
        Notify(PSTR("\r\nsetAddr: "), 0x80);
        D_PrintHex<uint8_t > (rcode, 0x80);
#endif
        p->lowspeed = false;
        goto Fail;
    }
#ifdef EXTRADEBUG
    Notify(PSTR("\r\nAddr: "), 0x80);
    D_PrintHex<uint8_t > (bAddress, 0x80);
#endif

    p->lowspeed = false;

    p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
    if(!p) {
#ifdef DEBUG_USB_HOST
        Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
        return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
    }

    p->lowspeed = lowspeed;

    rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
    if(rcode)
        goto FailSetDevTblEntry;

    if(VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
        delay(100);
        rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 1); // We only need the Control endpoint, so we don't have to initialize the other endpoints of device
        if(rcode)
            goto FailSetConfDescr;

#ifdef DEBUG_USB_HOST
        if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
            if(PID == PS3_PID)
                Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
            else // It must be a navigation controller
                Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
        } else // It must be a Motion controller
            Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
#endif

        if(my_bdaddr[0] == 0x00 && my_bdaddr[1] == 0x00 && my_bdaddr[2] == 0x00 && my_bdaddr[3] == 0x00 && my_bdaddr[4] == 0x00 && my_bdaddr[5] == 0x00) {
#ifdef DEBUG_USB_HOST
            Notify(PSTR("\r\nPlease plug in the dongle before trying to pair with the PS3 Controller\r\nor set the Bluetooth address in the constructor of the PS3BT class"), 0x80);
#endif
        } else {
            if(PID == PS3_PID || PID == PS3NAVIGATION_PID)
                setBdaddr(my_bdaddr); // Set internal Bluetooth address
            else
                setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
#ifdef DEBUG_USB_HOST
            Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
            for(int8_t i = 5; i > 0; i--) {
                D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
                Notify(PSTR(":"), 0x80);
            }
            D_PrintHex<uint8_t > (my_bdaddr[0], 0x80);
#endif
        }

        pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 0); // Reset configuration value
        pUsb->setAddr(bAddress, 0, 0); // Reset address
        Release(); // Release device
        return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Return
    } else {
        // Check if attached device is a Bluetooth dongle and fill endpoint data structure
        // First interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
        // And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order
        for(uint8_t i = 0; i < num_of_conf; i++) {
            if(VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) {
                ConfigDescParser<USB_CLASS_VENDOR_SPECIFIC, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Needed for the IOGEAR GBU521
                rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
            } else {
                ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
                rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
            }
            if(rcode) // Check error code
                goto FailGetConfDescr;
            if(bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted
                break;
        }

        if(bNumEP < BTD_MAX_ENDPOINTS)
            goto FailUnknownDevice;

        // Assign epInfo to epinfo pointer - this time all 3 endpoins
        rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
        if(rcode)
            goto FailSetDevTblEntry;

        // Set Configuration Value
        rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
        if(rcode)
            goto FailSetConfDescr;

        hci_num_reset_loops = 100; // only loop 100 times before trying to send the hci reset command
        hci_counter = 0;
        hci_state = HCI_INIT_STATE;
        watingForConnection = false;
        bPollEnable = true;

#ifdef DEBUG_USB_HOST
        Notify(PSTR("\r\nBluetooth Dongle Initialized"), 0x80);
#endif
    }
    return 0; // Successful configuration

    /* Diagnostic messages */
FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST
    NotifyFailSetDevTblEntry();
    goto Fail;
#endif

FailGetConfDescr:
#ifdef DEBUG_USB_HOST
    NotifyFailGetConfDescr();
    goto Fail;
#endif

FailSetConfDescr:
#ifdef DEBUG_USB_HOST
    NotifyFailSetConfDescr();
#endif
    goto Fail;

FailUnknownDevice:
#ifdef DEBUG_USB_HOST
    NotifyFailUnknownDevice(VID, PID);
#endif
    pUsb->setAddr(bAddress, 0, 0); // Reset address
    rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
Fail:
#ifdef DEBUG_USB_HOST
    Notify(PSTR("\r\nBTD Init Failed, error code: "), 0x80);
    NotifyFail(rcode);
#endif
    Release();
    return rcode;
}
Exemplo n.º 7
0
uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool 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;
        UsbDevice *p = NULL;
        EpInfo *oldep_ptr = NULL;
        uint8_t num_of_conf; // number of configurations
		enum pl2303_type pltype = unknown;

        AddressPool &addrPool = pUsb->GetAddressPool();

        USBTRACE("PL Init\r\n");

        if(bAddress)
                return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;

        // Get pointer to pseudo device with address 0 assigned
        p = addrPool.GetUsbDevicePtr(0);

        if(!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        if(!p->epinfo) {
                USBTRACE("epinfo\r\n");
                return USB_ERROR_EPINFO_IS_NULL;
        }

        // Save old pointer to EP_RECORD of address 0
        oldep_ptr = p->epinfo;

        // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
        p->epinfo = epInfo;

        p->lowspeed = lowspeed;

        // Get device descriptor
        rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);

        // Restore p->epinfo
        p->epinfo = oldep_ptr;

        if(rcode)
                goto FailGetDevDescr;

        if(udd->idVendor != PL_VID && udd->idProduct != PL_PID)
                return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;

		/* determine chip variant */
		
		if (udd->bDeviceClass == 0x02 ) {
			pltype = type_0;
		}
		else if (udd->bMaxPacketSize0 == 0x40 ) { 
			pltype = rev_HX;
		}
		else if (udd->bDeviceClass == 0x00) {
			pltype = type_1;
		}
		else if (udd->bDeviceClass == 0xff) {
			pltype = type_1;
		}
				
        // Save type of PL chip
        wPLType = udd->bcdDevice;

        // Allocate new address according to device class
        bAddress = addrPool.AllocAddress(parent, false, port);

        if(!bAddress)
                return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;

        // Extract Max Packet Size from the device descriptor
        epInfo[0].maxPktSize = udd->bMaxPacketSize0;

        // Assign new address to the device
        rcode = pUsb->setAddr(0, 0, bAddress);

        if(rcode) {
                p->lowspeed = false;
                addrPool.FreeAddress(bAddress);
                bAddress = 0;
                USBTRACE2("setAddr:", rcode);
                return rcode;
        }

        USBTRACE2("Addr:", bAddress);

        p->lowspeed = false;

        p = addrPool.GetUsbDevicePtr(bAddress);

        if(!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        p->lowspeed = lowspeed;

        num_of_conf = udd->bNumConfigurations;

        // Assign epInfo to epinfo pointer
        rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);

        if(rcode)
                goto FailSetDevTblEntry;

        USBTRACE2("NC:", num_of_conf);

        for(uint8_t i = 0; i < num_of_conf; i++) {
                HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
                ConfigDescParser < 0xFF, 0, 0, CP_MASK_COMPARE_CLASS> confDescrParser(this);

                rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);

                if(rcode)
                        goto FailGetConfDescr;

                rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);

                if(rcode)
                        goto FailGetConfDescr;

                if(bNumEP > 1)
                        break;
        } // for

        if(bNumEP < 2)
                return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;

        // Assign epInfo to epinfo pointer
        rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);

        USBTRACE2("Conf:", bConfNum);

        // Set Configuration Value
        rcode = pUsb->setConf(bAddress, 0, bConfNum);

        if(rcode)
                goto FailSetConfDescr;
				
		#if defined(PL2303_COMPAT)
			/* shamanic dance - sending Prolific init data as-is */
			vendorRead( 0x84, 0x84, 0, buf );
			vendorWrite( 0x04, 0x04, 0 );
			vendorRead( 0x84, 0x84, 0, buf );
			vendorRead( 0x83, 0x83, 0, buf );
			vendorRead( 0x84, 0x84, 0, buf );
			vendorWrite( 0x04, 0x04, 1 );
			vendorRead( 0x84, 0x84, 0, buf);
			vendorRead( 0x83, 0x83, 0, buf);
			vendorWrite( 0, 0, 1 );
			vendorWrite( 1, 0, 0 );
			if ( pltype == rev_HX ) {
				vendorWrite( 2, 0, 0x44 );
				vendorWrite( 0x06, 0x06, 0 );   //from W7 init
			}
			else {
			vendorWrite( 2, 0, 0x24 );
			}
			/* shamanic dance end */
		#endif
		
		/* calling post-init callback */
        rcode = pAsync->OnInit(this);

        if(rcode)
                goto FailOnInit;

        USBTRACE("PL configured\r\n");

        //bPollEnable = true;
        ready = true;
        return 0;

FailGetDevDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetDevDescr();
        goto Fail;
#endif

FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST
        NotifyFailSetDevTblEntry();
        goto Fail;
#endif

FailGetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetConfDescr();
        goto Fail;
#endif

FailSetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailSetConfDescr();
        goto Fail;
#endif

FailOnInit:
#ifdef DEBUG_USB_HOST
        USBTRACE("OnInit:");
#endif

#ifdef DEBUG_USB_HOST
Fail:
        NotifyFail(rcode);
#endif
        Release();
        return rcode;
}
Exemplo n.º 8
0
uint32_t DeviceHandleSAM3XE::Init(uint32_t parent_, uint32_t port_, uint32_t lowspeed_)
{
  uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];

  uint32_t retCode = 0;
  UsbDevice* pDevice = nullptr;
  EpInfo* pEpInfo_old = nullptr;
  uint32_t nOfConfigurations = 0;

  if (m_deviceAddress)
  {
    return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
  }

  AddressPool& addrPool = m_pUsb->GetAddressPool();
  pDevice = addrPool.GetUsbDevicePtr(0);

  if (!pDevice)
  {
    return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
  }
  else if (!pDevice->epinfo)
  {
    return USB_ERROR_EPINFO_IS_NULL;
  }

  pEpInfo_old = pDevice->epinfo;
  pDevice->epinfo = m_epInfo;
  pDevice->lowspeed = lowspeed_;
  retCode = m_pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), static_cast<uint8_t*>(buf));
  pDevice->epinfo = pEpInfo_old;

  if (retCode != 0)
  {
    M_LOG("ERROR (" << retCode << "): Failed to get device descriptor");
    Release();
    return retCode;
  }

  m_deviceAddress = addrPool.AllocAddress(parent_, false, port_);
  // Extract Max Packet Size from device descriptor
  m_epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;

  // Assign new address to the device
  retCode = m_pUsb->setAddr(0, 0, m_deviceAddress);
  if (retCode)
  {
    pDevice->lowspeed = false;
    addrPool.FreeAddress(m_deviceAddress);
    m_deviceAddress = 0;
    M_LOG("ERROR (" << retCode << "): setAddr failed");
    return retCode;
  }

  M_LOG("Device address is now " << m_deviceAddress);

  pDevice->lowspeed = false;

  // get pointer to assigned address record
  pDevice = addrPool.GetUsbDevicePtr(m_deviceAddress);
  if (!pDevice)
  {
    m_deviceAddress = 0;
    M_LOG("ERROR: address not found in pool");
    return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
  }

  pDevice->lowspeed = lowspeed_;

  // Assign epInfo to epinfo pointer - only EP0 is known
  retCode = m_pUsb->setEpInfoEntry(m_deviceAddress, 1, m_epInfo);
  if (retCode)
  {
    m_deviceAddress = 0;
    M_LOG("ERROR (" << retCode << "): setEpInfoEntry failed");
    return retCode;
  }

  // Check if ADK device is already in accessory mode; if yes, configure and exit
  if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor == ADK_VID
      && (((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID
           || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID))
  {
    nOfConfigurations = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;

    M_LOG("Thid device has a total of " << nOfConfigurations << " configurations");

    for (uint32_t i = 0; i < nOfConfigurations; ++i)
    {
      ConfigDescParser<0, 0, 0, 0> confDescrParser(this);

      delay(1);
      retCode = m_pUsb->getConfDescr(m_deviceAddress, 0, i, &confDescrParser);


      if (retCode)
      {
        M_LOG("ERROR (" << retCode << "): Failed to get config descriptor for configuration n. ");
        Release();
        return retCode;
      }

      if (bNumEP > 2)
      {
        break;
      }
    }

    if (bNumEP == 3)
    {
      // Assign epInfo to epinfo pointer - this time all 3 endpoins
      retCode = m_pUsb->setEpInfoEntry(m_deviceAddress, 3, epInfo);
      if (retCode)
      {
        goto FailSetDevTblEntry;
      }
    }

    // Set Configuration Value
    retCode = m_pUsb->setConf(m_deviceAddress, 0, bConfNum);
    if (retCode)
    {
      goto FailSetConf;
    }

    TRACE_USBHOST(printf("ADK::Init : ADK device configured successfully\r\n");)