Sergey Pastor / grbl1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usb_core.c Source File

usb_core.c

00001 /******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
00002 * File Name          : usb_core.c
00003 * Author             : MCD Application Team
00004 * Version            : V3.2.1
00005 * Date               : 07/05/2010
00006 * Description        : Standard protocol processing (USB v2.0)
00007 ********************************************************************************
00008 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00009 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
00010 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
00011 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
00012 * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
00013 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00014 *******************************************************************************/
00015 
00016 /* Includes ------------------------------------------------------------------*/
00017 #include "usb_lib.h"
00018 /* Private typedef -----------------------------------------------------------*/
00019 /* Private define ------------------------------------------------------------*/
00020 #define ValBit(VAR,Place)    (VAR & (1 << Place))
00021 #define SetBit(VAR,Place)    (VAR |= (1 << Place))
00022 #define ClrBit(VAR,Place)    (VAR &= ((1 << Place) ^ 255))
00023 
00024 #ifdef STM32F10X_CL
00025  #define Send0LengthData()  {PCD_EP_Write (0, 0, 0) ; vSetEPTxStatus(EP_TX_VALID);}
00026 #else
00027 #define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \
00028     vSetEPTxStatus(EP_TX_VALID); \
00029   }
00030 #endif /* STM32F10X_CL */
00031 
00032 #define vSetEPRxStatus(st) (SaveRState = st)
00033 #define vSetEPTxStatus(st) (SaveTState = st)
00034 
00035 #define USB_StatusIn() Send0LengthData()
00036 #define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID)
00037 
00038 #define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */
00039 #define StatusInfo1 StatusInfo.bw.bb0
00040 
00041 /* Private macro -------------------------------------------------------------*/
00042 /* Private variables ---------------------------------------------------------*/
00043 uint16_t_uint8_t StatusInfo;
00044 
00045 bool Data_Mul_MaxPacketSize = FALSE;
00046 /* Private function prototypes -----------------------------------------------*/
00047 static void DataStageOut(void);
00048 static void DataStageIn(void);
00049 static void NoData_Setup0(void);
00050 static void Data_Setup0(void);
00051 /* Private functions ---------------------------------------------------------*/
00052 
00053 /*******************************************************************************
00054 * Function Name  : Standard_GetConfiguration.
00055 * Description    : Return the current configuration variable address.
00056 * Input          : Length - How many bytes are needed.
00057 * Output         : None.
00058 * Return         : Return 1 , if the request is invalid when "Length" is 0.
00059 *                  Return "Buffer" if the "Length" is not 0.
00060 *******************************************************************************/
00061 uint8_t *Standard_GetConfiguration(uint16_t Length)
00062 {
00063   if (Length == 0)
00064   {
00065     pInformation->Ctrl_Info.Usb_wLength =
00066       sizeof(pInformation->Current_Configuration);
00067     return 0;
00068   }
00069   pUser_Standard_Requests->User_GetConfiguration();
00070   return (uint8_t *)&pInformation->Current_Configuration;
00071 }
00072 
00073 /*******************************************************************************
00074 * Function Name  : Standard_SetConfiguration.
00075 * Description    : This routine is called to set the configuration value
00076 *                  Then each class should configure device themself.
00077 * Input          : None.
00078 * Output         : None.
00079 * Return         : Return USB_SUCCESS, if the request is performed.
00080 *                  Return USB_UNSUPPORT, if the request is invalid.
00081 *******************************************************************************/
00082 RESULT Standard_SetConfiguration(void)
00083 {
00084 
00085   if ((pInformation->USBwValue0 <=
00086       Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0)
00087       && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/
00088   {
00089     pInformation->Current_Configuration = pInformation->USBwValue0;
00090     pUser_Standard_Requests->User_SetConfiguration();
00091     return USB_SUCCESS;
00092   }
00093   else
00094   {
00095     return USB_UNSUPPORT;
00096   }
00097 }
00098 
00099 /*******************************************************************************
00100 * Function Name  : Standard_GetInterface.
00101 * Description    : Return the Alternate Setting of the current interface.
00102 * Input          : Length - How many bytes are needed.
00103 * Output         : None.
00104 * Return         : Return 0, if the request is invalid when "Length" is 0.
00105 *                  Return "Buffer" if the "Length" is not 0.
00106 *******************************************************************************/
00107 uint8_t *Standard_GetInterface(uint16_t Length)
00108 {
00109   if (Length == 0)
00110   {
00111     pInformation->Ctrl_Info.Usb_wLength =
00112       sizeof(pInformation->Current_AlternateSetting);
00113     return 0;
00114   }
00115   pUser_Standard_Requests->User_GetInterface();
00116   return (uint8_t *)&pInformation->Current_AlternateSetting;
00117 }
00118 
00119 /*******************************************************************************
00120 * Function Name  : Standard_SetInterface.
00121 * Description    : This routine is called to set the interface.
00122 *                  Then each class should configure the interface them self.
00123 * Input          : None.
00124 * Output         : None.
00125 * Return         : - Return USB_SUCCESS, if the request is performed.
00126 *                  - Return USB_UNSUPPORT, if the request is invalid.
00127 *******************************************************************************/
00128 RESULT Standard_SetInterface(void)
00129 {
00130   RESULT Re;
00131   /*Test if the specified Interface and Alternate Setting are supported by
00132     the application Firmware*/
00133   Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0);
00134 
00135   if (pInformation->Current_Configuration != 0)
00136   {
00137     if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0)
00138         || (pInformation->USBwValue1 != 0))
00139     {
00140       return  USB_UNSUPPORT;
00141     }
00142     else if (Re == USB_SUCCESS)
00143     {
00144       pUser_Standard_Requests->User_SetInterface();
00145       pInformation->Current_Interface = pInformation->USBwIndex0;
00146       pInformation->Current_AlternateSetting = pInformation->USBwValue0;
00147       return USB_SUCCESS;
00148     }
00149 
00150   }
00151 
00152   return USB_UNSUPPORT;
00153 }
00154 
00155 /*******************************************************************************
00156 * Function Name  : Standard_GetStatus.
00157 * Description    : Copy the device request data to "StatusInfo buffer".
00158 * Input          : - Length - How many bytes are needed.
00159 * Output         : None.
00160 * Return         : Return 0, if the request is at end of data block,
00161 *                  or is invalid when "Length" is 0.
00162 *******************************************************************************/
00163 uint8_t *Standard_GetStatus(uint16_t Length)
00164 {
00165   if (Length == 0)
00166   {
00167     pInformation->Ctrl_Info.Usb_wLength = 2;
00168     return 0;
00169   }
00170 
00171   /* Reset Status Information */
00172   StatusInfo.w = 0;
00173 
00174   if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
00175   {
00176     /*Get Device Status */
00177     uint8_t Feature = pInformation->Current_Feature;
00178 
00179     /* Remote Wakeup enabled */
00180     if (ValBit(Feature, 5))
00181     {
00182       SetBit(StatusInfo0, 1);
00183     }
00184     else
00185     {
00186       ClrBit(StatusInfo0, 1);
00187     }      
00188 
00189     /* Bus-powered */
00190     if (ValBit(Feature, 6))
00191     {
00192       SetBit(StatusInfo0, 0);
00193     }
00194     else /* Self-powered */
00195     {
00196       ClrBit(StatusInfo0, 0);
00197     }
00198   }
00199   /*Interface Status*/
00200   else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
00201   {
00202     return (uint8_t *)&StatusInfo;
00203   }
00204   /*Get EndPoint Status*/
00205   else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
00206   {
00207     uint8_t Related_Endpoint;
00208     uint8_t wIndex0 = pInformation->USBwIndex0;
00209 
00210     Related_Endpoint = (wIndex0 & 0x0f);
00211     if (ValBit(wIndex0, 7))
00212     {
00213       /* IN endpoint */
00214       if (_GetTxStallStatus(Related_Endpoint))
00215       {
00216         SetBit(StatusInfo0, 0); /* IN Endpoint stalled */
00217       }
00218     }
00219     else
00220     {
00221       /* OUT endpoint */
00222       if (_GetRxStallStatus(Related_Endpoint))
00223       {
00224         SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */
00225       }
00226     }
00227 
00228   }
00229   else
00230   {
00231     return NULL;
00232   }
00233   pUser_Standard_Requests->User_GetStatus();
00234   return (uint8_t *)&StatusInfo;
00235 }
00236 
00237 /*******************************************************************************
00238 * Function Name  : Standard_ClearFeature.
00239 * Description    : Clear or disable a specific feature.
00240 * Input          : None.
00241 * Output         : None.
00242 * Return         : - Return USB_SUCCESS, if the request is performed.
00243 *                  - Return USB_UNSUPPORT, if the request is invalid.
00244 *******************************************************************************/
00245 RESULT Standard_ClearFeature(void)
00246 {
00247   uint32_t     Type_Rec = Type_Recipient;
00248   uint32_t     Status;
00249 
00250 
00251   if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT))
00252   {/*Device Clear Feature*/
00253     ClrBit(pInformation->Current_Feature, 5);
00254     return USB_SUCCESS;
00255   }
00256   else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
00257   {/*EndPoint Clear Feature*/
00258     DEVICE* pDev;
00259     uint32_t Related_Endpoint;
00260     uint32_t wIndex0;
00261     uint32_t rEP;
00262 
00263     if ((pInformation->USBwValue != ENDPOINT_STALL)
00264         || (pInformation->USBwIndex1 != 0))
00265     {
00266       return USB_UNSUPPORT;
00267     }
00268 
00269     pDev = &Device_Table;
00270     wIndex0 = pInformation->USBwIndex0;
00271     rEP = wIndex0 & ~0x80;
00272     Related_Endpoint = ENDP0 + rEP;
00273 
00274     if (ValBit(pInformation->USBwIndex0, 7))
00275     {
00276       /*Get Status of endpoint & stall the request if the related_ENdpoint
00277       is Disabled*/
00278       Status = _GetEPTxStatus(Related_Endpoint);
00279     }
00280     else
00281     {
00282       Status = _GetEPRxStatus(Related_Endpoint);
00283     }
00284 
00285     if ((rEP >= pDev->Total_Endpoint) || (Status == 0)
00286         || (pInformation->Current_Configuration == 0))
00287     {
00288       return USB_UNSUPPORT;
00289     }
00290 
00291 
00292     if (wIndex0 & 0x80)
00293     {
00294       /* IN endpoint */
00295       if (_GetTxStallStatus(Related_Endpoint ))
00296       {
00297       #ifndef STM32F10X_CL
00298         ClearDTOG_TX(Related_Endpoint);
00299       #endif /* STM32F10X_CL */
00300         SetEPTxStatus(Related_Endpoint, EP_TX_VALID);
00301       }
00302     }
00303     else
00304     {
00305       /* OUT endpoint */
00306       if (_GetRxStallStatus(Related_Endpoint))
00307       {
00308         if (Related_Endpoint == ENDP0)
00309         {
00310           /* After clear the STALL, enable the default endpoint receiver */
00311           SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize);
00312           _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
00313         }
00314         else
00315         {
00316         #ifndef STM32F10X_CL
00317           ClearDTOG_RX(Related_Endpoint);
00318         #endif /* STM32F10X_CL */
00319           _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
00320         }
00321       }
00322     }
00323     pUser_Standard_Requests->User_ClearFeature();
00324     return USB_SUCCESS;
00325   }
00326 
00327   return USB_UNSUPPORT;
00328 }
00329 
00330 /*******************************************************************************
00331 * Function Name  : Standard_SetEndPointFeature
00332 * Description    : Set or enable a specific feature of EndPoint
00333 * Input          : None.
00334 * Output         : None.
00335 * Return         : - Return USB_SUCCESS, if the request is performed.
00336 *                  - Return USB_UNSUPPORT, if the request is invalid.
00337 *******************************************************************************/
00338 RESULT Standard_SetEndPointFeature(void)
00339 {
00340   uint32_t    wIndex0;
00341   uint32_t    Related_Endpoint;
00342   uint32_t    rEP;
00343   uint32_t    Status;
00344 
00345   wIndex0 = pInformation->USBwIndex0;
00346   rEP = wIndex0 & ~0x80;
00347   Related_Endpoint = ENDP0 + rEP;
00348 
00349   if (ValBit(pInformation->USBwIndex0, 7))
00350   {
00351     /* get Status of endpoint & stall the request if the related_ENdpoint
00352     is Disabled*/
00353     Status = _GetEPTxStatus(Related_Endpoint);
00354   }
00355   else
00356   {
00357     Status = _GetEPRxStatus(Related_Endpoint);
00358   }
00359 
00360   if (Related_Endpoint >= Device_Table.Total_Endpoint
00361       || pInformation->USBwValue != 0 || Status == 0
00362       || pInformation->Current_Configuration == 0)
00363   {
00364     return USB_UNSUPPORT;
00365   }
00366   else
00367   {
00368     if (wIndex0 & 0x80)
00369     {
00370       /* IN endpoint */
00371       _SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
00372     }
00373 
00374     else
00375     {
00376       /* OUT endpoint */
00377       _SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
00378     }
00379   }
00380   pUser_Standard_Requests->User_SetEndPointFeature();
00381   return USB_SUCCESS;
00382 }
00383 
00384 /*******************************************************************************
00385 * Function Name  : Standard_SetDeviceFeature.
00386 * Description    : Set or enable a specific feature of Device.
00387 * Input          : None.
00388 * Output         : None.
00389 * Return         : - Return USB_SUCCESS, if the request is performed.
00390 *                  - Return USB_UNSUPPORT, if the request is invalid.
00391 *******************************************************************************/
00392 RESULT Standard_SetDeviceFeature(void)
00393 {
00394   SetBit(pInformation->Current_Feature, 5);
00395   pUser_Standard_Requests->User_SetDeviceFeature();
00396   return USB_SUCCESS;
00397 }
00398 
00399 /*******************************************************************************
00400 * Function Name  : Standard_GetDescriptorData.
00401 * Description    : Standard_GetDescriptorData is used for descriptors transfer.
00402 *                : This routine is used for the descriptors resident in Flash
00403 *                  or RAM
00404 *                  pDesc can be in either Flash or RAM
00405 *                  The purpose of this routine is to have a versatile way to
00406 *                  response descriptors request. It allows user to generate
00407 *                  certain descriptors with software or read descriptors from
00408 *                  external storage part by part.
00409 * Input          : - Length - Length of the data in this transfer.
00410 *                  - pDesc - A pointer points to descriptor struct.
00411 *                  The structure gives the initial address of the descriptor and
00412 *                  its original size.
00413 * Output         : None.
00414 * Return         : Address of a part of the descriptor pointed by the Usb_
00415 *                  wOffset The buffer pointed by this address contains at least
00416 *                  Length bytes.
00417 *******************************************************************************/
00418 uint8_t *Standard_GetDescriptorData(uint16_t Length, ONE_DESCRIPTOR *pDesc)
00419 {
00420   uint32_t  wOffset;
00421 
00422   wOffset = pInformation->Ctrl_Info.Usb_wOffset;
00423   if (Length == 0)
00424   {
00425     pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
00426     return 0;
00427   }
00428 
00429   return pDesc->Descriptor + wOffset;
00430 }
00431 
00432 /*******************************************************************************
00433 * Function Name  : DataStageOut.
00434 * Description    : Data stage of a Control Write Transfer.
00435 * Input          : None.
00436 * Output         : None.
00437 * Return         : None.
00438 *******************************************************************************/
00439 void DataStageOut(void)
00440 {
00441   ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
00442   uint32_t save_rLength;
00443 
00444   save_rLength = pEPinfo->Usb_rLength;
00445 
00446   if (pEPinfo->CopyData && save_rLength)
00447   {
00448     uint8_t *Buffer;
00449     uint32_t Length;
00450 
00451     Length = pEPinfo->PacketSize;
00452     if (Length > save_rLength)
00453     {
00454       Length = save_rLength;
00455     }
00456 
00457     Buffer = (*pEPinfo->CopyData)(Length);
00458     pEPinfo->Usb_rLength -= Length;
00459     pEPinfo->Usb_rOffset += Length;
00460 
00461   #ifdef STM32F10X_CL  
00462     PCD_EP_Read(ENDP0, Buffer, Length); 
00463   #else  
00464     PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
00465   #endif  /* STM32F10X_CL */
00466   }
00467 
00468   if (pEPinfo->Usb_rLength != 0)
00469   {
00470     vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */
00471     SetEPTxCount(ENDP0, 0);
00472     vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */
00473   }
00474   /* Set the next State*/
00475   if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize)
00476   {
00477     pInformation->ControlState = OUT_DATA;
00478   }
00479   else
00480   {
00481     if (pEPinfo->Usb_rLength > 0)
00482     {
00483       pInformation->ControlState = LAST_OUT_DATA;
00484     }
00485     else if (pEPinfo->Usb_rLength == 0)
00486     {
00487       pInformation->ControlState = WAIT_STATUS_IN;
00488       USB_StatusIn();
00489     }
00490   }
00491 }
00492 
00493 /*******************************************************************************
00494 * Function Name  : DataStageIn.
00495 * Description    : Data stage of a Control Read Transfer.
00496 * Input          : None.
00497 * Output         : None.
00498 * Return         : None.
00499 *******************************************************************************/
00500 void DataStageIn(void)
00501 {
00502   ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
00503   uint32_t save_wLength = pEPinfo->Usb_wLength;
00504   uint32_t ControlState = pInformation->ControlState;
00505 
00506   uint8_t *DataBuffer;
00507   uint32_t Length;
00508 
00509   if ((save_wLength == 0) && (ControlState == LAST_IN_DATA))
00510   {
00511     if(Data_Mul_MaxPacketSize == TRUE)
00512     {
00513       /* No more data to send and empty packet */
00514       Send0LengthData();
00515       ControlState = LAST_IN_DATA;
00516       Data_Mul_MaxPacketSize = FALSE;
00517     }
00518     else 
00519     {
00520       /* No more data to send so STALL the TX Status*/
00521       ControlState = WAIT_STATUS_OUT;
00522 
00523     #ifdef STM32F10X_CL      
00524       PCD_EP_Read (ENDP0, 0, 0);
00525     #endif  /* STM32F10X_CL */ 
00526     
00527     #ifndef STM32F10X_CL 
00528       vSetEPTxStatus(EP_TX_STALL);
00529     #endif  /* STM32F10X_CL */ 
00530     }
00531     
00532     goto Expect_Status_Out;
00533   }
00534 
00535   Length = pEPinfo->PacketSize;
00536   ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA;
00537 
00538   if (Length > save_wLength)
00539   {
00540     Length = save_wLength;
00541   }
00542 
00543   DataBuffer = (*pEPinfo->CopyData)(Length);
00544 
00545 #ifdef STM32F10X_CL
00546   PCD_EP_Write (ENDP0, DataBuffer, Length);
00547 #else   
00548   UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
00549 #endif /* STM32F10X_CL */ 
00550 
00551   SetEPTxCount(ENDP0, Length);
00552 
00553   pEPinfo->Usb_wLength -= Length;
00554   pEPinfo->Usb_wOffset += Length;
00555   vSetEPTxStatus(EP_TX_VALID);
00556 
00557   USB_StatusOut();/* Expect the host to abort the data IN stage */
00558 
00559 Expect_Status_Out:
00560   pInformation->ControlState = ControlState;
00561 }
00562 
00563 /*******************************************************************************
00564 * Function Name  : NoData_Setup0.
00565 * Description    : Proceed the processing of setup request without data stage.
00566 * Input          : None.
00567 * Output         : None.
00568 * Return         : None.
00569 *******************************************************************************/
00570 void NoData_Setup0(void)
00571 {
00572   RESULT Result = USB_UNSUPPORT;
00573   uint32_t RequestNo = pInformation->USBbRequest;
00574   uint32_t ControlState;
00575 
00576   if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
00577   {
00578     /* Device Request*/
00579     /* SET_CONFIGURATION*/
00580     if (RequestNo == SET_CONFIGURATION)
00581     {
00582       Result = Standard_SetConfiguration();
00583     }
00584 
00585     /*SET ADDRESS*/
00586     else if (RequestNo == SET_ADDRESS)
00587     {
00588       if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0)
00589           || (pInformation->USBwIndex != 0)
00590           || (pInformation->Current_Configuration != 0))
00591         /* Device Address should be 127 or less*/
00592       {
00593         ControlState = STALLED;
00594         goto exit_NoData_Setup0;
00595       }
00596       else
00597       {
00598         Result = USB_SUCCESS;
00599 
00600       #ifdef STM32F10X_CL
00601          SetDeviceAddress(pInformation->USBwValue0);
00602       #endif  /* STM32F10X_CL */
00603       }
00604     }
00605     /*SET FEATURE for Device*/
00606     else if (RequestNo == SET_FEATURE)
00607     {
00608       if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP)
00609           && (pInformation->USBwIndex == 0)
00610           && (ValBit(pInformation->Current_Feature, 5)))
00611       {
00612         Result = Standard_SetDeviceFeature();
00613       }
00614       else
00615       {
00616         Result = USB_UNSUPPORT;
00617       }
00618     }
00619     /*Clear FEATURE for Device */
00620     else if (RequestNo == CLEAR_FEATURE)
00621     {
00622       if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
00623           && pInformation->USBwIndex == 0
00624           && ValBit(pInformation->Current_Feature, 5))
00625       {
00626         Result = Standard_ClearFeature();
00627       }
00628       else
00629       {
00630         Result = USB_UNSUPPORT;
00631       }
00632     }
00633 
00634   }
00635 
00636   /* Interface Request*/
00637   else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
00638   {
00639     /*SET INTERFACE*/
00640     if (RequestNo == SET_INTERFACE)
00641     {
00642       Result = Standard_SetInterface();
00643     }
00644   }
00645 
00646   /* EndPoint Request*/
00647   else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
00648   {
00649     /*CLEAR FEATURE for EndPoint*/
00650     if (RequestNo == CLEAR_FEATURE)
00651     {
00652       Result = Standard_ClearFeature();
00653     }
00654     /* SET FEATURE for EndPoint*/
00655     else if (RequestNo == SET_FEATURE)
00656     {
00657       Result = Standard_SetEndPointFeature();
00658     }
00659   }
00660   else
00661   {
00662     Result = USB_UNSUPPORT;
00663   }
00664 
00665 
00666   if (Result != USB_SUCCESS)
00667   {
00668     Result = (*pProperty->Class_NoData_Setup)(RequestNo);
00669     if (Result == USB_NOT_READY)
00670     {
00671       ControlState = PAUSE;
00672       goto exit_NoData_Setup0;
00673     }
00674   }
00675 
00676   if (Result != USB_SUCCESS)
00677   {
00678     ControlState = STALLED;
00679     goto exit_NoData_Setup0;
00680   }
00681 
00682   ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */
00683 
00684   USB_StatusIn();
00685 
00686 exit_NoData_Setup0:
00687   pInformation->ControlState = ControlState;
00688   return;
00689 }
00690 
00691 /*******************************************************************************
00692 * Function Name  : Data_Setup0.
00693 * Description    : Proceed the processing of setup request with data stage.
00694 * Input          : None.
00695 * Output         : None.
00696 * Return         : None.
00697 *******************************************************************************/
00698 void Data_Setup0(void)
00699 {
00700   uint8_t *(*CopyRoutine)(uint16_t);
00701   RESULT Result;
00702   uint32_t Request_No = pInformation->USBbRequest;
00703 
00704   uint32_t Related_Endpoint, Reserved;
00705   uint32_t wOffset, Status;
00706 
00707 
00708 
00709   CopyRoutine = NULL;
00710   wOffset = 0;
00711 
00712   /*GET DESCRIPTOR*/
00713   if (Request_No == GET_DESCRIPTOR)
00714   {
00715     if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
00716     {
00717       uint8_t wValue1 = pInformation->USBwValue1;
00718       if (wValue1 == DEVICE_DESCRIPTOR)
00719       {
00720         CopyRoutine = pProperty->GetDeviceDescriptor;
00721       }
00722       else if (wValue1 == CONFIG_DESCRIPTOR)
00723       {
00724         CopyRoutine = pProperty->GetConfigDescriptor;
00725       }
00726       else if (wValue1 == STRING_DESCRIPTOR)
00727       {
00728         CopyRoutine = pProperty->GetStringDescriptor;
00729       }  /* End of GET_DESCRIPTOR */
00730     }
00731   }
00732 
00733   /*GET STATUS*/
00734   else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0)
00735            && (pInformation->USBwLength == 0x0002)
00736            && (pInformation->USBwIndex1 == 0))
00737   {
00738     /* GET STATUS for Device*/
00739     if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
00740         && (pInformation->USBwIndex == 0))
00741     {
00742       CopyRoutine = Standard_GetStatus;
00743     }
00744 
00745     /* GET STATUS for Interface*/
00746     else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
00747     {
00748       if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)
00749           && (pInformation->Current_Configuration != 0))
00750       {
00751         CopyRoutine = Standard_GetStatus;
00752       }
00753     }
00754 
00755     /* GET STATUS for EndPoint*/
00756     else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
00757     {
00758       Related_Endpoint = (pInformation->USBwIndex0 & 0x0f);
00759       Reserved = pInformation->USBwIndex0 & 0x70;
00760 
00761       if (ValBit(pInformation->USBwIndex0, 7))
00762       {
00763         /*Get Status of endpoint & stall the request if the related_ENdpoint
00764         is Disabled*/
00765         Status = _GetEPTxStatus(Related_Endpoint);
00766       }
00767       else
00768       {
00769         Status = _GetEPRxStatus(Related_Endpoint);
00770       }
00771 
00772       if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0)
00773           && (Status != 0))
00774       {
00775         CopyRoutine = Standard_GetStatus;
00776       }
00777     }
00778 
00779   }
00780 
00781   /*GET CONFIGURATION*/
00782   else if (Request_No == GET_CONFIGURATION)
00783   {
00784     if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
00785     {
00786       CopyRoutine = Standard_GetConfiguration;
00787     }
00788   }
00789   /*GET INTERFACE*/
00790   else if (Request_No == GET_INTERFACE)
00791   {
00792     if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
00793         && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0)
00794         && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001)
00795         && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS))
00796     {
00797       CopyRoutine = Standard_GetInterface;
00798     }
00799 
00800   }
00801   
00802   if (CopyRoutine)
00803   {
00804     pInformation->Ctrl_Info.Usb_wOffset = wOffset;
00805     pInformation->Ctrl_Info.CopyData = CopyRoutine;
00806     /* sb in the original the cast to word was directly */
00807     /* now the cast is made step by step */
00808     (*CopyRoutine)(0);
00809     Result = USB_SUCCESS;
00810   }
00811   else
00812   {
00813     Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
00814     if (Result == USB_NOT_READY)
00815     {
00816       pInformation->ControlState = PAUSE;
00817       return;
00818     }
00819   }
00820 
00821   if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)
00822   {
00823     /* Data is not ready, wait it */
00824     pInformation->ControlState = PAUSE;
00825     return;
00826   }
00827   if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
00828   {
00829     /* Unsupported request */
00830     pInformation->ControlState = STALLED;
00831     return;
00832   }
00833 
00834 
00835   if (ValBit(pInformation->USBbmRequestType, 7))
00836   {
00837     /* Device ==> Host */
00838     __IO uint32_t wLength = pInformation->USBwLength;
00839      
00840     /* Restrict the data length to be the one host asks for */
00841     if (pInformation->Ctrl_Info.Usb_wLength > wLength)
00842     {
00843       pInformation->Ctrl_Info.Usb_wLength = wLength;
00844     }
00845     
00846     else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)
00847     {
00848       if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize)
00849       {
00850         Data_Mul_MaxPacketSize = FALSE;
00851       }
00852       else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)
00853       {
00854         Data_Mul_MaxPacketSize = TRUE;
00855       }
00856     }   
00857 
00858     pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize;
00859     DataStageIn();
00860   }
00861   else
00862   {
00863     pInformation->ControlState = OUT_DATA;
00864     vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */
00865   }
00866 
00867   return;
00868 }
00869 
00870 /*******************************************************************************
00871 * Function Name  : Setup0_Process
00872 * Description    : Get the device request data and dispatch to individual process.
00873 * Input          : None.
00874 * Output         : None.
00875 * Return         : Post0_Process.
00876 *******************************************************************************/
00877 uint8_t Setup0_Process(void)
00878 {
00879 
00880   union
00881   {
00882     uint8_t* b;
00883     uint16_t* w;
00884   } pBuf;
00885 
00886 #ifdef STM32F10X_CL
00887   USB_OTG_EP *ep;
00888   uint16_t offset = 0;
00889  
00890   ep = PCD_GetOutEP(ENDP0);
00891   pBuf.b = ep->xfer_buff;
00892 #else  
00893   uint16_t offset = 1;
00894   
00895   pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
00896 #endif /* STM32F10X_CL */
00897 
00898   if (pInformation->ControlState != PAUSE)
00899   {
00900     pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
00901     pInformation->USBbRequest = *pBuf.b++; /* bRequest */
00902     pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
00903     pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
00904     pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
00905     pInformation->USBwIndex  = ByteSwap(*pBuf.w++); /* wIndex */
00906     pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
00907     pInformation->USBwLength = *pBuf.w; /* wLength */
00908   }
00909 
00910   pInformation->ControlState = SETTING_UP;
00911   if (pInformation->USBwLength == 0)
00912   {
00913     /* Setup with no data stage */
00914     NoData_Setup0();
00915   }
00916   else
00917   {
00918     /* Setup with data stage */
00919     Data_Setup0();
00920   }
00921   return Post0_Process();
00922 }
00923 
00924 /*******************************************************************************
00925 * Function Name  : In0_Process
00926 * Description    : Process the IN token on all default endpoint.
00927 * Input          : None.
00928 * Output         : None.
00929 * Return         : Post0_Process.
00930 *******************************************************************************/
00931 uint8_t In0_Process(void)
00932 {
00933   uint32_t ControlState = pInformation->ControlState;
00934 
00935   if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
00936   {
00937     DataStageIn();
00938     /* ControlState may be changed outside the function */
00939     ControlState = pInformation->ControlState;
00940   }
00941 
00942   else if (ControlState == WAIT_STATUS_IN)
00943   {
00944     if ((pInformation->USBbRequest == SET_ADDRESS) &&
00945         (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
00946     {
00947       SetDeviceAddress(pInformation->USBwValue0);
00948       pUser_Standard_Requests->User_SetDeviceAddress();
00949     }
00950     (*pProperty->Process_Status_IN)();
00951     ControlState = STALLED;
00952   }
00953 
00954   else
00955   {
00956     ControlState = STALLED;
00957   }
00958 
00959   pInformation->ControlState = ControlState;
00960 
00961   return Post0_Process();
00962 }
00963 
00964 /*******************************************************************************
00965 * Function Name  : Out0_Process
00966 * Description    : Process the OUT token on all default endpoint.
00967 * Input          : None.
00968 * Output         : None.
00969 * Return         : Post0_Process.
00970 *******************************************************************************/
00971 uint8_t Out0_Process(void)
00972 {
00973   uint32_t ControlState = pInformation->ControlState;
00974 
00975   if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
00976   {
00977     /* host aborts the transfer before finish */
00978     ControlState = STALLED;
00979   }
00980   else if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA))
00981   {
00982     DataStageOut();
00983     ControlState = pInformation->ControlState; /* may be changed outside the function */
00984   }
00985 
00986   else if (ControlState == WAIT_STATUS_OUT)
00987   {
00988     (*pProperty->Process_Status_OUT)();
00989   #ifndef STM32F10X_CL
00990     ControlState = STALLED;
00991   #endif /* STM32F10X_CL */
00992   }
00993 
00994 
00995   /* Unexpect state, STALL the endpoint */
00996   else
00997   {
00998     ControlState = STALLED;
00999   }
01000 
01001   pInformation->ControlState = ControlState;
01002 
01003   return Post0_Process();
01004 }
01005 
01006 /*******************************************************************************
01007 * Function Name  : Post0_Process
01008 * Description    : Stall the Endpoint 0 in case of error.
01009 * Input          : None.
01010 * Output         : None.
01011 * Return         : - 0 if the control State is in PAUSE
01012 *                  - 1 if not.
01013 *******************************************************************************/
01014 uint8_t Post0_Process(void)
01015 {
01016 #ifdef STM32F10X_CL  
01017   USB_OTG_EP *ep;
01018 #endif /* STM32F10X_CL */
01019       
01020   SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
01021 
01022   if (pInformation->ControlState == STALLED)
01023   {
01024     vSetEPRxStatus(EP_RX_STALL);
01025     vSetEPTxStatus(EP_TX_STALL);
01026   }
01027 
01028 #ifdef STM32F10X_CL
01029   else if ((pInformation->ControlState == OUT_DATA) ||
01030       (pInformation->ControlState == WAIT_STATUS_OUT))
01031   {
01032     ep = PCD_GetInEP(0);
01033     ep->is_in = 0;
01034     OTGD_FS_EP0StartXfer(ep);
01035     
01036     vSetEPTxStatus(EP_TX_VALID);
01037   }
01038   
01039   else if ((pInformation->ControlState == IN_DATA) || 
01040       (pInformation->ControlState == WAIT_STATUS_IN))
01041   {
01042     ep = PCD_GetInEP(0);
01043     ep->is_in = 1;
01044     OTGD_FS_EP0StartXfer(ep);    
01045   }  
01046 #endif /* STM32F10X_CL */
01047 
01048   return (pInformation->ControlState == PAUSE);
01049 }
01050 
01051 /*******************************************************************************
01052 * Function Name  : SetDeviceAddress.
01053 * Description    : Set the device and all the used Endpoints addresses.
01054 * Input          : - Val: device adress.
01055 * Output         : None.
01056 * Return         : None.
01057 *******************************************************************************/
01058 void SetDeviceAddress(uint8_t Val)
01059 {
01060 #ifdef STM32F10X_CL 
01061   PCD_EP_SetAddress ((uint8_t)Val);
01062 #else 
01063   uint32_t i;
01064   uint32_t nEP = Device_Table.Total_Endpoint;
01065 
01066   /* set address in every used endpoint */
01067   for (i = 0; i < nEP; i++)
01068   {
01069     _SetEPAddress((uint8_t)i, (uint8_t)i);
01070   } /* for */
01071   _SetDADDR(Val | DADDR_EF); /* set device address and enable function */
01072 #endif  /* STM32F10X_CL */  
01073 }
01074 
01075 /*******************************************************************************
01076 * Function Name  : NOP_Process
01077 * Description    : No operation function.
01078 * Input          : None.
01079 * Output         : None.
01080 * Return         : None.
01081 *******************************************************************************/
01082 void NOP_Process(void)
01083 {
01084 }
01085 
01086 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/