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