Renamed all library events to properly seperate out Device and Host mode events....
[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_ProcessControlRequest(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_Device_UnhandledControlRequest();
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 #if defined(FIXED_NUM_CONFIGURATIONS)
143 if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
144 return;
145 #else
146 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
147 uint8_t MemoryAddressSpace;
148 #endif
149
150 USB_Descriptor_Device_t* DevDescriptorPtr;
151
152 if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
153 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
154 , &MemoryAddressSpace
155 #endif
156 ) == NO_DESCRIPTOR)
157 {
158 return;
159 }
160
161 #if defined(USE_RAM_DESCRIPTORS)
162 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
163 return;
164 #elif defined (USE_EEPROM_DESCRIPTORS)
165 if ((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations))
166 return;
167 #elif defined (USE_FLASH_DESCRIPTORS)
168 if ((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations))
169 return;
170 #else
171 if (MemoryAddressSpace == MEMSPACE_FLASH)
172 {
173 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
174 return;
175 }
176 else if (MemoryAddressSpace == MEMSPACE_EEPROM)
177 {
178 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
179 return;
180 }
181 else
182 {
183 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
184 return;
185 }
186 #endif
187 #endif
188
189 Endpoint_ClearSETUP();
190
191 USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
192
193 Endpoint_ClearIN();
194
195 if (USB_ConfigurationNumber)
196 USB_DeviceState = DEVICE_STATE_Configured;
197 else
198 USB_DeviceState = DEVICE_STATE_Addressed;
199
200 EVENT_USB_Device_ConfigurationChanged();
201 }
202
203 void USB_Device_GetConfiguration(void)
204 {
205 Endpoint_ClearSETUP();
206
207 Endpoint_Write_Byte(USB_ConfigurationNumber);
208
209 Endpoint_ClearIN();
210
211 while (!(Endpoint_IsOUTReceived()))
212 {
213 if (USB_DeviceState == DEVICE_STATE_Unattached)
214 return;
215 }
216
217 Endpoint_ClearOUT();
218 }
219
220 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
221 static char USB_Device_NibbleToASCII(uint8_t Nibble)
222 {
223 Nibble = ((Nibble & 0x0F) + '0');
224 return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
225 }
226
227 static void USB_Device_GetInternalSerialDescriptor(void)
228 {
229 struct
230 {
231 USB_Descriptor_Header_t Header;
232 int16_t UnicodeString[20];
233 } SignatureDescriptor;
234
235 #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
236 SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
237 SignatureDescriptor.Header.Type = DTYPE_String;
238 #else
239 SignatureDescriptor.Header.bLength = sizeof(SignatureDescriptor);
240 SignatureDescriptor.Header.bDescriptorType = DTYPE_String;
241 #endif
242
243 uint8_t SigReadAddress = 0x0E;
244
245 for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
246 {
247 uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
248
249 if (SerialCharNum & 0x01)
250 {
251 SerialByte >>= 4;
252 SigReadAddress++;
253 }
254
255 SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
256 }
257
258 Endpoint_ClearSETUP();
259 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
260 Endpoint_ClearOUT();
261 }
262 #endif
263
264 static void USB_Device_GetDescriptor(void)
265 {
266 void* DescriptorPointer;
267 uint16_t DescriptorSize;
268
269 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
270 uint8_t DescriptorAddressSpace;
271 #endif
272
273 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
274 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
275 {
276 USB_Device_GetInternalSerialDescriptor();
277 return;
278 }
279 #endif
280
281 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
282 &DescriptorPointer
283 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
284 , &DescriptorAddressSpace
285 #endif
286 )) == NO_DESCRIPTOR)
287 {
288 return;
289 }
290
291 Endpoint_ClearSETUP();
292
293 #if defined(USE_RAM_DESCRIPTORS)
294 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
295 #elif defined(USE_EEPROM_DESCRIPTORS)
296 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
297 #elif defined(USE_FLASH_DESCRIPTORS)
298 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
299 #else
300 if (DescriptorAddressSpace == MEMSPACE_FLASH)
301 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
302 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
303 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
304 else
305 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
306 #endif
307
308 Endpoint_ClearOUT();
309 }
310
311 static void USB_Device_GetStatus(void)
312 {
313 uint8_t CurrentStatus = 0;
314
315 switch (USB_ControlRequest.bmRequestType)
316 {
317 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
318 if (USB_CurrentlySelfPowered)
319 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
320
321 if (USB_RemoteWakeupEnabled)
322 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
323
324 break;
325 #if !defined(CONTROL_ONLY_DEVICE)
326 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
327 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex);
328
329 CurrentStatus = Endpoint_IsStalled();
330
331 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
332
333 break;
334 #endif
335 }
336
337 Endpoint_ClearSETUP();
338
339 Endpoint_Write_Word_LE(CurrentStatus);
340
341 Endpoint_ClearIN();
342
343 while (!(Endpoint_IsOUTReceived()))
344 {
345 if (USB_DeviceState == DEVICE_STATE_Unattached)
346 return;
347 }
348
349 Endpoint_ClearOUT();
350 }
351
352 static void USB_Device_ClearSetFeature(void)
353 {
354 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
355 {
356 case REQREC_DEVICE:
357 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
358 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
359 else
360 return;
361
362 break;
363 #if !defined(CONTROL_ONLY_DEVICE)
364 case REQREC_ENDPOINT:
365 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
366 {
367 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
368
369 if (EndpointIndex == ENDPOINT_CONTROLEP)
370 return;
371
372 Endpoint_SelectEndpoint(EndpointIndex);
373
374 if (Endpoint_IsEnabled())
375 {
376 if (USB_ControlRequest.bRequest == REQ_ClearFeature)
377 {
378 Endpoint_ClearStall();
379 Endpoint_ResetFIFO(EndpointIndex);
380 Endpoint_ResetDataToggle();
381 }
382 else
383 {
384 Endpoint_StallTransaction();
385 }
386 }
387 }
388
389 break;
390 #endif
391 }
392
393 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
394
395 Endpoint_ClearSETUP();
396
397 Endpoint_ClearIN();
398 }
399
400 #endif