Fri, 17 Nov 2017 10:13:31 +0100
proper configuration, homing and planner optimization
2 | 1 | /* |
2 | LUFA Library | |
3 | Copyright (C) Dean Camera, 2010. | |
4 | ||
5 | dean [at] fourwalledcubicle [dot] com | |
6 | www.fourwalledcubicle.com | |
7 | */ | |
8 | ||
9 | /* | |
10 | Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |
11 | ||
12 | Permission to use, copy, modify, distribute, and sell this | |
13 | software and its documentation for any purpose is hereby granted | |
14 | without fee, provided that the above copyright notice appear in | |
15 | all copies and that both that the copyright notice and this | |
16 | permission notice and warranty disclaimer appear in supporting | |
17 | documentation, and that the name of the author not be used in | |
18 | advertising or publicity pertaining to distribution of the | |
19 | software without specific, written prior permission. | |
20 | ||
21 | The author disclaim all warranties with regard to this | |
22 | software, including all implied warranties of merchantability | |
23 | and fitness. In no event shall the author be liable for any | |
24 | special, indirect or consequential damages or any damages | |
25 | whatsoever resulting from loss of use, data or profits, whether | |
26 | in an action of contract, negligence or other tortious action, | |
27 | arising out of or in connection with the use or performance of | |
28 | this software. | |
29 | */ | |
30 | ||
31 | /** \file | |
32 | * | |
33 | * USB Device Descriptors, for library use when in USB device mode. Descriptors are special | |
34 | * computer-readable structures which the host requests upon device enumeration, to determine | |
35 | * the device's capabilities and functions. | |
36 | */ | |
37 | ||
38 | #include "Descriptors.h" | |
39 | ||
40 | /* On some devices, there is a factory set internal serial number which can be automatically sent to the host as | |
41 | * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL. | |
42 | * This allows the host to track a device across insertions on different ports, allowing them to retain allocated | |
43 | * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices | |
44 | * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value | |
45 | * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and | |
46 | * port location). | |
47 | */ | |
48 | #if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR) | |
49 | #warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor. | |
50 | #endif | |
51 | ||
52 | /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall | |
53 | * device characteristics, including the supported USB version, control endpoint size and the | |
54 | * number of device configurations. The descriptor is read out by the USB host when the enumeration | |
55 | * process begins. | |
56 | */ | |
57 | USB_Descriptor_Device_t PROGMEM DeviceDescriptor = | |
58 | { | |
59 | .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, | |
60 | ||
61 | .USBSpecification = VERSION_BCD(01.10), | |
62 | .Class = 0x02, | |
63 | .SubClass = 0x00, | |
64 | .Protocol = 0x00, | |
65 | ||
66 | .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, | |
67 | ||
68 | .VendorID = 0x03EB, // Atmel | |
69 | ||
70 | .ProductID = 0x204B, // LUFA USB to Serial Demo Application | |
71 | .ReleaseNumber = 0x0001, | |
72 | ||
73 | .ManufacturerStrIndex = 0x01, | |
74 | .ProductStrIndex = 0x02, | |
75 | .SerialNumStrIndex = USE_INTERNAL_SERIAL, | |
76 | ||
77 | .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS | |
78 | }; | |
79 | ||
80 | /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage | |
81 | * of the device in one of its supported configurations, including information about any device interfaces | |
82 | * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting | |
83 | * a configuration so that the host may correctly communicate with the USB device. | |
84 | */ | |
85 | USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = | |
86 | { | |
87 | .Config = | |
88 | { | |
89 | .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, | |
90 | ||
91 | .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), | |
92 | .TotalInterfaces = 2, | |
93 | ||
94 | .ConfigurationNumber = 1, | |
95 | .ConfigurationStrIndex = NO_DESCRIPTOR, | |
96 | ||
97 | .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), | |
98 | ||
99 | .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) | |
100 | }, | |
101 | ||
102 | .CDC_CCI_Interface = | |
103 | { | |
104 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
105 | ||
106 | .InterfaceNumber = 0, | |
107 | .AlternateSetting = 0, | |
108 | ||
109 | .TotalEndpoints = 1, | |
110 | ||
111 | .Class = 0x02, | |
112 | .SubClass = 0x02, | |
113 | .Protocol = 0x01, | |
114 | ||
115 | .InterfaceStrIndex = NO_DESCRIPTOR | |
116 | }, | |
117 | ||
118 | .CDC_Functional_IntHeader = | |
119 | { | |
120 | .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, | |
121 | .SubType = 0x00, | |
122 | ||
123 | .Data = {0x01, 0x10} | |
124 | }, | |
125 | ||
126 | .CDC_Functional_AbstractControlManagement = | |
127 | { | |
128 | .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24}, | |
129 | .SubType = 0x02, | |
130 | ||
131 | .Data = {0x06} | |
132 | }, | |
133 | ||
134 | .CDC_Functional_Union = | |
135 | { | |
136 | .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, | |
137 | .SubType = 0x06, | |
138 | ||
139 | .Data = {0x00, 0x01} | |
140 | }, | |
141 | ||
142 | .CDC_NotificationEndpoint = | |
143 | { | |
144 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
145 | ||
146 | .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM), | |
147 | .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |
148 | .EndpointSize = CDC_NOTIFICATION_EPSIZE, | |
149 | .PollingIntervalMS = 0xFF | |
150 | }, | |
151 | ||
152 | .CDC_DCI_Interface = | |
153 | { | |
154 | .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | |
155 | ||
156 | .InterfaceNumber = 1, | |
157 | .AlternateSetting = 0, | |
158 | ||
159 | .TotalEndpoints = 2, | |
160 | ||
161 | .Class = 0x0A, | |
162 | .SubClass = 0x00, | |
163 | .Protocol = 0x00, | |
164 | ||
165 | .InterfaceStrIndex = NO_DESCRIPTOR | |
166 | }, | |
167 | ||
168 | .CDC_DataOutEndpoint = | |
169 | { | |
170 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
171 | ||
172 | .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM), | |
173 | .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |
174 | .EndpointSize = CDC_TXRX_EPSIZE, | |
175 | .PollingIntervalMS = 0x01 | |
176 | }, | |
177 | ||
178 | .CDC_DataInEndpoint = | |
179 | { | |
180 | .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, | |
181 | ||
182 | .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM), | |
183 | .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), | |
184 | .EndpointSize = CDC_TXRX_EPSIZE, | |
185 | .PollingIntervalMS = 0x01 | |
186 | } | |
187 | }; | |
188 | ||
189 | /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests | |
190 | * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate | |
191 | * via the language ID table available at USB.org what languages the device supports for its string descriptors. | |
192 | */ | |
193 | USB_Descriptor_String_t PROGMEM LanguageString = | |
194 | { | |
195 | .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, | |
196 | ||
197 | .UnicodeString = {LANGUAGE_ID_ENG} | |
198 | }; | |
199 | ||
200 | /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable | |
201 | * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |
202 | * Descriptor. | |
203 | */ | |
204 | USB_Descriptor_String_t PROGMEM ManufacturerString = | |
205 | { | |
206 | .Header = {.Size = USB_STRING_LEN(24), .Type = DTYPE_String}, | |
207 | ||
208 | .UnicodeString = L"Arduino (www.arduino.cc)" | |
209 | }; | |
210 | ||
211 | /** Product descriptor string. This is a Unicode string containing the product's details in human readable form, | |
212 | * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device | |
213 | * Descriptor. | |
214 | */ | |
215 | USB_Descriptor_String_t PROGMEM ProductString = | |
216 | { | |
217 | #if (ARDUINO_MODEL_PID == ARDUINO_UNO_PID) | |
218 | .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, | |
219 | ||
220 | .UnicodeString = L"Arduino Uno" | |
221 | #elif (ARDUINO_MODEL_PID == ARDUINO_MEGA2560_PID) | |
222 | .Header = {.Size = USB_STRING_LEN(17), .Type = DTYPE_String}, | |
223 | ||
224 | .UnicodeString = L"Arduino Mega 2560" | |
225 | #endif | |
226 | ||
227 | }; | |
228 | ||
229 | /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" | |
230 | * documentation) by the application code so that the address and size of a requested descriptor can be given | |
231 | * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function | |
232 | * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | |
233 | * USB host. | |
234 | */ | |
235 | uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | |
236 | const uint8_t wIndex, | |
237 | void** const DescriptorAddress) | |
238 | { | |
239 | const uint8_t DescriptorType = (wValue >> 8); | |
240 | const uint8_t DescriptorNumber = (wValue & 0xFF); | |
241 | ||
242 | void* Address = NULL; | |
243 | uint16_t Size = NO_DESCRIPTOR; | |
244 | ||
245 | switch (DescriptorType) | |
246 | { | |
247 | case DTYPE_Device: | |
248 | Address = (void*)&DeviceDescriptor; | |
249 | Size = sizeof(USB_Descriptor_Device_t); | |
250 | break; | |
251 | case DTYPE_Configuration: | |
252 | Address = (void*)&ConfigurationDescriptor; | |
253 | Size = sizeof(USB_Descriptor_Configuration_t); | |
254 | break; | |
255 | case DTYPE_String: | |
256 | switch (DescriptorNumber) | |
257 | { | |
258 | case 0x00: | |
259 | Address = (void*)&LanguageString; | |
260 | Size = pgm_read_byte(&LanguageString.Header.Size); | |
261 | break; | |
262 | case 0x01: | |
263 | Address = (void*)&ManufacturerString; | |
264 | Size = pgm_read_byte(&ManufacturerString.Header.Size); | |
265 | break; | |
266 | case 0x02: | |
267 | Address = (void*)&ProductString; | |
268 | Size = pgm_read_byte(&ProductString.Header.Size); | |
269 | break; | |
270 | } | |
271 | ||
272 | break; | |
273 | } | |
274 | ||
275 | *DescriptorAddress = Address; | |
276 | return Size; | |
277 | } |