]> git.sur5r.net Git - freertos/blob
d2f30789e1fbae2fd3699246440d91d65427f5ec
[freertos] /
1 /*\r
2  * @brief USB device standard request management\r
3  *\r
4  * @note\r
5  * Copyright(C) NXP Semiconductors, 2012\r
6  * Copyright(C) Dean Camera, 2011, 2012\r
7  * All rights reserved.\r
8  *\r
9  * @par\r
10  * Software that is described herein is for illustrative purposes only\r
11  * which provides customers with programming information regarding the\r
12  * LPC products.  This software is supplied "AS IS" without any warranties of\r
13  * any kind, and NXP Semiconductors and its licensor disclaim any and\r
14  * all warranties, express or implied, including all implied warranties of\r
15  * merchantability, fitness for a particular purpose and non-infringement of\r
16  * intellectual property rights.  NXP Semiconductors assumes no responsibility\r
17  * or liability for the use of the software, conveys no license or rights under any\r
18  * patent, copyright, mask work right, or any other intellectual property rights in\r
19  * or to any products. NXP Semiconductors reserves the right to make changes\r
20  * in the software without notification. NXP Semiconductors also makes no\r
21  * representation or warranty that such application will be suitable for the\r
22  * specified use without further testing or modification.\r
23  *\r
24  * @par\r
25  * Permission to use, copy, modify, and distribute this software and its\r
26  * documentation is hereby granted, under NXP Semiconductors' and its\r
27  * licensor's relevant copyrights in the software, without fee, provided that it\r
28  * is used in conjunction with NXP Semiconductors microcontrollers.  This\r
29  * copyright, permission, and disclaimer notice must appear in all copies of\r
30  * this code.\r
31  */\r
32 \r
33 \r
34 #define  __INCLUDE_FROM_USB_DRIVER\r
35 #include "USBMode.h"\r
36 \r
37 #if defined(USB_CAN_BE_DEVICE)\r
38 \r
39 #define  __INCLUDE_FROM_DEVICESTDREQ_C\r
40 #include "DeviceStandardReq.h"\r
41 \r
42 uint8_t USB_Device_ConfigurationNumber;\r
43 \r
44 #if !defined(NO_DEVICE_SELF_POWER)\r
45 bool    USB_Device_CurrentlySelfPowered;\r
46 #endif\r
47 \r
48 #if !defined(NO_DEVICE_REMOTE_WAKEUP)\r
49 bool    USB_Device_RemoteWakeupEnabled;\r
50 #endif\r
51 \r
52 void USB_Device_ProcessControlRequest(uint8_t corenum)\r
53 {\r
54 //      USB_ControlRequest.bmRequestType = Endpoint_Read_8();\r
55 //      USB_ControlRequest.bRequest      = Endpoint_Read_8();\r
56 //      USB_ControlRequest.wValue        = Endpoint_Read_16_LE();\r
57 //      USB_ControlRequest.wIndex        = Endpoint_Read_16_LE();\r
58 //      USB_ControlRequest.wLength       = Endpoint_Read_16_LE();\r
59 \r
60         Endpoint_GetSetupPackage(corenum, (uint8_t*) &USB_ControlRequest);\r
61 \r
62         EVENT_USB_Device_ControlRequest();\r
63 \r
64         if (Endpoint_IsSETUPReceived(corenum))\r
65         {\r
66                 uint8_t bmRequestType = USB_ControlRequest.bmRequestType;\r
67 \r
68                 switch (USB_ControlRequest.bRequest)\r
69                 {\r
70                         case REQ_GetStatus:\r
71                                 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
72                                         (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))\r
73                                 {\r
74                                         USB_Device_GetStatus(corenum);\r
75                                 }\r
76 \r
77                                 break;\r
78                         case REQ_ClearFeature:\r
79                         case REQ_SetFeature:\r
80                                 if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
81                                         (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))\r
82                                 {\r
83                                         USB_Device_ClearSetFeature(corenum);\r
84                                 }\r
85 \r
86                                 break;\r
87                         case REQ_SetAddress:\r
88                                 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))\r
89                                   USB_Device_SetAddress(corenum);\r
90 \r
91                                 break;\r
92                         case REQ_GetDescriptor:\r
93                                 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
94                                         (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))\r
95                                 {\r
96                                         USB_Device_GetDescriptor(corenum);\r
97                                 }\r
98 \r
99                                 break;\r
100                         case REQ_GetConfiguration:\r
101                                 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))\r
102                                   USB_Device_GetConfiguration(corenum);\r
103 \r
104                                 break;\r
105                         case REQ_SetConfiguration:\r
106                                 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))\r
107                                   USB_Device_SetConfiguration(corenum);\r
108 \r
109                                 break;\r
110                 }\r
111         }\r
112 \r
113         if (Endpoint_IsSETUPReceived(corenum))\r
114         {\r
115                 Endpoint_ClearSETUP(corenum);\r
116                 Endpoint_StallTransaction(corenum);\r
117         }\r
118 }\r
119 \r
120 static void USB_Device_SetAddress(uint8_t corenum)\r
121 {\r
122         uint8_t    DeviceAddress    = (USB_ControlRequest.wValue & 0x7F);\r
123         uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
124         GlobalInterruptDisable();\r
125                                 \r
126         Endpoint_ClearSETUP(corenum);\r
127 \r
128         Endpoint_ClearStatusStage(corenum);\r
129 \r
130         while (!(Endpoint_IsINReady(corenum)));\r
131 \r
132         USB_Device_SetDeviceAddress(corenum, DeviceAddress);\r
133         USB_DeviceState[corenum] = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;\r
134         \r
135         SetGlobalInterruptMask(CurrentGlobalInt);\r
136 }\r
137 \r
138 static void USB_Device_SetConfiguration(uint8_t corenum)\r
139 {\r
140         #if defined(FIXED_NUM_CONFIGURATIONS)\r
141         if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)\r
142           return;\r
143         #else\r
144         USB_Descriptor_Device_t* DevDescriptorPtr;\r
145 \r
146         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)\r
147                 #if defined(USE_FLASH_DESCRIPTORS)\r
148                         #define MemoryAddressSpace  MEMSPACE_FLASH\r
149                 #elif defined(USE_EEPROM_DESCRIPTORS)\r
150                         #define MemoryAddressSpace  MEMSPACE_EEPROM\r
151                 #elif defined(USE_RAM_DESCRIPTORS)\r
152                         #define MemoryAddressSpace  MEMSPACE_SRAM\r
153                 #else\r
154                         uint8_t MemoryAddressSpace;\r
155                 #endif\r
156         #endif\r
157         \r
158         if (CALLBACK_USB_GetDescriptor(corenum, (DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr\r
159         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \\r
160             !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))\r
161                                        , &MemoryAddressSpace\r
162         #endif\r
163                                        ) == NO_DESCRIPTOR)\r
164         {\r
165                 return;\r
166         }\r
167 \r
168         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)\r
169         if (MemoryAddressSpace == MEMSPACE_FLASH)\r
170         {\r
171                 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))\r
172                   return;\r
173         }\r
174         else if (MemoryAddressSpace == MEMSPACE_EEPROM)\r
175         {\r
176                 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))\r
177                   return;\r
178         }\r
179         else\r
180         {\r
181                 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)\r
182                   return;\r
183         }\r
184         #else\r
185         if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)\r
186           return;       \r
187         #endif\r
188         #endif\r
189 \r
190         Endpoint_ClearSETUP(corenum);\r
191 \r
192         USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;\r
193 \r
194         Endpoint_ClearStatusStage(corenum);\r
195 \r
196         if (USB_Device_ConfigurationNumber)\r
197           USB_DeviceState[corenum] = DEVICE_STATE_Configured;\r
198         else\r
199           USB_DeviceState[corenum] = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;\r
200 \r
201         EVENT_USB_Device_ConfigurationChanged();\r
202 }\r
203 \r
204 static void USB_Device_GetConfiguration(uint8_t corenum)\r
205 {\r
206         Endpoint_ClearSETUP(corenum);\r
207 \r
208         Endpoint_Write_8(corenum, USB_Device_ConfigurationNumber);\r
209         Endpoint_ClearIN(corenum);\r
210 \r
211         Endpoint_ClearStatusStage(corenum);\r
212 }\r
213 \r
214 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)\r
215 static void USB_Device_GetInternalSerialDescriptor(uint8_t corenum)\r
216 {\r
217         struct\r
218         {\r
219                 USB_Descriptor_Header_t Header;\r
220                 uint16_t                UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];\r
221         } SignatureDescriptor;\r
222 \r
223         SignatureDescriptor.Header.Type = DTYPE_String;\r
224         SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);\r
225         \r
226         USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);\r
227 \r
228         Endpoint_ClearSETUP(corenum);\r
229 \r
230         Endpoint_Write_Control_Stream_LE(corenum, &SignatureDescriptor, sizeof(SignatureDescriptor));\r
231         Endpoint_ClearOUT(corenum);\r
232 }\r
233 #endif\r
234 \r
235 static void USB_Device_GetDescriptor(uint8_t corenum)\r
236 {\r
237         const void* DescriptorPointer;\r
238         uint16_t    DescriptorSize;\r
239 \r
240         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \\r
241             !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))\r
242         uint8_t DescriptorAddressSpace;\r
243         #endif\r
244 \r
245         #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)\r
246         if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))\r
247         {\r
248                 USB_Device_GetInternalSerialDescriptor(corenum);\r
249                 return;\r
250         }\r
251         #endif\r
252 \r
253         if ((DescriptorSize = CALLBACK_USB_GetDescriptor(corenum, USB_ControlRequest.wValue, USB_ControlRequest.wIndex,\r
254                                                          &DescriptorPointer\r
255         #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \\r
256             !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))\r
257                                                          , &DescriptorAddressSpace\r
258         #endif\r
259                                                                                                          )) == NO_DESCRIPTOR)\r
260         {\r
261                 return;\r
262         }\r
263 \r
264         Endpoint_ClearSETUP(corenum);\r
265 \r
266         #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)\r
267         Endpoint_Write_Control_Stream_LE(corenum, DescriptorPointer, DescriptorSize);\r
268         #elif defined(USE_EEPROM_DESCRIPTORS)\r
269         Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);\r
270         #elif defined(USE_FLASH_DESCRIPTORS)\r
271         Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);\r
272         #else\r
273         if (DescriptorAddressSpace == MEMSPACE_FLASH)\r
274           Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);\r
275         else if (DescriptorAddressSpace == MEMSPACE_EEPROM)\r
276           Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);\r
277         else\r
278           Endpoint_Write_Control_Stream_LE(corenum, DescriptorPointer, DescriptorSize);\r
279         #endif\r
280 \r
281         Endpoint_ClearOUT(corenum);\r
282 }\r
283 \r
284 static void USB_Device_GetStatus(uint8_t corenum)\r
285 {\r
286         uint8_t CurrentStatus = 0;\r
287 \r
288         switch (USB_ControlRequest.bmRequestType)\r
289         {\r
290                 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)\r
291                 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):\r
292                         #if !defined(NO_DEVICE_SELF_POWER)\r
293                         if (USB_Device_CurrentlySelfPowered)\r
294                           CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;\r
295                         #endif\r
296 \r
297                         #if !defined(NO_DEVICE_REMOTE_WAKEUP)\r
298                         if (USB_Device_RemoteWakeupEnabled)\r
299                           CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;\r
300                         #endif\r
301                         break;\r
302                 #endif\r
303                 #if !defined(CONTROL_ONLY_DEVICE)\r
304                 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):\r
305                         Endpoint_SelectEndpoint(corenum, (uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);\r
306 \r
307                         CurrentStatus = Endpoint_IsStalled(corenum);\r
308 \r
309                         Endpoint_SelectEndpoint(corenum, ENDPOINT_CONTROLEP);\r
310 \r
311                         break;\r
312                 #endif\r
313                 default:\r
314                         return;\r
315         }\r
316 \r
317         Endpoint_ClearSETUP(corenum);\r
318 \r
319         Endpoint_Write_16_LE(corenum, CurrentStatus);\r
320         Endpoint_ClearIN(corenum);\r
321 \r
322         Endpoint_ClearStatusStage(corenum);\r
323 }\r
324 \r
325 static void USB_Device_ClearSetFeature(uint8_t corenum)\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(corenum, EndpointIndex);\r
348 \r
349                                 if (Endpoint_IsEnabled())\r
350                                 {\r
351                                         if (USB_ControlRequest.bRequest == REQ_SetFeature)\r
352                                         {\r
353                                                 Endpoint_StallTransaction(corenum);\r
354                                         }\r
355                                         else\r
356                                         {\r
357                                                 Endpoint_ClearStall(corenum);\r
358                                                 Endpoint_ResetEndpoint(EndpointIndex);\r
359                                                 Endpoint_ResetDataToggle(corenum);\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(corenum, ENDPOINT_CONTROLEP);\r
371 \r
372         Endpoint_ClearSETUP(corenum);\r
373 \r
374         Endpoint_ClearStatusStage(corenum);\r
375 }\r
376 \r
377 #endif\r
378 \r