Add optional pipe double banking support to the Host mode Class drivers.
[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_ClearStatusStage();
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_ClearStatusStage();
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 Endpoint_ClearIN();
209
210 Endpoint_ClearStatusStage();
211 }
212
213 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
214 static char USB_Device_NibbleToASCII(uint8_t Nibble)
215 {
216 Nibble = ((Nibble & 0x0F) + '0');
217 return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
218 }
219
220 static void USB_Device_GetInternalSerialDescriptor(void)
221 {
222 struct
223 {
224 USB_Descriptor_Header_t Header;
225 int16_t UnicodeString[20];
226 } SignatureDescriptor;
227
228 SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
229 SignatureDescriptor.Header.Type = DTYPE_String;
230
231 uint8_t SigReadAddress = 0x0E;
232
233 for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
234 {
235 uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
236
237 if (SerialCharNum & 0x01)
238 {
239 SerialByte >>= 4;
240 SigReadAddress++;
241 }
242
243 SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
244 }
245
246 Endpoint_ClearSETUP();
247
248 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
249
250 Endpoint_ClearOUT();
251 }
252 #endif
253
254 static void USB_Device_GetDescriptor(void)
255 {
256 void* DescriptorPointer;
257 uint16_t DescriptorSize;
258
259 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
260 uint8_t DescriptorAddressSpace;
261 #endif
262
263 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
264 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
265 {
266 USB_Device_GetInternalSerialDescriptor();
267 return;
268 }
269 #endif
270
271 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
272 &DescriptorPointer
273 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
274 , &DescriptorAddressSpace
275 #endif
276 )) == NO_DESCRIPTOR)
277 {
278 return;
279 }
280
281 Endpoint_ClearSETUP();
282
283 #if defined(USE_RAM_DESCRIPTORS)
284 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
285 #elif defined(USE_EEPROM_DESCRIPTORS)
286 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
287 #elif defined(USE_FLASH_DESCRIPTORS)
288 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
289 #else
290 if (DescriptorAddressSpace == MEMSPACE_FLASH)
291 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
292 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
293 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
294 else
295 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
296 #endif
297
298 Endpoint_ClearOUT();
299 }
300
301 static void USB_Device_GetStatus(void)
302 {
303 uint8_t CurrentStatus = 0;
304
305 switch (USB_ControlRequest.bmRequestType)
306 {
307 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
308 if (USB_CurrentlySelfPowered)
309 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
310
311 if (USB_RemoteWakeupEnabled)
312 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
313
314 break;
315 #if !defined(CONTROL_ONLY_DEVICE)
316 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
317 Endpoint_SelectEndpoint(USB_ControlRequest.wIndex & 0xFF);
318
319 CurrentStatus = Endpoint_IsStalled();
320
321 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
322
323 break;
324 #endif
325 default:
326 return;
327 }
328
329 Endpoint_ClearSETUP();
330
331 Endpoint_Write_Word_LE(CurrentStatus);
332 Endpoint_ClearIN();
333
334 Endpoint_ClearStatusStage();
335 }
336
337 static void USB_Device_ClearSetFeature(void)
338 {
339 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
340 {
341 case REQREC_DEVICE:
342 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
343 USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
344 else
345 return;
346
347 break;
348 #if !defined(CONTROL_ONLY_DEVICE)
349 case REQREC_ENDPOINT:
350 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
351 {
352 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
353
354 if (EndpointIndex == ENDPOINT_CONTROLEP)
355 return;
356
357 Endpoint_SelectEndpoint(EndpointIndex);
358
359 if (Endpoint_IsEnabled())
360 {
361 if (USB_ControlRequest.bRequest == REQ_ClearFeature)
362 {
363 Endpoint_ClearStall();
364 Endpoint_ResetFIFO(EndpointIndex);
365 Endpoint_ResetDataToggle();
366 }
367 else
368 {
369 Endpoint_StallTransaction();
370 }
371 }
372 }
373
374 break;
375 #endif
376 }
377
378 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
379
380 Endpoint_ClearSETUP();
381
382 Endpoint_ClearStatusStage();
383 }
384
385 #endif