Author Topic: Adding an IAD  (Read 8826 times)

rallysjd

  • Member
  • ***
  • Posts: 21
    • PiXCL Automation Technologies Inc
Adding an IAD
« on: June 10, 2012, 10:54:33 am »
Hello Jan,
I note  topic http://www.lvr.com/forum/index.php?topic=723.msg2725#msg2725 which has been helpful.

Running with Win 7:

I have HID device code that works properly, and my intent is to eventually merge MSD code to create a composite device. I'm starting with adding just the IAD section to the HID descriptor. This code seems to be correct, and Windows can identify it, though still as an HID input device, but the enumeration then fails and the device is not accessible. My understanding at present is that the host identifies the device as a Composite, then loads the appropriate driver, in this case the generic HID.

Here's the descriptor.

Code: [Select]
const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] =
  {
    0x12,                       /*bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/

    0x00,                       /*bcdUSB  = 0x0200*/
    0x02,

    0xEF,                       /*bDeviceClass: 0x00 for single HID, 0xEF for composite with IAD, below */
    0x02,                       /*bDeviceSubClass:0x00 for single HID, 0x02 for composite with IAD, below*/
    0x01,                       /*bDeviceProtocol: 0x00 for single HID, 0x01 with IAD*/
    0x40,                       /*bMaxPacketSize 40*/

    0x83, 0x04,                 /*idVendor = 0x0483. Adjust this when PiXCL VID is available */
   
0x50, 0x57,                 /*idProduct = 0x5750. Adjust this when PiXCL PID is available */

    0x10, 0x03,                 /*bcdDevice rel. 3.10 */

// these indices refer to ONE_DESCRIPTOR String_Descriptor array elements in usb_props.c
    1,                          /*Index of string descriptor describing manufacturer */
    2,                          /*Index of string descriptor describing product*/
    3,                          /*Index of string descriptor describing the device serial number */

    0x01                        /*bNumConfigurations*/
  }
  ; /* CustomHID_DeviceDescriptor */


/* USB Configuration Descriptor */
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
{
    0x09, /* bLength: Configuration Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,     /* wTotalLength: Bytes returned */
    0x00,
    0x01,         /* bNumInterfaces: 1 interface for the HID only*/
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xC0,         /* bmAttributes: Bus powered */
    0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */


/* here is where the USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE is defined  */

0x08, // bLength, size of this descriptor, #define required?
USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE, // 0x0B
0x00, // bFirstInterface usually 0x00
0x01, // bInterfaceCount. 1 at present.
0x03, // bFunctionClass, use HID, as below
0x00, // bFunctionSubClass
0x00, // bFunctionProtocol
0x00, // Function string descriptor index. 0x00 = no string descriptor


    /************** Custom HID Interface Descriptor ****************/

    0x09,         /* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
    0x00,         /* bInterfaceNumber: Number of Interface */
    0x00,         /* bAlternateSetting: Alternate setting */
    0x02,         /* bNumEndpoints */
    0x03,         /* bInterfaceClass: HID */
    0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
    0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
    0,            /* iInterface: Index of string descriptor */
    /******************** Descriptor of Custom HID HID ********************/
   

    0x09,         /* bLength: HID Descriptor size */
    HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
    0x10, 0x01,         /* bcdHID: HID Class Spec release number 0x0110 = v1.1*/
    0x00,         /* bCountryCode: Hardware target country */
    0x01,         /* bNumDescriptors: Number of HID class descriptors to follow */
    0x22,         /* bDescriptorType */
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */
    0x00,


    . . .


What's unclear to me is whether having an IAD with just one device is valid. If I reset the device class to HID (0x03) from Generic AID (0xEF), and leave the IAD structure in place, the device is not enumerated correctly (as above).
Can you suggest what's wrong in the descriptor code?

regards
SD

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Adding an IAD
« Reply #1 on: June 10, 2012, 02:36:33 pm »
An IAD is for use when a device has multiple functions and one or more of the functions uses multiple interfaces.

Neither HID nor mass storage use multiple interfaces so you don't need an IAD.

Jan

rallysjd

  • Member
  • ***
  • Posts: 21
    • PiXCL Automation Technologies Inc
Re: Adding an IAD
« Reply #2 on: June 10, 2012, 06:27:55 pm »
Thanks for the fast reply. If I understand you correctly, a MSD/HID composite device does not require an IAD. My HID will eventually handle sensor data (input) and control data (output) reports, plus events from the touch screen and other process control inputs. Am I right in thinking that these would normally have their IN/OUT endpoints all on the one interface?

If so then my next work item is to merge the HID and MSD descriptors (and related code) into one composite descriptor.

regards
SD

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Adding an IAD
« Reply #3 on: June 10, 2012, 09:45:22 pm »
Yes, a HID uses a single interface and a mass-storage device uses a single interface.

Jan