55b49b8034c2323dd7885434afa77a5035b68e2e
[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 Endpoint_ClearSETUP();
121
122 Endpoint_ClearIN();
123
124 while (!(Endpoint_IsINReady()));
125
126 UDADDR = ((1 << ADDEN) | ((uint8_t)USB_ControlRequest.wValue & 0x7F));
127
128 return;
129 }
130
131 static void USB_Device_SetConfiguration(void)
132 {
133 bool AlreadyConfigured = (USB_ConfigurationNumber != 0);
134
135 #if defined(USE_SINGLE_DEVICE_CONFIGURATION)
136 if ((uint8_t)USB_ControlRequest.wValue > 1)
137 #else
138 USB_Descriptor_Device_t* DevDescriptorPtr;
139
140 if ((CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr) == NO_DESCRIPTOR) ||
141 #if defined(USE_RAM_DESCRIPTORS)
142 ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations))
143 #elif defined (USE_EEPROM_DESCRIPTORS)
144 ((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
145 #else
146 ((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
147 #endif
148 #endif
149 {
150 return;
151 }
152
153 Endpoint_ClearSETUP();
154
155 USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
156
157 Endpoint_ClearIN();
158
159 if (!(AlreadyConfigured) && USB_ConfigurationNumber)
160 EVENT_USB_DeviceEnumerationComplete();
161
162 EVENT_USB_ConfigurationChanged();
163 }
164
165 void USB_Device_GetConfiguration(void)
166 {
167 Endpoint_ClearSETUP();
168
169 Endpoint_Write_Byte(USB_ConfigurationNumber);
170
171 Endpoint_ClearIN();
172
173 while (!(Endpoint_IsOUTReceived()));
174 Endpoint_ClearOUT();
175 }
176
177 static void USB_Device_GetDescriptor(void)
178 {
179 void* DescriptorPointer;
180 uint16_t DescriptorSize;
181
182 #if defined(USE_INTERNAL_SERIAL)
183 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
184 {
185 uint8_t SignatureDescriptor[2 + (sizeof(int16_t) * 12)];
186
187 SignatureDescriptor[0] = sizeof(SignatureDescriptor);
188 SignatureDescriptor[1] = DTYPE_String;
189
190 uint16_t* SigUnicodeChars = (uint16_t*)&SignatureDescriptor[2];
191
192 for (uint8_t SerialByteNum = 0; SerialByteNum < 6; SerialByteNum++)
193 {
194 char ConvSigString[3];
195
196 itoa(boot_signature_byte_get(0x0E + SerialByteNum), ConvSigString, 16);
197
198 SigUnicodeChars[0] = toupper(ConvSigString[0]);
199 SigUnicodeChars[1] = toupper(ConvSigString[1]);
200
201 SigUnicodeChars += 2;
202 }
203
204 Endpoint_ClearSETUP();
205 Endpoint_Write_Control_Stream_LE(SignatureDescriptor, sizeof(SignatureDescriptor));
206 Endpoint_ClearOUT();
207
208 return;
209 }
210 #endif
211
212 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
213 &DescriptorPointer)) == NO_DESCRIPTOR)
214 {
215 return;
216 }
217
218 Endpoint_ClearSETUP();
219
220 #if defined(USE_RAM_DESCRIPTORS)
221 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
222 #else
223 bool SendZLP;
224
225 if (USB_ControlRequest.wLength > DescriptorSize)
226 USB_ControlRequest.wLength = DescriptorSize;
227
228 while (USB_ControlRequest.wLength)
229 {
230 while (!(Endpoint_IsINReady()))
231 {
232 if (Endpoint_IsOUTReceived())
233 {
234 Endpoint_ClearOUT();
235 return;
236 }
237 }
238
239 while (USB_ControlRequest.wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
240 {
241 #if defined (USE_EEPROM_DESCRIPTORS)
242 Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++));
243 #else
244 Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++));
245 #endif
246
247 USB_ControlRequest.wLength--;
248 }
249
250 SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
251 Endpoint_ClearIN();
252 }
253
254 if (SendZLP)
255 {
256 while (!(Endpoint_IsINReady()));
257 Endpoint_ClearIN();
258 }
259
260 while (!(Endpoint_IsOUTReceived()));
261 #endif
262
263 Endpoint_ClearOUT();
264 }
265
266 static void USB_Device_GetStatus(void)
267 {
268 uint8_t CurrentStatus = 0;
269
270 switch (USB_ControlRequest.bmRequestType)
271 {
272 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
273 if (USB_CurrentlySelfPowered)
274 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
275
276 if (USB_RemoteWakeupEnabled)
277 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
278
279 break;
280 #if !defined(CONTROL_ONLY_DEVICE)
281 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
282 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex);
283
284 CurrentStatus = Endpoint_IsStalled();
285
286 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
287
288 break;
289 #endif
290 }
291
292 Endpoint_ClearSETUP();
293
294 Endpoint_Write_Word_LE(CurrentStatus);
295
296 Endpoint_ClearIN();
297
298 while (!(Endpoint_IsOUTReceived()));
299 Endpoint_ClearOUT();
300 }
301
302 static void USB_Device_ClearSetFeature(void)
303 {
304 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
305 {
306 case REQREC_DEVICE:
307 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
308 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
309 else
310 return;
311
312 break;
313 #if !defined(CONTROL_ONLY_DEVICE)
314 case REQREC_ENDPOINT:
315 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
316 {
317 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
318
319 if (EndpointIndex == ENDPOINT_CONTROLEP)
320 return;
321
322 Endpoint_SelectEndpoint(EndpointIndex);
323
324 if (Endpoint_IsEnabled())
325 {
326 if (USB_ControlRequest.bRequest == REQ_ClearFeature)
327 {
328 Endpoint_ClearStall();
329 Endpoint_ResetFIFO(EndpointIndex);
330 Endpoint_ResetDataToggle();
331 }
332 else
333 {
334 Endpoint_StallTransaction();
335 }
336 }
337 }
338
339 break;
340 #endif
341 }
342
343 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
344
345 Endpoint_ClearSETUP();
346
347 Endpoint_ClearIN();
348 }
349
350 #endif