Fix issue with CDC device demos causing broken communications when the device tries...
[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(FIXED_NUM_CONFIGURATIONS)
145 if ((uint8_t)USB_ControlRequest.wValue > FIXED_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 char USB_Device_NibbleToASCII(uint8_t Nibble)
231 {
232 Nibble = ((Nibble & 0x0F) + '0');
233 return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
234 }
235
236 static void USB_Device_GetInternalSerialDescriptor(void)
237 {
238 struct
239 {
240 USB_Descriptor_Header_t Header;
241 int16_t UnicodeString[20];
242 } SignatureDescriptor;
243
244 #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
245 SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
246 SignatureDescriptor.Header.Type = DTYPE_String;
247 #else
248 SignatureDescriptor.Header.bLength = sizeof(SignatureDescriptor);
249 SignatureDescriptor.Header.bDescriptorType = DTYPE_String;
250 #endif
251
252 uint8_t SigReadAddress = 0x0E;
253
254 for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
255 {
256 uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
257
258 if (SerialCharNum & 0x01)
259 {
260 SerialByte >>= 4;
261 SigReadAddress++;
262 }
263
264 SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
265 }
266
267 Endpoint_ClearSETUP();
268 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
269 Endpoint_ClearOUT();
270 }
271 #endif
272
273 static void USB_Device_GetDescriptor(void)
274 {
275 void* DescriptorPointer;
276 uint16_t DescriptorSize;
277
278 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
279 uint8_t DescriptorAddressSpace;
280 #endif
281
282 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
283 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
284 {
285 USB_Device_GetInternalSerialDescriptor();
286 return;
287 }
288 #endif
289
290 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
291 &DescriptorPointer
292 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
293 , &DescriptorAddressSpace
294 #endif
295 )) == NO_DESCRIPTOR)
296 {
297 return;
298 }
299
300 Endpoint_ClearSETUP();
301
302 #if defined(USE_RAM_DESCRIPTORS)
303 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
304 #elif defined(USE_EEPROM_DESCRIPTORS)
305 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
306 #elif defined(USE_FLASH_DESCRIPTORS)
307 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
308 #else
309 if (DescriptorAddressSpace == MEMSPACE_FLASH)
310 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
311 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
312 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
313 else
314 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
315 #endif
316
317 Endpoint_ClearOUT();
318 }
319
320 static void USB_Device_GetStatus(void)
321 {
322 uint8_t CurrentStatus = 0;
323
324 switch (USB_ControlRequest.bmRequestType)
325 {
326 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
327 if (USB_CurrentlySelfPowered)
328 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
329
330 if (USB_RemoteWakeupEnabled)
331 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
332
333 break;
334 #if !defined(CONTROL_ONLY_DEVICE)
335 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
336 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex);
337
338 CurrentStatus = Endpoint_IsStalled();
339
340 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
341
342 break;
343 #endif
344 }
345
346 Endpoint_ClearSETUP();
347
348 Endpoint_Write_Word_LE(CurrentStatus);
349
350 Endpoint_ClearIN();
351
352 while (!(Endpoint_IsOUTReceived()))
353 {
354 if (USB_DeviceState == DEVICE_STATE_Unattached)
355 return;
356 }
357
358 Endpoint_ClearOUT();
359 }
360
361 static void USB_Device_ClearSetFeature(void)
362 {
363 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
364 {
365 case REQREC_DEVICE:
366 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
367 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
368 else
369 return;
370
371 break;
372 #if !defined(CONTROL_ONLY_DEVICE)
373 case REQREC_ENDPOINT:
374 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
375 {
376 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
377
378 if (EndpointIndex == ENDPOINT_CONTROLEP)
379 return;
380
381 Endpoint_SelectEndpoint(EndpointIndex);
382
383 if (Endpoint_IsEnabled())
384 {
385 if (USB_ControlRequest.bRequest == REQ_ClearFeature)
386 {
387 Endpoint_ClearStall();
388 Endpoint_ResetFIFO(EndpointIndex);
389 Endpoint_ResetDataToggle();
390 }
391 else
392 {
393 Endpoint_StallTransaction();
394 }
395 }
396 }
397
398 break;
399 #endif
400 }
401
402 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
403
404 Endpoint_ClearSETUP();
405
406 Endpoint_ClearIN();
407 }
408
409 #endif