Added new NO_DEVICE_SELF_POWER and NO_DEVICE_REMOTE_WAKEUP compile time options.
[pub/USBasp.git] / LUFA / Drivers / USB / LowLevel / DevChapter9.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2009.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 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 #include "../HighLevel/USBMode.h"
32
33 #if defined(USB_CAN_BE_DEVICE)
34
35 #define INCLUDE_FROM_DEVCHAPTER9_C
36 #include "DevChapter9.h"
37
38 uint8_t USB_ConfigurationNumber;
39
40 #if !defined(NO_DEVICE_SELF_POWER)
41 bool USB_CurrentlySelfPowered;
42 #endif
43
44 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
45 bool USB_RemoteWakeupEnabled;
46 #endif
47
48 void USB_Device_ProcessControlRequest(void)
49 {
50 bool RequestHandled = false;
51 uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;
52
53 for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
54 *(RequestHeader++) = Endpoint_Read_Byte();
55
56 uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
57
58 switch (USB_ControlRequest.bRequest)
59 {
60 case REQ_GetStatus:
61 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
62 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
63 {
64 USB_Device_GetStatus();
65 RequestHandled = true;
66 }
67
68 break;
69 case REQ_ClearFeature:
70 case REQ_SetFeature:
71 if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
72 (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
73 {
74 USB_Device_ClearSetFeature();
75 RequestHandled = true;
76 }
77
78 break;
79 case REQ_SetAddress:
80 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
81 {
82 USB_Device_SetAddress();
83 RequestHandled = true;
84 }
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 RequestHandled = true;
93 }
94
95 break;
96 case REQ_GetConfiguration:
97 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
98 {
99 USB_Device_GetConfiguration();
100 RequestHandled = true;
101 }
102
103 break;
104 case REQ_SetConfiguration:
105 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
106 {
107 USB_Device_SetConfiguration();
108 RequestHandled = true;
109 }
110
111 break;
112 }
113
114 if (!(RequestHandled))
115 EVENT_USB_Device_UnhandledControlRequest();
116
117 if (Endpoint_IsSETUPReceived())
118 {
119 Endpoint_StallTransaction();
120 Endpoint_ClearSETUP();
121 }
122 }
123
124 static void USB_Device_SetAddress(void)
125 {
126 uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
127
128 Endpoint_ClearSETUP();
129
130 Endpoint_ClearStatusStage();
131
132 while (!(Endpoint_IsINReady()))
133 {
134 if (USB_DeviceState == DEVICE_STATE_Unattached)
135 return;
136 }
137
138 if (DeviceAddress)
139 USB_DeviceState = DEVICE_STATE_Addressed;
140
141 UDADDR = ((1 << ADDEN) | DeviceAddress);
142
143 return;
144 }
145
146 static void USB_Device_SetConfiguration(void)
147 {
148 #if defined(FIXED_NUM_CONFIGURATIONS)
149 if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
150 return;
151 #else
152 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
153 uint8_t MemoryAddressSpace;
154 #endif
155
156 USB_Descriptor_Device_t* DevDescriptorPtr;
157
158 if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
159 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
160 , &MemoryAddressSpace
161 #endif
162 ) == NO_DESCRIPTOR)
163 {
164 return;
165 }
166
167 #if defined(USE_RAM_DESCRIPTORS)
168 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
169 return;
170 #elif defined (USE_EEPROM_DESCRIPTORS)
171 if ((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations))
172 return;
173 #elif defined (USE_FLASH_DESCRIPTORS)
174 if ((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations))
175 return;
176 #else
177 if (MemoryAddressSpace == MEMSPACE_FLASH)
178 {
179 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
180 return;
181 }
182 else if (MemoryAddressSpace == MEMSPACE_EEPROM)
183 {
184 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
185 return;
186 }
187 else
188 {
189 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
190 return;
191 }
192 #endif
193 #endif
194
195 Endpoint_ClearSETUP();
196
197 USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
198
199 Endpoint_ClearStatusStage();
200
201 USB_DeviceState = (USB_ConfigurationNumber) ? DEVICE_STATE_Configured : DEVICE_STATE_Addressed;
202
203 EVENT_USB_Device_ConfigurationChanged();
204 }
205
206 void USB_Device_GetConfiguration(void)
207 {
208 Endpoint_ClearSETUP();
209
210 Endpoint_Write_Byte(USB_ConfigurationNumber);
211 Endpoint_ClearIN();
212
213 Endpoint_ClearStatusStage();
214 }
215
216 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
217 static char USB_Device_NibbleToASCII(uint8_t Nibble)
218 {
219 Nibble = ((Nibble & 0x0F) + '0');
220 return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
221 }
222
223 static void USB_Device_GetInternalSerialDescriptor(void)
224 {
225 struct
226 {
227 USB_Descriptor_Header_t Header;
228 int16_t UnicodeString[20];
229 } SignatureDescriptor;
230
231 SignatureDescriptor.Header.Type = DTYPE_String;
232 SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
233
234 uint8_t SigReadAddress = 0x0E;
235
236 for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
237 {
238 uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
239
240 if (SerialCharNum & 0x01)
241 {
242 SerialByte >>= 4;
243 SigReadAddress++;
244 }
245
246 SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
247 }
248
249 Endpoint_ClearSETUP();
250
251 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
252
253 Endpoint_ClearOUT();
254 }
255 #endif
256
257 static void USB_Device_GetDescriptor(void)
258 {
259 void* DescriptorPointer;
260 uint16_t DescriptorSize;
261
262 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
263 uint8_t DescriptorAddressSpace;
264 #endif
265
266 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
267 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
268 {
269 USB_Device_GetInternalSerialDescriptor();
270 return;
271 }
272 #endif
273
274 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
275 &DescriptorPointer
276 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
277 , &DescriptorAddressSpace
278 #endif
279 )) == NO_DESCRIPTOR)
280 {
281 return;
282 }
283
284 Endpoint_ClearSETUP();
285
286 #if defined(USE_RAM_DESCRIPTORS)
287 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
288 #elif defined(USE_EEPROM_DESCRIPTORS)
289 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
290 #elif defined(USE_FLASH_DESCRIPTORS)
291 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
292 #else
293 if (DescriptorAddressSpace == MEMSPACE_FLASH)
294 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
295 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
296 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
297 else
298 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
299 #endif
300
301 Endpoint_ClearOUT();
302 }
303
304 static void USB_Device_GetStatus(void)
305 {
306 uint8_t CurrentStatus = 0;
307
308 switch (USB_ControlRequest.bmRequestType)
309 {
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
321 break;
322 #if !defined(CONTROL_ONLY_DEVICE)
323 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
324 Endpoint_SelectEndpoint(USB_ControlRequest.wIndex & 0xFF);
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 case REQREC_DEVICE:
349 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
350 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
351 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
352 else
353 return;
354 #endif
355
356 break;
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 }
386
387 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
388
389 Endpoint_ClearSETUP();
390
391 Endpoint_ClearStatusStage();
392 }
393
394 #endif