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(18),
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('C'),
218  WBVAL('D'),
219  WBVAL('C'),
220  WBVAL(' '),
221  WBVAL('D'),
222  WBVAL('e'),
223  WBVAL('m'),
224  WBVAL('o'),
225 };
227 
234 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
235  const uint8_t wIndex,
236  const void * *const DescriptorAddress)
237 {
238  const uint8_t DescriptorType = (wValue >> 8);
239  const uint8_t DescriptorNumber = (wValue & 0xFF);
240 
241  const void *Address = NULL;
242  uint16_t Size = NO_DESCRIPTOR;
243 
244  switch (DescriptorType) {
245  case DTYPE_Device:
246  Address = &DeviceDescriptor;
247  Size = sizeof(USB_Descriptor_Device_t);
248  break;
249 
250  case DTYPE_Configuration:
251  Address = &ConfigurationDescriptor;
252  Size = sizeof(USB_Descriptor_Configuration_t);
253  break;
254 
255  case DTYPE_String:
256  switch (DescriptorNumber) {
257  case 0x00:
258  Address = LanguageStringPtr;
259  Size = pgm_read_byte(&LanguageStringPtr->Header.Size);
260  break;
261 
262  case 0x01:
263  Address = ManufacturerStringPtr;
264  Size = pgm_read_byte(&ManufacturerStringPtr->Header.Size);
265  break;
266 
267  case 0x02:
268  Address = ProductStringPtr;
269  Size = pgm_read_byte(&ProductStringPtr->Header.Size);
270  break;
271  }
272 
273  break;
274  }
275 
276  *DescriptorAddress = Address;
277  return Size;
278 }