Move out many of the common class driver constants into grouped enums, to make them...
[pub/USBasp.git] / LUFA / Drivers / USB / HighLevel / DeviceStandardReq.c
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 #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_ConfigurationNumber;
40
41 #if !defined(NO_DEVICE_SELF_POWER)
42 bool USB_CurrentlySelfPowered;
43 #endif
44
45 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
46 bool USB_RemoteWakeupEnabled;
47 #endif
48
49 void USB_Device_ProcessControlRequest(void)
50 {
51 bool RequestHandled = false;
52 uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;
53
54 for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
55 *(RequestHeader++) = Endpoint_Read_Byte();
56
57 uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
58
59 switch (USB_ControlRequest.bRequest)
60 {
61 case REQ_GetStatus:
62 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
63 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
64 {
65 USB_Device_GetStatus();
66 RequestHandled = true;
67 }
68
69 break;
70 case REQ_ClearFeature:
71 case REQ_SetFeature:
72 if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
73 (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
74 {
75 USB_Device_ClearSetFeature();
76 RequestHandled = true;
77 }
78
79 break;
80 case REQ_SetAddress:
81 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
82 {
83 USB_Device_SetAddress();
84 RequestHandled = true;
85 }
86
87 break;
88 case REQ_GetDescriptor:
89 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
90 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
91 {
92 USB_Device_GetDescriptor();
93 RequestHandled = true;
94 }
95
96 break;
97 case REQ_GetConfiguration:
98 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
99 {
100 USB_Device_GetConfiguration();
101 RequestHandled = true;
102 }
103
104 break;
105 case REQ_SetConfiguration:
106 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
107 {
108 USB_Device_SetConfiguration();
109 RequestHandled = true;
110 }
111
112 break;
113 }
114
115 if (!(RequestHandled))
116 EVENT_USB_Device_UnhandledControlRequest();
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
129 Endpoint_ClearSETUP();
130
131 Endpoint_ClearStatusStage();
132
133 while (!(Endpoint_IsINReady()))
134 {
135 if (USB_DeviceState == DEVICE_STATE_Unattached)
136 return;
137 }
138
139 USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
140
141 USB_Device_SetDeviceAddress(DeviceAddress);
142 }
143
144 static void USB_Device_SetConfiguration(void)
145 {
146 #if defined(FIXED_NUM_CONFIGURATIONS)
147 if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
148 return;
149 #else
150 #if defined(USE_FLASH_DESCRIPTORS)
151 #define MemoryAddressSpace MEMSPACE_FLASH
152 #elif defined(USE_EEPROM_DESCRIPTORS)
153 #define MemoryAddressSpace MEMSPACE_EEPROM
154 #elif defined(USE_SRAM_DESCRIPTORS)
155 #define MemoryAddressSpace MEMSPACE_SRAM
156 #else
157 uint8_t MemoryAddressSpace;
158 #endif
159
160 USB_Descriptor_Device_t* DevDescriptorPtr;
161
162 if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
163 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
164 , &MemoryAddressSpace
165 #endif
166 ) == NO_DESCRIPTOR)
167 {
168 return;
169 }
170
171 if (MemoryAddressSpace == MEMSPACE_FLASH)
172 {
173 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
174 return;
175 }
176 else if (MemoryAddressSpace == MEMSPACE_EEPROM)
177 {
178 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
179 return;
180 }
181 else
182 {
183 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
184 return;
185 }
186 #endif
187
188 Endpoint_ClearSETUP();
189
190 USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
191
192 Endpoint_ClearStatusStage();
193
194 USB_DeviceState = (USB_ConfigurationNumber) ? DEVICE_STATE_Configured : DEVICE_STATE_Addressed;
195
196 EVENT_USB_Device_ConfigurationChanged();
197 }
198
199 void USB_Device_GetConfiguration(void)
200 {
201 Endpoint_ClearSETUP();
202
203 Endpoint_Write_Byte(USB_ConfigurationNumber);
204 Endpoint_ClearIN();
205
206 Endpoint_ClearStatusStage();
207 }
208
209 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
210 static char USB_Device_NibbleToASCII(uint8_t Nibble)
211 {
212 Nibble = ((Nibble & 0x0F) + '0');
213 return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
214 }
215
216 static void USB_Device_GetInternalSerialDescriptor(void)
217 {
218 struct
219 {
220 USB_Descriptor_Header_t Header;
221 int16_t UnicodeString[20];
222 } SignatureDescriptor;
223
224 SignatureDescriptor.Header.Type = DTYPE_String;
225 SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
226
227 uint8_t SigReadAddress = 0x0E;
228
229 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
230 {
231 for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
232 {
233 uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
234
235 if (SerialCharNum & 0x01)
236 {
237 SerialByte >>= 4;
238 SigReadAddress++;
239 }
240
241 SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
242 }
243 }
244
245 Endpoint_ClearSETUP();
246
247 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
248
249 Endpoint_ClearOUT();
250 }
251 #endif
252
253 static void USB_Device_GetDescriptor(void)
254 {
255 const void* DescriptorPointer;
256 uint16_t DescriptorSize;
257
258 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
259 uint8_t DescriptorAddressSpace;
260 #endif
261
262 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
263 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
264 {
265 USB_Device_GetInternalSerialDescriptor();
266 return;
267 }
268 #endif
269
270 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
271 &DescriptorPointer
272 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
273 , &DescriptorAddressSpace
274 #endif
275 )) == NO_DESCRIPTOR)
276 {
277 return;
278 }
279
280 Endpoint_ClearSETUP();
281
282 #if defined(USE_RAM_DESCRIPTORS)
283 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
284 #elif defined(USE_EEPROM_DESCRIPTORS)
285 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
286 #elif defined(USE_FLASH_DESCRIPTORS)
287 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
288 #else
289 if (DescriptorAddressSpace == MEMSPACE_FLASH)
290 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
291 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
292 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
293 else
294 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
295 #endif
296
297 Endpoint_ClearOUT();
298 }
299
300 static void USB_Device_GetStatus(void)
301 {
302 uint8_t CurrentStatus = 0;
303
304 switch (USB_ControlRequest.bmRequestType)
305 {
306 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
307 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
308 #if !defined(NO_DEVICE_SELF_POWER)
309 if (USB_CurrentlySelfPowered)
310 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
311 #endif
312
313 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
314 if (USB_RemoteWakeupEnabled)
315 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
316 #endif
317 break;
318 #endif
319 #if !defined(CONTROL_ONLY_DEVICE)
320 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
321 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
322
323 CurrentStatus = Endpoint_IsStalled();
324
325 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
326
327 break;
328 #endif
329 default:
330 return;
331 }
332
333 Endpoint_ClearSETUP();
334
335 Endpoint_Write_Word_LE(CurrentStatus);
336 Endpoint_ClearIN();
337
338 Endpoint_ClearStatusStage();
339 }
340
341 static void USB_Device_ClearSetFeature(void)
342 {
343 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
344 {
345 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
346 case REQREC_DEVICE:
347 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
348 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
349 else
350 return;
351
352 break;
353 #endif
354 #if !defined(CONTROL_ONLY_DEVICE)
355 case REQREC_ENDPOINT:
356 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
357 {
358 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
359
360 if (EndpointIndex == ENDPOINT_CONTROLEP)
361 return;
362
363 Endpoint_SelectEndpoint(EndpointIndex);
364
365 if (Endpoint_IsEnabled())
366 {
367 if (USB_ControlRequest.bRequest == REQ_SetFeature)
368 {
369 Endpoint_StallTransaction();
370 }
371 else
372 {
373 Endpoint_ClearStall();
374 Endpoint_ResetFIFO(EndpointIndex);
375 Endpoint_ResetDataToggle();
376 }
377 }
378 }
379
380 break;
381 #endif
382 default:
383 return;
384 }
385
386 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
387
388 Endpoint_ClearSETUP();
389
390 Endpoint_ClearStatusStage();
391 }
392
393 #endif