Add in new architecture attribute defines to selectively remove the EEPROM and FLASH...
[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(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
242 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
243 , &DescriptorAddressSpace
244 #endif
245 )) == NO_DESCRIPTOR)
246 {
247 return;
248 }
249
250 Endpoint_ClearSETUP();
251
252 #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
253 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
254 #elif defined(USE_EEPROM_DESCRIPTORS)
255 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
256 #elif defined(USE_FLASH_DESCRIPTORS)
257 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
258 #else
259 if (DescriptorAddressSpace == MEMSPACE_FLASH)
260 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
261 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
262 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
263 else
264 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
265 #endif
266
267 Endpoint_ClearOUT();
268 }
269
270 static void USB_Device_GetStatus(void)
271 {
272 uint8_t CurrentStatus = 0;
273
274 switch (USB_ControlRequest.bmRequestType)
275 {
276 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
277 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
278 #if !defined(NO_DEVICE_SELF_POWER)
279 if (USB_CurrentlySelfPowered)
280 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
281 #endif
282
283 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
284 if (USB_RemoteWakeupEnabled)
285 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
286 #endif
287 break;
288 #endif
289 #if !defined(CONTROL_ONLY_DEVICE)
290 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
291 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
292
293 CurrentStatus = Endpoint_IsStalled();
294
295 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
296
297 break;
298 #endif
299 default:
300 return;
301 }
302
303 Endpoint_ClearSETUP();
304
305 Endpoint_Write_Word_LE(CurrentStatus);
306 Endpoint_ClearIN();
307
308 Endpoint_ClearStatusStage();
309 }
310
311 static void USB_Device_ClearSetFeature(void)
312 {
313 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
314 {
315 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
316 case REQREC_DEVICE:
317 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
318 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
319 else
320 return;
321
322 break;
323 #endif
324 #if !defined(CONTROL_ONLY_DEVICE)
325 case REQREC_ENDPOINT:
326 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)
327 {
328 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
329
330 if (EndpointIndex == ENDPOINT_CONTROLEP)
331 return;
332
333 Endpoint_SelectEndpoint(EndpointIndex);
334
335 if (Endpoint_IsEnabled())
336 {
337 if (USB_ControlRequest.bRequest == REQ_SetFeature)
338 {
339 Endpoint_StallTransaction();
340 }
341 else
342 {
343 Endpoint_ClearStall();
344 Endpoint_ResetEndpoint(EndpointIndex);
345 Endpoint_ResetDataToggle();
346 }
347 }
348 }
349
350 break;
351 #endif
352 default:
353 return;
354 }
355
356 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
357
358 Endpoint_ClearSETUP();
359
360 Endpoint_ClearStatusStage();
361 }
362
363 #endif
364