Nirvana Jay / Mbed 2 deprecated F7DISCO_Demo

Dependencies:   BSP_DISCO_F746NG_patch mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbh_core.c Source File

usbh_core.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    usbh_core.c 
00004   * @author  MCD Application Team
00005   * @version V3.2.2
00006   * @date    07-July-2015
00007   * @brief   This file implements the functions for the core state machine process
00008   *          the enumeration and the control transfer process
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
00013   *
00014   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
00015   * You may not use this file except in compliance with the License.
00016   * You may obtain a copy of the License at:
00017   *
00018   *        http://www.st.com/software_license_agreement_liberty_v2
00019   *
00020   * Unless required by applicable law or agreed to in writing, software 
00021   * distributed under the License is distributed on an "AS IS" BASIS, 
00022   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00023   * See the License for the specific language governing permissions and
00024   * limitations under the License.
00025   *
00026   ******************************************************************************
00027   */ 
00028 /* Includes ------------------------------------------------------------------*/
00029 
00030 #include "usbh_core.h"
00031 
00032 
00033 /** @addtogroup USBH_LIB
00034   * @{
00035   */
00036 
00037 /** @addtogroup USBH_LIB_CORE
00038   * @{
00039   */
00040 
00041 /** @defgroup USBH_CORE 
00042   * @brief This file handles the basic enumeration when a device is connected 
00043   *          to the host.
00044   * @{
00045   */ 
00046 
00047 
00048 /** @defgroup USBH_CORE_Private_Defines
00049   * @{
00050   */ 
00051 #define USBH_ADDRESS_DEFAULT                     0
00052 #define USBH_ADDRESS_ASSIGNED                    1      
00053 #define USBH_MPS_DEFAULT                         0x40
00054 /**
00055   * @}
00056   */ 
00057 
00058 /** @defgroup USBH_CORE_Private_Macros
00059   * @{
00060   */ 
00061 /**
00062   * @}
00063   */ 
00064 
00065 
00066 /** @defgroup USBH_CORE_Private_Variables
00067   * @{
00068   */ 
00069 /**
00070   * @}
00071   */ 
00072  
00073 
00074 /** @defgroup USBH_CORE_Private_Functions
00075   * @{
00076   */ 
00077 static USBH_StatusTypeDef  USBH_HandleEnum    (USBH_HandleTypeDef *phost);
00078 static void                USBH_HandleSof     (USBH_HandleTypeDef *phost);
00079 static USBH_StatusTypeDef  DeInitStateMachine(USBH_HandleTypeDef *phost);
00080 
00081 #if (USBH_USE_OS == 1)  
00082 static void USBH_Process_OS(void const * argument);
00083 #endif
00084 
00085 /**
00086   * @brief  HCD_Init 
00087   *         Initialize the HOST Core.
00088   * @param  phost: Host Handle
00089   * @param  pUsrFunc: User Callback
00090   * @retval USBH Status
00091   */
00092 USBH_StatusTypeDef  USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id)
00093 {
00094   /* Check whether the USB Host handle is valid */
00095   if(phost == NULL)
00096   {
00097     USBH_ErrLog("Invalid Host handle");
00098     return USBH_FAIL; 
00099   }
00100   
00101   /* Set DRiver ID */
00102   phost->id = id;
00103   
00104   /* Unlink class*/
00105   phost->pActiveClass = NULL;
00106   phost->ClassNumber = 0;
00107   
00108   /* Restore default states and prepare EP0 */ 
00109   DeInitStateMachine(phost);
00110   
00111   /* Assign User process */
00112   if(pUsrFunc != NULL)
00113   {
00114     phost->pUser = pUsrFunc;
00115   }
00116   
00117 #if (USBH_USE_OS == 1) 
00118   
00119   /* Create USB Host Queue */
00120   osMessageQDef(USBH_Queue, 10, uint16_t);
00121   phost->os_event = osMessageCreate (osMessageQ(USBH_Queue), NULL); 
00122   
00123   /*Create USB Host Task */
00124 #if defined (USBH_PROCESS_STACK_SIZE)
00125   osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, USBH_PROCESS_STACK_SIZE);
00126 #else
00127   osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, 8 * configMINIMAL_STACK_SIZE);
00128 #endif  
00129   phost->thread = osThreadCreate (osThread(USBH_Thread), phost);
00130 #endif  
00131   
00132   /* Initialize low level driver */
00133   USBH_LL_Init(phost);
00134   return USBH_OK;
00135 }
00136 
00137 /**
00138   * @brief  HCD_Init 
00139   *         De-Initialize the Host portion of the driver.
00140   * @param  phost: Host Handle
00141   * @retval USBH Status
00142   */
00143 USBH_StatusTypeDef  USBH_DeInit(USBH_HandleTypeDef *phost)
00144 {
00145   DeInitStateMachine(phost);
00146   
00147   if(phost->pData != NULL)
00148   {
00149     phost->pActiveClass->pData = NULL;
00150     USBH_LL_Stop(phost);
00151   }
00152 
00153   return USBH_OK;
00154 }
00155 
00156 /**
00157   * @brief  DeInitStateMachine 
00158   *         De-Initialize the Host state machine.
00159   * @param  phost: Host Handle
00160   * @retval USBH Status
00161   */
00162 static USBH_StatusTypeDef  DeInitStateMachine(USBH_HandleTypeDef *phost)
00163 {
00164   uint32_t i = 0;
00165 
00166   /* Clear Pipes flags*/
00167   for ( ; i < USBH_MAX_PIPES_NBR; i++)
00168   {
00169     phost->Pipes[i] = 0;
00170   }
00171   
00172   for(i = 0; i< USBH_MAX_DATA_BUFFER; i++)
00173   {
00174     phost->device.Data[i] = 0;
00175   }
00176   
00177   phost->gState = HOST_IDLE;
00178   phost->EnumState = ENUM_IDLE;
00179   phost->RequestState = CMD_SEND;
00180   phost->Timer = 0;  
00181   
00182   phost->Control.state = CTRL_SETUP;
00183   phost->Control.pipe_size = USBH_MPS_DEFAULT;  
00184   phost->Control.errorcount = 0;
00185   
00186   phost->device.address = USBH_ADDRESS_DEFAULT;
00187   phost->device.speed   = USBH_SPEED_FULL;
00188   
00189   return USBH_OK;
00190 }
00191 
00192 /**
00193   * @brief  USBH_RegisterClass 
00194   *         Link class driver to Host Core.
00195   * @param  phost : Host Handle
00196   * @param  pclass: Class handle
00197   * @retval USBH Status
00198   */
00199 USBH_StatusTypeDef  USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass)
00200 {
00201   USBH_StatusTypeDef   status = USBH_OK;
00202   
00203   if(pclass != 0)
00204   {
00205     if(phost->ClassNumber < USBH_MAX_NUM_SUPPORTED_CLASS)
00206     {
00207       /* link the class to the USB Host handle */
00208       phost->pClass[phost->ClassNumber++] = pclass;
00209       status = USBH_OK;
00210     }
00211     else
00212     {
00213       USBH_ErrLog("Max Class Number reached");
00214       status = USBH_FAIL; 
00215     }
00216   }
00217   else
00218   {
00219     USBH_ErrLog("Invalid Class handle");
00220     status = USBH_FAIL; 
00221   }
00222   
00223   return status;
00224 }
00225 
00226 /**
00227   * @brief  USBH_SelectInterface 
00228   *         Select current interface.
00229   * @param  phost: Host Handle
00230   * @param  interface: Interface number
00231   * @retval USBH Status
00232   */
00233 USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface)
00234 {
00235   USBH_StatusTypeDef   status = USBH_OK;
00236   
00237   if(interface < phost->device.CfgDesc.bNumInterfaces)
00238   {
00239     phost->device.current_interface = interface;
00240     USBH_UsrLog ("Switching to Interface (#%d)", interface);
00241     USBH_UsrLog ("Class    : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass );
00242     USBH_UsrLog ("SubClass : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceSubClass );
00243     USBH_UsrLog ("Protocol : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol );                 
00244   }
00245   else
00246   {
00247     USBH_ErrLog ("Cannot Select This Interface.");
00248     status = USBH_FAIL; 
00249   }
00250   return status;  
00251 }
00252 
00253 /**
00254   * @brief  USBH_GetActiveClass 
00255   *         Return Device Class.
00256   * @param  phost: Host Handle
00257   * @param  interface: Interface index
00258   * @retval Class Code
00259   */
00260 uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost)
00261 {
00262    return (phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass);            
00263 }
00264 /**
00265   * @brief  USBH_FindInterface 
00266   *         Find the interface index for a specific class.
00267   * @param  phost: Host Handle
00268   * @param  Class: Class code
00269   * @param  SubClass: SubClass code
00270   * @param  Protocol: Protocol code
00271   * @retval interface index in the configuration structure
00272   * @note : (1)interface index 0xFF means interface index not found
00273   */
00274 uint8_t  USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol)
00275 {
00276   USBH_InterfaceDescTypeDef    *pif ;
00277   USBH_CfgDescTypeDef          *pcfg ;
00278   int8_t                        if_ix = 0;
00279   
00280   pif = (USBH_InterfaceDescTypeDef *)0;
00281   pcfg = &phost->device.CfgDesc;  
00282   
00283   while (if_ix < USBH_MAX_NUM_INTERFACES)
00284   {
00285     pif = &pcfg->Itf_Desc[if_ix];
00286     if(((pif->bInterfaceClass == Class) || (Class == 0xFF))&&
00287        ((pif->bInterfaceSubClass == SubClass) || (SubClass == 0xFF))&&
00288          ((pif->bInterfaceProtocol == Protocol) || (Protocol == 0xFF)))
00289     {
00290       return  if_ix;
00291     }
00292     if_ix++;
00293   }
00294   return 0xFF;
00295 }
00296 
00297 /**
00298   * @brief  USBH_FindInterfaceIndex 
00299   *         Find the interface index for a specific class interface and alternate setting number.
00300   * @param  phost: Host Handle
00301   * @param  interface_number: interface number
00302   * @param  alt_settings    : alternate setting number
00303   * @retval interface index in the configuration structure
00304   * @note : (1)interface index 0xFF means interface index not found
00305   */
00306 uint8_t  USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings)
00307 {
00308   USBH_InterfaceDescTypeDef    *pif ;
00309   USBH_CfgDescTypeDef          *pcfg ;
00310   int8_t                        if_ix = 0;
00311   
00312   pif = (USBH_InterfaceDescTypeDef *)0;
00313   pcfg = &phost->device.CfgDesc;  
00314   
00315   while (if_ix < USBH_MAX_NUM_INTERFACES)
00316   {
00317     pif = &pcfg->Itf_Desc[if_ix];
00318     if((pif->bInterfaceNumber == interface_number) && (pif->bAlternateSetting == alt_settings))
00319     {
00320       return  if_ix;
00321     }
00322     if_ix++;
00323   }
00324   return 0xFF;
00325 }
00326 
00327 /**
00328   * @brief  USBH_Start 
00329   *         Start the USB Host Core.
00330   * @param  phost: Host Handle
00331   * @retval USBH Status
00332   */
00333 USBH_StatusTypeDef  USBH_Start  (USBH_HandleTypeDef *phost)
00334 {
00335   /* Start the low level driver  */
00336   USBH_LL_Start(phost);
00337   
00338   /* Activate VBUS on the port */ 
00339   USBH_LL_DriverVBUS (phost, TRUE);
00340   
00341   return USBH_OK;  
00342 }
00343 
00344 /**
00345   * @brief  USBH_Stop 
00346   *         Stop the USB Host Core.
00347   * @param  phost: Host Handle
00348   * @retval USBH Status
00349   */
00350 USBH_StatusTypeDef  USBH_Stop   (USBH_HandleTypeDef *phost)
00351 {
00352   /* Stop and cleanup the low level driver  */
00353   USBH_LL_Stop(phost);  
00354   
00355   /* DeActivate VBUS on the port */ 
00356   USBH_LL_DriverVBUS (phost, FALSE);
00357   
00358   /* FRee Control Pipes */
00359   USBH_FreePipe  (phost, phost->Control.pipe_in);
00360   USBH_FreePipe  (phost, phost->Control.pipe_out);  
00361   
00362   return USBH_OK;  
00363 }
00364 
00365 /**
00366   * @brief  HCD_ReEnumerate 
00367   *         Perform a new Enumeration phase.
00368   * @param  phost: Host Handle
00369   * @retval USBH Status
00370   */
00371 USBH_StatusTypeDef  USBH_ReEnumerate   (USBH_HandleTypeDef *phost)
00372 {
00373   /*Stop Host */ 
00374   USBH_Stop(phost);
00375 
00376   /*Device has disconnected, so wait for 200 ms */  
00377   USBH_Delay(200);
00378   
00379   /* Set State machines in default state */
00380   DeInitStateMachine(phost);
00381    
00382   /* Start again the host */
00383   USBH_Start(phost);
00384       
00385 #if (USBH_USE_OS == 1)
00386       osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
00387 #endif  
00388   return USBH_OK;  
00389 }
00390 
00391 /**
00392   * @brief  USBH_Process 
00393   *         Background process of the USB Core.
00394   * @param  phost: Host Handle
00395   * @retval USBH Status
00396   */
00397 USBH_StatusTypeDef  USBH_Process(USBH_HandleTypeDef *phost)
00398 {
00399   __IO USBH_StatusTypeDef status = USBH_FAIL;
00400   uint8_t idx = 0;
00401   
00402   switch (phost->gState)
00403   {
00404   case HOST_IDLE :
00405     
00406     if (phost->device.is_connected)  
00407     {
00408       /* Wait for 200 ms after connection */
00409       phost->gState = HOST_DEV_WAIT_FOR_ATTACHMENT; 
00410       USBH_Delay(200); 
00411       USBH_LL_ResetPort(phost);
00412 #if (USBH_USE_OS == 1)
00413       osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
00414 #endif
00415     }
00416     break;
00417     
00418   case HOST_DEV_WAIT_FOR_ATTACHMENT:
00419     break;    
00420     
00421   case HOST_DEV_ATTACHED :
00422     
00423     USBH_UsrLog("USB Device Attached");  
00424       
00425     /* Wait for 100 ms after Reset */
00426     USBH_Delay(100); 
00427           
00428     phost->device.speed = USBH_LL_GetSpeed(phost);
00429     
00430     phost->gState = HOST_ENUMERATION;
00431     
00432     phost->Control.pipe_out = USBH_AllocPipe (phost, 0x00);
00433     phost->Control.pipe_in  = USBH_AllocPipe (phost, 0x80);    
00434     
00435     
00436     /* Open Control pipes */
00437     USBH_OpenPipe (phost,
00438                    phost->Control.pipe_in,
00439                    0x80,
00440                    phost->device.address,
00441                    phost->device.speed,
00442                    USBH_EP_CONTROL,
00443                    phost->Control.pipe_size); 
00444     
00445     /* Open Control pipes */
00446     USBH_OpenPipe (phost,
00447                    phost->Control.pipe_out,
00448                    0x00,
00449                    phost->device.address,
00450                    phost->device.speed,
00451                    USBH_EP_CONTROL,
00452                    phost->Control.pipe_size);
00453     
00454 #if (USBH_USE_OS == 1)
00455     osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
00456 #endif    
00457     
00458     break;
00459     
00460   case HOST_ENUMERATION:     
00461     /* Check for enumeration status */  
00462     if ( USBH_HandleEnum(phost) == USBH_OK)
00463     { 
00464       /* The function shall return USBH_OK when full enumeration is complete */
00465       USBH_UsrLog ("Enumeration done.");
00466       phost->device.current_interface = 0;
00467       if(phost->device.DevDesc.bNumConfigurations == 1)
00468       {
00469         USBH_UsrLog ("This device has only 1 configuration.");
00470         phost->gState  = HOST_SET_CONFIGURATION;        
00471         
00472       }
00473       else
00474       {
00475         phost->gState  = HOST_INPUT; 
00476       }
00477           
00478     }
00479     break;
00480     
00481   case HOST_INPUT:
00482     {
00483       /* user callback for end of device basic enumeration */
00484       if(phost->pUser != NULL)
00485       {
00486         phost->pUser(phost, HOST_USER_SELECT_CONFIGURATION);
00487         phost->gState = HOST_SET_CONFIGURATION;
00488         
00489 #if (USBH_USE_OS == 1)
00490         osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00491 #endif         
00492       }
00493     }
00494     break;
00495     
00496   case HOST_SET_CONFIGURATION:
00497     /* set configuration */
00498     if (USBH_SetCfg(phost, phost->device.CfgDesc.bConfigurationValue) == USBH_OK)
00499     {
00500       phost->gState  = HOST_CHECK_CLASS;
00501       USBH_UsrLog ("Default configuration set.");
00502       
00503     }      
00504     
00505     break;
00506     
00507   case HOST_CHECK_CLASS:
00508     
00509     if(phost->ClassNumber == 0)
00510     {
00511       USBH_UsrLog ("No Class has been registered.");
00512     }
00513     else
00514     {
00515       phost->pActiveClass = NULL;
00516       
00517       for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS ; idx ++)
00518       {
00519         if(phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass)
00520         {
00521           phost->pActiveClass = phost->pClass[idx];
00522         }
00523       }
00524       
00525       if(phost->pActiveClass != NULL)
00526       {
00527         if(phost->pActiveClass->Init(phost)== USBH_OK)
00528         {
00529           phost->gState  = HOST_CLASS_REQUEST; 
00530           USBH_UsrLog ("%s class started.", phost->pActiveClass->Name);
00531           
00532           /* Inform user that a class has been activated */
00533           phost->pUser(phost, HOST_USER_CLASS_SELECTED);   
00534         }
00535         else
00536         {
00537           phost->gState  = HOST_ABORT_STATE;
00538           USBH_UsrLog ("Device not supporting %s class.", phost->pActiveClass->Name);
00539         }
00540       }
00541       else
00542       {
00543         phost->gState  = HOST_ABORT_STATE;
00544         USBH_UsrLog ("No registered class for this device.");
00545       }
00546     }
00547     
00548 #if (USBH_USE_OS == 1)
00549     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00550 #endif 
00551     break;    
00552     
00553   case HOST_CLASS_REQUEST:  
00554     /* process class standard control requests state machine */
00555     if(phost->pActiveClass != NULL)
00556     {
00557       status = phost->pActiveClass->Requests(phost);
00558       
00559       if(status == USBH_OK)
00560       {
00561         phost->gState  = HOST_CLASS;        
00562       }  
00563     }
00564     else
00565     {
00566       phost->gState  = HOST_ABORT_STATE;
00567       USBH_ErrLog ("Invalid Class Driver.");
00568     
00569 #if (USBH_USE_OS == 1)
00570     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00571 #endif       
00572     }
00573     
00574     break;    
00575   case HOST_CLASS:   
00576     /* process class state machine */
00577     if(phost->pActiveClass != NULL)
00578     { 
00579       phost->pActiveClass->BgndProcess(phost);
00580     }
00581     break;       
00582 
00583   case HOST_DEV_DISCONNECTED :
00584     
00585     DeInitStateMachine(phost);  
00586     
00587     /* Re-Initilaize Host for new Enumeration */
00588     if(phost->pActiveClass != NULL)
00589     {
00590       phost->pActiveClass->DeInit(phost); 
00591       phost->pActiveClass = NULL;
00592     }     
00593     break;
00594     
00595   case HOST_ABORT_STATE:
00596   default :
00597     break;
00598   }
00599  return USBH_OK;  
00600 }
00601 
00602 
00603 /**
00604   * @brief  USBH_HandleEnum 
00605   *         This function includes the complete enumeration process
00606   * @param  phost: Host Handle
00607   * @retval USBH_Status
00608   */
00609 static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost)
00610 {
00611   USBH_StatusTypeDef Status = USBH_BUSY;  
00612   
00613   switch (phost->EnumState)
00614   {
00615   case ENUM_IDLE:  
00616     /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
00617     if ( USBH_Get_DevDesc(phost, 8) == USBH_OK)
00618     {
00619       phost->Control.pipe_size = phost->device.DevDesc.bMaxPacketSize;
00620 
00621       phost->EnumState = ENUM_GET_FULL_DEV_DESC;
00622       
00623       /* modify control channels configuration for MaxPacket size */
00624       USBH_OpenPipe (phost,
00625                            phost->Control.pipe_in,
00626                            0x80,
00627                            phost->device.address,
00628                            phost->device.speed,
00629                            USBH_EP_CONTROL,
00630                            phost->Control.pipe_size); 
00631       
00632       /* Open Control pipes */
00633       USBH_OpenPipe (phost,
00634                            phost->Control.pipe_out,
00635                            0x00,
00636                            phost->device.address,
00637                            phost->device.speed,
00638                            USBH_EP_CONTROL,
00639                            phost->Control.pipe_size);           
00640       
00641     }
00642     break;
00643     
00644   case ENUM_GET_FULL_DEV_DESC:  
00645     /* Get FULL Device Desc  */
00646     if ( USBH_Get_DevDesc(phost, USB_DEVICE_DESC_SIZE)== USBH_OK)
00647     {
00648       USBH_UsrLog("PID: %xh", phost->device.DevDesc.idProduct );  
00649       USBH_UsrLog("VID: %xh", phost->device.DevDesc.idVendor );  
00650       
00651       phost->EnumState = ENUM_SET_ADDR;
00652        
00653     }
00654     break;
00655    
00656   case ENUM_SET_ADDR: 
00657     /* set address */
00658     if ( USBH_SetAddress(phost, USBH_DEVICE_ADDRESS) == USBH_OK)
00659     {
00660       USBH_Delay(2);
00661       phost->device.address = USBH_DEVICE_ADDRESS;
00662       
00663       /* user callback for device address assigned */
00664       USBH_UsrLog("Address (#%d) assigned.", phost->device.address);
00665       phost->EnumState = ENUM_GET_CFG_DESC;
00666       
00667       /* modify control channels to update device address */
00668       USBH_OpenPipe (phost,
00669                            phost->Control.pipe_in,
00670                            0x80,
00671                            phost->device.address,
00672                            phost->device.speed,
00673                            USBH_EP_CONTROL,
00674                            phost->Control.pipe_size); 
00675       
00676       /* Open Control pipes */
00677       USBH_OpenPipe (phost,
00678                            phost->Control.pipe_out,
00679                            0x00,
00680                            phost->device.address,
00681                            phost->device.speed,
00682                            USBH_EP_CONTROL,
00683                            phost->Control.pipe_size);        
00684     }
00685     break;
00686     
00687   case ENUM_GET_CFG_DESC:  
00688     /* get standard configuration descriptor */
00689     if ( USBH_Get_CfgDesc(phost, 
00690                           USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
00691     {
00692       phost->EnumState = ENUM_GET_FULL_CFG_DESC;        
00693     }
00694     break;
00695     
00696   case ENUM_GET_FULL_CFG_DESC:  
00697     /* get FULL config descriptor (config, interface, endpoints) */
00698     if (USBH_Get_CfgDesc(phost, 
00699                          phost->device.CfgDesc.wTotalLength) == USBH_OK)
00700     {
00701       phost->EnumState = ENUM_GET_MFC_STRING_DESC;       
00702     }
00703     break;
00704     
00705   case ENUM_GET_MFC_STRING_DESC:  
00706     if (phost->device.DevDesc.iManufacturer != 0)
00707     { /* Check that Manufacturer String is available */
00708       
00709       if ( USBH_Get_StringDesc(phost,
00710                                phost->device.DevDesc.iManufacturer, 
00711                                 phost->device.Data , 
00712                                0xff) == USBH_OK)
00713       {
00714         /* User callback for Manufacturing string */
00715         USBH_UsrLog("Manufacturer : %s",  (char *)phost->device.Data);
00716         phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
00717         
00718 #if (USBH_USE_OS == 1)
00719     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00720 #endif          
00721       }
00722     }
00723     else
00724     {
00725      USBH_UsrLog("Manufacturer : N/A");      
00726      phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC; 
00727 #if (USBH_USE_OS == 1)
00728     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00729 #endif       
00730     }
00731     break;
00732     
00733   case ENUM_GET_PRODUCT_STRING_DESC:   
00734     if (phost->device.DevDesc.iProduct != 0)
00735     { /* Check that Product string is available */
00736       if ( USBH_Get_StringDesc(phost,
00737                                phost->device.DevDesc.iProduct, 
00738                                phost->device.Data, 
00739                                0xff) == USBH_OK)
00740       {
00741         /* User callback for Product string */
00742         USBH_UsrLog("Product : %s",  (char *)phost->device.Data);
00743         phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;        
00744       }
00745     }
00746     else
00747     {
00748       USBH_UsrLog("Product : N/A");
00749       phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC; 
00750 #if (USBH_USE_OS == 1)
00751     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00752 #endif        
00753     } 
00754     break;
00755     
00756   case ENUM_GET_SERIALNUM_STRING_DESC:   
00757     if (phost->device.DevDesc.iSerialNumber != 0)
00758     { /* Check that Serial number string is available */    
00759       if ( USBH_Get_StringDesc(phost,
00760                                phost->device.DevDesc.iSerialNumber, 
00761                                phost->device.Data, 
00762                                0xff) == USBH_OK)
00763       {
00764         /* User callback for Serial number string */
00765          USBH_UsrLog("Serial Number : %s",  (char *)phost->device.Data);
00766         Status = USBH_OK;
00767       }
00768     }
00769     else
00770     {
00771       USBH_UsrLog("Serial Number : N/A"); 
00772       Status = USBH_OK;
00773 #if (USBH_USE_OS == 1)
00774     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00775 #endif        
00776     }  
00777     break;
00778     
00779   default:
00780     break;
00781   }  
00782   return Status;
00783 }
00784 
00785 /**
00786   * @brief  USBH_LL_SetTimer 
00787   *         Set the initial Host Timer tick
00788   * @param  phost: Host Handle
00789   * @retval None
00790   */
00791 void  USBH_LL_SetTimer  (USBH_HandleTypeDef *phost, uint32_t time)
00792 {
00793   phost->Timer = time;
00794 }
00795 /**
00796   * @brief  USBH_LL_IncTimer 
00797   *         Increment Host Timer tick
00798   * @param  phost: Host Handle
00799   * @retval None
00800   */
00801 void  USBH_LL_IncTimer  (USBH_HandleTypeDef *phost)
00802 {
00803   phost->Timer ++;
00804   USBH_HandleSof(phost);
00805 }
00806 
00807 /**
00808   * @brief  USBH_HandleSof 
00809   *         Call SOF process
00810   * @param  phost: Host Handle
00811   * @retval None
00812   */
00813 void  USBH_HandleSof  (USBH_HandleTypeDef *phost)
00814 {
00815   if((phost->gState == HOST_CLASS)&&(phost->pActiveClass != NULL))
00816   {
00817     phost->pActiveClass->SOFProcess(phost);
00818   }
00819 }
00820 /**
00821   * @brief  USBH_LL_Connect 
00822   *         Handle USB Host connexion event
00823   * @param  phost: Host Handle
00824   * @retval USBH_Status
00825   */
00826 USBH_StatusTypeDef  USBH_LL_Connect  (USBH_HandleTypeDef *phost)
00827 {
00828   if(phost->gState == HOST_IDLE )
00829   {
00830     phost->device.is_connected = 1;
00831     
00832     if(phost->pUser != NULL)
00833     {    
00834       phost->pUser(phost, HOST_USER_CONNECTION);
00835     }
00836   } 
00837   else if(phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT )
00838   {
00839     phost->gState = HOST_DEV_ATTACHED ;
00840   }
00841 #if (USBH_USE_OS == 1)
00842   osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
00843 #endif 
00844   
00845   return USBH_OK;
00846 }
00847 
00848 /**
00849   * @brief  USBH_LL_Disconnect 
00850   *         Handle USB Host disconnection event
00851   * @param  phost: Host Handle
00852   * @retval USBH_Status
00853   */
00854 USBH_StatusTypeDef  USBH_LL_Disconnect  (USBH_HandleTypeDef *phost)
00855 {
00856   /*Stop Host */ 
00857   USBH_LL_Stop(phost);  
00858   
00859   /* FRee Control Pipes */
00860   USBH_FreePipe  (phost, phost->Control.pipe_in);
00861   USBH_FreePipe  (phost, phost->Control.pipe_out);  
00862    
00863   phost->device.is_connected = 0; 
00864    
00865   if(phost->pUser != NULL)
00866   {    
00867     phost->pUser(phost, HOST_USER_DISCONNECTION);
00868   }
00869   USBH_UsrLog("USB Device disconnected"); 
00870   
00871   /* Start the low level driver  */
00872   USBH_LL_Start(phost);
00873   
00874   phost->gState = HOST_DEV_DISCONNECTED;
00875   
00876 #if (USBH_USE_OS == 1)
00877   osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
00878 #endif 
00879   
00880   return USBH_OK;
00881 }
00882 
00883 
00884 #if (USBH_USE_OS == 1)  
00885 /**
00886   * @brief  USB Host Thread task
00887   * @param  pvParameters not used
00888   * @retval None
00889   */
00890 static void USBH_Process_OS(void const * argument)
00891 {
00892   osEvent event;
00893   
00894   for(;;)
00895   {
00896     event = osMessageGet(((USBH_HandleTypeDef *)argument)->os_event, osWaitForever );
00897     
00898     if( event.status == osEventMessage )
00899     {
00900       USBH_Process((USBH_HandleTypeDef *)argument);
00901     }
00902    }
00903 }
00904 
00905 /**
00906 * @brief  USBH_LL_NotifyURBChange 
00907 *         Notify URB state Change
00908 * @param  phost: Host handle
00909 * @retval USBH Status
00910 */
00911 USBH_StatusTypeDef  USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost)
00912 {
00913   osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00914   return USBH_OK;
00915 }
00916 #endif  
00917 /**
00918   * @}
00919   */ 
00920 
00921 /**
00922   * @}
00923   */ 
00924 
00925 /**
00926   * @}
00927   */
00928 
00929 /**
00930   * @}
00931   */ 
00932 
00933 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/