LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Descriptors.c
Go to the documentation of this file.
1 /*
2  * @brief USB Device Descriptors, for library use when in USB device mode. Descriptors are special
3  * computer-readable structures which the host requests upon device enumeration, to determine
4  * the device's capabilities and functions
5  *
6  * @note
7  * Copyright(C) NXP Semiconductors, 2012
8  * Copyright(C) Dean Camera, 2011, 2012
9  * All rights reserved.
10  *
11  * @par
12  * Software that is described herein is for illustrative purposes only
13  * which provides customers with programming information regarding the
14  * LPC products. This software is supplied "AS IS" without any warranties of
15  * any kind, and NXP Semiconductors and its licensor disclaim any and
16  * all warranties, express or implied, including all implied warranties of
17  * merchantability, fitness for a particular purpose and non-infringement of
18  * intellectual property rights. NXP Semiconductors assumes no responsibility
19  * or liability for the use of the software, conveys no license or rights under any
20  * patent, copyright, mask work right, or any other intellectual property rights in
21  * or to any products. NXP Semiconductors reserves the right to make changes
22  * in the software without notification. NXP Semiconductors also makes no
23  * representation or warranty that such application will be suitable for the
24  * specified use without further testing or modification.
25  *
26  * @par
27  * Permission to use, copy, modify, and distribute this software and its
28  * documentation is hereby granted, under NXP Semiconductors' and its
29  * licensor's relevant copyrights in the software, without fee, provided that it
30  * is used in conjunction with NXP Semiconductors microcontrollers. This
31  * copyright, permission, and disclaimer notice must appear in all copies of
32  * this code.
33  */
34 
35 #include "Descriptors.h"
36 
37 /* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
38  * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
39  * This allows the host to track a device across insertions on different ports, allowing them to retain allocated
40  * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
41  * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
42  * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
43  * port location).
44  */
45 
46 /*****************************************************************************
47  * Private types/enumerations/variables
48  ****************************************************************************/
49 
50 /*****************************************************************************
51  * Public types/enumerations/variables
52  ****************************************************************************/
53 
60  .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
61 
62  .USBSpecification = VERSION_BCD(01.10),
63  .Class = CDC_CSCP_CDCClass,
64  .SubClass = CDC_CSCP_NoSpecificSubclass,
65  .Protocol = CDC_CSCP_NoSpecificProtocol,
66 
67  .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
68 
69  .VendorID = 0x1fc9, /* NXP */
70  .ProductID = 0x2047,
71  .ReleaseNumber = VERSION_BCD(00.01),
72 
73  .ManufacturerStrIndex = 0x01,
74  .ProductStrIndex = 0x02,
75  .SerialNumStrIndex = USE_INTERNAL_SERIAL,
76 
77  .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
78 };
79 
86  .Config = {
87  .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
88 
89  .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t) - 1, // termination byte not included in size
90  .TotalInterfaces = 2,
91 
92  .ConfigurationNumber = 1,
93  .ConfigurationStrIndex = NO_DESCRIPTOR,
94 
96 
98  },
99 
100  .CDC_CCI_Interface = {
101  .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
102 
103  .InterfaceNumber = 0,
104  .AlternateSetting = 0,
105 
106  .TotalEndpoints = 1,
107 
111 
113  },
114 
115  .CDC_Functional_Header = {
116  .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
118 
119  .CDCSpecification = VERSION_BCD(01.10),
120  },
121 
122  .CDC_Functional_ACM = {
123  .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
125 
126  .Capabilities = 0x06,
127  },
128 
129  .CDC_Functional_Union = {
130  .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
132 
135  },
136 
137  .CDC_NotificationEndpoint = {
138  .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
139 
140  // .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
144  .PollingIntervalMS = 0xFF
145  },
146 
147  .CDC_DCI_Interface = {
148  .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
149 
150  .InterfaceNumber = 1,
151  .AlternateSetting = 0,
152 
153  .TotalEndpoints = 2,
154 
158 
160  },
161 
162  .CDC_DataOutEndpoint = {
163  .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
164 
165  // .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
169  .PollingIntervalMS = 0x01
170  },
171 
172  .CDC_DataInEndpoint = {
173  .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
174 
175  // .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
179  .PollingIntervalMS = 0x01
180  },
181  .CDC_Termination = 0x00
182 };
183 
188 uint8_t LanguageString[] = {
189  USB_STRING_LEN(1),
190  DTYPE_String,
192 };
194 
199 uint8_t ManufacturerString[] = {
200  USB_STRING_LEN(3),
201  DTYPE_String,
202  WBVAL('N'),
203  WBVAL('X'),
204  WBVAL('P'),
205 };
207 
212 uint8_t ProductString[] = {
213  USB_STRING_LEN(29),
214  DTYPE_String,
215  WBVAL('L'),
216  WBVAL('P'),
217  WBVAL('C'),
218  WBVAL('U'),
219  WBVAL('S'),
220  WBVAL('B'),
221  WBVAL('l'),
222  WBVAL('i'),
223  WBVAL('b'),
224  WBVAL(' '),
225  WBVAL('V'),
226  WBVAL('i'),
227  WBVAL('r'),
228  WBVAL('t'),
229  WBVAL('u'),
230  WBVAL('a'),
231  WBVAL('l'),
232  WBVAL(' '),
233  WBVAL('S'),
234  WBVAL('e'),
235  WBVAL('r'),
236  WBVAL('i'),
237  WBVAL('a'),
238  WBVAL('l'),
239  WBVAL(' '),
240  WBVAL('D'),
241  WBVAL('e'),
242  WBVAL('m'),
243  WBVAL('o'),
244 };
246 
247 /*****************************************************************************
248  * Private functions
249  ****************************************************************************/
250 
251 /*****************************************************************************
252  * Public functions
253  ****************************************************************************/
254 
261 uint16_t CALLBACK_USB_GetDescriptor(uint8_t corenum,
262  const uint16_t wValue,
263  const uint8_t wIndex,
264  const void * *const DescriptorAddress)
265 {
266  const uint8_t DescriptorType = (wValue >> 8);
267  const uint8_t DescriptorNumber = (wValue & 0xFF);
268 
269  const void *Address = NULL;
270  uint16_t Size = NO_DESCRIPTOR;
271 
272  switch (DescriptorType) {
273  case DTYPE_Device:
274  Address = &DeviceDescriptor;
275  Size = sizeof(USB_Descriptor_Device_t);
276  break;
277 
278  case DTYPE_Configuration:
279  Address = &ConfigurationDescriptor;
280  Size = sizeof(USB_Descriptor_Configuration_t);
281  break;
282 
283  case DTYPE_String:
284  switch (DescriptorNumber) {
285  case 0x00:
286  Address = LanguageStringPtr;
287  Size = pgm_read_byte(&LanguageStringPtr->Header.Size);
288  break;
289 
290  case 0x01:
291  Address = ManufacturerStringPtr;
292  Size = pgm_read_byte(&ManufacturerStringPtr->Header.Size);
293  break;
294 
295  case 0x02:
296  Address = ProductStringPtr;
297  Size = pgm_read_byte(&ProductStringPtr->Header.Size);
298  break;
299  }
300 
301  break;
302  }
303 
304  *DescriptorAddress = Address;
305  return Size;
306 }