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