]> git.sur5r.net Git - freertos/blob
7d2b805b641b5818fd3b5d7b47594bc97ecfe675
[freertos] /
1 /*\r
2  * @brief USB host 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 #define  __INCLUDE_FROM_USB_DRIVER\r
34 #include "USBMode.h"\r
35 \r
36 #if defined(USB_CAN_BE_HOST)\r
37 \r
38 #define  __INCLUDE_FROM_HOSTSTDREQ_C\r
39 #include "HostStandardReq.h"\r
40 \r
41 uint8_t USB_Host_ConfigurationNumber;\r
42 \r
43 #if 1\r
44 \r
45 uint8_t USB_Host_SendControlRequest(const uint8_t corenum, void* const BufferPtr)\r
46 {\r
47         uint8_t* DataStream   = (uint8_t*)BufferPtr;\r
48         uint16_t DataLen      = USB_ControlRequest.wLength;\r
49         uint8_t ret;\r
50 \r
51         if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_HOSTTODEVICE)\r
52         {\r
53                 Pipe_Write_Stream_LE(corenum, BufferPtr, DataLen, NULL);\r
54         }\r
55 \r
56         ret = (uint8_t)HcdControlTransfer(PipeInfo[corenum][pipeselected[corenum]].PipeHandle, &USB_ControlRequest,\r
57                                            PipeInfo[corenum][pipeselected[corenum]].Buffer);\r
58 \r
59         if(ret == (uint8_t)HOST_SENDCONTROL_Successful)\r
60         {\r
61                 if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST)\r
62                 {\r
63                         PipeInfo[corenum][pipeselected[corenum]].ByteTransfered = USB_ControlRequest.wLength;\r
64                         while(DataLen)\r
65                         {\r
66                                 *(DataStream++) = Pipe_Read_8(corenum);\r
67                                 DataLen--;\r
68                         }\r
69                         /* Pipe_Read_Stream_LE(BufferPtr, DataLen, NULL); cannot use read stream as it call HcdDataTransfer*/\r
70                 }\r
71                 PipeInfo[corenum][pipeselected[corenum]].StartIdx = PipeInfo[corenum][pipeselected[corenum]].ByteTransfered = 0; /* Clear Control Pipe */\r
72                 return HOST_SENDCONTROL_Successful;\r
73         }\r
74         else\r
75         {\r
76                 return HOST_SENDCONTROL_PipeError;\r
77         }\r
78 }\r
79 \r
80 #else // The following code is deprecated\r
81 uint8_t USB_Host_SendControlRequest(void* const BufferPtr)\r
82 {\r
83         uint8_t* DataStream   = (uint8_t*)BufferPtr;\r
84         bool     BusSuspended = USB_Host_IsBusSuspended();\r
85         uint8_t  ReturnStatus = HOST_SENDCONTROL_Successful;\r
86         uint16_t DataLen      = USB_ControlRequest.wLength;\r
87 \r
88         USB_Host_ResumeBus();\r
89 \r
90         if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)\r
91           goto End_Of_Control_Send;\r
92 \r
93         Pipe_SetPipeToken(PIPE_TOKEN_SETUP);\r
94         Pipe_ClearError();\r
95 \r
96         Pipe_Unfreeze();\r
97 \r
98         Pipe_Write_8(USB_ControlRequest.bmRequestType);\r
99         Pipe_Write_8(USB_ControlRequest.bRequest);\r
100         Pipe_Write_16_LE(USB_ControlRequest.wValue);\r
101         Pipe_Write_16_LE(USB_ControlRequest.wIndex);\r
102         Pipe_Write_16_LE(USB_ControlRequest.wLength);\r
103 \r
104         Pipe_ClearSETUP();\r
105 \r
106         if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_SetupSent)) != HOST_SENDCONTROL_Successful)\r
107           goto End_Of_Control_Send;\r
108 \r
109         Pipe_Freeze();\r
110 \r
111         if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)\r
112           goto End_Of_Control_Send;\r
113 \r
114         if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST)\r
115         {\r
116                 Pipe_SetPipeToken(PIPE_TOKEN_IN);\r
117 \r
118                 if (DataStream != NULL)\r
119                 {\r
120                         while (DataLen)\r
121                         {\r
122                                 Pipe_Unfreeze();\r
123 \r
124                                 if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful)\r
125                                   goto End_Of_Control_Send;\r
126 \r
127                                 if (!(Pipe_BytesInPipe()))\r
128                                   DataLen = 0;\r
129 \r
130                                 while (Pipe_BytesInPipe() && DataLen)\r
131                                 {\r
132                                         *(DataStream++) = Pipe_Read_8();\r
133                                         DataLen--;\r
134                                 }\r
135 \r
136                                 Pipe_Freeze();\r
137                                 Pipe_ClearIN();\r
138                         }\r
139                 }\r
140 \r
141                 Pipe_SetPipeToken(PIPE_TOKEN_OUT);\r
142                 Pipe_Unfreeze();\r
143 \r
144                 if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)\r
145                   goto End_Of_Control_Send;\r
146 \r
147                 Pipe_ClearOUT();\r
148 \r
149                 if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)\r
150                   goto End_Of_Control_Send;\r
151         }\r
152         else\r
153         {\r
154                 if (DataStream != NULL)\r
155                 {\r
156                         Pipe_SetPipeToken(PIPE_TOKEN_OUT);\r
157                         Pipe_Unfreeze();\r
158 \r
159                         while (DataLen)\r
160                         {\r
161                                 if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)\r
162                                   goto End_Of_Control_Send;\r
163 \r
164                                 while (DataLen && (Pipe_BytesInPipe() < USB_Host_ControlPipeSize))\r
165                                 {\r
166                                         Pipe_Write_8(*(DataStream++));\r
167                                         DataLen--;\r
168                                 }\r
169 \r
170                                 Pipe_ClearOUT();\r
171                         }\r
172 \r
173                         if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)\r
174                           goto End_Of_Control_Send;\r
175 \r
176                         Pipe_Freeze();\r
177                 }\r
178 \r
179                 Pipe_SetPipeToken(PIPE_TOKEN_IN);\r
180                 Pipe_Unfreeze();\r
181 \r
182                 if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful)\r
183                   goto End_Of_Control_Send;\r
184 \r
185                 Pipe_ClearIN();\r
186         }\r
187 \r
188 End_Of_Control_Send:\r
189         Pipe_Freeze();\r
190 \r
191         if (BusSuspended)\r
192           USB_Host_SuspendBus();\r
193 \r
194         Pipe_ResetPipe(PIPE_CONTROLPIPE);\r
195 \r
196         return ReturnStatus;\r
197 }\r
198 \r
199 static uint8_t USB_Host_WaitForIOS(const uint8_t WaitType)\r
200 {\r
201         #if (USB_HOST_TIMEOUT_MS < 0xFF)\r
202         uint8_t  TimeoutCounter = USB_HOST_TIMEOUT_MS;\r
203         #else\r
204         uint16_t TimeoutCounter = USB_HOST_TIMEOUT_MS;\r
205         #endif\r
206 \r
207         while (!(((WaitType == USB_HOST_WAITFOR_SetupSent)  && Pipe_IsSETUPSent())  ||\r
208                  ((WaitType == USB_HOST_WAITFOR_InReceived) && Pipe_IsINReceived()) ||\r
209                  ((WaitType == USB_HOST_WAITFOR_OutReady)   && Pipe_IsOUTReady())))\r
210         {\r
211                 uint8_t ErrorCode;\r
212 \r
213                 if ((ErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)\r
214                   return ErrorCode;\r
215 \r
216                 if (!(TimeoutCounter--))\r
217                   return HOST_SENDCONTROL_SoftwareTimeOut;\r
218         }\r
219 \r
220         return HOST_SENDCONTROL_Successful;\r
221 }\r
222 #endif\r
223 \r
224 uint8_t USB_Host_SetDeviceConfiguration(const uint8_t corenum, const uint8_t ConfigNumber)\r
225 {\r
226         uint8_t ErrorCode;\r
227 \r
228         USB_ControlRequest = (USB_Request_Header_t)\r
229                 {\r
230                         .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),\r
231                         .bRequest      = REQ_SetConfiguration,\r
232                         .wValue        = ConfigNumber,\r
233                         .wIndex        = 0,\r
234                         .wLength       = 0,\r
235                 };\r
236 \r
237         Pipe_SelectPipe(corenum, PIPE_CONTROLPIPE);\r
238         \r
239         if ((ErrorCode = USB_Host_SendControlRequest(corenum, NULL)) == HOST_SENDCONTROL_Successful)\r
240         {\r
241                 USB_Host_ConfigurationNumber = ConfigNumber;\r
242                 USB_HostState[corenum]       = (ConfigNumber) ? HOST_STATE_Configured : HOST_STATE_Addressed;\r
243         }\r
244 \r
245         return ErrorCode;\r
246 }\r
247 \r
248 uint8_t USB_Host_GetDeviceDescriptor(const uint8_t corenum, void* const DeviceDescriptorPtr)\r
249 {\r
250         USB_ControlRequest = (USB_Request_Header_t)\r
251                 {\r
252                         .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),\r
253                         .bRequest      = REQ_GetDescriptor,\r
254                         .wValue        = (DTYPE_Device << 8),\r
255                         .wIndex        = 0,\r
256                         .wLength       = sizeof(USB_Descriptor_Device_t),\r
257                 };\r
258 \r
259         Pipe_SelectPipe(corenum, PIPE_CONTROLPIPE);\r
260 \r
261         return USB_Host_SendControlRequest(corenum,DeviceDescriptorPtr);\r
262 }\r
263 \r
264 uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t corenum,\r
265                                                                                    const uint8_t Index,\r
266                                            void* const Buffer,\r
267                                            const uint8_t BufferLength)\r
268 {\r
269         USB_ControlRequest = (USB_Request_Header_t)\r
270                 {\r
271                         .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),\r
272                         .bRequest      = REQ_GetDescriptor,\r
273                         .wValue        = (DTYPE_String << 8) | Index,\r
274                         .wIndex        = 0,\r
275                         .wLength       = BufferLength,\r
276                 };\r
277 \r
278         Pipe_SelectPipe(corenum, PIPE_CONTROLPIPE);\r
279 \r
280         return USB_Host_SendControlRequest(corenum,Buffer);\r
281 }\r
282 \r
283 uint8_t USB_Host_GetDeviceStatus(const uint8_t corenum, uint8_t* const FeatureStatus)\r
284 {\r
285         USB_ControlRequest = (USB_Request_Header_t)\r
286                 {\r
287                         .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),\r
288                         .bRequest      = REQ_GetStatus,\r
289                         .wValue        = 0,\r
290                         .wIndex        = 0,\r
291                         .wLength       = 0,\r
292                 };\r
293 \r
294         Pipe_SelectPipe(corenum, PIPE_CONTROLPIPE);\r
295 \r
296         return USB_Host_SendControlRequest(corenum, FeatureStatus);\r
297 }\r
298 \r
299 uint8_t USB_Host_ClearEndpointStall(const uint8_t corenum, const uint8_t EndpointAddress)\r
300 {\r
301         USB_ControlRequest = (USB_Request_Header_t)\r
302                 {\r
303                         .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),\r
304                         .bRequest      = REQ_ClearFeature,\r
305                         .wValue        = FEATURE_SEL_EndpointHalt,\r
306                         .wIndex        = EndpointAddress,\r
307                         .wLength       = 0,\r
308                 };\r
309 \r
310         Pipe_SelectPipe(corenum, PIPE_CONTROLPIPE);\r
311 \r
312         return USB_Host_SendControlRequest(corenum,NULL);\r
313 }\r
314 \r
315 uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t corenum,\r
316                                                                                 const uint8_t InterfaceIndex,\r
317                                         const uint8_t AltSetting)\r
318 {\r
319         USB_ControlRequest = (USB_Request_Header_t)\r
320                 {\r
321                         .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),\r
322                         .bRequest      = REQ_SetInterface,\r
323                         .wValue        = AltSetting,\r
324                         .wIndex        = InterfaceIndex,\r
325                         .wLength       = 0,\r
326                 };\r
327 \r
328         Pipe_SelectPipe(corenum, PIPE_CONTROLPIPE);\r
329 \r
330         return USB_Host_SendControlRequest(corenum,NULL);\r
331 }\r
332 \r
333 #endif\r
334 \r