d13ac7439d736683dc19b6edccde7c7a1479fd6c
[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 if (USB_ConfigurationNumber)
195 USB_DeviceState = DEVICE_STATE_Configured;
196 else
197 USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
198
199 EVENT_USB_Device_ConfigurationChanged();
200 }
201
202 void USB_Device_GetConfiguration(void)
203 {
204 Endpoint_ClearSETUP();
205
206 Endpoint_Write_Byte(USB_ConfigurationNumber);
207 Endpoint_ClearIN();
208
209 Endpoint_ClearStatusStage();
210 }
211
212 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
213 static char USB_Device_NibbleToASCII(uint8_t Nibble)
214 {
215 Nibble = ((Nibble & 0x0F) + '0');
216 return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
217 }
218
219 static void USB_Device_GetInternalSerialDescriptor(void)
220 {
221 struct
222 {
223 USB_Descriptor_Header_t Header;
224 int16_t UnicodeString[20];
225 } SignatureDescriptor;
226
227 SignatureDescriptor.Header.Type = DTYPE_String;
228 SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
229
230 uint8_t SigReadAddress = 0x0E;
231
232 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
233 {
234 for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
235 {
236 uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
237
238 if (SerialCharNum & 0x01)
239 {
240 SerialByte >>= 4;
241 SigReadAddress++;
242 }
243
244 SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
245 }
246 }
247
248 Endpoint_ClearSETUP();
249
250 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
251
252 Endpoint_ClearOUT();
253 }
254 #endif
255
256 static void USB_Device_GetDescriptor(void)
257 {
258 const void* DescriptorPointer;
259 uint16_t DescriptorSize;
260
261 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
262 uint8_t DescriptorAddressSpace;
263 #endif
264
265 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
266 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
267 {
268 USB_Device_GetInternalSerialDescriptor();
269 return;
270 }
271 #endif
272
273 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
274 &DescriptorPointer
275 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
276 , &DescriptorAddressSpace
277 #endif
278 )) == NO_DESCRIPTOR)
279 {
280 return;
281 }
282
283 Endpoint_ClearSETUP();
284
285 #if defined(USE_RAM_DESCRIPTORS)
286 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
287 #elif defined(USE_EEPROM_DESCRIPTORS)
288 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
289 #elif defined(USE_FLASH_DESCRIPTORS)
290 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
291 #else
292 if (DescriptorAddressSpace == MEMSPACE_FLASH)
293 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
294 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
295 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
296 else
297 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
298 #endif
299
300 Endpoint_ClearOUT();
301 }
302
303 static void USB_Device_GetStatus(void)
304 {
305 uint8_t CurrentStatus = 0;
306
307 switch (USB_ControlRequest.bmRequestType)
308 {
309 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
310 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
311 #if !defined(NO_DEVICE_SELF_POWER)
312 if (USB_CurrentlySelfPowered)
313 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
314 #endif
315
316 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
317 if (USB_RemoteWakeupEnabled)
318 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
319 #endif
320 break;
321 #endif
322 #if !defined(CONTROL_ONLY_DEVICE)
323 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
324 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
325
326 CurrentStatus = Endpoint_IsStalled();
327
328 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
329
330 break;
331 #endif
332 default:
333 return;
334 }
335
336 Endpoint_ClearSETUP();
337
338 Endpoint_Write_Word_LE(CurrentStatus);
339 Endpoint_ClearIN();
340
341 Endpoint_ClearStatusStage();
342 }
343
344 static void USB_Device_ClearSetFeature(void)
345 {
346 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
347 {
348 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
349 case REQREC_DEVICE:
350 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
351 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
352 else
353 return;
354
355 break;
356 #endif
357 #if !defined(CONTROL_ONLY_DEVICE)
358 case REQREC_ENDPOINT:
359 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
360 {
361 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
362
363 if (EndpointIndex == ENDPOINT_CONTROLEP)
364 return;
365
366 Endpoint_SelectEndpoint(EndpointIndex);
367
368 if (Endpoint_IsEnabled())
369 {
370 if (USB_ControlRequest.bRequest == REQ_SetFeature)
371 {
372 Endpoint_StallTransaction();
373 }
374 else
375 {
376 Endpoint_ClearStall();
377 Endpoint_ResetFIFO(EndpointIndex);
378 Endpoint_ResetDataToggle();
379 }
380 }
381 }
382
383 break;
384 #endif
385 default:
386 return;
387 }
388
389 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
390
391 Endpoint_ClearSETUP();
392
393 Endpoint_ClearStatusStage();
394 }
395
396 #endif