USB host for composite device like Android phone

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USB host for composite device like Android phone

1,887 Views
kai_liu
Senior Contributor I

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?

Tags (3)
0 Kudos
1 Reply

825 Views
kai_liu
Senior Contributor I

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.