Merge pull request #93 from zyp/master
[fw/stlink] / example / stm32f4 / STM32_USB_HOST_Library / Core / src / usbh_ioreq.c
1 /** 
2   ******************************************************************************
3   * @file    usbh_ioreq.c 
4   * @author  MCD Application Team
5   * @version V2.0.0
6   * @date    22-July-2011
7   * @brief   This file handles the issuing of the USB transactions
8   ******************************************************************************
9   * @attention
10   *
11   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17   *
18   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
19   ******************************************************************************
20   */ 
21 /* Includes ------------------------------------------------------------------*/
22
23 #include "usbh_ioreq.h"
24
25 /** @addtogroup USBH_LIB
26   * @{
27   */
28
29 /** @addtogroup USBH_LIB_CORE
30 * @{
31 */
32   
33 /** @defgroup USBH_IOREQ 
34   * @brief This file handles the standard protocol processing (USB v2.0)
35   * @{
36   */
37
38
39 /** @defgroup USBH_IOREQ_Private_Defines
40   * @{
41   */ 
42 /**
43   * @}
44   */ 
45  
46
47 /** @defgroup USBH_IOREQ_Private_TypesDefinitions
48   * @{
49   */ 
50 /**
51   * @}
52   */ 
53
54
55
56 /** @defgroup USBH_IOREQ_Private_Macros
57   * @{
58   */ 
59 /**
60   * @}
61   */ 
62
63
64 /** @defgroup USBH_IOREQ_Private_Variables
65   * @{
66   */ 
67 /**
68   * @}
69   */ 
70
71
72 /** @defgroup USBH_IOREQ_Private_FunctionPrototypes
73   * @{
74   */ 
75 static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
76                                            uint8_t* buff, 
77                                            uint16_t length);
78
79 /**
80   * @}
81   */ 
82
83
84 /** @defgroup USBH_IOREQ_Private_Functions
85   * @{
86   */ 
87
88
89 /**
90   * @brief  USBH_CtlReq
91   *         USBH_CtlReq sends a control request and provide the status after 
92   *            completion of the request
93   * @param  pdev: Selected device
94   * @param  req: Setup Request Structure
95   * @param  buff: data buffer address to store the response
96   * @param  length: length of the response
97   * @retval Status
98   */
99 USBH_Status USBH_CtlReq     (USB_OTG_CORE_HANDLE *pdev, 
100                              USBH_HOST           *phost, 
101                              uint8_t             *buff,
102                              uint16_t            length)
103 {
104   USBH_Status status;
105   URB_STATE URB_Status = URB_IDLE;
106   
107   URB_Status = HCD_GetURB_State(pdev, phost->Control.hc_num_out); 
108   
109   status = USBH_BUSY;
110   
111   switch (phost->RequestState)
112   {
113   case CMD_SEND:
114     /* Start a SETUP transfer */
115     USBH_SubmitSetupRequest(phost, buff, length);
116     phost->RequestState = CMD_WAIT;
117     status = USBH_BUSY;
118     break;
119     
120   case CMD_WAIT:
121     if  (URB_Status == URB_DONE)
122     {
123       /* Commands successfully sent and Response Received  */       
124       phost->RequestState = CMD_SEND;
125       status = USBH_OK;
126     }
127     else if  (URB_Status == URB_ERROR)
128     {
129       /* Failure Mode */
130       phost->RequestState = CMD_SEND;
131       status = USBH_FAIL;
132     }   
133      else if  (URB_Status == URB_STALL)
134     {
135       /* Commands successfully sent and Response Received  */       
136       phost->RequestState = CMD_SEND;
137       status = USBH_NOT_SUPPORTED;
138     }
139     break;
140     
141   default:
142     break; 
143   }
144   return status;
145 }
146
147 /**
148   * @brief  USBH_CtlSendSetup
149   *         Sends the Setup Packet to the Device
150   * @param  pdev: Selected device
151   * @param  buff: Buffer pointer from which the Data will be send to Device
152   * @param  hc_num: Host channel Number
153   * @retval Status
154   */
155 USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev, 
156                                 uint8_t *buff, 
157                                 uint8_t hc_num){
158   pdev->host.hc[hc_num].ep_is_in = 0;
159   pdev->host.hc[hc_num].data_pid = HC_PID_SETUP;   
160   pdev->host.hc[hc_num].xfer_buff = buff;
161   pdev->host.hc[hc_num].xfer_len = USBH_SETUP_PKT_SIZE;   
162
163   return (USBH_Status)HCD_SubmitRequest (pdev , hc_num);   
164 }
165
166
167 /**
168   * @brief  USBH_CtlSendData
169   *         Sends a data Packet to the Device
170   * @param  pdev: Selected device
171   * @param  buff: Buffer pointer from which the Data will be sent to Device
172   * @param  length: Length of the data to be sent
173   * @param  hc_num: Host channel Number
174   * @retval Status
175   */
176 USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev, 
177                                 uint8_t *buff, 
178                                 uint8_t length,
179                                 uint8_t hc_num)
180 {
181   pdev->host.hc[hc_num].ep_is_in = 0;
182   pdev->host.hc[hc_num].xfer_buff = buff;
183   pdev->host.hc[hc_num].xfer_len = length;
184  
185   if ( length == 0 )
186   { /* For Status OUT stage, Length==0, Status Out PID = 1 */
187     pdev->host.hc[hc_num].toggle_out = 1;   
188   }
189  
190  /* Set the Data Toggle bit as per the Flag */
191   if ( pdev->host.hc[hc_num].toggle_out == 0)
192   { /* Put the PID 0 */
193       pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;    
194   }
195  else
196  { /* Put the PID 1 */
197       pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
198  }
199
200   HCD_SubmitRequest (pdev , hc_num);   
201    
202   return USBH_OK;
203 }
204
205
206 /**
207   * @brief  USBH_CtlReceiveData
208   *         Receives the Device Response to the Setup Packet
209   * @param  pdev: Selected device
210   * @param  buff: Buffer pointer in which the response needs to be copied
211   * @param  length: Length of the data to be received
212   * @param  hc_num: Host channel Number
213   * @retval Status. 
214   */
215 USBH_Status USBH_CtlReceiveData(USB_OTG_CORE_HANDLE *pdev, 
216                                 uint8_t* buff, 
217                                 uint8_t length,
218                                 uint8_t hc_num)
219 {
220
221   pdev->host.hc[hc_num].ep_is_in = 1;
222   pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
223   pdev->host.hc[hc_num].xfer_buff = buff;
224   pdev->host.hc[hc_num].xfer_len = length;  
225
226   HCD_SubmitRequest (pdev , hc_num);   
227   
228   return USBH_OK;
229   
230 }
231
232
233 /**
234   * @brief  USBH_BulkSendData
235   *         Sends the Bulk Packet to the device
236   * @param  pdev: Selected device
237   * @param  buff: Buffer pointer from which the Data will be sent to Device
238   * @param  length: Length of the data to be sent
239   * @param  hc_num: Host channel Number
240   * @retval Status
241   */
242 USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev, 
243                                 uint8_t *buff, 
244                                 uint16_t length,
245                                 uint8_t hc_num)
246
247   pdev->host.hc[hc_num].ep_is_in = 0;
248   pdev->host.hc[hc_num].xfer_buff = buff;
249   pdev->host.hc[hc_num].xfer_len = length;  
250
251  /* Set the Data Toggle bit as per the Flag */
252   if ( pdev->host.hc[hc_num].toggle_out == 0)
253   { /* Put the PID 0 */
254       pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;    
255   }
256  else
257  { /* Put the PID 1 */
258       pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
259  }
260
261   HCD_SubmitRequest (pdev , hc_num);   
262   return USBH_OK;
263 }
264
265
266 /**
267   * @brief  USBH_BulkReceiveData
268   *         Receives IN bulk packet from device
269   * @param  pdev: Selected device
270   * @param  buff: Buffer pointer in which the received data packet to be copied
271   * @param  length: Length of the data to be received
272   * @param  hc_num: Host channel Number
273   * @retval Status. 
274   */
275 USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev, 
276                                 uint8_t *buff, 
277                                 uint16_t length,
278                                 uint8_t hc_num)
279 {
280   pdev->host.hc[hc_num].ep_is_in = 1;   
281   pdev->host.hc[hc_num].xfer_buff = buff;
282   pdev->host.hc[hc_num].xfer_len = length;
283   
284
285   if( pdev->host.hc[hc_num].toggle_in == 0)
286   {
287     pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
288   }
289   else
290   {
291     pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
292   }
293
294   HCD_SubmitRequest (pdev , hc_num);  
295   return USBH_OK;
296 }
297
298
299 /**
300   * @brief  USBH_InterruptReceiveData
301   *         Receives the Device Response to the Interrupt IN token
302   * @param  pdev: Selected device
303   * @param  buff: Buffer pointer in which the response needs to be copied
304   * @param  length: Length of the data to be received
305   * @param  hc_num: Host channel Number
306   * @retval Status. 
307   */
308 USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev, 
309                                 uint8_t *buff, 
310                                 uint8_t length,
311                                 uint8_t hc_num)
312 {
313
314   pdev->host.hc[hc_num].ep_is_in = 1;  
315   pdev->host.hc[hc_num].xfer_buff = buff;
316   pdev->host.hc[hc_num].xfer_len = length;
317   
318
319   
320   if(pdev->host.hc[hc_num].toggle_in == 0)
321   {
322     pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
323   }
324   else
325   {
326     pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
327   }
328
329   /* toggle DATA PID */
330   pdev->host.hc[hc_num].toggle_in ^= 1;  
331   
332   HCD_SubmitRequest (pdev , hc_num);  
333   
334   return USBH_OK;
335 }
336
337 /**
338   * @brief  USBH_InterruptSendData
339   *         Sends the data on Interrupt OUT Endpoint
340   * @param  pdev: Selected device
341   * @param  buff: Buffer pointer from where the data needs to be copied
342   * @param  length: Length of the data to be sent
343   * @param  hc_num: Host channel Number
344   * @retval Status. 
345   */
346 USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev, 
347                                 uint8_t *buff, 
348                                 uint8_t length,
349                                 uint8_t hc_num)
350 {
351
352   pdev->host.hc[hc_num].ep_is_in = 0;  
353   pdev->host.hc[hc_num].xfer_buff = buff;
354   pdev->host.hc[hc_num].xfer_len = length;
355   
356   if(pdev->host.hc[hc_num].toggle_in == 0)
357   {
358     pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
359   }
360   else
361   {
362     pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
363   }
364
365   pdev->host.hc[hc_num].toggle_in ^= 1;  
366   
367   HCD_SubmitRequest (pdev , hc_num);  
368   
369   return USBH_OK;
370 }
371
372
373 /**
374   * @brief  USBH_SubmitSetupRequest
375   *         Start a setup transfer by changing the state-machine and 
376   *         initializing  the required variables needed for the Control Transfer
377   * @param  pdev: Selected device
378   * @param  setup: Setup Request Structure
379   * @param  buff: Buffer used for setup request
380   * @param  length: Length of the data
381   * @retval Status. 
382 */
383 static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
384                                            uint8_t* buff, 
385                                            uint16_t length)
386 {
387   
388   /* Save Global State */
389   phost->gStateBkp =   phost->gState; 
390   
391   /* Prepare the Transactions */
392   phost->gState = HOST_CTRL_XFER;
393   phost->Control.buff = buff; 
394   phost->Control.length = length;
395   phost->Control.state = CTRL_SETUP;  
396
397   return USBH_OK;  
398 }
399
400 /**
401 * @}
402 */ 
403
404 /**
405 * @}
406 */ 
407
408 /**
409 * @}
410 */
411
412 /**
413 * @}
414 */ 
415
416 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
417
418
419