LPCOpen Platform
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 
52  .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
53 
54  .USBSpecification = VERSION_BCD(01.10),
55  .Class = CDC_CSCP_CDCClass,
56  .SubClass = CDC_CSCP_NoSpecificSubclass,
57  .Protocol = CDC_CSCP_NoSpecificProtocol,
58 
59  .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
60 
61  .VendorID = 0x1fc9, /* NXP */
62  .ProductID = 0x2047,
63  .ReleaseNumber = VERSION_BCD(00.01),
64 
65  .ManufacturerStrIndex = 0x01,
66  .ProductStrIndex = 0x02,
67  .SerialNumStrIndex = USE_INTERNAL_SERIAL,
68 
69  .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
70 };
71 
78  .Config = {
79  .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
80 
81  .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t) - 1, // termination byte not included in size
82  .TotalInterfaces = 2,
83 
84  .ConfigurationNumber = 1,
85  .ConfigurationStrIndex = NO_DESCRIPTOR,
86 
88 
90  },
91 
92  .CDC_CCI_Interface = {
93  .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
94 
95  .InterfaceNumber = 0,
96  .AlternateSetting = 0,
97 
98  .TotalEndpoints = 1,
99 
103 
105  },
106 
107  .CDC_Functional_Header = {
108  .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
110 
111  .CDCSpecification = VERSION_BCD(01.10),
112  },
113 
114  .CDC_Functional_ACM = {
115  .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
117 
118  .Capabilities = 0x06,
119  },
120 
121  .CDC_Functional_Union = {
122  .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
124 
127  },
128 
129  .CDC_NotificationEndpoint = {
130  .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
131 
132  // .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
136  .PollingIntervalMS = 0xFF
137  },
138 
139  .CDC_DCI_Interface = {
140  .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
141 
142  .InterfaceNumber = 1,
143  .AlternateSetting = 0,
144 
145  .TotalEndpoints = 2,
146 
150 
152  },
153 
154  .CDC_DataOutEndpoint = {
155  .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
156 
157  // .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
161  .PollingIntervalMS = 0x01
162  },
163 
164  .CDC_DataInEndpoint = {
165  .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
166 
167  // .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
171  .PollingIntervalMS = 0x01
172  },
173  .CDC_Termination = 0x00
174 };
175 
180 uint8_t LanguageString[] = {
181  USB_STRING_LEN(1),
182  DTYPE_String,
184 };
186 
191 uint8_t ManufacturerString[] = {
192  USB_STRING_LEN(3),
193  DTYPE_String,
194  WBVAL('N'),
195  WBVAL('X'),
196  WBVAL('P'),
197 };
199 
204 uint8_t ProductString[] = {
205  USB_STRING_LEN(29),
206  DTYPE_String,
207  WBVAL('L'),
208  WBVAL('P'),
209  WBVAL('C'),
210  WBVAL('U'),
211  WBVAL('S'),
212  WBVAL('B'),
213  WBVAL('l'),
214  WBVAL('i'),
215  WBVAL('b'),
216  WBVAL(' '),
217  WBVAL('V'),
218  WBVAL('i'),
219  WBVAL('r'),
220  WBVAL('t'),
221  WBVAL('u'),
222  WBVAL('a'),
223  WBVAL('l'),
224  WBVAL(' '),
225  WBVAL('S'),
226  WBVAL('e'),
227  WBVAL('r'),
228  WBVAL('i'),
229  WBVAL('a'),
230  WBVAL('l'),
231  WBVAL(' '),
232  WBVAL('D'),
233  WBVAL('e'),
234  WBVAL('m'),
235  WBVAL('o'),
236 };
244 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
245  const uint8_t wIndex,
246  const void * *const DescriptorAddress)
247 {
248  const uint8_t DescriptorType = (wValue >> 8);
249  const uint8_t DescriptorNumber = (wValue & 0xFF);
250 
251  const void *Address = NULL;
252  uint16_t Size = NO_DESCRIPTOR;
253 
254  switch (DescriptorType) {
255  case DTYPE_Device:
256  Address = &DeviceDescriptor;
257  Size = sizeof(USB_Descriptor_Device_t);
258  break;
259 
260  case DTYPE_Configuration:
261  Address = &ConfigurationDescriptor;
262  Size = sizeof(USB_Descriptor_Configuration_t);
263  break;
264 
265  case DTYPE_String:
266  switch (DescriptorNumber) {
267  case 0x00:
268  Address = LanguageStringPtr;
269  Size = pgm_read_byte(&LanguageStringPtr->Header.Size);
270  break;
271 
272  case 0x01:
273  Address = ManufacturerStringPtr;
274  Size = pgm_read_byte(&ManufacturerStringPtr->Header.Size);
275  break;
276 
277  case 0x02:
278  Address = ProductStringPtr;
279  Size = pgm_read_byte(&ProductStringPtr->Header.Size);
280  break;
281  }
282 
283  break;
284  }
285 
286  *DescriptorAddress = Address;
287  return Size;
288 }