]> git.sur5r.net Git - freertos/blob
44c19e8f54ed00ac7b8346c5e249a2757fa5a157
[freertos] /
1 /*\r
2  * @brief USB Host definitions for the LPC microcontrollers\r
3  *\r
4  * @note\r
5  * Copyright(C) NXP Semiconductors, 2012\r
6  * All rights reserved.\r
7  *\r
8  * @par\r
9  * Software that is described herein is for illustrative purposes only\r
10  * which provides customers with programming information regarding the\r
11  * LPC products.  This software is supplied "AS IS" without any warranties of\r
12  * any kind, and NXP Semiconductors and its licensor disclaim any and\r
13  * all warranties, express or implied, including all implied warranties of\r
14  * merchantability, fitness for a particular purpose and non-infringement of\r
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility\r
16  * or liability for the use of the software, conveys no license or rights under any\r
17  * patent, copyright, mask work right, or any other intellectual property rights in\r
18  * or to any products. NXP Semiconductors reserves the right to make changes\r
19  * in the software without notification. NXP Semiconductors also makes no\r
20  * representation or warranty that such application will be suitable for the\r
21  * specified use without further testing or modification.\r
22  *\r
23  * @par\r
24  * Permission to use, copy, modify, and distribute this software and its\r
25  * documentation is hereby granted, under NXP Semiconductors' and its\r
26  * licensor's relevant copyrights in the software, without fee, provided that it\r
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This\r
28  * copyright, permission, and disclaimer notice must appear in all copies of\r
29  * this code.\r
30  */\r
31 \r
32 #define  __INCLUDE_FROM_USB_DRIVER\r
33 #include "USBMode.h"\r
34 \r
35 #if defined(USB_CAN_BE_HOST)\r
36 \r
37 #define  __INCLUDE_FROM_HOST_C\r
38 #include "Host.h"\r
39 \r
40 //static uint8_t CurrentHostID = 0;\r
41 uint8_t USB_Host_ControlPipeSize[MAX_USB_CORE];\r
42 \r
43 void USB_Host_SetDeviceSpeed(uint8_t hostid, HCD_USB_SPEED speed);\r
44 \r
45 HCD_USB_SPEED USB_Host_GetDeviceSpeed(uint8_t hostid);\r
46 \r
47 void USB_Host_ProcessNextHostState(uint8_t corenum)\r
48 {\r
49         uint8_t ErrorCode    = HOST_ENUMERROR_NoError;\r
50         uint8_t SubErrorCode = HOST_ENUMERROR_NoError;\r
51 \r
52         static uint16_t WaitMSRemaining;\r
53         static uint8_t  PostWaitState;\r
54 \r
55         switch (USB_HostState[corenum]) {\r
56         case HOST_STATE_WaitForDevice:\r
57                 if (WaitMSRemaining) {\r
58                         if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) {\r
59                                 USB_HostState[corenum] = PostWaitState;\r
60                                 ErrorCode     = HOST_ENUMERROR_WaitStage;\r
61                                 break;\r
62                         }\r
63 \r
64                         if (!(--WaitMSRemaining)) {\r
65                                 USB_HostState[corenum] = PostWaitState;\r
66                         }\r
67                 }\r
68                 break;\r
69 \r
70         case HOST_STATE_Powered:\r
71                 WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS;\r
72 \r
73                 USB_HostState[corenum] = HOST_STATE_Powered_WaitForDeviceSettle;\r
74                 break;\r
75 \r
76         case HOST_STATE_Powered_WaitForDeviceSettle:\r
77                 if (WaitMSRemaining--) {\r
78                         Delay_MS(1);\r
79                         break;\r
80                 }\r
81                 else {\r
82                         USB_Host_VBUS_Manual_Off();\r
83 \r
84                         USB_OTGPAD_On();\r
85                         USB_Host_VBUS_Auto_Enable();\r
86                         USB_Host_VBUS_Auto_On();\r
87 \r
88                         USB_HostState[corenum] = HOST_STATE_Powered_WaitForConnect;\r
89                 }\r
90                 break;\r
91 \r
92         case HOST_STATE_Powered_WaitForConnect:\r
93                 HOST_TASK_NONBLOCK_WAIT(corenum, 100, HOST_STATE_Powered_DoReset);\r
94                 break;\r
95 \r
96         case HOST_STATE_Powered_DoReset: {\r
97                 HCD_USB_SPEED DeviceSpeed;\r
98                 HcdRhPortReset(corenum);\r
99                 HcdGetDeviceSpeed(corenum,&DeviceSpeed);        // skip checking status\r
100                 USB_Host_SetDeviceSpeed(corenum, DeviceSpeed);\r
101                 HOST_TASK_NONBLOCK_WAIT(corenum, 200, HOST_STATE_Powered_ConfigPipe);\r
102         }\r
103         break;\r
104 \r
105         case HOST_STATE_Powered_ConfigPipe:\r
106                 if (!Pipe_ConfigurePipe(corenum, PIPE_CONTROLPIPE, EP_TYPE_CONTROL,\r
107                                                                 PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,\r
108                                                                 PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE) ) {\r
109                         ErrorCode    = HOST_ENUMERROR_PipeConfigError;\r
110                         SubErrorCode = 0;\r
111                         break;\r
112                 }\r
113 \r
114                 USB_HostState[corenum] = HOST_STATE_Default;\r
115                 break;\r
116 \r
117         case HOST_STATE_Default: {\r
118                 USB_Descriptor_Device_t DevDescriptor;\r
119                 USB_ControlRequest = (USB_Request_Header_t)\r
120                 {\r
121                         .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),\r
122                         .bRequest      = REQ_GetDescriptor,\r
123                         .wValue        = (DTYPE_Device << 8),\r
124                         .wIndex        = 0,\r
125                         .wLength       = 8,\r
126                 };\r
127 \r
128                 if ((SubErrorCode = USB_Host_SendControlRequest(corenum, &DevDescriptor)) != HOST_SENDCONTROL_Successful) {\r
129                         ErrorCode = HOST_ENUMERROR_ControlError;\r
130                         break;\r
131                 }\r
132 \r
133                 USB_Host_ControlPipeSize[corenum] = DevDescriptor.Endpoint0Size;\r
134 \r
135                 Pipe_ClosePipe(corenum, PIPE_CONTROLPIPE);\r
136                 HcdRhPortReset(corenum);\r
137 \r
138                 HOST_TASK_NONBLOCK_WAIT(corenum, 200, HOST_STATE_Default_PostReset);\r
139         }\r
140         break;\r
141 \r
142         case HOST_STATE_Default_PostReset:\r
143                 if (!Pipe_ConfigurePipe(corenum, PIPE_CONTROLPIPE, EP_TYPE_CONTROL,\r
144                                                                 PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,\r
145                                                                 USB_Host_ControlPipeSize[corenum], PIPE_BANK_SINGLE) ) {\r
146                         ErrorCode    = HOST_ENUMERROR_PipeConfigError;\r
147                         SubErrorCode = 0;\r
148                         break;\r
149                 }\r
150 \r
151                 USB_ControlRequest = (USB_Request_Header_t)\r
152                 {\r
153                         .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),\r
154                         .bRequest      = REQ_SetAddress,\r
155                         .wValue        = USB_HOST_DEVICEADDRESS,\r
156                         .wIndex        = 0,\r
157                         .wLength       = 0,\r
158                 };\r
159 \r
160                 if ((SubErrorCode = USB_Host_SendControlRequest(corenum, NULL)) != HOST_SENDCONTROL_Successful) {\r
161                         ErrorCode = HOST_ENUMERROR_ControlError;\r
162                         break;\r
163                 }\r
164 \r
165                 Pipe_ClosePipe(corenum, PIPE_CONTROLPIPE);\r
166                 HOST_TASK_NONBLOCK_WAIT(corenum, 100, HOST_STATE_Default_PostAddressSet);\r
167                 break;\r
168 \r
169         case HOST_STATE_Default_PostAddressSet:\r
170                 Pipe_ConfigurePipe(corenum, PIPE_CONTROLPIPE, EP_TYPE_CONTROL,\r
171                                                    PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,\r
172                                                    USB_Host_ControlPipeSize[corenum], PIPE_BANK_SINGLE);\r
173 \r
174                 USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);\r
175 \r
176                 USB_HostState[corenum] = HOST_STATE_Addressed;\r
177 \r
178                 EVENT_USB_Host_DeviceEnumerationComplete(corenum);\r
179                 break;\r
180         }\r
181 \r
182         if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState[corenum] != HOST_STATE_Unattached)) {\r
183                 EVENT_USB_Host_DeviceEnumerationFailed(corenum, ErrorCode, SubErrorCode);\r
184 \r
185                 USB_Host_VBUS_Auto_Off();\r
186 \r
187                 EVENT_USB_Host_DeviceUnattached(corenum);\r
188 \r
189                 USB_ResetInterface(corenum, USB_MODE_Host);\r
190         }\r
191 }\r
192 \r
193 uint8_t USB_Host_WaitMS(uint8_t MS)\r
194 {\r
195         return HOST_WAITERROR_Successful;\r
196 }\r
197 \r
198 void USB_Host_Enumerate(uint8_t HostId) /* Part of Interrupt Service Routine */\r
199 {\r
200         //      CurrentHostID = HostId;\r
201         //      hostselected = HostId;\r
202         EVENT_USB_Host_DeviceAttached(HostId);\r
203         USB_HostState[HostId] = HOST_STATE_Powered;\r
204 }\r
205 \r
206 void USB_Host_DeEnumerate(uint8_t HostId)       /* Part of Interrupt Service Routine */\r
207 {\r
208         uint8_t i;\r
209 \r
210         Pipe_ClosePipe(HostId, PIPE_CONTROLPIPE);       // FIXME close only relevant pipes , take long time in ISR\r
211         for (i = PIPE_CONTROLPIPE + 1; i < PIPE_TOTAL_PIPES; i++)\r
212                 if (PipeInfo[HostId][i].PipeHandle != 0) {\r
213                         Pipe_ClosePipe(HostId, i);\r
214                 }\r
215 \r
216         EVENT_USB_Host_DeviceUnattached(HostId);\r
217         USB_HostState[HostId] = HOST_STATE_Unattached;\r
218 }\r
219 \r
220 void USB_Host_SetActiveHost(uint8_t hostid)\r
221 {\r
222         hostselected = hostid;\r
223 }\r
224 \r
225 uint8_t USB_Host_GetActiveHost(void)\r
226 {\r
227         return hostselected;\r
228 }\r
229 \r
230 void USB_Host_SetDeviceSpeed(uint8_t hostid, HCD_USB_SPEED speed)\r
231 {\r
232         hostportspeed[hostid] = speed;\r
233 }\r
234 \r
235 HCD_USB_SPEED USB_Host_GetDeviceSpeed(uint8_t hostid)\r
236 {\r
237         if (hostid <= 1) {\r
238                 return hostportspeed[hostid];\r
239         }\r
240         else {return LOW_SPEED; }\r
241 }\r
242 \r
243 uint16_t USB_Host_GetFrameNumber(void)\r
244 {\r
245         return HcdGetFrameNumber(USB_Host_GetActiveHost());\r
246 }\r
247 \r
248 #endif\r