Forum: Mikrocontroller und Digitale Elektronik NXP LPCOpen: USB Composite Device (HID Generic und CDC ACM) erzeugt zweites Geistergerät


von Robert B. (robertb)


Lesenswert?

Hi!

Ich rätsel momentan leider ein wenig an einem USB Composite Device 
Descriptor für HID Generic und CDC ACM.

Basierend auf dem Composite Device Beispiel aus der NXP LPCOpen Library 
(HID Mouse + CDC) habe ich die HID Mouse auf HID Generic geändert. Da 
die HID-Mouse nur IN-Reports sendet, ich aber ein bidirektionales HID 
brauche musste ich einen weiteren OUT-Endpoint definieren.

1. EP-out vom CDC ACM auf 0x01, dafür neuen Out-EP für HID
2. Descriptor LÄnge plus weitere USB_ENDPOINT_DESC_SIZE
3. bNumEndpoints des HID Descriptors von 1 auf 2
4. Out-EP Descriptor hinzugefügt
1
/* HID In/Out Endpoint Address */
2
#define HID_EP_IN                           0x81
3
#define HID_EP_OUT                          0x01
4
#define USB_HID_IF_NUM                      0
5
6
#define HID_INPUT_REPORT_BYTES       8        /* size of report in Bytes */
7
#define HID_OUTPUT_REPORT_BYTES      8        /* size of report in Bytes */
8
#define HID_FEATURE_REPORT_BYTES     1        /* size of report in Bytes */
9
10
/* Manifest constants defining interface numbers and endpoints used by a
11
   CDC class interfaces in this application.
12
 */
13
#define USB_CDC_CIF_NUM                     1
14
#define USB_CDC_DIF_NUM                     2
15
#define USB_CDC_IN_EP                       0x82
16
#define USB_CDC_OUT_EP                      0x02
17
#define USB_CDC_INT_EP                      0x83
18
19
/**
20
 * HID Report Descriptor
21
 */
22
const uint8_t HID_ReportDescriptor[] = {
23
  HID_UsagePageVendor(0x00),
24
  HID_Usage(0x01),
25
  HID_Collection(HID_Application),
26
  HID_LogicalMin(0),  /* value range: 0 - 0xFF */
27
  HID_LogicalMaxS(0xFF),
28
  HID_ReportSize(8),  /* 8 bits */
29
  HID_ReportCount(HID_INPUT_REPORT_BYTES),
30
  HID_Usage(0x01),
31
  HID_Input(HID_Data | HID_Variable | HID_Absolute),
32
  HID_ReportCount(HID_OUTPUT_REPORT_BYTES),
33
  HID_Usage(0x01),
34
  HID_Output(HID_Data | HID_Variable | HID_Absolute),
35
  HID_ReportCount(HID_FEATURE_REPORT_BYTES),
36
  HID_Usage(0x01),
37
  HID_Feature(HID_Data | HID_Variable | HID_Absolute),
38
  HID_EndCollection,
39
};
40
const uint16_t HID_ReportDescSize = sizeof(HID_ReportDescriptor);
41
42
/**
43
 * USB Standard Device Descriptor
44
 */
45
ALIGNED(4) const uint8_t USB_DeviceDescriptor[] = {
46
  USB_DEVICE_DESC_SIZE,      /* bLength */
47
  USB_DEVICE_DESCRIPTOR_TYPE,    /* bDescriptorType */
48
  WBVAL(0x0200),          /* bcdUSB : 2.00*/
49
  USB_DEVICE_CLASS_MISCELLANEOUS,  /* bDeviceClass */
50
  0x02,              /* bDeviceSubClass */
51
  0x01,              /* bDeviceProtocol */
52
  USB_MAX_PACKET0,        /* bMaxPacketSize0 */
53
  WBVAL(0x1FC9),          /* idVendor */
54
  WBVAL(0x0087),          /* idProduct */
55
  WBVAL(0x0100),          /* bcdDevice : 1.00 */
56
  0x01,              /* iManufacturer */
57
  0x02,              /* iProduct */
58
  0x03,              /* iSerialNumber */
59
  0x01              /* bNumConfigurations */
60
};
61
62
/**
63
 * USB FSConfiguration Descriptor
64
 * All Descriptors (Configuration, Interface, Endpoint, Class, Vendor)
65
 */
66
ALIGNED(4) uint8_t USB_FsConfigDescriptor[] = {
67
  /* Configuration 1 */
68
  USB_CONFIGURATION_DESC_SIZE,      /* bLength */
69
  USB_CONFIGURATION_DESCRIPTOR_TYPE,    /* bDescriptorType */
70
  WBVAL(                  /* wTotalLength */
71
    USB_CONFIGURATION_DESC_SIZE     +
72
    /* HID class related descriptors */
73
    USB_INTERFACE_DESC_SIZE         +
74
    HID_DESC_SIZE                   +
75
    USB_ENDPOINT_DESC_SIZE          +
76
    USB_ENDPOINT_DESC_SIZE          +
77
    /* CDC class related descriptors */
78
    USB_INTERFACE_ASSOC_DESC_SIZE   +  /* interface association descriptor */
79
    USB_INTERFACE_DESC_SIZE         +  /* communication control interface */
80
    0x0013                          +  /* CDC functions */
81
    1 * USB_ENDPOINT_DESC_SIZE      +  /* interrupt endpoint */
82
    USB_INTERFACE_DESC_SIZE         +  /* communication data interface */
83
    2 * USB_ENDPOINT_DESC_SIZE      +  /* bulk endpoints */
84
    0
85
    ),
86
  0x03,              /* bNumInterfaces */
87
  0x01,              /* bConfigurationValue */
88
  0x00,              /* iConfiguration */
89
  USB_CONFIG_SELF_POWERED,    /* bmAttributes */
90
  USB_CONFIG_POWER_MA(100),      /* bMaxPower */
91
92
  /* Interface 0, Alternate Setting 0, HID Class */
93
  USB_INTERFACE_DESC_SIZE,    /* bLength */
94
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType */
95
  USB_HID_IF_NUM,          /* bInterfaceNumber */
96
  0x00,              /* bAlternateSetting */
97
  0x02,              /* bNumEndpoints */
98
  USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
99
  HID_SUBCLASS_NONE,        /* bInterfaceSubClass */
100
  HID_PROTOCOL_NONE,        /* bInterfaceProtocol */
101
  0x04,              /* iInterface */
102
  /* HID Class Descriptor */
103
  /* HID_DESC_OFFSET = 0x0012 */
104
  HID_DESC_SIZE,          /* bLength */
105
  HID_HID_DESCRIPTOR_TYPE,    /* bDescriptorType */
106
  WBVAL(0x0111),          /* bcdHID : 1.11*/
107
  0x00,              /* bCountryCode */
108
  0x01,              /* bNumDescriptors */
109
  HID_REPORT_DESCRIPTOR_TYPE,    /* bDescriptorType */
110
  WBVAL(sizeof(HID_ReportDescriptor)),  /* wDescriptorLength */
111
  /* Endpoint, HID Interrupt In */
112
  USB_ENDPOINT_DESC_SIZE,      /* bLength */
113
  USB_ENDPOINT_DESCRIPTOR_TYPE,  /* bDescriptorType */
114
  HID_EP_IN,            /* bEndpointAddress */
115
  USB_ENDPOINT_TYPE_INTERRUPT,  /* bmAttributes */
116
  WBVAL(HID_INPUT_REPORT_BYTES),          /* wMaxPacketSize */
117
  0x20,              /* bInterval: 32ms */
118
  /* Endpoint, HID Interrupt Out */
119
  USB_ENDPOINT_DESC_SIZE,      /* bLength */
120
  USB_ENDPOINT_DESCRIPTOR_TYPE,  /* bDescriptorType */
121
  HID_EP_OUT,            /* bEndpointAddress */
122
  USB_ENDPOINT_TYPE_INTERRUPT,  /* bmAttributes */
123
  WBVAL(HID_OUTPUT_REPORT_BYTES),          /* wMaxPacketSize */
124
  0x20,              /* bInterval: 32ms */
125
126
  /* Interface association descriptor IAD*/
127
  USB_INTERFACE_ASSOC_DESC_SIZE,    /* bLength */
128
  USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE,  /* bDescriptorType */
129
  USB_CDC_CIF_NUM,          /* bFirstInterface */
130
  0x02,                /* bInterfaceCount */
131
  CDC_COMMUNICATION_INTERFACE_CLASS,  /* bFunctionClass */
132
  CDC_ABSTRACT_CONTROL_MODEL,      /* bFunctionSubClass */
133
  0x00,                /* bFunctionProtocol */
134
  0x05,                /* iFunction */
135
136
  /* Interface 1, Alternate Setting 0, Communication class interface descriptor */
137
  USB_INTERFACE_DESC_SIZE,      /* bLength */
138
  USB_INTERFACE_DESCRIPTOR_TYPE,    /* bDescriptorType */
139
  USB_CDC_CIF_NUM,          /* bInterfaceNumber: Number of Interface */
140
  0x00,                /* bAlternateSetting: Alternate setting */
141
  0x01,                /* bNumEndpoints: One endpoint used */
142
  CDC_COMMUNICATION_INTERFACE_CLASS,  /* bInterfaceClass: Communication Interface Class */
143
  CDC_ABSTRACT_CONTROL_MODEL,      /* bInterfaceSubClass: Abstract Control Model */
144
  0x00,                /* bInterfaceProtocol: no protocol used */
145
  0x05,                /* iInterface: */
146
  /* Header Functional Descriptor*/
147
  0x05,                /* bLength: CDC header Descriptor size */
148
  CDC_CS_INTERFACE,          /* bDescriptorType: CS_INTERFACE */
149
  CDC_HEADER,              /* bDescriptorSubtype: Header Func Desc */
150
  WBVAL(CDC_V1_10),          /* bcdCDC 1.10 */
151
  /* Call Management Functional Descriptor*/
152
  0x05,                /* bFunctionLength */
153
  CDC_CS_INTERFACE,          /* bDescriptorType: CS_INTERFACE */
154
  CDC_CALL_MANAGEMENT,        /* bDescriptorSubtype: Call Management Func Desc */
155
  0x01,                /* bmCapabilities: device handles call management */
156
  USB_CDC_DIF_NUM,          /* bDataInterface: CDC data IF ID */
157
  /* Abstract Control Management Functional Descriptor*/
158
  0x04,                /* bFunctionLength */
159
  CDC_CS_INTERFACE,          /* bDescriptorType: CS_INTERFACE */
160
  CDC_ABSTRACT_CONTROL_MANAGEMENT,  /* bDescriptorSubtype: Abstract Control Management desc */
161
  0x02,                /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */
162
  /* Union Functional Descriptor*/
163
  0x05,                /* bFunctionLength */
164
  CDC_CS_INTERFACE,          /* bDescriptorType: CS_INTERFACE */
165
  CDC_UNION,              /* bDescriptorSubtype: Union func desc */
166
  USB_CDC_CIF_NUM,          /* bMasterInterface: Communication class interface is master */
167
  USB_CDC_DIF_NUM,          /* bSlaveInterface0: Data class interface is slave 0 */
168
  /* Endpoint 1 Descriptor*/
169
  USB_ENDPOINT_DESC_SIZE,        /* bLength */
170
  USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType */
171
  USB_CDC_INT_EP,            /* bEndpointAddress */
172
  USB_ENDPOINT_TYPE_INTERRUPT,    /* bmAttributes */
173
  WBVAL(0x0010),            /* wMaxPacketSize */
174
  0x02,      /* 2ms */           /* bInterval */
175
176
  /* Interface 2, Alternate Setting 0, Data class interface descriptor*/
177
  USB_INTERFACE_DESC_SIZE,      /* bLength */
178
  USB_INTERFACE_DESCRIPTOR_TYPE,    /* bDescriptorType */
179
  USB_CDC_DIF_NUM,          /* bInterfaceNumber: Number of Interface */
180
  0x00,                /* bAlternateSetting: no alternate setting */
181
  0x02,                /* bNumEndpoints: two endpoints used */
182
  CDC_DATA_INTERFACE_CLASS,      /* bInterfaceClass: Data Interface Class */
183
  0x00,                /* bInterfaceSubClass: no subclass available */
184
  0x00,                /* bInterfaceProtocol: no protocol used */
185
  0x05,                /* iInterface: */
186
  /* Endpoint, EP Bulk Out */
187
  USB_ENDPOINT_DESC_SIZE,        /* bLength */
188
  USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType */
189
  USB_CDC_OUT_EP,            /* bEndpointAddress */
190
  USB_ENDPOINT_TYPE_BULK,        /* bmAttributes */
191
  WBVAL(USB_FS_MAX_BULK_PACKET),    /* wMaxPacketSize */
192
  0x00,                /* bInterval: ignore for Bulk transfer */
193
  /* Endpoint, EP Bulk In */
194
  USB_ENDPOINT_DESC_SIZE,        /* bLength */
195
  USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType */
196
  USB_CDC_IN_EP,            /* bEndpointAddress */
197
  USB_ENDPOINT_TYPE_BULK,        /* bmAttributes */
198
  WBVAL(64),              /* wMaxPacketSize */
199
  0x00,                /* bInterval: ignore for Bulk transfer */
200
201
  /* Terminator */
202
  0                /* bLength */
203
};
204
205
/**
206
 * USB String Descriptor (optional)
207
 */
208
const uint8_t USB_StringDescriptor[] = {
209
  /* Index 0x00: LANGID Codes */
210
  0x04,              /* bLength */
211
  USB_STRING_DESCRIPTOR_TYPE,    /* bDescriptorType */
212
  WBVAL(0x0409),          /* wLANGID : US English */
213
  /* Index 0x01: Manufacturer */
214
  (6 * 2 + 2),          /* bLength (18 Char + Type + lenght) */
215
  USB_STRING_DESCRIPTOR_TYPE,    /* bDescriptorType */
216
  'R', 0,
217
  'o', 0,
218
  'b', 0,
219
  'e', 0,
220
  'r', 0,
221
  't', 0,
222
  /* Index 0x02: Product */
223
  (14 * 2 + 2),          /* bLength (13 Char + Type + lenght) */
224
  USB_STRING_DESCRIPTOR_TYPE,    /* bDescriptorType */
225
  'R', 0,
226
  'e', 0,
227
  'f', 0,
228
  'l', 0,
229
  'o', 0,
230
  'w', 0,
231
  '-', 0,
232
  'C', 0,
233
  'o', 0,
234
  'n', 0,
235
  't', 0,
236
  'r', 0,
237
  'o', 0,
238
  'l', 0,
239
  /* Index 0x03: Serial Number */
240
  (4 * 2 + 2),          /* bLength (13 Char + Type + lenght) */
241
  USB_STRING_DESCRIPTOR_TYPE,    /* bDescriptorType */
242
  '0', 0,
243
  '0', 0,
244
  '0', 0,
245
  '1', 0,
246
  /* Index 0x04: Interface 0, Alternate Setting 0 */
247
  (3 * 2 + 2),          /* bLength (9 Char + Type + lenght) */
248
  USB_STRING_DESCRIPTOR_TYPE,    /* bDescriptorType */
249
  'H', 0,
250
  'I', 0,
251
  'D', 0,
252
  /* Index 0x05: Interface 1, Alternate Setting 0 */
253
  ( 4 * 2 + 2),            /* bLength (4 Char + Type + lenght) */
254
  USB_STRING_DESCRIPTOR_TYPE,      /* bDescriptorType */
255
  'V', 0,
256
  'C', 0,
257
  'O', 0,
258
  'M', 0,
259
};

Die Enumeration von CDC ACM und HID funktioniert, jedoch bekomme ich 
nach ca. 20 weiteren Sekunden ein weiteres Composite Device (auf einem 
anderen Port!) angezeigt, was keinen Descriptor liefert!? Mit USBlyzer 
kann ich keine Fehler finden, bzw. USBlyzer bestand auf
1
  USB_DEVICE_CLASS_MISCELLANEOUS,  /* bDeviceClass */
2
  0x02,              /* bDeviceSubClass */
3
  0x01,              /* bDeviceProtocol */
(USB_DEVICE_CLASS_MISCELLANEOUS=0xEF) um ein IAD anzuzeigen. Keine 
Ahnung warum NXP das Beispiel mit 00,00,00 ausliefert, 
funktionstechnisch hilft es aber auch nichts.

Gerne lade ich auch das Keil-Projekt hoch, allerdings ist das nicht ohne 
weiteres auf einem beliebigen Eval-Board lauffähig da alle Pinmuxes etc. 
auf ein Custom-Board angepasst wurden.

Grüße
Robert

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.