]> git.donarmstrong.com Git - qmk_firmware.git/blob - protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.c
Squashed 'tmk_core/' changes from b9e0ea0..caca2c0
[qmk_firmware.git] / protocol / lufa / LUFA-120730 / LUFA / Drivers / USB / Core / DeviceStandardReq.c
1 /*\r
2              LUFA Library\r
3      Copyright (C) Dean Camera, 2012.\r
4 \r
5   dean [at] fourwalledcubicle [dot] com\r
6            www.lufa-lib.org\r
7 */\r
8 \r
9 /*\r
10   Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
11 \r
12   Permission to use, copy, modify, distribute, and sell this\r
13   software and its documentation for any purpose is hereby granted\r
14   without fee, provided that the above copyright notice appear in\r
15   all copies and that both that the copyright notice and this\r
16   permission notice and warranty disclaimer appear in supporting\r
17   documentation, and that the name of the author not be used in\r
18   advertising or publicity pertaining to distribution of the\r
19   software without specific, written prior permission.\r
20 \r
21   The author disclaim all warranties with regard to this\r
22   software, including all implied warranties of merchantability\r
23   and fitness.  In no event shall the author be liable for any\r
24   special, indirect or consequential damages or any damages\r
25   whatsoever resulting from loss of use, data or profits, whether\r
26   in an action of contract, negligence or other tortious action,\r
27   arising out of or in connection with the use or performance of\r
28   this software.\r
29 */\r
30 \r
31 #define  __INCLUDE_FROM_USB_DRIVER\r
32 #include "USBMode.h"\r
33 \r
34 #if defined(USB_CAN_BE_DEVICE)\r
35 \r
36 #define  __INCLUDE_FROM_DEVICESTDREQ_C\r
37 #include "DeviceStandardReq.h"\r
38 \r
39 uint8_t USB_Device_ConfigurationNumber;\r
40 \r
41 #if !defined(NO_DEVICE_SELF_POWER)\r
42 bool    USB_Device_CurrentlySelfPowered;\r
43 #endif\r
44 \r
45 #if !defined(NO_DEVICE_REMOTE_WAKEUP)\r
46 bool    USB_Device_RemoteWakeupEnabled;\r
47 #endif\r
48 \r
49 void USB_Device_ProcessControlRequest(void)\r
50 {\r
51         #if defined(ARCH_BIG_ENDIAN)\r
52         USB_ControlRequest.bmRequestType = Endpoint_Read_8();\r
53         USB_ControlRequest.bRequest      = Endpoint_Read_8();\r
54         USB_ControlRequest.wValue        = Endpoint_Read_16_LE();\r
55         USB_ControlRequest.wIndex        = Endpoint_Read_16_LE();\r
56         USB_ControlRequest.wLength       = Endpoint_Read_16_LE();\r
57         #else\r
58         uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;\r
59 \r
60         for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)\r
61           *(RequestHeader++) = Endpoint_Read_8();\r
62         #endif\r
63 \r
64         EVENT_USB_Device_ControlRequest();\r
65 \r
66         if (Endpoint_IsSETUPReceived())\r
67         {\r
68                 uint8_t bmRequestType = USB_ControlRequest.bmRequestType;\r
69 \r
70                 switch (USB_ControlRequest.bRequest)\r
71                 {\r
72                         case REQ_GetStatus:\r
73                                 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
74                                         (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))\r
75                                 {\r
76                                         USB_Device_GetStatus();\r
77                                 }\r
78 \r
79                                 break;\r
80                         case REQ_ClearFeature:\r
81                         case REQ_SetFeature:\r
82                                 if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
83                                         (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))\r
84                                 {\r
85                                         USB_Device_ClearSetFeature();\r
86                                 }\r
87 \r
88                                 break;\r
89                         case REQ_SetAddress:\r
90                                 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))\r
91                                   USB_Device_SetAddress();\r
92 \r
93                                 break;\r
94                         case REQ_GetDescriptor:\r
95                                 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
96                                         (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))\r
97                                 {\r
98                                         USB_Device_GetDescriptor();\r
99                                 }\r
100 \r
101                                 break;\r
102                         case REQ_GetConfiguration:\r
103                                 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))\r
104                                   USB_Device_GetConfiguration();\r
105 \r
106                                 break;\r
107                         case REQ_SetConfiguration:\r
108                                 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))\r
109                                   USB_Device_SetConfiguration();\r
110 \r
111                                 break;\r
112                 }\r
113         }\r
114 \r
115         if (Endpoint_IsSETUPReceived())\r
116         {\r
117                 Endpoint_StallTransaction();\r
118                 Endpoint_ClearSETUP();\r
119         }\r
120 }\r
121 \r
122 static void USB_Device_SetAddress(void)\r
123 {\r
124         uint8_t    DeviceAddress    = (USB_ControlRequest.wValue & 0x7F);\r
125         uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
126         GlobalInterruptDisable();\r
127 \r
128         Endpoint_ClearSETUP();\r
129 \r
130         Endpoint_ClearStatusStage();\r
131 \r
132         while (!(Endpoint_IsINReady()));\r
133 \r
134         USB_Device_SetDeviceAddress(DeviceAddress);\r
135         USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;\r
136 \r
137         SetGlobalInterruptMask(CurrentGlobalInt);\r
138 }\r
139 \r
140 static void USB_Device_SetConfiguration(void)\r
141 {\r
142         #if defined(FIXED_NUM_CONFIGURATIONS)\r
143         if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)\r
144           return;\r
145         #else\r
146         USB_Descriptor_Device_t* DevDescriptorPtr;\r
147 \r
148         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)\r
149                 #if defined(USE_FLASH_DESCRIPTORS)\r
150                         #define MemoryAddressSpace  MEMSPACE_FLASH\r
151                 #elif defined(USE_EEPROM_DESCRIPTORS)\r
152                         #define MemoryAddressSpace  MEMSPACE_EEPROM\r
153                 #elif defined(USE_SRAM_DESCRIPTORS)\r
154                         #define MemoryAddressSpace  MEMSPACE_SRAM\r
155                 #else\r
156                         uint8_t MemoryAddressSpace;\r
157                 #endif\r
158         #endif\r
159 \r
160         if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr\r
161         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \\r
162             !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))\r
163                                        , &MemoryAddressSpace\r
164         #endif\r
165                                        ) == NO_DESCRIPTOR)\r
166         {\r
167                 return;\r
168         }\r
169 \r
170         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)\r
171         if (MemoryAddressSpace == MEMSPACE_FLASH)\r
172         {\r
173                 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))\r
174                   return;\r
175         }\r
176         else if (MemoryAddressSpace == MEMSPACE_EEPROM)\r
177         {\r
178                 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))\r
179                   return;\r
180         }\r
181         else\r
182         {\r
183                 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)\r
184                   return;\r
185         }\r
186         #else\r
187         if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)\r
188           return;\r
189         #endif\r
190         #endif\r
191 \r
192         Endpoint_ClearSETUP();\r
193 \r
194         USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;\r
195 \r
196         Endpoint_ClearStatusStage();\r
197 \r
198         if (USB_Device_ConfigurationNumber)\r
199           USB_DeviceState = DEVICE_STATE_Configured;\r
200         else\r
201           USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;\r
202 \r
203         EVENT_USB_Device_ConfigurationChanged();\r
204 }\r
205 \r
206 static void USB_Device_GetConfiguration(void)\r
207 {\r
208         Endpoint_ClearSETUP();\r
209 \r
210         Endpoint_Write_8(USB_Device_ConfigurationNumber);\r
211         Endpoint_ClearIN();\r
212 \r
213         Endpoint_ClearStatusStage();\r
214 }\r
215 \r
216 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)\r
217 static void USB_Device_GetInternalSerialDescriptor(void)\r
218 {\r
219         struct\r
220         {\r
221                 USB_Descriptor_Header_t Header;\r
222                 uint16_t                UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];\r
223         } SignatureDescriptor;\r
224 \r
225         SignatureDescriptor.Header.Type = DTYPE_String;\r
226         SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);\r
227 \r
228         USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);\r
229 \r
230         Endpoint_ClearSETUP();\r
231 \r
232         Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));\r
233         Endpoint_ClearOUT();\r
234 }\r
235 #endif\r
236 \r
237 static void USB_Device_GetDescriptor(void)\r
238 {\r
239         const void* DescriptorPointer;\r
240         uint16_t    DescriptorSize;\r
241 \r
242         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \\r
243             !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))\r
244         uint8_t DescriptorAddressSpace;\r
245         #endif\r
246 \r
247         #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)\r
248         if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))\r
249         {\r
250                 USB_Device_GetInternalSerialDescriptor();\r
251                 return;\r
252         }\r
253         #endif\r
254 \r
255         if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,\r
256                                                          &DescriptorPointer\r
257         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \\r
258             !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))\r
259                                                          , &DescriptorAddressSpace\r
260         #endif\r
261                                                                                                          )) == NO_DESCRIPTOR)\r
262         {\r
263                 return;\r
264         }\r
265 \r
266         Endpoint_ClearSETUP();\r
267 \r
268         #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)\r
269         Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);\r
270         #elif defined(USE_EEPROM_DESCRIPTORS)\r
271         Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);\r
272         #elif defined(USE_FLASH_DESCRIPTORS)\r
273         Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);\r
274         #else\r
275         if (DescriptorAddressSpace == MEMSPACE_FLASH)\r
276           Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);\r
277         else if (DescriptorAddressSpace == MEMSPACE_EEPROM)\r
278           Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);\r
279         else\r
280           Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);\r
281         #endif\r
282 \r
283         Endpoint_ClearOUT();\r
284 }\r
285 \r
286 static void USB_Device_GetStatus(void)\r
287 {\r
288         uint8_t CurrentStatus = 0;\r
289 \r
290         switch (USB_ControlRequest.bmRequestType)\r
291         {\r
292                 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):\r
293                         #if !defined(NO_DEVICE_SELF_POWER)\r
294                         if (USB_Device_CurrentlySelfPowered)\r
295                           CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;\r
296                         #endif\r
297 \r
298                         #if !defined(NO_DEVICE_REMOTE_WAKEUP)\r
299                         if (USB_Device_RemoteWakeupEnabled)\r
300                           CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;\r
301                         #endif\r
302                         break;\r
303                 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):\r
304                         #if !defined(CONTROL_ONLY_DEVICE)\r
305                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);\r
306 \r
307                         CurrentStatus = Endpoint_IsStalled();\r
308 \r
309                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);\r
310                         #endif\r
311 \r
312                         break;\r
313                 default:\r
314                         return;\r
315         }\r
316 \r
317         Endpoint_ClearSETUP();\r
318 \r
319         Endpoint_Write_16_LE(CurrentStatus);\r
320         Endpoint_ClearIN();\r
321 \r
322         Endpoint_ClearStatusStage();\r
323 }\r
324 \r
325 static void USB_Device_ClearSetFeature(void)\r
326 {\r
327         switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)\r
328         {\r
329                 #if !defined(NO_DEVICE_REMOTE_WAKEUP)\r
330                 case REQREC_DEVICE:\r
331                         if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)\r
332                           USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);\r
333                         else\r
334                           return;\r
335 \r
336                         break;\r
337                 #endif\r
338                 #if !defined(CONTROL_ONLY_DEVICE)\r
339                 case REQREC_ENDPOINT:\r
340                         if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)\r
341                         {\r
342                                 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);\r
343 \r
344                                 if (EndpointIndex == ENDPOINT_CONTROLEP)\r
345                                   return;\r
346 \r
347                                 Endpoint_SelectEndpoint(EndpointIndex);\r
348 \r
349                                 if (Endpoint_IsEnabled())\r
350                                 {\r
351                                         if (USB_ControlRequest.bRequest == REQ_SetFeature)\r
352                                         {\r
353                                                 Endpoint_StallTransaction();\r
354                                         }\r
355                                         else\r
356                                         {\r
357                                                 Endpoint_ClearStall();\r
358                                                 Endpoint_ResetEndpoint(EndpointIndex);\r
359                                                 Endpoint_ResetDataToggle();\r
360                                         }\r
361                                 }\r
362                         }\r
363 \r
364                         break;\r
365                 #endif\r
366                 default:\r
367                         return;\r
368         }\r
369 \r
370         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);\r
371 \r
372         Endpoint_ClearSETUP();\r
373 \r
374         Endpoint_ClearStatusStage();\r
375 }\r
376 \r
377 #endif\r
378 \r