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