Merge pull request #93 from zyp/master
[fw/stlink] / example / stm32f4 / STM32_USB_HOST_Library / Core / src / usbh_core.c
1 /**
2   ******************************************************************************
3   * @file    usbh_core.c 
4   * @author  MCD Application Team
5   * @version V2.0.0
6   * @date    22-July-2011
7   * @brief   This file implements the functions for the core state machine process
8   *          the enumeration and the control transfer process
9   ******************************************************************************
10   * @attention
11   *
12   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
13   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
14   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
15   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
16   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
17   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18   *
19   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
20   ******************************************************************************
21   */ 
22 /* Includes ------------------------------------------------------------------*/
23
24 #include "usbh_ioreq.h"
25 #include "usb_bsp.h"
26 #include "usbh_hcs.h"
27 #include "usbh_stdreq.h"
28 #include "usbh_core.h"
29
30
31 /** @addtogroup USBH_LIB
32   * @{
33   */
34
35 /** @addtogroup USBH_LIB_CORE
36 * @{
37 */
38
39 /** @defgroup USBH_CORE 
40   * @brief TThis file handles the basic enumaration when a device is connected 
41   *          to the host.
42   * @{
43   */ 
44
45 /** @defgroup USBH_CORE_Private_TypesDefinitions
46   * @{
47   */ 
48 void USBH_Disconnect (void *pdev); 
49 void USBH_Connect (void *pdev); 
50
51 USB_OTG_hPort_TypeDef  USBH_DeviceConnStatus_cb = 
52 {
53   USBH_Disconnect,
54   USBH_Connect,
55   0,
56   0,
57   0,
58   0
59 };
60 /**
61   * @}
62   */ 
63
64
65 /** @defgroup USBH_CORE_Private_Defines
66   * @{
67   */ 
68 /**
69   * @}
70   */ 
71
72
73 /** @defgroup USBH_CORE_Private_Macros
74   * @{
75   */ 
76 /**
77   * @}
78   */ 
79
80
81 /** @defgroup USBH_CORE_Private_Variables
82   * @{
83   */ 
84 /**
85   * @}
86   */ 
87
88
89 /** @defgroup USBH_CORE_Private_FunctionPrototypes
90   * @{
91   */
92 static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
93 USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
94
95 /**
96   * @}
97   */ 
98
99
100 /** @defgroup USBH_CORE_Private_Functions
101   * @{
102   */ 
103
104
105 /**
106   * @brief  USBH_Connect
107   *         USB Connect callback function from the Interrupt. 
108   * @param  selected device
109   * @retval none
110   */
111 void USBH_Connect (void *pdev)
112 {
113   USB_OTG_CORE_HANDLE *ppdev = pdev;
114   ppdev->host.port_cb->ConnStatus = 1;
115   ppdev->host.port_cb->ConnHandled = 0; 
116 }
117
118 /**
119   * @brief  USBH_Disconnect
120   *         USB Disconnect callback function from the Interrupt. 
121   * @param  selected device
122   * @retval none
123   */
124
125 void USBH_Disconnect (void *pdev)
126 {
127   
128   USB_OTG_CORE_HANDLE *ppdev = pdev;
129     
130   /* Make device Not connected flag true */
131   ppdev->host.port_cb->DisconnStatus = 1; 
132   ppdev->host.port_cb->DisconnHandled = 0;
133 }
134
135 /**
136   * @brief  USBH_Init
137   *         Host hardware and stack initializations 
138   * @param  class_cb: Class callback structure address
139   * @param  usr_cb: User callback structure address
140   * @retval None
141   */
142 void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
143                USB_OTG_CORE_ID_TypeDef coreID,
144                USBH_HOST *phost,               
145                USBH_Class_cb_TypeDef *class_cb, 
146                USBH_Usr_cb_TypeDef *usr_cb)
147 {
148      
149   /* Hardware Init */
150   USB_OTG_BSP_Init(pdev);  
151   
152   /* configure GPIO pin used for switching VBUS power */
153   USB_OTG_BSP_ConfigVBUS(0);  
154   
155   
156   /* Host de-initializations */
157   USBH_DeInit(pdev, phost);
158   
159   /*Register class and user callbacks */
160   phost->class_cb = class_cb;
161   phost->usr_cb = usr_cb;  
162   pdev->host.port_cb = &USBH_DeviceConnStatus_cb;
163   
164   pdev->host.port_cb->ConnStatus = 0;   
165   pdev->host.port_cb->DisconnStatus = 0; 
166   
167     
168   /* Start the USB OTG core */     
169    HCD_Init(pdev , coreID);
170    
171   /* Upon Init call usr call back */
172   phost->usr_cb->Init();
173   
174   /* Enable Interrupts */
175   USB_OTG_BSP_EnableInterrupt(pdev);
176 }
177
178 /**
179   * @brief  USBH_DeInit 
180   *         Re-Initialize Host
181   * @param  None 
182   * @retval status: USBH_Status
183   */
184 USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
185 {
186   /* Software Init */
187   
188   phost->gState = HOST_IDLE;
189   phost->gStateBkp = HOST_IDLE; 
190   phost->EnumState = ENUM_IDLE;
191   phost->RequestState = CMD_SEND;  
192   
193   phost->Control.state = CTRL_SETUP;
194   phost->Control.ep0size = USB_OTG_MAX_EP0_SIZE;  
195   
196   phost->device_prop.address = USBH_DEVICE_ADDRESS_DEFAULT;
197   phost->device_prop.speed = HPRT0_PRTSPD_FULL_SPEED;
198   
199   USBH_Free_Channel  (pdev, phost->Control.hc_num_in);
200   USBH_Free_Channel  (pdev, phost->Control.hc_num_out);  
201   return USBH_OK;
202 }
203
204 /**
205 * @brief  USBH_Process
206 *         USB Host core main state machine process
207 * @param  None 
208 * @retval None
209 */
210 void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
211 {
212   volatile USBH_Status status = USBH_FAIL;
213     
214   switch (phost->gState)
215   {
216   case HOST_ISSUE_CORE_RESET :
217      
218     if ( HCD_ResetPort(pdev) == 0)
219     {
220       phost->gState = HOST_IDLE;
221     }
222     break;
223     
224   case HOST_IDLE :
225     
226     if (HCD_IsDeviceConnected(pdev))  
227     {
228       /* Wait for USB Connect Interrupt void USBH_ISR_Connected(void) */     
229       USBH_DeAllocate_AllChannel(pdev);
230       phost->gState = HOST_DEV_ATTACHED;
231     }
232     break;
233    
234   case HOST_DEV_ATTACHED :
235     
236     phost->usr_cb->DeviceAttached();
237     pdev->host.port_cb->DisconnStatus = 0; 
238     pdev->host.port_cb->ConnHandled = 1;  
239
240     phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00);
241     phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80);  
242   
243     /* Reset USB Device */
244     if ( HCD_ResetPort(pdev) == 0)
245     {
246       phost->usr_cb->ResetDevice();
247       /*  Wait for USB USBH_ISR_PrtEnDisableChange()  
248       Host is Now ready to start the Enumeration 
249       */
250       
251       phost->device_prop.speed = HCD_GetCurrentSpeed(pdev);
252       
253       phost->gState = HOST_ENUMERATION;
254       phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed);
255         
256       /* Open Control pipes */
257       USBH_Open_Channel (pdev,
258                            phost->Control.hc_num_in,
259                            phost->device_prop.address,
260                            phost->device_prop.speed,
261                            EP_TYPE_CTRL,
262                            phost->Control.ep0size); 
263       
264       /* Open Control pipes */
265       USBH_Open_Channel (pdev,
266                            phost->Control.hc_num_out,
267                            phost->device_prop.address,
268                            phost->device_prop.speed,
269                            EP_TYPE_CTRL,
270                            phost->Control.ep0size);          
271    }
272     break;
273     
274   case HOST_ENUMERATION:     
275     /* Check for enumeration status */  
276     if ( USBH_HandleEnum(pdev , phost) == USBH_OK)
277     { 
278       /* The function shall return USBH_OK when full enumeration is complete */
279       
280       /* user callback for end of device basic enumeration */
281       phost->usr_cb->EnumerationDone();
282       
283       phost->gState  = HOST_USR_INPUT;    
284     }
285     break;
286     
287   case HOST_USR_INPUT:    
288     /*The function should return user response true to move to class state */
289     if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK)
290     {
291       if((phost->class_cb->Init(pdev, phost))\
292         == USBH_OK)
293       {
294         phost->gState  = HOST_CLASS_REQUEST;     
295       }     
296     }   
297     break;
298     
299   case HOST_CLASS_REQUEST:  
300     /* process class standard contol requests state machine */ 
301     status = phost->class_cb->Requests(pdev, phost);
302     
303      if(status == USBH_OK)
304      {
305        phost->gState  = HOST_CLASS;
306      }  
307      
308      else
309      {
310        USBH_ErrorHandle(phost, status);
311      }
312  
313     
314     break;    
315   case HOST_CLASS:   
316     /* process class state machine */
317     status = phost->class_cb->Machine(pdev, phost);
318     USBH_ErrorHandle(phost, status);
319     break;       
320     
321   case HOST_CTRL_XFER:
322     /* process control transfer state machine */
323     USBH_HandleControl(pdev, phost);    
324     break;
325     
326   case HOST_SUSPENDED:
327     break;
328   
329   case HOST_ERROR_STATE:
330     /* Re-Initilaize Host for new Enumeration */
331     USBH_DeInit(pdev, phost);
332     phost->usr_cb->DeInit();
333     phost->class_cb->DeInit(pdev, &phost->device_prop);
334     break;
335     
336   default :
337     break;
338   }
339   
340   /* check device disconnection event */
341    if (!(HCD_IsDeviceConnected(pdev)) && 
342        (pdev->host.port_cb->DisconnHandled == 0))
343   { 
344     /* Manage User disconnect operations*/
345     phost->usr_cb->DeviceDisconnected();
346     
347     pdev->host.port_cb->DisconnHandled = 1; /* Handle to avoid the Re-entry*/
348     
349     /* Re-Initilaize Host for new Enumeration */
350     USBH_DeInit(pdev, phost);
351     phost->usr_cb->DeInit();
352     phost->class_cb->DeInit(pdev, &phost->device_prop);
353   }   
354 }
355
356
357 /**
358   * @brief  USBH_ErrorHandle 
359   *         This function handles the Error on Host side.
360   * @param  errType : Type of Error or Busy/OK state
361   * @retval None
362   */
363 void USBH_ErrorHandle(USBH_HOST *phost, USBH_Status errType)
364 {
365   /* Error unrecovered or not supported device speed */
366   if ( (errType == USBH_ERROR_SPEED_UNKNOWN) ||
367        (errType == USBH_UNRECOVERED_ERROR) )
368   {
369     phost->usr_cb->UnrecoveredError(); 
370     phost->gState = HOST_ERROR_STATE;   
371   }  
372   /* USB host restart requested from application layer */
373   else if(errType == USBH_APPLY_DEINIT)
374   {
375     phost->gState = HOST_ERROR_STATE;  
376     /* user callback for initalization */
377     phost->usr_cb->Init();
378   } 
379 }
380
381
382 /**
383   * @brief  USBH_HandleEnum 
384   *         This function includes the complete enumeration process
385   * @param  pdev: Selected device
386   * @retval USBH_Status
387   */
388 static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
389 {
390   USBH_Status Status = USBH_BUSY;  
391   uint8_t Local_Buffer[64];
392   
393   switch (phost->EnumState)
394   {
395   case ENUM_IDLE:  
396     /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
397     if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK)
398     {
399       phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize;
400       
401       /* Issue Reset  */
402       HCD_ResetPort(pdev);
403       phost->EnumState = ENUM_GET_FULL_DEV_DESC;
404       
405       /* modify control channels configuration for MaxPacket size */
406       USBH_Modify_Channel (pdev,
407                            phost->Control.hc_num_out,
408                            0,
409                            0,
410                            0,
411                            phost->Control.ep0size);
412       
413       USBH_Modify_Channel (pdev,
414                            phost->Control.hc_num_in,
415                            0,
416                            0,
417                            0,
418                            phost->Control.ep0size);      
419     }
420     break;
421     
422   case ENUM_GET_FULL_DEV_DESC:  
423     /* Get FULL Device Desc  */
424     if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\
425       == USBH_OK)
426     {
427       /* user callback for device descriptor available */
428       phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc);      
429       phost->EnumState = ENUM_SET_ADDR;
430     }
431     break;
432    
433   case ENUM_SET_ADDR: 
434     /* set address */
435     if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK)
436     {
437       phost->device_prop.address = USBH_DEVICE_ADDRESS;
438       
439       /* user callback for device address assigned */
440       phost->usr_cb->DeviceAddressAssigned();
441       phost->EnumState = ENUM_GET_CFG_DESC;
442       
443       /* modify control channels to update device address */
444       USBH_Modify_Channel (pdev,
445                            phost->Control.hc_num_in,
446                            phost->device_prop.address,
447                            0,
448                            0,
449                            0);
450       
451       USBH_Modify_Channel (pdev,
452                            phost->Control.hc_num_out,
453                            phost->device_prop.address,
454                            0,
455                            0,
456                            0);         
457     }
458     break;
459     
460   case ENUM_GET_CFG_DESC:  
461     /* get standard configuration descriptor */
462     if ( USBH_Get_CfgDesc(pdev, 
463                           phost,
464                           USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
465     {
466       phost->EnumState = ENUM_GET_FULL_CFG_DESC;
467     }
468     break;
469     
470   case ENUM_GET_FULL_CFG_DESC:  
471     /* get FULL config descriptor (config, interface, endpoints) */
472     if (USBH_Get_CfgDesc(pdev, 
473                          phost,
474                          phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK)
475     {
476       /* User callback for configuration descriptors available */
477       phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc,
478                                                       phost->device_prop.Itf_Desc,
479                                                       phost->device_prop.Ep_Desc[0]);
480       
481       phost->EnumState = ENUM_GET_MFC_STRING_DESC;
482     }
483     break;
484     
485   case ENUM_GET_MFC_STRING_DESC:  
486     if (phost->device_prop.Dev_Desc.iManufacturer != 0)
487     { /* Check that Manufacturer String is available */
488       
489       if ( USBH_Get_StringDesc(pdev,
490                                phost,
491                                phost->device_prop.Dev_Desc.iManufacturer, 
492                                Local_Buffer , 
493                                0xff) == USBH_OK)
494       {
495         /* User callback for Manufacturing string */
496         phost->usr_cb->ManufacturerString(Local_Buffer);
497         phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
498       }
499     }
500     else
501     {
502       phost->usr_cb->ManufacturerString("N/A");      
503       phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
504     }
505     break;
506     
507   case ENUM_GET_PRODUCT_STRING_DESC:   
508     if (phost->device_prop.Dev_Desc.iProduct != 0)
509     { /* Check that Product string is available */
510       if ( USBH_Get_StringDesc(pdev,
511                                phost,
512                                phost->device_prop.Dev_Desc.iProduct, 
513                                Local_Buffer, 
514                                0xff) == USBH_OK)
515       {
516         /* User callback for Product string */
517         phost->usr_cb->ProductString(Local_Buffer);
518         phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
519       }
520     }
521     else
522     {
523       phost->usr_cb->ProductString("N/A");
524       phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
525     } 
526     break;
527     
528   case ENUM_GET_SERIALNUM_STRING_DESC:   
529     if (phost->device_prop.Dev_Desc.iSerialNumber != 0)
530     { /* Check that Serial number string is available */    
531       if ( USBH_Get_StringDesc(pdev, 
532                                phost,
533                                phost->device_prop.Dev_Desc.iSerialNumber, 
534                                Local_Buffer, 
535                                0xff) == USBH_OK)
536       {
537         /* User callback for Serial number string */
538         phost->usr_cb->SerialNumString(Local_Buffer);
539         phost->EnumState = ENUM_SET_CONFIGURATION;
540       }
541     }
542     else
543     {
544       phost->usr_cb->SerialNumString("N/A");      
545       phost->EnumState = ENUM_SET_CONFIGURATION;
546     }  
547     break;
548       
549   case ENUM_SET_CONFIGURATION:
550     /* set configuration  (default config) */
551     if (USBH_SetCfg(pdev, 
552                     phost,
553                     phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK)
554     {
555       phost->EnumState = ENUM_DEV_CONFIGURED;
556     }
557     break;
558
559     
560   case ENUM_DEV_CONFIGURED:
561     /* user callback for enumeration done */
562     Status = USBH_OK;
563     break;
564     
565   default:
566     break;
567   }  
568   return Status;
569 }
570
571
572 /**
573   * @brief  USBH_HandleControl
574   *         Handles the USB control transfer state machine
575   * @param  pdev: Selected device
576   * @retval Status
577   */
578 USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
579 {
580   uint8_t direction;  
581   static uint16_t timeout = 0;
582   USBH_Status status = USBH_OK;
583   URB_STATE URB_Status = URB_IDLE;
584   
585   phost->Control.status = CTRL_START;
586
587   
588   switch (phost->Control.state)
589   {
590   case CTRL_SETUP:
591     /* send a SETUP packet */
592     USBH_CtlSendSetup     (pdev, 
593                            phost->Control.setup.d8 , 
594                            phost->Control.hc_num_out);  
595     phost->Control.state = CTRL_SETUP_WAIT;  
596     break; 
597     
598   case CTRL_SETUP_WAIT:
599     
600     URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out); 
601     /* case SETUP packet sent successfully */
602     if(URB_Status == URB_DONE)
603     { 
604       direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
605       
606       /* check if there is a data stage */
607       if (phost->Control.setup.b.wLength.w != 0 )
608       {        
609         timeout = DATA_STAGE_TIMEOUT;
610         if (direction == USB_D2H)
611         {
612           /* Data Direction is IN */
613           phost->Control.state = CTRL_DATA_IN;
614         }
615         else
616         {
617           /* Data Direction is OUT */
618           phost->Control.state = CTRL_DATA_OUT;
619         } 
620       }
621       /* No DATA stage */
622       else
623       {
624         timeout = NODATA_STAGE_TIMEOUT;
625         
626         /* If there is No Data Transfer Stage */
627         if (direction == USB_D2H)
628         {
629           /* Data Direction is IN */
630           phost->Control.state = CTRL_STATUS_OUT;
631         }
632         else
633         {
634           /* Data Direction is OUT */
635           phost->Control.state = CTRL_STATUS_IN;
636         } 
637       }          
638       /* Set the delay timer to enable timeout for data stage completion */
639       phost->Control.timer = HCD_GetCurrentFrame(pdev);
640     }
641     else if(URB_Status == URB_ERROR)
642     {
643       phost->Control.state = CTRL_ERROR;     
644       phost->Control.status = CTRL_XACTERR;
645     }    
646     break;
647     
648   case CTRL_DATA_IN:  
649     /* Issue an IN token */ 
650     USBH_CtlReceiveData(pdev,
651                         phost->Control.buff, 
652                         phost->Control.length,
653                         phost->Control.hc_num_in);
654  
655     phost->Control.state = CTRL_DATA_IN_WAIT;
656     break;    
657     
658   case CTRL_DATA_IN_WAIT:
659     
660     URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in); 
661     
662     /* check is DATA packet transfered successfully */
663     if  (URB_Status == URB_DONE)
664     { 
665       phost->Control.state = CTRL_STATUS_OUT;
666     }
667    
668     /* manage error cases*/
669     if  (URB_Status == URB_STALL) 
670     { 
671       /* In stall case, return to previous machine state*/
672       phost->gState =   phost->gStateBkp;
673     }   
674     else if (URB_Status == URB_ERROR)
675     {
676       /* Device error */
677       phost->Control.state = CTRL_ERROR;    
678     }
679     else if ((HCD_GetCurrentFrame(pdev)- phost->Control.timer) > timeout)
680     {
681       /* timeout for IN transfer */
682       phost->Control.state = CTRL_ERROR; 
683     }   
684     break;
685     
686   case CTRL_DATA_OUT:
687     /* Start DATA out transfer (only one DATA packet)*/
688     
689     pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1; 
690     
691     USBH_CtlSendData (pdev,
692                       phost->Control.buff, 
693                       phost->Control.length , 
694                       phost->Control.hc_num_out);
695     
696     phost->Control.state = CTRL_DATA_OUT_WAIT;
697     break;
698     
699   case CTRL_DATA_OUT_WAIT:
700     
701     URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);     
702     if  (URB_Status == URB_DONE)
703     { /* If the Setup Pkt is sent successful, then change the state */
704       phost->Control.state = CTRL_STATUS_IN;
705     }
706     
707     /* handle error cases */
708     else if  (URB_Status == URB_STALL) 
709     { 
710       /* In stall case, return to previous machine state*/
711       phost->gState =   phost->gStateBkp;
712     } 
713     else if  (URB_Status == URB_NOTREADY)
714     { 
715       /* Nack received from device */
716       phost->Control.state = CTRL_DATA_OUT;
717     }    
718     else if (URB_Status == URB_ERROR)
719     {
720       /* device error */
721       phost->Control.state = CTRL_ERROR;      
722     } 
723     break;
724     
725     
726   case CTRL_STATUS_IN:
727     /* Send 0 bytes out packet */
728     USBH_CtlReceiveData (pdev,
729                          0,
730                          0,
731                          phost->Control.hc_num_in);
732     
733     phost->Control.state = CTRL_STATUS_IN_WAIT;
734     
735     break;
736     
737   case CTRL_STATUS_IN_WAIT:
738     
739     URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in); 
740     
741     if  ( URB_Status == URB_DONE)
742     { /* Control transfers completed, Exit the State Machine */
743       phost->gState =   phost->gStateBkp;
744     }
745     
746     else if (URB_Status == URB_ERROR)
747     {
748       phost->Control.state = CTRL_ERROR;  
749     }
750     
751     else if((HCD_GetCurrentFrame(pdev)\
752       - phost->Control.timer) > timeout)
753     {
754       phost->Control.state = CTRL_ERROR; 
755     }
756      else if(URB_Status == URB_STALL)
757     {
758       /* Control transfers completed, Exit the State Machine */
759       phost->gState =   phost->gStateBkp;
760       phost->Control.status = CTRL_STALL;
761       status = USBH_NOT_SUPPORTED;
762     }
763     break;
764     
765   case CTRL_STATUS_OUT:
766     pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1; 
767     USBH_CtlSendData (pdev,
768                       0,
769                       0,
770                       phost->Control.hc_num_out);
771     
772     phost->Control.state = CTRL_STATUS_OUT_WAIT;
773     break;
774     
775   case CTRL_STATUS_OUT_WAIT: 
776     
777     URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);  
778     if  (URB_Status == URB_DONE)
779     { 
780       phost->gState =   phost->gStateBkp;    
781     }
782     else if  (URB_Status == URB_NOTREADY)
783     { 
784       phost->Control.state = CTRL_STATUS_OUT;
785     }      
786     else if (URB_Status == URB_ERROR)
787     {
788       phost->Control.state = CTRL_ERROR;      
789     }
790     break;
791     
792   case CTRL_ERROR:
793     /* 
794     After a halt condition is encountered or an error is detected by the 
795     host, a control endpoint is allowed to recover by accepting the next Setup 
796     PID; i.e., recovery actions via some other pipe are not required for control
797     endpoints. For the Default Control Pipe, a device reset will ultimately be 
798     required to clear the halt or error condition if the next Setup PID is not 
799     accepted.
800     */
801     if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT)
802     {
803       /* Do the transmission again, starting from SETUP Packet */
804       phost->Control.state = CTRL_SETUP; 
805     }
806     else
807     {
808       phost->Control.status = CTRL_FAIL;
809       phost->gState =   phost->gStateBkp;
810       
811       status = USBH_FAIL;
812     }
813     break;
814     
815   default:
816     break;
817   }
818   return status;
819 }
820
821
822 /**
823 * @}
824 */ 
825
826 /**
827 * @}
828 */ 
829
830 /**
831 * @}
832 */
833
834 /**
835 * @}
836 */ 
837
838 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
839
840
841
842