Update copyrights for 2017.
[pub/USBasp.git] / LUFA / Drivers / USB / Core / DeviceStandardReq.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2017.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2017 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 disclaims 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 #define __INCLUDE_FROM_USB_DRIVER
32 #include "USBMode.h"
33
34 #if defined(USB_CAN_BE_DEVICE)
35
36 #define __INCLUDE_FROM_DEVICESTDREQ_C
37 #include "DeviceStandardReq.h"
38
39 uint8_t USB_Device_ConfigurationNumber;
40
41 #if !defined(NO_DEVICE_SELF_POWER)
42 bool USB_Device_CurrentlySelfPowered;
43 #endif
44
45 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
46 bool USB_Device_RemoteWakeupEnabled;
47 #endif
48
49 void USB_Device_ProcessControlRequest(void)
50 {
51 #if defined(ARCH_BIG_ENDIAN)
52 USB_ControlRequest.bmRequestType = Endpoint_Read_8();
53 USB_ControlRequest.bRequest = Endpoint_Read_8();
54 USB_ControlRequest.wValue = Endpoint_Read_16_LE();
55 USB_ControlRequest.wIndex = Endpoint_Read_16_LE();
56 USB_ControlRequest.wLength = Endpoint_Read_16_LE();
57 #else
58 uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;
59
60 for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
61 *(RequestHeader++) = Endpoint_Read_8();
62 #endif
63
64 EVENT_USB_Device_ControlRequest();
65
66 if (Endpoint_IsSETUPReceived())
67 {
68 uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
69
70 switch (USB_ControlRequest.bRequest)
71 {
72 case REQ_GetStatus:
73 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
74 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
75 {
76 USB_Device_GetStatus();
77 }
78
79 break;
80 case REQ_ClearFeature:
81 case REQ_SetFeature:
82 if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
83 (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
84 {
85 USB_Device_ClearSetFeature();
86 }
87
88 break;
89 case REQ_SetAddress:
90 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
91 USB_Device_SetAddress();
92
93 break;
94 case REQ_GetDescriptor:
95 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
96 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
97 {
98 USB_Device_GetDescriptor();
99 }
100
101 break;
102 case REQ_GetConfiguration:
103 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
104 USB_Device_GetConfiguration();
105
106 break;
107 case REQ_SetConfiguration:
108 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
109 USB_Device_SetConfiguration();
110
111 break;
112
113 default:
114 break;
115 }
116 }
117
118 if (Endpoint_IsSETUPReceived())
119 {
120 Endpoint_ClearSETUP();
121 Endpoint_StallTransaction();
122 }
123 }
124
125 static void USB_Device_SetAddress(void)
126 {
127 uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
128
129 USB_Device_SetDeviceAddress(DeviceAddress);
130
131 Endpoint_ClearSETUP();
132
133 Endpoint_ClearStatusStage();
134
135 while (!(Endpoint_IsINReady()));
136
137 USB_Device_EnableDeviceAddress(DeviceAddress);
138
139 USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
140 }
141
142 static void USB_Device_SetConfiguration(void)
143 {
144 #if defined(FIXED_NUM_CONFIGURATIONS)
145 if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
146 return;
147 #else
148 USB_Descriptor_Device_t* DevDescriptorPtr;
149
150 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
151 #if defined(USE_FLASH_DESCRIPTORS)
152 #define MemoryAddressSpace MEMSPACE_FLASH
153 #elif defined(USE_EEPROM_DESCRIPTORS)
154 #define MemoryAddressSpace MEMSPACE_EEPROM
155 #elif defined(USE_RAM_DESCRIPTORS)
156 #define MemoryAddressSpace MEMSPACE_RAM
157 #else
158 uint8_t MemoryAddressSpace;
159 #endif
160 #endif
161
162 if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
163 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
164 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
165 , &MemoryAddressSpace
166 #endif
167 ) == NO_DESCRIPTOR)
168 {
169 return;
170 }
171
172 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
173 if (MemoryAddressSpace == MEMSPACE_FLASH)
174 {
175 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
176 return;
177 }
178 else if (MemoryAddressSpace == MEMSPACE_EEPROM)
179 {
180 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
181 return;
182 }
183 else
184 {
185 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
186 return;
187 }
188 #else
189 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
190 return;
191 #endif
192 #endif
193
194 Endpoint_ClearSETUP();
195
196 USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
197
198 Endpoint_ClearStatusStage();
199
200 if (USB_Device_ConfigurationNumber)
201 USB_DeviceState = DEVICE_STATE_Configured;
202 else
203 USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
204
205 EVENT_USB_Device_ConfigurationChanged();
206 }
207
208 static void USB_Device_GetConfiguration(void)
209 {
210 Endpoint_ClearSETUP();
211
212 Endpoint_Write_8(USB_Device_ConfigurationNumber);
213 Endpoint_ClearIN();
214
215 Endpoint_ClearStatusStage();
216 }
217
218 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
219 static void USB_Device_GetInternalSerialDescriptor(void)
220 {
221 struct
222 {
223 USB_Descriptor_Header_t Header;
224 uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
225 } SignatureDescriptor;
226
227 SignatureDescriptor.Header.Type = DTYPE_String;
228 SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);
229
230 USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);
231
232 Endpoint_ClearSETUP();
233
234 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
235 Endpoint_ClearOUT();
236 }
237 #endif
238
239 static void USB_Device_GetDescriptor(void)
240 {
241 const void* DescriptorPointer;
242 uint16_t DescriptorSize;
243
244 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
245 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
246 uint8_t DescriptorAddressSpace;
247 #endif
248
249 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
250 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
251 {
252 USB_Device_GetInternalSerialDescriptor();
253 return;
254 }
255 #endif
256
257 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
258 &DescriptorPointer
259 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
260 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
261 , &DescriptorAddressSpace
262 #endif
263 )) == NO_DESCRIPTOR)
264 {
265 return;
266 }
267
268 Endpoint_ClearSETUP();
269
270 #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
271 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
272 #elif defined(USE_EEPROM_DESCRIPTORS)
273 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
274 #elif defined(USE_FLASH_DESCRIPTORS)
275 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
276 #else
277 if (DescriptorAddressSpace == MEMSPACE_FLASH)
278 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
279 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
280 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
281 else
282 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
283 #endif
284
285 Endpoint_ClearOUT();
286 }
287
288 static void USB_Device_GetStatus(void)
289 {
290 uint8_t CurrentStatus = 0;
291
292 switch (USB_ControlRequest.bmRequestType)
293 {
294 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
295 {
296 #if !defined(NO_DEVICE_SELF_POWER)
297 if (USB_Device_CurrentlySelfPowered)
298 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
299 #endif
300
301 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
302 if (USB_Device_RemoteWakeupEnabled)
303 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
304 #endif
305 break;
306 }
307 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
308 {
309 #if !defined(CONTROL_ONLY_DEVICE)
310 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
311
312 if (EndpointIndex >= ENDPOINT_TOTAL_ENDPOINTS)
313 return;
314
315 Endpoint_SelectEndpoint(EndpointIndex);
316
317 CurrentStatus = Endpoint_IsStalled();
318
319 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
320 #endif
321
322 break;
323 }
324 default:
325 return;
326 }
327
328 Endpoint_ClearSETUP();
329
330 Endpoint_Write_16_LE(CurrentStatus);
331 Endpoint_ClearIN();
332
333 Endpoint_ClearStatusStage();
334 }
335
336 static void USB_Device_ClearSetFeature(void)
337 {
338 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
339 {
340 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
341 case REQREC_DEVICE:
342 {
343 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
344 USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
345 else
346 return;
347
348 break;
349 }
350 #endif
351 #if !defined(CONTROL_ONLY_DEVICE)
352 case REQREC_ENDPOINT:
353 {
354 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)
355 {
356 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
357
358 if (EndpointIndex == ENDPOINT_CONTROLEP || EndpointIndex >= ENDPOINT_TOTAL_ENDPOINTS)
359 return;
360
361 Endpoint_SelectEndpoint(EndpointIndex);
362
363 if (Endpoint_IsEnabled())
364 {
365 if (USB_ControlRequest.bRequest == REQ_SetFeature)
366 {
367 Endpoint_StallTransaction();
368 }
369 else
370 {
371 Endpoint_ClearStall();
372 Endpoint_ResetEndpoint(EndpointIndex);
373 Endpoint_ResetDataToggle();
374 }
375 }
376 }
377
378 break;
379 }
380 #endif
381 default:
382 return;
383 }
384
385 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
386
387 Endpoint_ClearSETUP();
388
389 Endpoint_ClearStatusStage();
390 }
391
392 #endif
393