ガレスタさんのDIY日記

電子回路、Web、組み込み、自作エフェクターを語るblog

自分用メモ Interface Association Descriptor

Interface Association Descriptor

USB2.0により増えた規格。
それまでは複合デバイスを作る際どれがどのインターフェイスがわからず無法地帯だったらしい
そこでIAD増やして明示的にした

結局どゆことかというと
USBデバイスではコンフィグに複数のInterfaceを持つことができる。
そのときにどれがどのファンクションに対応するかわからんのでそいつの補足をする機能
f:id:gsmcustomeffects:20170621022247p:plain

でぃすくりぷたと兼ねて説明

バイスディスクリプタ欄にあらかじめIADであると明示することで最初のGetDesicriptorの段階でホスト側にIADですよ~と伝える
そうするとホストはInterfaceが複数いる何かがつながったな?やれやれと理解するわけだ

f:id:gsmcustomeffects:20170621023624p:plain

んで肝心なInterface Association Descriptorはこういう構成

f:id:gsmcustomeffects:20170621025130p:plain


あとは

コンフィグ→IAD→インターフェイス→その他→エンドポイント

的な感じでディスクリプタを記述していく

STでDualCOMを実現するときのディスクリプタはこんな感じ

device descriptor

__ALIGN_BEGIN uint8_t USBD_HS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = // Virtual_Com_Port_DeviceDescriptor
  {
    0x12,                       /* 00 bLength */
    USB_DESC_TYPE_DEVICE,       /* 01 bDescriptorType*/
#if (USBD_LPM_ENABLED == 1)
    0x01,                       /* 02 bcdUSB */ /* changed to USB version 2.01
                                               in order to support LPM L1 suspend
                                               resume test of USBCV3.0*/
#else
    0x00,                       /* 02 bcdUSB */
#endif

    0x02,						/* 03 */
    0xEF,                       /* 04 bDeviceClass IAD*/
    0x02,                       /* 05 bDeviceSubClass*/
    0x01,                       /* 06 bDeviceProtocol IAD*/
    USB_MAX_EP0_SIZE,           /* 07 bMaxPacketSize*/
    LOBYTE(USBD_VID),           /* 08 idVendor*/
    HIBYTE(USBD_VID),           /* 09 idVendor*/
    LOBYTE(USBD_PID_HS),        /* 10 idVendor*/
    HIBYTE(USBD_PID_HS),        /* 11 idVendor*/
    0x00,                       /* 12 bcdDevice rel. 2.00*/
    0x02,						/* 13 */
    USBD_IDX_MFC_STR,           /* 14 Index of manufacturer  string*/
    USBD_IDX_PRODUCT_STR,       /* 15 Index of product string*/
    USBD_IDX_SERIAL_STR,        /* 16 Index of serial number string*/
    USBD_MAX_NUM_CONFIGURATION  /* 17 bNumConfigurations*/
  } ;

config descriptorおよび他の記述

__ALIGN_BEGIN uint8_t USBD_IAD_CfgHSDesc[USB_IAD_CONFIG_DESC_SIZ] __ALIGN_END =
{
	//Configuation Descriptor
	0x09,								// 00 bLength: Configuation Descriptor size
	USB_DESC_TYPE_CONFIGURATION,		// 01 bDescriptorType: Configuration
	USB_IAD_CONFIG_DESC_SIZ,			// 02 wTotalLength:no of returned bytes
	0x00,								// 03
	0x04,								// 04 bNumInterfaces: 4 interface
	0x01,								// 05 bConfigurationValue: Configuration value
	0x00,								// 06 iConfiguration: Index of string descriptor describing the configuration
	0xC0,								// 07 bmAttributes: self powered
	0x32,								// 08 MaxPower 100 mA

	// IAD 1 -> CDC1
	0x08,// 09 bLength: Interface Descriptor size
	0x0B,								// 10 bDescriptorType: IAD
	0x00,								// 11 bFirstInterface
	0x02,								// 12 bInterfaceCount
	0x02,								// 13 bFunctionClass: CDC
	0x02,								// 14 bFunctionSubClass
	0x01,								// 15 bFunctionProtocol
	0x02,								// 16 iFunction

	//Interface Descriptor
	0x09,								// 17 bLength: Interface Descriptor size
	USB_DESC_TYPE_INTERFACE,			// 18 bDescriptorType: Interface
	// Interface descriptor type
	0x00,								// 19 bInterfaceNumber: Number of Interface
	0x00,								// 20 bAlternateSetting: Alternate setting
	0x01,								// 21 bNumEndpoints: One endpoints used
	0x02,								// 22 bInterfaceClass: Communication Interface Class
	0x02,								// 23 bInterfaceSubClass: Abstract Control Model
	0x01,								// 24 bInterfaceProtocol: Common AT commands
	0x00,								// 25 iInterface:

	//Header Functional Descriptor
	0x05,								// 26 bLength: Endpoint Descriptor size
	0x24,								// 27 bDescriptorType: CS_INTERFACE
	0x00,								// 28 bDescriptorSubtype: Header Func Desc
	0x10,								// 29 bcdIAD: spec release number
	0x01,								// 30

	//Call Managment Functional Descriptor
	0x05,								// 31 bFunctionLength
	0x24,								// 32 bDescriptorType: CS_INTERFACE
	0x01,								// 33 bDescriptorSubtype: Call Management Func Desc
	0x00,								// 34 bmCapabilities: D0+D1
	0x01,								// 35 bDataInterface: 1

	//ACM CDC1 Functional Descriptor
	0x04,								// 36 bFunctionLength
	0x24,								// 37 bDescriptorType: CS_INTERFACE
	0x02,								// 38 bDescriptorSubtype: Abstract Control Management desc
	0x02,								// 39 bmCapabilities

	//Union Functional Descriptor
	0x05,								// 40 bFunctionLength
	0x24,								// 41 bDescriptorType: CS_INTERFACE
	0x06,								// 42 bDescriptorSubtype: Union func desc
	0x00,								// 43 bMasterInterface: Communication class interface
	0x01,								// 44 bSlaveInterface0: Data Class Interface

	//Endpoint CDC1 CMD Descriptor
	0x07,								// 45 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_ENDPOINT,				// 46 bDescriptorType: Endpoint
	IAD_CDC1_CMD_EP,					// 47 bEndpointAddress: (IN2)
	0x03,								// 48 bmAttributes: Interrupt
	LOBYTE(IAD_CDC_CMD_PACKET_SIZE),	// 49 wMaxPacketSize:
	HIBYTE(IAD_CDC_CMD_PACKET_SIZE),	// 50
	0xFF,								// 51 bInterval:
	//---------------------------------------------------------------------------

	//Data class interface descriptor
	0x09,								// 52 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_INTERFACE,			// 53 bDescriptorType:
	0x01,								// 54 bInterfaceNumber: Number of Interface
	0x00,								// 55 bAlternateSetting: Alternate setting
	0x02,								// 56 bNumEndpoints: Two endpoints used
	0x0A,								// 57 bInterfaceClass: CDC
	0x00,								// 58 bInterfaceSubClass:
	0x00,								// 59 bInterfaceProtocol:
	0x00,								// 60 iInterface:

	//Endpoint CDC1 OUT Descriptor
	0x07,								// 61 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_ENDPOINT,				// 62 bDescriptorType: Endpoint
	IAD_CDC1_OUT_EP,					// 63 bEndpointAddress: (OUT1)
	0x02,								// 64 bmAttributes: Bulk
	LOBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 65 wMaxPacketSize:
	HIBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 66
	0x00,								// 67 bInterval: ignore for Bulk transfer

	//Endpoint CDC1 IN Descriptor
	0x07,								// 68 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_ENDPOINT,				// 69 bDescriptorType: Endpoint
	IAD_CDC1_IN_EP,						// 70 bEndpointAddress: (IN1)
	0x02,								// 71 bmAttributes: Bulk
	LOBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 72 wMaxPacketSize:
	HIBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 73
	0x00,								// 74 bInterval

	// IAD 2 -> CDC2
	0x08,// 75 bLength: Interface Descriptor size
	0x0B,								// 76 bDescriptorType: IAD
	0x02,								// 77 bFirstInterface
	0x02,								// 78 bInterfaceCount
	0x02,								// 79 bFunctionClass: CDC
	0x02,								// 80 bFunctionSubClass
	0x01,								// 81 bFunctionProtocol
	0x02,								// 82 iFunction

	//Interface Descriptor
	0x09,// 83 bLength: Interface Descriptor size
	USB_DESC_TYPE_INTERFACE,			// 84 bDescriptorType: Interface
	// Interface descriptor type
	0x02,								// 85 bInterfaceNumber: Number of Interface
	0x00,								// 86 bAlternateSetting: Alternate setting
	0x01,								// 87 bNumEndpoints: One endpoints used
	0x02,								// 88 bInterfaceClass: Communication Interface Class
	0x02,								// 89 bInterfaceSubClass: Abstract Control Model
	0x01,								// 90 bInterfaceProtocol: Common AT commands
	0x00,								// 91 iInterface:

	//Header Functional Descriptor
	0x05,								// 92 bLength: Endpoint Descriptor size
	0x24,								// 93 bDescriptorType: CS_INTERFACE
	0x00,								// 94 bDescriptorSubtype: Header Func Desc
	0x10,								// 95 bcdCDC: spec release number
	0x01,								// 96

	//Call Managment Functional Descriptor
	0x05,								// 97 bFunctionLength
	0x24,								// 98 bDescriptorType: CS_INTERFACE
	0x01,								// 99 bDescriptorSubtype: Call Management Func Desc
	0x00,								// 100 bmCapabilities: D0+D1
	0x03,								// 101 !! bDataInterface:

	//ACM CDC2 Functional Descriptor
	0x04,								// 102 bFunctionLength
	0x24,								// 103 bDescriptorType: CS_INTERFACE
	0x02,								// 104 bDescriptorSubtype: Abstract Control Management desc
	0x02,								// 105 bmCapabilities

	//Union Functional Descriptor
	0x05,								// 106 bFunctionLength
	0x24,								// 107 bDescriptorType: CS_INTERFACE
	0x06,								// 108 bDescriptorSubtype: Union func desc
	0x02,								// 109 !! bMasterInterface: Communication class interface
	0x03,								// 110 !! bSlaveInterface0: Data Class Interface

	//Endpoint CDC2 CMD Descriptor
	0x07,								// 111 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_ENDPOINT,				// 112 bDescriptorType: Endpoint
	IAD_CDC2_CMD_EP,					// 113 bEndpointAddress: (IN4)
	0x03,								// 114 bmAttributes: Interrupt
	LOBYTE(IAD_CDC_CMD_PACKET_SIZE),	// 115 wMaxPacketSize:
	HIBYTE(IAD_CDC_CMD_PACKET_SIZE),	// 116
	0xFF,								// 117 bInterval:
	//---------------------------------------------------------------------------

	//Data class interface descriptor
	0x09,								// 118 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_INTERFACE,			// 119 bDescriptorType:
	0x03,								// 120 bInterfaceNumber: Number of Interface
	0x00,								// 121 bAlternateSetting: Alternate setting
	0x02,								// 122 bNumEndpoints: Two endpoints used
	0x0A,								// 123 bInterfaceClass: CDC
	0x00,								// 124 bInterfaceSubClass:
	0x00,								// 125 bInterfaceProtocol:
	0x00,								// 126 iInterface:

	//Endpoint CDC2 OUT Descriptor
	0x07,								// 127 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_ENDPOINT,				// 128 bDescriptorType: Endpoint
	IAD_CDC2_OUT_EP,					// 129 bEndpointAddress: (OUT3)
	0x02,								// 130 bmAttributes: Bulk
	LOBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 131 wMaxPacketSize:
	HIBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 132
	0x00,								// 133 bInterval: ignore for Bulk transfer

	//Endpoint CDC2 IN Descriptor
	0x07,								// 134 bLength: Endpoint Descriptor size
	USB_DESC_TYPE_ENDPOINT,				// 135 bDescriptorType: Endpoint
	IAD_CDC2_IN_EP,						// 136 bEndpointAddress: (IN3)
	0x02,								// 137 bmAttributes: Bulk
	LOBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 138 wMaxPacketSize:
	HIBYTE(IAD_DATA_HS_MAX_PACKET_SIZE),// 139
	0x00,								// 140 bInterval
};

恥ずかしい余談

ちなみにCDCはInterfaceがもともと二つある。
DATAクラス、CDCクラスがそれにあたる。
なのでCDCが2つあるとどっちがどっちのDATAやねん?という問題が発生する。
それを解決するのがIAD1とIAD2なわけ
CDCが2つ→DATAクラス2個、CDCクラス2個→よって総インターフェイス数は4つ(最初CDC2つなら2やん?と勘違いしてた僕
なので下記の記述が4になってる
f:id:gsmcustomeffects:20170621030224p:plain

まとめ

f:id:gsmcustomeffects:20170621030336p:plain