I am developing USB host application for Android phone to support ADB and AOA protocal.
Before kicking off the project, I verified the idea on Arduino + UHS (share similiar hardware platform with ADK) and PyUSB. PyUSB is not stable, however it works fine by reading from IN endpoint and writing to OUT endpoint of ADB interface.
Obviously, each phone has its own VID/PID, and its bDeviceClass / bDeviceSubClass / bDeviceProtocol as 0x00/0x00/0x00. The following information comes from USBVIEW tool from microsoft.
============================== HTC Mass Storage Device Descriptor: bcdUSB: 0x0200 bDeviceClass: 0x00 bDeviceSubClass: 0x00 bDeviceProtocol: 0x00 bMaxPacketSize0: 0x40 (64) idVendor: 0x0BB4 idProduct: 0x0C02 bcdDevice: 0x0100 iManufacturer: 0x03 0x0409: "HTC" iProduct: 0x02 0x0409: "Android Phone" iSerialNumber: 0x01 0x0409: "HT99SLG00034" bNumConfigurations: 0x01 ConnectionStatus: DeviceConnected Current Config Value: 0x01 Device Bus Speed: Full Device Address: 0x02 Open Pipes: 4 Endpoint Descriptor: bEndpointAddress: 0x01 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00 Endpoint Descriptor: bEndpointAddress: 0x81 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00 Endpoint Descriptor: bEndpointAddress: 0x02 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00 Endpoint Descriptor: bEndpointAddress: 0x82 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00 Configuration Descriptor: wTotalLength: 0x0037 bNumInterfaces: 0x02 bConfigurationValue: 0x01 iConfiguration: 0x00 bmAttributes: 0x80 (Bus Powered ) MaxPower: 0x80 (256 Ma) Interface Descriptor: bInterfaceNumber: 0x00 bAlternateSetting: 0x00 bNumEndpoints: 0x02 bInterfaceClass: 0x08 bInterfaceSubClass: 0x06 bInterfaceProtocol: 0x50 iInterface: 0x04 0x0409: "Mass Storage" Endpoint Descriptor: bEndpointAddress: 0x01 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00 Endpoint Descriptor: bEndpointAddress: 0x81 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00 Interface Descriptor: bInterfaceNumber: 0x01 bAlternateSetting: 0x00 bNumEndpoints: 0x02 bInterfaceClass: 0xFF bInterfaceSubClass: 0x42 bInterfaceProtocol: 0x01 iInterface: 0x05 0x0409: "ADB" Endpoint Descriptor: bEndpointAddress: 0x02 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00 Endpoint Descriptor: bEndpointAddress: 0x82 Transfer Type: Bulk wMaxPacketSize: 0x0200 (512) bInterval: 0x00
Currently I am still browsing source code for Freescale USB stack and trying to understand its internal data structure. The static table "USB_HOST_DRIVER_INFO DriverInfoTable[]" must be registered. If I use it, then it will be filled as zero for all information fields. Since USB_CLASS_ADB = 0x00, USB_SUBCLASS_ADB = 0x00, USB_PROTOCOL_ADB = 0x00.
static const USB_HOST_DRIVER_INFO DriverInfoTable[] = { { {0x00,0x00}, /* Vendor ID per USB-IF */ {0x00,0x00}, /* Product ID per manufacturer */ USB_CLASS_ADB, /* Class code */ USB_SUBCLASS_ADB, /* Sub-Class code */ USB_PROTOCOL_ADB, /* Protocol */ 0, /* Reserved */ usb_host_adb_event /* Application call back function */ }, /* USB 1.1 hub */ { {0x00,0x00}, /* Vendor ID per USB-IF */ {0x00,0x00}, /* Product ID per manufacturer */ USB_CLASS_HUB, /* Class code */ USB_SUBCLASS_HUB_NONE, /* Sub-Class code */ USB_PROTOCOL_HUB_LS, /* Protocol */ 0, /* Reserved */ usb_host_hub_device_event /* Application call back function */ }, { {0x00,0x00}, /* All-zero entry terminates */ {0x00,0x00}, /* driver info list. */ 0, 0, 0, 0, NULL } };
In fact, when I double checked with other devices like DELL mouse (HID), PL2303(CDC) , FT232 (CDC), all of them defines their deviceClass/deviceSubCLass/deviceProtocal as 0x00/0x00/0x00. How can user application match desired devices from others? It is better to find a method/data structure to match device's interface parameters such as bInterfaceClass/bInterfaceSubClass/bInterfaceProtocol.
Does freescale has any demo software to support USB host for composite devices?
After reading source code, I found that:
usb_host_driver_info_match(dev, intf, info) if idVendor && idProduct (dev/info) matches? return TRUE if bDeviceClass == 0xFF or bDeviceClass matches? if bDeviceSubClass && bDeviceProtocol matches? return TRUE if bDeviceSubClass && bDeviceProtocol == 0xFF? return TRUE if bDeviceSubClass == 0xFF && bDeviceProtocol matches? return TRUE if bDeviceSubClass == 0xFF && bDeviceProtocol = 0xFF? return TRUE if bDeviceClass = 0xFF or info.bDeviceClass == intf.bInterfaceClass? if (info.bDeviceSubClass == intf.bInterfaceSubClass) && (info.bDeviceProtocol == intf.bInterfaceProtocol)? return TRUE ====> matches if (info.bDeviceSubClass == intf.bInterfaceSubClass) && (info.bDeviceProtocol == 0xFF)? return TRUE if (info.bDeviceSubClass == 0xFF) && (info.bDeviceProtocol == intf.bInterfaceProtocol)? return TRUE if (info.bDeviceSubClass == 0xFF) && (info.bDeviceProtocol == 0xFF)? return TRUE
In usb_host_driver_info_match(), the Drivertable constant table will be compared with
idVendor/idProduct
bDeviceClass/bDeviceSubClass/bDeviceProtocol
bInterfaceClass/bInterfaceSubClass/bInterfaceProtocol
Most of the return values are Ture.
Basically I define 0xFF/0x42/0x01 in the driver table. It should return True from one branch.