Minor documentation improvements.
[pub/USBasp.git] / LUFA / Drivers / USB / Core / DeviceStandardReq.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2012.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2012 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_StallTransaction();
121 Endpoint_ClearSETUP();
122 }
123 }
124
125 static void USB_Device_SetAddress(void)
126 {
127 uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
128 uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
129 GlobalInterruptDisable();
130
131 Endpoint_ClearSETUP();
132
133 Endpoint_ClearStatusStage();
134
135 while (!(Endpoint_IsINReady()));
136
137 USB_Device_SetDeviceAddress(DeviceAddress);
138 USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
139
140 SetGlobalInterruptMask(CurrentGlobalInt);
141 }
142
143 static void USB_Device_SetConfiguration(void)
144 {
145 #if defined(FIXED_NUM_CONFIGURATIONS)
146 if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
147 return;
148 #else
149 USB_Descriptor_Device_t* DevDescriptorPtr;
150
151 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
152 #if defined(USE_FLASH_DESCRIPTORS)
153 #define MemoryAddressSpace MEMSPACE_FLASH
154 #elif defined(USE_EEPROM_DESCRIPTORS)
155 #define MemoryAddressSpace MEMSPACE_EEPROM
156 #elif defined(USE_SRAM_DESCRIPTORS)
157 #define MemoryAddressSpace MEMSPACE_SRAM
158 #else
159 uint8_t MemoryAddressSpace;
160 #endif
161 #endif
162
163 if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
164 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
165 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
166 , &MemoryAddressSpace
167 #endif
168 ) == NO_DESCRIPTOR)
169 {
170 return;
171 }
172
173 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
174 if (MemoryAddressSpace == MEMSPACE_FLASH)
175 {
176 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
177 return;
178 }
179 else if (MemoryAddressSpace == MEMSPACE_EEPROM)
180 {
181 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
182 return;
183 }
184 else
185 {
186 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
187 return;
188 }
189 #else
190 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
191 return;
192 #endif
193 #endif
194
195 Endpoint_ClearSETUP();
196
197 USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
198
199 Endpoint_ClearStatusStage();
200
201 if (USB_Device_ConfigurationNumber)
202 USB_DeviceState = DEVICE_STATE_Configured;
203 else
204 USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
205
206 EVENT_USB_Device_ConfigurationChanged();
207 }
208
209 static void USB_Device_GetConfiguration(void)
210 {
211 Endpoint_ClearSETUP();
212
213 Endpoint_Write_8(USB_Device_ConfigurationNumber);
214 Endpoint_ClearIN();
215
216 Endpoint_ClearStatusStage();
217 }
218
219 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
220 static void USB_Device_GetInternalSerialDescriptor(void)
221 {
222 struct
223 {
224 USB_Descriptor_Header_t Header;
225 uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
226 } SignatureDescriptor;
227
228 SignatureDescriptor.Header.Type = DTYPE_String;
229 SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);
230
231 USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);
232
233 Endpoint_ClearSETUP();
234
235 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
236 Endpoint_ClearOUT();
237 }
238 #endif
239
240 static void USB_Device_GetDescriptor(void)
241 {
242 const void* DescriptorPointer;
243 uint16_t DescriptorSize;
244
245 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
246 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
247 uint8_t DescriptorAddressSpace;
248 #endif
249
250 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
251 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
252 {
253 USB_Device_GetInternalSerialDescriptor();
254 return;
255 }
256 #endif
257
258 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
259 &DescriptorPointer
260 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
261 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
262 , &DescriptorAddressSpace
263 #endif
264 )) == NO_DESCRIPTOR)
265 {
266 return;
267 }
268
269 Endpoint_ClearSETUP();
270
271 #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
272 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
273 #elif defined(USE_EEPROM_DESCRIPTORS)
274 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
275 #elif defined(USE_FLASH_DESCRIPTORS)
276 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
277 #else
278 if (DescriptorAddressSpace == MEMSPACE_FLASH)
279 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
280 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
281 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
282 else
283 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
284 #endif
285
286 Endpoint_ClearOUT();
287 }
288
289 static void USB_Device_GetStatus(void)
290 {
291 uint8_t CurrentStatus = 0;
292
293 switch (USB_ControlRequest.bmRequestType)
294 {
295 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
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 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
307 #if !defined(CONTROL_ONLY_DEVICE)
308 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
309
310 CurrentStatus = Endpoint_IsStalled();
311
312 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
313 #endif
314
315 break;
316 default:
317 return;
318 }
319
320 Endpoint_ClearSETUP();
321
322 Endpoint_Write_16_LE(CurrentStatus);
323 Endpoint_ClearIN();
324
325 Endpoint_ClearStatusStage();
326 }
327
328 static void USB_Device_ClearSetFeature(void)
329 {
330 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
331 {
332 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
333 case REQREC_DEVICE:
334 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
335 USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
336 else
337 return;
338
339 break;
340 #endif
341 #if !defined(CONTROL_ONLY_DEVICE)
342 case REQREC_ENDPOINT:
343 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)
344 {
345 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
346
347 if (EndpointIndex == ENDPOINT_CONTROLEP)
348 return;
349
350 Endpoint_SelectEndpoint(EndpointIndex);
351
352 if (Endpoint_IsEnabled())
353 {
354 if (USB_ControlRequest.bRequest == REQ_SetFeature)
355 {
356 Endpoint_StallTransaction();
357 }
358 else
359 {
360 Endpoint_ClearStall();
361 Endpoint_ResetEndpoint(EndpointIndex);
362 Endpoint_ResetDataToggle();
363 }
364 }
365 }
366
367 break;
368 #endif
369 default:
370 return;
371 }
372
373 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
374
375 Endpoint_ClearSETUP();
376
377 Endpoint_ClearStatusStage();
378 }
379
380 #endif
381