/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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");)