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; }
void NotifyFailGetConfDescr(uint8_t reason) { NotifyFailGetConfDescr(); 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; }
void NotifyFailSetDevTblEntry(uint8_t reason) { NotifyFailSetDevTblEntry(); NotifyFail(reason); }
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; }
/** * * @param parent (not used) * @param port (not used) * @param lowspeed true if device is low speed * @return 0 for success */ uint8_t BulkOnly::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; USBTRACE("MS Init\r\n"); AddressPool &addrPool = pUsb->GetAddressPool(); UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); if(!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; // Assign new address to the device delay(2000); 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; // 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_MASS_STORAGE, MASS_SUBCLASS_SCSI, MASS_PROTO_BBB, CP_MASK_COMPARE_CLASS | CP_MASK_COMPARE_SUBCLASS | CP_MASK_COMPARE_PROTOCOL > BulkOnlyParser(this); rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); if(rcode) goto FailGetConfDescr; if(bNumEP > 1) break; } if(bNumEP < 3) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Assign epInfo to epinfo pointer pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); USBTRACE2("Conf:", bConfNum); // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); if(rcode) goto FailSetConfDescr; //Linux does a 1sec delay after this. delay(1000); rcode = GetMaxLUN(&bMaxLUN); if(rcode) goto FailGetMaxLUN; if(bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1; ErrorMessage<uint8_t > (PSTR("MaxLUN"), bMaxLUN); delay(1000); // Delay a bit for slow firmware. for(uint8_t lun = 0; lun <= bMaxLUN; lun++) { InquiryResponse response; rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response); if(rcode) { ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode); } else { #if 0 printf("LUN %i `", lun); uint8_t *buf = response.VendorID; for(int i = 0; i < 28; i++) printf("%c", buf[i]); printf("'\r\nQualifier %1.1X ", response.PeripheralQualifier); printf("Device type %2.2X ", response.DeviceType); printf("RMB %1.1X ", response.Removable); printf("SSCS %1.1X ", response.SCCS); uint8_t sv = response.Version; printf("SCSI version %2.2X\r\nDevice conforms to ", sv); switch(sv) { case 0: printf("No specific"); break; case 1: printf("ANSI X3.131-1986 (ANSI 1)"); break; case 2: printf("ANSI X3.131-1994 (ANSI 2)"); break; case 3: printf("ANSI INCITS 301-1997 (SPC)"); break; case 4: printf("ANSI INCITS 351-2001 (SPC-2)"); break; case 5: printf("ANSI INCITS 408-2005 (SPC-4)"); break; case 6: printf("T10/1731-D (SPC-4)"); break; default: printf("unknown"); } printf(" standards.\r\n"); #endif uint8_t tries = 0xf0; while((rcode = TestUnitReady(lun))) { if(rcode == 0x08) break; // break on no media, this is OK to do. // try to lock media and spin up if(tries < 14) { LockMedia(lun, 1); MediaCTL(lun, 1); // I actually have a USB stick that needs this! } else delay(2 * (tries + 1)); tries++; if(!tries) break; } if(!rcode) { delay(1000); LUNOk[lun] = CheckLUN(lun); if(!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun); } } } CheckMedia(); rcode = OnInit(); if(rcode) goto FailOnInit; #ifdef DEBUG_USB_HOST USBTRACE("MS configured\r\n\r\n"); #endif bPollEnable = true; //USBTRACE("Poll enabled\r\n"); return 0; FailSetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailSetConfDescr(); goto Fail; #endif FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); goto Fail; #endif FailGetMaxLUN: #ifdef DEBUG_USB_HOST USBTRACE("GetMaxLUN:"); goto Fail; #endif //#ifdef DEBUG_USB_HOST //FailInvalidSectorSize: // USBTRACE("Sector Size is NOT VALID: "); // goto Fail; //#endif FailSetDevTblEntry: #ifdef DEBUG_USB_HOST NotifyFailSetDevTblEntry(); goto Fail; #endif FailGetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailGetConfDescr(); #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 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; }
/** * * @param parent (not used) * @param port (not used) * @param lowspeed true if device is low speed * @return 0 for success */ uint8_t BulkOnly::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; USBTRACE("MS Init\r\n"); AddressPool &addrPool = pUsb->GetAddressPool(); UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; // Assign new address to the device delay(2000); 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; // 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_MASS_STORAGE, MASS_SUBCLASS_SCSI, MASS_PROTO_BBB, CP_MASK_COMPARE_CLASS | CP_MASK_COMPARE_SUBCLASS | CP_MASK_COMPARE_PROTOCOL > BulkOnlyParser(this); rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); if (rcode) goto FailGetConfDescr; if (bNumEP > 1) break; } // for if (bNumEP < 3) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Assign epInfo to epinfo pointer pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); USBTRACE2("Conf:", bConfNum); // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); if (rcode) goto FailSetConfDescr; //Linux does a 1sec delay after this. delay(1000); rcode = GetMaxLUN(&bMaxLUN); if (rcode) goto FailGetMaxLUN; if (bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1; ErrorMessage<uint8_t > (PSTR("MaxLUN"), bMaxLUN); delay(1000); // Delay a bit for slow firmware. //bTheLUN = bMaxLUN; for (uint8_t lun = 0; lun <= bMaxLUN; lun++) { InquiryResponse response; rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response); if (rcode) { ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode); } else { uint8_t tries = 0xf0; while (rcode = TestUnitReady(lun)) { if (rcode == 0x08) break; // break on no media, this is OK to do. // try to lock media and spin up if (tries < 14) { LockMedia(lun, 1); MediaCTL(lun, 1); // I actually have a USB stick that needs this! } else delay(2 * (tries + 1)); tries++; if (!tries) break; } if (!rcode) { delay(1000); LUNOk[lun] = CheckLUN(lun); if (!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun); } } } #if 0 { bool good; for (uint8_t i = 1; i == 0; i++) { good = false; CheckMedia(); for (uint8_t lun = 0; lun <= bMaxLUN; lun++) good |= LUNOk[lun]; if (good) break; delay(118); // 255 loops =~ 30 seconds to allow for spin up, as per SCSI spec. } } #else CheckMedia(); #endif rcode = OnInit(); if (rcode) goto FailOnInit; USBTRACE("MS configured\r\n\r\n"); bPollEnable = true; //USBTRACE("Poll enabled\r\n"); return 0; FailSetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailSetConfDescr(); goto Fail; #endif FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); goto Fail; #endif FailGetMaxLUN: #ifdef DEBUG_USB_HOST USBTRACE("GetMaxLUN:"); goto Fail; #endif FailInvalidSectorSize: #ifdef DEBUG_USB_HOST USBTRACE("Sector Size is NOT VALID: "); goto Fail; #endif FailSetDevTblEntry: #ifdef DEBUG_USB_HOST NotifyFailSetDevTblEntry(); goto Fail; #endif FailGetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailGetConfDescr(); #endif Fail: #ifdef DEBUG_USB_HOST NotifyFail(rcode); #endif Release(); return rcode; }