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; }
/* 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; }
void NotifyFailGetDevDescr(uint8_t reason) { NotifyFailGetDevDescr(); NotifyFail(reason); }
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 PS3USB::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; uint16_t PID; uint16_t VID; // get memory address of USB device address pool AddressPool &addrPool = pUsb->GetAddressPool(); #ifdef EXTRADEBUG Notify(PSTR("\r\nPS3USB Init"), 0x80); #endif // check if address has already been assigned to an instance if (bAddress) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nAddress in use"), 0x80); #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_USB_HOST Notify(PSTR("\r\nAddress not found"), 0x80); #endif return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; } if (!p->epinfo) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nepinfo is null"), 0x80); #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; 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)) goto FailUnknownDevice; // 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_USB_HOST Notify(PSTR("\r\nsetAddr: "), 0x80); D_PrintHex<uint8_t > (rcode, 0x80); #endif return rcode; } #ifdef EXTRADEBUG Notify(PSTR("\r\nAddr: "), 0x80); D_PrintHex<uint8_t > (bAddress, 0x80); #endif delay(300); // Spec says you should wait at least 200ms 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; /* The application will work in reduced host mode, so we can save program and data memory space. After verifying the PID and VID we will use known values for the configuration values for device, interface, endpoints and HID for the PS3 Controllers */ /* Initialize data structures for endpoints of device */ epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint epInfo[ PS3_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT; epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE; epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0; epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0; epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint epInfo[ PS3_INPUT_PIPE ].epAttribs = EP_INTERRUPT; epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE; epInfo[ PS3_INPUT_PIPE ].bmSndToggle = bmSNDTOG0; epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0; rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo); if (rcode) goto FailSetDevTblEntry; delay(200); //Give time for address change rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1); if (rcode) goto FailSetConfDescr; if (PID == PS3_PID || PID == PS3NAVIGATION_PID) { if (PID == PS3_PID) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80); #endif PS3Connected = true; } else { // must be a navigation controller #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nNavigation Controller Connected"), 0x80); #endif PS3NavigationConnected = true; } enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data // Needed for PS3 Dualshock and Navigation commands to work for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); for (uint8_t i = 6; i < 10; i++) readBuf[i] = 0x7F; // Set the analog joystick values to center position } else { // must be a Motion controller #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nMotion Controller Connected"), 0x80); #endif PS3MoveConnected = true; writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work } 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) { if (PS3MoveConnected) setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address else setBdaddr(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 } onInit(); bPollEnable = true; Notify(PSTR("\r\n"), 0x80); timer = millis(); return 0; // successful configuration /* diagnostic messages */ FailGetDevDescr: #ifdef DEBUG_USB_HOST NotifyFailGetDevDescr(); goto Fail; #endif FailSetDevTblEntry: #ifdef DEBUG_USB_HOST NotifyFailSetDevTblEntry(); goto Fail; #endif FailSetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailSetConfDescr(); #endif goto Fail; FailUnknownDevice: #ifdef DEBUG_USB_HOST NotifyFailUnknownDevice(VID, PID); #endif rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; Fail: #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80); NotifyFail(rcode); #endif Release(); return rcode; }
uint8_t XR21B1411::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 AddressPool &addrPool = pUsb->GetAddressPool(); USBTRACE("XR 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, constBufSize, (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); 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; if((((udd->idVendor != 0x2890U) || (udd->idProduct != 0x0201U)) && ((udd->idVendor != 0x04e2U) || (udd->idProduct != 0x1411U)))) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // 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++) { ConfigDescParser< USB_CLASS_COM_AND_CDC_CTRL, CDC_SUBCLASS_ACM, CDC_PROTOCOL_ITU_T_V_250, CP_MASK_COMPARE_CLASS | CP_MASK_COMPARE_SUBCLASS | CP_MASK_COMPARE_PROTOCOL > CdcControlParser(this); ConfigDescParser<USB_CLASS_CDC_DATA, 0, 0, CP_MASK_COMPARE_CLASS> CdcDataParser(this); rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcControlParser); if(rcode) goto FailGetConfDescr; rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcDataParser); if(rcode) goto FailGetConfDescr; if(bNumEP > 1) break; } // for if(bNumEP < 4) 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; // Set up features status _enhanced_status = enhanced_features(); half_duplex(false); autoflowRTS(false); autoflowDSR(false); autoflowXON(false); wide(false); // Always false, because this is only available in custom mode. rcode = pAsync->OnInit(this); if(rcode) goto FailOnInit; USBTRACE("XR configured\r\n"); ready = true; //bPollEnable = true; //USBTRACE("Poll enabled\r\n"); 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; }
/** * USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET == success * We need to standardize either the rcode, or change the API to return values * so a signal that additional actions are required can be produced. * Some of these codes do exist already. * * TECHNICAL: We could do most of this code elsewhere, with the exception of checking the class instance. * Doing so would save some program memory when using multiple drivers. * * @param parent USB address of parent * @param port address of port on parent * @param lowspeed true if device is low speed * @return */ uint8_t BulkOnly::ConfigureDevice(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; USBTRACE("MS ConfigureDevice\r\n"); ClearAllEP(); AddressPool &addrPool = pUsb->GetAddressPool(); if(bAddress) return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; // <TECHNICAL> // 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, constBufSize, (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); if(!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; // Extract Max Packet Size from the device descriptor epInfo[0].maxPktSize = udd->bMaxPacketSize0; // Steal and abuse from epInfo structure to save on memory. epInfo[1].epAddr = udd->bNumConfigurations; // </TECHNICAL> return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; FailGetDevDescr: #ifdef DEBUG_USB_HOST NotifyFailGetDevDescr(rcode); #endif rcode = USB_ERROR_FailGetDevDescr; Release(); return rcode; };
uint8_t BTD::ConfigureDevice(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; Initialize(); // Set all variables, endpoint structs etc. to default values AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool #ifdef EXTRADEBUG Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80); #endif if(bAddress) { // Check if address has already been assigned to an instance #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nAddress in use"), 0x80); #endif return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; } p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned if(!p) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nAddress not found"), 0x80); #endif return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; } if(!p->epinfo) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nepinfo is null"), 0x80); #endif return USB_ERROR_EPINFO_IS_NULL; } oldep_ptr = p->epinfo; // Save old pointer to EP_RECORD of address 0 p->epinfo = epInfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence p->lowspeed = lowspeed; rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data p->epinfo = oldep_ptr; // Restore p->epinfo if(rcode) goto FailGetDevDescr; bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class if(!bAddress) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nOut of address space"), 0x80); #endif return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; } epInfo[0].maxPktSize = udd->bMaxPacketSize0; // Extract Max Packet Size from device descriptor epInfo[1].epAddr = udd->bNumConfigurations; // Steal and abuse from epInfo structure to save memory VID = udd->idVendor; PID = udd->idProduct; return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; FailGetDevDescr: #ifdef DEBUG_USB_HOST NotifyFailGetDevDescr(rcode); #endif if(rcode != hrJERR) rcode = USB_ERROR_FailGetDevDescr; 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; }