uint8_t * ChipKITUSBHost::GetCurrentConfigurationDescriptor(uint8_t deviceAddress) { return(USBHostGetCurrentConfigurationDescriptor(deviceAddress)); }
BOOL USBHostUSBBTInit( BYTE address, DWORD flags, BYTE clientDriverID ) { int i = 0; BYTE *descriptor; UART2PrintString( "USBBT init\r\n" ); descriptor = USBHostGetCurrentConfigurationDescriptor( address ); // Find the next interface descriptor. while (i < ((USB_CONFIGURATION_DESCRIPTOR *)descriptor)->wTotalLength) { // See if we are pointing to an interface descriptor. if (descriptor[i+1] == USB_DESCRIPTOR_INTERFACE) { g_usbbt.endpointCtrl = 0; g_usbbt.endpointInt = 0; g_usbbt.endpointBulkIN = 0; g_usbbt.endpointBulkOUT = 0; // Scan for endpoint descriptors. i += descriptor[i]; while (descriptor[i+1] == USB_DESCRIPTOR_ENDPOINT) { if (descriptor[i+3] == 0x02) // Bulk { if (((descriptor[i+2] & 0x80) == 0x80) && (g_usbbt.endpointBulkIN == 0)) { g_usbbt.endpointBulkIN = descriptor[i+2]; } if (((descriptor[i+2] & 0x80) == 0x00) && (g_usbbt.endpointBulkOUT == 0)) { g_usbbt.endpointBulkOUT = descriptor[i+2]; } } else if(descriptor[i+3] == 0x03) // Interrupt { g_usbbt.endpointInt = descriptor[i+2]; } else if(descriptor[i+3] == 0x00) // Control { g_usbbt.endpointCtrl = descriptor[i+2]; } i += descriptor[i]; } if ((g_usbbt.endpointInt != 0) && (g_usbbt.endpointBulkIN != 0) && (g_usbbt.endpointBulkOUT != 0)) { g_usbbt.initialized = 1; g_usbbt.deviceAddress = address; g_usbbt.clientDriverID = clientDriverID; /* if(g_usbbt.endpointBulkIN_Busy == 0) { USBHostBlukRead(address,bulk_buf,MAX_DATA_PACKET_LENGTH); } if(g_usbbt.endpointInt_Busy == 0) { USBHostIntRead(address,int_buf,MAX_DATA_PACKET_LENGTH); }*/ UART2PrintString( " Control endpoint : " ); UART2PutHex( g_usbbt.endpointCtrl ); UART2PrintString( " Interrupt endpoint IN: " ); UART2PutHex( g_usbbt.endpointInt ); UART2PrintString( " Bulk endpoint IN: " ); UART2PutHex( g_usbbt.endpointBulkIN ); UART2PrintString( " Bulk endpoint OUT: " ); UART2PutHex( g_usbbt.endpointBulkOUT ); UART2PrintString( "\r\n" ); usb_bt_init(); return TRUE; } } // Jump to the next descriptor in this configuration. i += descriptor[i]; } return FALSE; }
/**************************************************************************** Function: void* AndroidInitialize_Pv1 ( BYTE address, DWORD flags, BYTE clientDriverID ) Summary: Per instance client driver for Android device. Called by USB host stack from the client driver table. Description: Per instance client driver for Android device. Called by USB host stack from the client driver table. Precondition: None Parameters: BYTE address - the address of the device that is being initialized DWORD flags - the initialization flags for the device BYTE clientDriverID - the clientDriverID for the device Return Values: TRUE - initialized successfully FALSE - does not support this device Remarks: This is a internal API only. This should not be called by anything other than the USB host stack via the client driver table ***************************************************************************/ void* AndroidInitialize_Pv1 ( BYTE address, DWORD flags, BYTE clientDriverID ) { BYTE *config_descriptor = NULL; BYTE *device_descriptor = NULL; WORD tempWord; BYTE *config_desc_end; ANDROID_PROTOCOL_V1_DEVICE_DATA* device = NULL; BYTE i; device_descriptor = USBHostGetDeviceDescriptor(address); ReadWORD(&tempWord, &device_descriptor[USB_DEV_DESC_VID_OFFSET]); if(tempWord == 0x18D1) { ReadWORD(&tempWord, &device_descriptor[USB_DEV_DESC_PID_OFFSET]); if((tempWord == 0x2D00) || (tempWord == 0x2D01)) { for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++) { if(devices_pv1[i].state == WAITING_FOR_ACCESSORY_RETURN) { device = &devices_pv1[i]; device->state = RETURN_OF_THE_ACCESSORY; break; } } } } //if this isn't an old accessory, then it must be a new one if(device == NULL) { //Find the first available device. for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++) { if(devices_pv1[i].state == NO_DEVICE) { device = &devices_pv1[i]; if( (flags & ANDROID_INIT_FLAG_BYPASS_PROTOCOL) == ANDROID_INIT_FLAG_BYPASS_PROTOCOL) { device->state = RETURN_OF_THE_ACCESSORY; } else { device->state = DEVICE_ATTACHED; } break; } } } config_descriptor = USBHostGetCurrentConfigurationDescriptor( address ); //Save the total length for this configuration descriptor ReadWORD(&tempWord,&config_descriptor[2]); //Record the end of the descriptor so we know when to stop searching through // the descriptor list config_desc_end = config_descriptor + tempWord; //Skip past the configuration part of this descriptor to the next // descriptor in the configuration descriptor list. The size of the config // part of the descriptor is the first byte of the list. config_descriptor += *config_descriptor; //Search the entire configuration descriptor for COMM interfaces while(config_descriptor < config_desc_end) { //We are expecting a interface descriptor if(config_descriptor[USB_DESC_BDESCRIPTORTYPE_OFFSET] != USB_DESCRIPTOR_INTERFACE) { //Jump past this descriptor by adding the current descriptor length // to the current descriptor pointer. config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; //Jump back to the top of the while loop to continue searching through // this configuration for the next interface continue; } device->address = address; device->clientDriverID = clientDriverID; if( (config_descriptor[USB_INTERFACE_DESC_BINTERFACECLASS_OFFSET] == 0xFF) && (config_descriptor[USB_INTERFACE_DESC_BINTERFACESUBCLASS_OFFSET] == 0xFF) && (config_descriptor[USB_INTERFACE_DESC_BINTERFACEPROTOCOL_OFFSET] == 0x00)) { //Jump past this descriptor to the next descriptor. config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; //Parse through the rest of this interface. Stop when we reach the // next interface or the end of the configuration descriptor while((config_descriptor[USB_DESC_BDESCRIPTORTYPE_OFFSET] != USB_DESCRIPTOR_INTERFACE) && (config_descriptor < config_desc_end)) { if(config_descriptor[USB_DESC_BDESCRIPTORTYPE_OFFSET] == USB_DESCRIPTOR_ENDPOINT) { //If this is an endpoint descriptor in the DATA interface, then // copy all of the endpoint data to the device information. if((config_descriptor[USB_ENDPOINT_DESC_BENDPOINTADDRESS_OFFSET] & 0x80) == 0x80) { //If this is an IN endpoint, record the endpoint number device->INEndpointNum = config_descriptor[USB_ENDPOINT_DESC_BENDPOINTADDRESS_OFFSET]; //record the endpoint size (2 bytes) device->INEndpointSize = (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET]) + (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET+1] << 8); } else { //Otherwise this is an OUT endpoint, record the endpoint number device->OUTEndpointNum = config_descriptor[USB_ENDPOINT_DESC_BENDPOINTADDRESS_OFFSET]; //record the endpoint size (2 bytes) device->OUTEndpointSize = (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET]) + (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET+1] << 8); } } config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; } } else { //Jump past this descriptor by adding the current descriptor length // to the current descriptor pointer. config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; } } return device; }
BOOL USBHostMIDIInit ( BYTE address, DWORD flags, BYTE clientDriverID ) { BYTE *config_descriptor; BYTE *ptr; BYTE bDescriptorType; BYTE bLength; BYTE bNumEndpoints; BYTE bNumInterfaces; BYTE bInterfaceNumber; BYTE bAlternateSetting; BYTE Class; BYTE SubClass; BYTE Protocol; BYTE currentEndpoint; WORD wTotalLength; BYTE index = 0; BOOL error = FALSE; MIDI_DEVICE *device = &devices[0]; config_descriptor = USBHostGetCurrentConfigurationDescriptor(address); ptr = config_descriptor; // Load up the values from the Configuration Descriptor bLength = *ptr++; bDescriptorType = *ptr++; wTotalLength = *ptr++; // In case these are not word aligned wTotalLength += (*ptr++) << 8; bNumInterfaces = *ptr++; // Skip over the rest of the Configuration Descriptor index += bLength; ptr = &config_descriptor[index]; while (!error && (index < wTotalLength)) { // Check the descriptor length and type bLength = *ptr++; bDescriptorType = *ptr++; // Find an interface descriptor if (bDescriptorType != USB_DESCRIPTOR_INTERFACE) { // Skip over the rest of the Descriptor index += bLength; ptr = &config_descriptor[index]; } else { // Read some data from the interface descriptor bInterfaceNumber = *ptr++; bAlternateSetting = *ptr++; bNumEndpoints = *ptr++; Class = *ptr++; SubClass = *ptr++; Protocol = *ptr++; // Check to see if this is a MIDI inteface descripter if (Class != AUDIO_CLASS || SubClass != MIDI_SUB_CLASS || Protocol != MIDI_PROTOCOL) { // If we cannot support this interface, skip it. index += bLength; ptr = &config_descriptor[index]; continue; } // Initialize the device device->deviceAddress = address; device->clientDriverID = clientDriverID; device->numEndpoints = bNumEndpoints; // Allocate enough memory for each endpoint if ((device->endpoints = (MIDI_ENDPOINT_DATA*)malloc( sizeof(MIDI_ENDPOINT_DATA) * bNumEndpoints)) == NULL) { // Out of memory error = TRUE; } if (!error) { // Skip over the rest of the Interface Descriptor index += bLength; ptr = &config_descriptor[index]; // Find the Endpoint Descriptors. There might be Class and Vendor descriptors in here currentEndpoint = 0; while (!error && (index < wTotalLength) && (currentEndpoint < bNumEndpoints)) { bLength = *ptr++; bDescriptorType = *ptr++; if (bDescriptorType != USB_DESCRIPTOR_ENDPOINT) { // Skip over the rest of the Descriptor index += bLength; ptr = &config_descriptor[index]; } else { device->endpoints[currentEndpoint].endpointAddress = *ptr++; ptr++; device->endpoints[currentEndpoint].endpointSize = *ptr++; device->endpoints[currentEndpoint].endpointSize += (*ptr++) << 8; device->endpoints[currentEndpoint].busy = FALSE; if(device->endpoints[currentEndpoint].endpointSize > 64) { // For full speed bulk endpoints, only 8, 16, 32, and 64 byte packets are supported // But we will accept anything less than or equal to 64. error = TRUE; } // Get ready for the next endpoint. currentEndpoint++; index += bLength; ptr = &config_descriptor[index]; } } } // Ensure that we found all the endpoints for this interface. if (currentEndpoint != bNumEndpoints) { error = TRUE; } } } if (error) { // Destroy whatever list of interfaces, settings, and endpoints we created. // The "new" variables point to the current node we are trying to remove. if (device->endpoints != NULL) { free( device->endpoints ); device->endpoints = NULL; } return FALSE; } #ifdef DEBUG_MODE UART2PrintString( "USB MIDI Client Initalized: " ); UART2PrintString( " address=" ); UART2PutDec( address ); UART2PrintString( " Number of Endpoings=" ); UART2PutHex( bNumEndpoints ); UART2PrintString( "\r\n" ); #endif // Notify that application that we've been attached to a device. USB_HOST_APP_EVENT_HANDLER(address, EVENT_MIDI_ATTACH, device, sizeof(MIDI_DEVICE) ); return TRUE; } // USBHostMIDIInit