www.pudn.com > LPC2148_IAR_LPC2148.zip > usb_9.c


/************************************************************************* 
 * 
 *    Used with ICCARM and AARM. 
 * 
 *    (c) Copyright IAR Systems 2003 
 * 
 *    File name   : usb_9.c 
 *    Description : USB chapter 9 (device framework) module 
 * 
 *    History : 
 *    1. Data        : August 5, 2005 
 *       Author      : Stanimir Bonev 
 *       Description : Create 
 *    2. Data        : December 19, 2005 
 *       Author      : Stanimir Bonev 
 *       Description : Modify 
 *        Modify user callback function for EP0 
 *        Change prameter transfered to function form packet type to 
 *        pointer to UsbEp0Ctrl structure 
 * 
 *    $Revision: 1.1.2.1 $ 
**************************************************************************/ 
#include "usb_9.h" 
 
UsbEpCtrl_t UsbEp0Ctrl; 
UsbSetupPacket_t UsbEp0SetupPacket; 
 
#pragma data_alignment=4 
Int8U EpCtrlDataBuf[Ep0MaxSize]; 
UsbDevCtrl_t UsbDevCtrl = {{UsbDevStatusUnknow,UsbDevStatusNoSuspend},0,0,0,0}; 
 
// User funcrions 
CommUserFpnt_t UsbCoreUserFun[UsbUserLastInd] = 
{ 
  // UsbUserClass 
  NULL, 
  // UsbUserVendor 
  NULL, 
  // UsbClassEp0OutPacket 
  NULL, 
  // UsbVendorEp0OutPacket 
  NULL, 
  // UsbUserConfigure 
  NULL, 
  // UsbUserReset 
  NULL, 
  // UsbUserConnect 
  NULL, 
  // UsbUserSuspend 
  NULL, 
}; 
 
/************************************************************************* 
 * Function Name: UsbCoreInit 
 * Parameters:  CommUserFpnt_t UserCoreConfigure 
 * 
 * Return: none 
 * 
 * Description: USB init core 
 * 
 *************************************************************************/ 
void UsbCoreInit (CommUserFpnt_t UserCoreConfigure) 
{ 
  UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket; 
  UserCoreConfigure(NULL); 
  UsbCoreUserFuncRegistered(UserCoreConfigure,UsbUserConfigure); 
  UsbSetDevState(UsbDevStatusUnknow); 
  // Registerd Core functions 
  USB_UserFuncRegistered(UsbDevResetCallback  ,UsbResetEvent  ); 
  USB_UserFuncRegistered(UsbDevConnectCallback,UsbConnectEvent); 
  USB_UserFuncRegistered(UsbDevSuspendCallback,UsbSuspendEvent); 
  USB_UserFuncRegistered(UsbCtrlEpCallback    ,UsbEp0Out      ); 
  USB_UserFuncRegistered(UsbCtrlEpCallback    ,UsbEp0In       ); 
} 
 
/************************************************************************* 
 * Function Name: UsbCoreUserFuncRegistered 
 * Parameters: CommUserFpnt_t UserFunc, UsbCoreUserFuncInd_t UserFuncInd 
 * 
 * Return: CommUserFpnt_t 
 * 
 * Description: Registed User core callback function 
 * 
 *************************************************************************/ 
CommUserFpnt_t UsbCoreUserFuncRegistered (CommUserFpnt_t UserCoreFunc, 
                                          UsbCoreUserFuncInd_t UserFuncInd) 
{ 
CommUserFpnt_t PrevUserFunc = UsbCoreUserFun[UserFuncInd]; 
  UsbCoreUserFun[UserFuncInd] = UserCoreFunc; 
  return(PrevUserFunc); 
} 
 
/************************************************************************* 
 * Function Name: UsbCoreReq 
 * Parameters:  UsbCoreReqType_t Type 
 * 
 * Return: Int32U 
 * 
 * Description: Return different device states 
 * 
 *************************************************************************/ 
Int32U UsbCoreReq (UsbCoreReqType_t Type) 
{ 
  switch(Type) 
  { 
  case UsbCoreReqDevState: 
    return(UsbDevCtrl.State.DS); 
  case UsbCoreReqDevSusState: 
    return(UsbDevCtrl.State.Suspend); 
  case UsbCoreReqConfiquration: 
    return(UsbDevCtrl.Configuration); 
  case UsbCoreReqInterface: 
    return(UsbDevCtrl.Interface); 
  case UsbCoreReqAlternateSetting: 
    return(UsbDevCtrl.AlternateSetting); 
  case UsbCoreReqDevOwnAddress: 
    return(UsbDevCtrl.DevAdd); 
  case UsbCoreReqWakeUpEnableStatus: 
    return(UsbDevCtrl.Feature.RemoteWakeupEnable); 
  case UsbCoreReqSelfPoweredStatus: 
    return(UsbDevCtrl.Feature.SelfPowered); 
  } 
  return((Int32U) -1); 
} 
 
/************************************************************************* 
 * Function Name: UsbWakeUp 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: WakeUp device from suspend mode 
 * 
 *************************************************************************/ 
void UsbWakeUp (void) 
{ 
  if(UsbDevCtrl.Feature.RemoteWakeupEnable && UsbDevCtrl.State.Suspend) 
  { 
    USB_WakeUp(); 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbSetDevState 
 * Parameters:  _UsbDevState_t DevState 
 * 
 * Return: none 
 * 
 * Description: Set device state 
 * 
 *************************************************************************/ 
void UsbSetDevState (_UsbDevState_t DevState) 
{ 
  UsbDevCtrl.State.DS = DevState; 
  switch (DevState) 
  { 
  case UsbDevStatusConfigured: 
    USB_Configure(TRUE); 
    break; 
  case UsbDevStatusAddress: 
    UsbDevCtrl.Configuration = UsbDevCtrl.AlternateSetting =\ 
    UsbDevCtrl.Interface = 0; 
    USB_Configure(FALSE); 
    break; 
  default: 
    UsbDevCtrl.DevAdd = UsbDevCtrl.Configuration = \ 
    UsbDevCtrl.AlternateSetting = UsbDevCtrl.Interface = 0; 
    USB_Configure(FALSE); 
 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbGetDevState 
 * Parameters:  none 
 * 
 * Return: UsbDevState_t 
 * 
 * Description: Get device state 
 * 
 *************************************************************************/ 
UsbDevState_t UsbGetDevState (void) 
{ 
  return(UsbDevCtrl.State); 
} 
 
/************************************************************************* 
 * Function Name: UsbSetDevSuspend 
 * Parameters:  none 
 * 
 * Return: UsbDevState_t 
 * 
 * Description: Set device suspend mode 
 * 
 *************************************************************************/ 
void UsbSetDevSuspend (Boolean Suspend) 
{ 
  UsbDevCtrl.State.Suspend = Suspend ? UsbDevStatusSuspend : UsbDevStatusNoSuspend; 
} 
 
/************************************************************************* 
 * Function Name: UsbFindInterface 
 * Parameters:  UsbStandardConfigurationDescriptor_t * pConfiguration 
 *              Int32U Interface,Int32U AlternativeSetting 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: Set Interface and  Alternative setting state 
 * 
 *************************************************************************/ 
UsbCommStatus_t UsbFindInterface (UsbStandardConfigurationDescriptor_t * pConfiguration, 
                                  UsbDevCtrl_t * UsbDev) 
{ 
UsbStandardInterfaceDescriptor_t *pData; 
  // Find Interface 
  for(pData = (UsbStandardInterfaceDescriptor_t *)pConfiguration; 
      (Int8U*)pData < (Int8U *)pConfiguration + pConfiguration->wTotalLength; 
      pData =(UsbStandardInterfaceDescriptor_t *)((Int8U *)pData + pData->bLength)) 
  { 
    if((pData->bDescriptorType == UsbDescriptorInterface) && 
       (pData->bInterfaceNumber == UsbDev->Interface) && 
       (pData->bAlternateSetting == UsbDev->AlternateSetting)) 
    { 
      return(UsbPass); 
    } 
  } 
  return(UsbFault); 
} 
 
/************************************************************************* 
 * Function Name: UsbFindConfiguration 
 * Parameters:  Int32U 
 * 
 * Return: UsbStandardConfigurationDescriptor_t * 
 * 
 * Description: Return pointer to current configuration 
 * 
 *************************************************************************/ 
UsbStandardConfigurationDescriptor_t * UsbFindConfiguration(Int32U Configuration) 
{ 
UsbStandardConfigurationDescriptor_t * pData = 
 (UsbStandardConfigurationDescriptor_t *) &UsbStandardConfigurationDescriptor[0]; 
  while(pData->bLength) 
  { 
    if(pData->bDescriptorType == UsbDescriptorConfiguration) 
    { 
      if(pData->bConfigurationValue == Configuration) 
      { 
         return(pData); 
      } 
    } 
    pData = (UsbStandardConfigurationDescriptor_t *)((Int8U *)pData + pData->bLength); 
  } 
  return(NULL); 
} 
 
/************************************************************************* 
 * Function Name: UsbDevConnectCallback 
 * Parameters:  void * pArg 
 * 
 * Return: none 
 * 
 * Description: USB connect callback 
 * 
 *************************************************************************/ 
void UsbDevConnectCallback (void * pArg) 
{ 
  UsbSetDevState(pArg?UsbDevStatusAttached:UsbDevStatusUnknow); 
  if(UsbCoreUserFun[UsbUserConnect] != NULL) 
  { 
    UsbCoreUserFun[UsbUserConnect](pArg); 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbDevSuspendCallback 
 * Parameters:  void * pArg 
 * 
 * Return: none 
 * 
 * Description: USB suspend callback 
 * 
 *************************************************************************/ 
void UsbDevSuspendCallback (void * pArg) 
{ 
  UsbSetDevSuspend(pArg?UsbDevStatusSuspend:UsbDevStatusNoSuspend); 
  if(UsbCoreUserFun[UsbUserSuspend] != NULL) 
  { 
    UsbCoreUserFun[UsbUserSuspend](pArg); 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbDevResetCallback 
 * Parameters:  void * pArg 
 * 
 * Return: none 
 * 
 * Description: USB reset callback 
 * 
 *************************************************************************/ 
void UsbDevResetCallback (void * pArg) 
{ 
  UsbSetDevState(UsbDevStatusDefault); 
  UsbCoreUserFun[UsbUserConfigure](NULL); 
 
  if(UsbCoreUserFun[UsbUserReset] != NULL) 
  { 
    UsbCoreUserFun[UsbUserReset](pArg); 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbEp0SetupWrite 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB EP Write implement (IN) 
 * 
 *************************************************************************/ 
void UsbEp0SetupWrite (void) 
{ 
Int32U CurrCount = Ep0MaxSize; 
  if((UsbEp0Ctrl.Counter == Ep0MaxSize) && UsbEp0Ctrl.EpStatus.NoZeroLength) 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpSetupLastIn; 
  } 
  else if(UsbEp0Ctrl.Counter < Ep0MaxSize) 
  { 
    CurrCount = UsbEp0Ctrl.Counter; 
    UsbEp0Ctrl.EpStatus.Status = UsbEpSetupLastIn; 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpSetupDataIn; 
  } 
 
  USB_EpWrite(CTRL_ENP_IN,(Int32U *)UsbEp0Ctrl.pData,CurrCount); 
  UsbEp0Ctrl.Counter -= CurrCount; 
  UsbEp0Ctrl.pData += CurrCount; 
} 
 
/************************************************************************* 
 * Function Name: UsbSetConfigurtonState 
 * Parameters:  Int32U 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: Set configuration state 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbSetConfigurtonState (Int32U Configuration) 
{ 
  if(Configuration) 
  { 
    // Find configuration 
    UsbStandardConfigurationDescriptor_t * pData = UsbFindConfiguration(Configuration); 
    UsbDevCtrl_t UsbDevCtrlNew = UsbDevCtrl; 
 
    if(pData == NULL) 
    { 
      return(UsbFault); 
    } 
    // Set Interfce and Alternative Setting 
    UsbDevCtrlNew.Configuration = Configuration; 
    UsbDevCtrlNew.Interface = UsbDevCtrlNew.AlternateSetting = 0; 
    UsbDevCtrlNew.Feature.RemoteWakeupEnable = 0; 
    UsbDevCtrlNew.Feature.SelfPowered = pData->bmAttributes.SelfPowered?1:0; 
    // Whether the interface is exist into current conficuration? 
    if(UsbFindInterface(pData,&UsbDevCtrlNew) != UsbPass) 
    { 
      return(UsbFault); 
    } 
    // User function that realize EP and init buffers 
    UsbCoreUserFun[UsbUserConfigure]((void *)&UsbDevCtrlNew); 
    UsbDevCtrl = UsbDevCtrlNew; 
    UsbSetDevState(UsbDevStatusConfigured); 
  } 
  else 
  { 
    UsbCoreUserFun[UsbUserConfigure](NULL); 
    UsbSetDevState(UsbDevStatusAddress); 
  } 
  return(UsbPass); 
} 
 
/************************************************************************* 
 * Function Name: UsbDevStatus 
 * Parameters:  Int8U * pData, Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: Usb Return device status into pData 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbDevStatus(Int8U * pData, Int16U Index) 
{ 
  if(Index == 0) 
  { 
    UsbEp0Ctrl.pData = pData; 
    UsbEp0Ctrl.Counter = 2; 
    *pData++ = UsbDevCtrl.Feature.Data; 
    *pData   = 0; 
    return(UsbPass); 
  } 
  return(UsbFault); 
} 
 
/************************************************************************* 
 * Function Name: UsbInterfaceStatus 
 * Parameters:  Int8U * pData, Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: Usb Return interface status into pData 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbInterfaceStatus(Int8U * pData, Int16U Index) 
{ 
  UsbEp0Ctrl.pData = pData; 
  UsbEp0Ctrl.Counter = 2; 
  *pData++ = 0; 
  *pData   = 0; 
  return(UsbPass); 
} 
 
/************************************************************************* 
 * Function Name: UsbEpStatus 
 * Parameters:  Int8U * pData, Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: Usb Return Ep status into pData 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbEpStatus(Int8U * pData, Int16U Index) 
{ 
  if((Index & 0x7F) > 16) 
  { 
    return(UsbFault); 
  } 
  UsbEp0Ctrl.pData = pData; 
  UsbEp0Ctrl.Counter = 2; 
  *pData++ = USB_GetStallEP(USB_EpLogToPhysAdd(Index)) ? 1:0; 
  *pData = 0; 
  return(UsbPass); 
} 
 
/************************************************************************* 
 * Function Name: UsbGetStatus 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: Usb Get status implement 
 * 
 *************************************************************************/ 
inline 
void UsbGetStatus (void) 
{ 
  if((UsbDevCtrl.State.DS >= UsbDevStatusAddress) && 
     // Length must be 2 
     (UsbEp0SetupPacket.wLength.Word == 2) && 
     // Direction of data from device 
     (UsbEp0SetupPacket.mRequestType.Dir == 1) && 
     // wValue mut be 0 
     (UsbEp0SetupPacket.wValue.Word == 0) ) 
  { 
    // This request is valid only for Address and Configured device's states 
    switch(UsbEp0SetupPacket.mRequestType.Recipient) 
    { 
    case UsbRecipientDevice: 
      if(UsbDevStatus(EpCtrlDataBuf,UsbEp0SetupPacket.wIndex.Word) == UsbPass) 
      { 
        UsbEp0SetupWrite(); 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    case UsbRecipientInterface: 
      if(UsbInterfaceStatus(EpCtrlDataBuf,UsbEp0SetupPacket.wIndex.Word) == UsbPass) 
      { 
        UsbEp0SetupWrite(); 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    case UsbRecipientEndpoint: 
      if(UsbEpStatus(EpCtrlDataBuf,UsbEp0SetupPacket.wIndex.Word) == UsbPass) 
      { 
        UsbEp0SetupWrite(); 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    default: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
    } 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbClearFeature 
 * Parameters:  Int16U Feature,Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB Clear Device feature implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbClearDevFeature(Int16U Feature,Int16U Index) 
{ 
  if((Index != 0) || (Feature != UsbDeviceRemoteWakeupSelector)) 
  { 
    return(UsbFault); 
  } 
  UsbDevCtrl.Feature.RemoteWakeupEnable = 0; 
  return(UsbPass); 
} 
/************************************************************************* 
 * Function Name: UsbClearInterfaceFeature 
 * Parameters:  Int16U Feature,Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB Clear Interface feature implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbClearInterfaceFeature(Int16U Feature,Int16U Index) 
{ 
  return(UsbFault); 
} 
 
/************************************************************************* 
 * Function Name: UsbClearEpFeature 
 * Parameters:  Int16U Feature,Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB Clear Ep feature implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbClearEpFeature(Int16U Feature,Int16U Index) 
{ 
USB_Endpoint_t UsbEpAdd; 
  if(((Index & 0x7F) > 16) || (Feature != UsbEpHaltSelector)) 
  { 
    return(UsbFault); 
  } 
  UsbEpAdd = USB_EpLogToPhysAdd(Index); 
  USB_SetStallEP(UsbEpAdd,FALSE); 
  if (UsbUserFun[UsbEpAdd] != NULL) 
  { 
    UsbUserFun[UsbEpAdd]((void *)UsbEpUnstall); 
  } 
  return(UsbPass); 
} 
 
/************************************************************************* 
 * Function Name: UsbClearFeature 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB Clear feature implement 
 * 
 *************************************************************************/ 
inline 
void UsbClearFeature (void) 
{ 
  if((UsbDevCtrl.State.DS >= UsbDevStatusAddress) && 
     // Length must be 0 
     (UsbEp0SetupPacket.wLength.Word == 0)) 
  { 
    switch(UsbEp0SetupPacket.mRequestType.Recipient) 
    { 
    case UsbRecipientDevice: 
      if(UsbClearDevFeature(UsbEp0SetupPacket.wValue.Word,UsbEp0SetupPacket.wIndex.Word) == UsbPass) 
      { 
        USB_EpWrite(CTRL_ENP_IN,NULL,0); 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    case UsbRecipientInterface: 
      if((UsbDevCtrl.State.DS > UsbDevStatusAddress) && 
         (UsbClearInterfaceFeature(UsbEp0SetupPacket.wValue.Word,UsbEp0SetupPacket.wIndex.Word) == UsbPass)) 
      { 
        USB_EpWrite(CTRL_ENP_IN,NULL,0); 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    case UsbRecipientEndpoint: 
      if(((UsbDevCtrl.State.DS > UsbDevStatusAddress) || ((UsbEp0SetupPacket.wIndex.Word & 0x7F) == 0)) && 
         (UsbClearEpFeature(UsbEp0SetupPacket.wValue.Word,UsbEp0SetupPacket.wIndex.Word) == UsbPass)) 
      { 
        USB_EpWrite(CTRL_ENP_IN,NULL,0); 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    default: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
    } 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbSetFeature 
 * Parameters:  Int16U Feature,Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB Set Device feature implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbSetDevFeature(Int16U Feature,Int16U Index) 
{ 
  if((Index != 0) || (Feature != UsbDeviceRemoteWakeupSelector)) 
  { 
    return(UsbFault); 
  } 
  UsbDevCtrl.Feature.RemoteWakeupEnable = 1; 
  return(UsbPass); 
} 
/************************************************************************* 
 * Function Name: UsbSetInterfaceFeature 
 * Parameters:  Int16U Feature,Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB Set Interface feature implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbSetInterfaceFeature(Int16U Feature,Int16U Index) 
{ 
  return(UsbFault); 
} 
 
/************************************************************************* 
 * Function Name: UsbSetEpFeature 
 * Parameters:  Int16U Feature,Int16U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB Set Ep feature implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbSetEpFeature(Int16U Feature,Int16U Index) 
{ 
USB_Endpoint_t UsbEpAdd; 
  if(((Index & 0x7F) > 16) || (Feature != UsbEpHaltSelector)) 
  { 
    return(UsbFault); 
  } 
  UsbEpAdd = USB_EpLogToPhysAdd(Index); 
  USB_SetStallEP(UsbEpAdd,TRUE); 
  if (UsbUserFun[UsbEpAdd] != NULL) 
  { 
    UsbUserFun[UsbEpAdd]((void *)UsbEpStall); 
  } 
  return(UsbPass); 
} 
 
/************************************************************************* 
 * Function Name: UsbSetFeature 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB Set feature implement 
 * 
 *************************************************************************/ 
inline 
void UsbSetFeature (void) 
{ 
  if((UsbDevCtrl.State.DS >= UsbDevStatusAddress) && 
     // Length must be 0 
     (UsbEp0SetupPacket.wLength.Word == 0)) 
  { 
    switch(UsbEp0SetupPacket.mRequestType.Recipient) 
    { 
    case UsbRecipientDevice: 
      if(UsbSetDevFeature(UsbEp0SetupPacket.wValue.Word,UsbEp0SetupPacket.wIndex.Word) == UsbPass) 
      { 
        USB_EpWrite(CTRL_ENP_IN,NULL,0); 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    case UsbRecipientInterface: 
      if((UsbDevCtrl.State.DS > UsbDevStatusAddress) && 
         (UsbSetInterfaceFeature(UsbEp0SetupPacket.wValue.Word,UsbEp0SetupPacket.wIndex.Word) == UsbPass)) 
      { 
        USB_EpWrite(CTRL_ENP_IN,NULL,0); 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    case UsbRecipientEndpoint: 
      if(((UsbDevCtrl.State.DS > UsbDevStatusAddress) || ((UsbEp0SetupPacket.wIndex.Lo & 0x7F) == 0)) && 
         (UsbSetEpFeature(UsbEp0SetupPacket.wValue.Word,UsbEp0SetupPacket.wIndex.Word) == UsbPass)) 
      { 
        USB_EpWrite(CTRL_ENP_IN,NULL,0); 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    default: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
    } 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbSetAddress 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB Set address request implement 
 * 
 *************************************************************************/ 
inline 
void UsbSetAddress (void) 
{ 
  if((UsbDevCtrl.State.DS >= UsbDevStatusDefault) && 
     (UsbEp0SetupPacket.mRequestType.Recipient == 0) && 
     (UsbEp0SetupPacket.wIndex.Word  == 0) && 
     (UsbEp0SetupPacket.wLength.Word == 0) && 
     (UsbEp0SetupPacket.wValue.Word < 128)) 
  { 
    USB_EpWrite(CTRL_ENP_IN,NULL,0); 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStatusInSetAdd; 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbGetDescriptorDevice 
 * Parameters:  Int8U Index - must be 0 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB get device's descriptor request implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbGetDescriptorDevice(Int8U Index) 
{ 
  if(Index == 0) 
  { 
    UsbEp0Ctrl.Counter = UsbStandardDeviceDescriptorStr.bLength; 
    UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE; 
    if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word) 
    { 
      UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word; 
      UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE; 
    } 
    UsbEp0Ctrl.pData = (Int8U *)&UsbStandardDeviceDescriptorStr; 
    UsbEp0SetupWrite(); 
    return(UsbPass); 
  } 
  return(UsbFault); 
} 
 
/************************************************************************* 
 * Function Name: UsbGetDescriptorConfiguration 
 * Parameters:  Int8U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB get configuration's descriptor request implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbGetDescriptorConfiguration(Int8U Index) 
{ 
UsbStandardConfigurationDescriptor_t *pData; 
  for(pData = (UsbStandardConfigurationDescriptor_t *)UsbStandardConfigurationDescriptor; 
      pData->bLength; 
      pData=(UsbStandardConfigurationDescriptor_t*)((Int8U *)pData + pData->bLength)) 
  { 
    if((pData->bDescriptorType == UsbDescriptorConfiguration) && 
       ((UsbStandardDeviceDescriptorStr.bNumConfigurations == 1) || 
       (pData->bConfigurationValue == Index))) 
    { 
      break; 
    } 
  } 
  if(pData->bLength == 0) 
  { 
     return(UsbFault); 
  } 
  UsbEp0Ctrl.Counter = ((UsbStandardConfigurationDescriptor_t*)pData)->wTotalLength; 
  UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE; 
  if(UsbEp0Ctrl.Counter > UsbEp0SetupPacket.wLength.Word) 
  { 
    UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word; 
    UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE; 
  } 
  UsbEp0Ctrl.pData = (Int8U *)pData; 
  UsbEp0SetupWrite(); 
  return(UsbPass); 
} 
 
/************************************************************************* 
 * Function Name: UsbGetDescriptorString 
 * Parameters:  Int8U Index 
 * 
 * Return: UsbCommStatus_t 
 * 
 * Description: USB get string's descriptor request implement 
 * 
 *************************************************************************/ 
inline 
UsbCommStatus_t UsbGetDescriptorString(Int8U Index) 
{ 
Int8U **pData; 
Int32U i; 
  if(Index == 0) 
  { 
    UsbEp0Ctrl.Counter = UsbLanguagesStr[UsbDescLengthOffset]; 
    UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE; 
    if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word) 
    { 
      UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word; 
      UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE; 
    } 
    UsbEp0Ctrl.pData = (Int8U *)&UsbLanguagesStr; 
    UsbEp0SetupWrite(); 
    return(UsbPass); 
  } 
  else 
  { 
    Int32U LanguagesOffset = 0; 
    // Find Languages index 
    for(i = 2; i < UsbLanguagesStr[UsbDescLengthOffset]; i+=2) 
    { 
      if((UsbLanguagesStr[i] == UsbEp0SetupPacket.wIndex.Lo) && 
         (UsbLanguagesStr[i+1] == UsbEp0SetupPacket.wIndex.Hi)) 
      { 
        break; 
      } 
      ++LanguagesOffset; 
    } 
    if(i >= UsbLanguagesStr[UsbDescLengthOffset]) 
    { 
      return(UsbFault); 
    } 
    // Find String index 
    for(pData = (Int8U **)UsbString[LanguagesOffset]; pData ; ++pData) 
    { 
      if(--Index == 0) 
      { 
        break; 
      } 
    } 
    if(pData == NULL) 
    { 
      return(UsbFault); 
    } 
    UsbEp0Ctrl.Counter = *(*pData+UsbDescLengthOffset); 
    UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE; 
    if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word) 
    { 
      UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word; 
      UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE; 
    } 
    UsbEp0Ctrl.pData = *pData; 
    UsbEp0SetupWrite(); 
  } 
  return(UsbPass); 
} 
 
/************************************************************************* 
 * Function Name: UsbGetDescriptor 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB get descriptor request implement 
 * 
 *************************************************************************/ 
inline 
void UsbGetDescriptor (void) 
{ 
    if(UsbDevCtrl.State.DS >= UsbDevStatusDefault) 
    { 
      switch(UsbEp0SetupPacket.wValue.Hi) 
      { 
      case UsbDescriptorDevice: 
        if(UsbGetDescriptorDevice(UsbEp0SetupPacket.wValue.Lo) != UsbPass) 
        { 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
        break; 
      case UsbDescriptorConfiguration: 
        if(UsbGetDescriptorConfiguration(UsbEp0SetupPacket.wValue.Lo) != UsbPass) 
        { 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
        break; 
      case UsbDescriptorString: 
        if(UsbGetDescriptorString(UsbEp0SetupPacket.wValue.Lo) != UsbPass) 
        { 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
        break; 
      default: 
        if ((UsbCoreUserFun[UsbUserGetDescriptor] == NULL) || 
            ((Int32U)UsbCoreUserFun[UsbUserGetDescriptor](&UsbEp0Ctrl) != UsbPass)) 
        { 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
      } 
    } 
    else 
    { 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
    } 
} 
 
/************************************************************************* 
 * Function Name: UsbSetDescriptor 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB Set descriptor 
 * 
 *************************************************************************/ 
inline 
void UsbSetDescriptor(void) 
{ 
  if(UsbDevCtrl.State.DS >= UsbDevStatusAddress) 
  { 
    // This request is valid only for Address state and Configured state. 
    // If supported 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbGetConfiguration 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB Get configuration implement 
 * 
 *************************************************************************/ 
inline 
void UsbGetConfiguration(void) 
{ 
  if((UsbDevCtrl.State.DS >= UsbDevStatusAddress) && 
     (UsbEp0SetupPacket.wValue.Word == 0) && 
     (UsbEp0SetupPacket.wIndex.Word == 0) && 
     (UsbEp0SetupPacket.wLength.Word == 1)) 
  { 
    UsbEp0Ctrl.Counter = 1; 
    EpCtrlDataBuf[0] = UsbCoreReq(UsbCoreReqConfiquration); 
    UsbEp0Ctrl.pData = EpCtrlDataBuf; 
    UsbEp0SetupWrite(); 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbSetConfiguration 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: USB Set configuration implement 
 * 
 *************************************************************************/ 
inline 
void UsbSetConfiguration(void) 
{ 
  if((UsbDevCtrl.State.DS >= UsbDevStatusAddress) && 
     (UsbEp0SetupPacket.wIndex.Word == 0) && 
     (UsbEp0SetupPacket.wLength.Word == 0) && 
     (UsbSetConfigurtonState(UsbEp0SetupPacket.wValue.Lo) == UsbPass)) 
  { 
    USB_EpWrite(CTRL_ENP_IN,NULL,0); 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbGetInterface 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: Implement get interface request 
 * 
 *************************************************************************/ 
inline 
void UsbGetInterface (void) 
{ 
  if((UsbDevCtrl.State.DS == UsbDevStatusConfigured) && 
     (UsbEp0SetupPacket.wIndex.Word == UsbDevCtrl.Interface) && 
     (UsbEp0SetupPacket.wLength.Word == 1) && 
     (UsbEp0SetupPacket.wValue.Word == 0)) 
  { 
    UsbEp0Ctrl.Counter = 1; 
    EpCtrlDataBuf[0] = UsbDevCtrl.AlternateSetting; 
    UsbEp0Ctrl.pData = EpCtrlDataBuf; 
    UsbEp0SetupWrite(); 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbSetInterface 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: Implement set interface request 
 * 
 *************************************************************************/ 
inline 
void UsbSetInterface (void) 
{ 
  if((UsbDevCtrl.State.DS == UsbDevStatusConfigured) && 
     (UsbEp0SetupPacket.wLength.Word == 0)) 
  { 
    UsbStandardConfigurationDescriptor_t * pData = UsbFindConfiguration(UsbDevCtrl.Configuration); 
    UsbDevCtrl_t UsbDevCtrlNew = UsbDevCtrl; 
 
    UsbDevCtrlNew.Interface = UsbEp0SetupPacket.wIndex.Word; 
    UsbDevCtrlNew.AlternateSetting = UsbEp0SetupPacket.wValue.Word; 
    UsbDevCtrlNew.Feature.RemoteWakeupEnable = 0; 
 
    // Whether the interface is exist into current conficuration? 
    if(UsbFindInterface(pData,&UsbDevCtrlNew) != UsbPass) 
    { 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      return; 
    } 
 
    UsbCoreUserFun[UsbUserConfigure]((void *)&UsbDevCtrlNew); 
    UsbDevCtrl = UsbDevCtrlNew; 
 
    USB_EpWrite(CTRL_ENP_IN,NULL,0); 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbSynchFrame 
 * Parameters:  none 
 * 
 * Return: none 
 * 
 * Description: Implement synch frame request 
 * 
 *************************************************************************/ 
inline 
void UsbSynchFrame (void) 
{ 
  if( USB_SOF_EVENT && 
     (UsbDevCtrl.State.DS == UsbDevStatusConfigured) && 
     (UsbEp0SetupPacket.wLength.Word == 2) && 
     (UsbEp0SetupPacket.wValue.Word == 0)) 
  { 
  Int32U FrameNumb = 0; 
  #if USB_SOF_EVENT > 0 
    FrameNumb = USB_GetFrameNumb(); 
  #endif 
    UsbEp0Ctrl.Counter = 2; 
    EpCtrlDataBuf[0]   = FrameNumb; 
    EpCtrlDataBuf[1]   = FrameNumb>>8; 
    UsbEp0Ctrl.pData   = EpCtrlDataBuf; 
    UsbEp0SetupWrite(); 
  } 
  else 
  { 
    UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
  } 
} 
 
/************************************************************************* 
 * Function Name: UsbCtrlEpCallback 
 * Parameters:  void * pArg 
 * 
 * Return: none 
 * 
 * Description: USB Ctrl EP Callback 
 * 
 *************************************************************************/ 
void UsbCtrlEpCallback (void * pArg) 
{ 
Int32U PacketSize; 
 
  switch((Int32U)pArg) 
  { 
  case UsbSetupPacket: 
setup_packet_overwrited: 
    UsbEp0Ctrl.pData   = EpCtrlDataBuf; 
    UsbEp0Ctrl.Counter = USB_EpRead(CTRL_ENP_OUT,(Int32U *)EpCtrlDataBuf,Ep0MaxSize); 
    if(UsbEp0Ctrl.EpStatus.Status != UsbEpPause) 
    { 
      // Copy new setup packet int setup buffer 
      memcpy((Int8U *)&UsbEp0SetupPacket,EpCtrlDataBuf,sizeof(UsbEp0SetupPacket)); 
    } 
    switch(UsbEp0SetupPacket.mRequestType.Type) 
    { 
    // Standart 
    case UsbTypeStandart: 
      // Decoding standart request 
      switch (UsbEp0SetupPacket.bRequest) 
      { 
      case GET_STATUS: 
        UsbGetStatus(); 
        break; 
      case CLEAR_FEATURE: 
        UsbClearFeature(); 
        break; 
      case SET_FEATURE: 
        UsbSetFeature(); 
        break; 
      case SET_ADDRESS: 
        UsbSetAddress(); 
        break; 
      case GET_DESCRIPTOR: 
        if(UsbEp0SetupPacket.mRequestType.Recipient == UsbRecipientDevice) 
        { 
          UsbGetDescriptor(); 
        } 
        // Only get descriptof for device is standart request 
        else if ((UsbCoreUserFun[UsbUserGetDescriptor] != NULL) && 
                 ((Int32U)UsbCoreUserFun[UsbUserGetDescriptor](&UsbEp0Ctrl) == UsbUserSendPacket)) 
        { 
          if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word) 
          { 
            UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word; 
            UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE; 
          } 
          else 
          { 
             UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE; 
          } 
          UsbEp0SetupWrite(); 
        } 
        else 
        { 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
        break; 
      case SET_DESCRIPTOR: 
        // Optional (only for configuration and string descriptors) 
        UsbSetDescriptor(); 
        break; 
      case GET_CONFIGURATION: 
        UsbGetConfiguration(); 
        break; 
      case SET_CONFIGURATION: 
        UsbSetConfiguration(); 
        break; 
      case GET_INTERFACE: 
        UsbGetInterface(); 
        break; 
      case SET_INTERFACE: 
        UsbSetInterface(); 
        break; 
      case SYNCH_FRAME: 
        UsbSynchFrame(); 
        break; 
      default: 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    // Class 
    case UsbTypeClass: 
      if(UsbCoreUserFun[UsbUserClass] != NULL) 
      { 
        switch((Int32U)UsbCoreUserFun[UsbUserClass](&UsbEp0Ctrl)) 
        { 
        case UsbUserNone: 
          break; 
        case UsbUserSendPacket: 
          if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word) 
          { 
            UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word; 
            UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE; 
          } 
          else 
          { 
            UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE; 
          } 
          UsbEp0SetupWrite(); 
          break; 
        case UsbUserReceivePacket: 
          if((UsbEp0Ctrl.Counter == UsbEp0SetupPacket.wLength.Word) && 
             (UsbCoreUserFun[UsbClassEp0OutPacket] != NULL)) 
          { 
            UsbEp0Ctrl.EpStatus.Status = UsbEpClassDataOut; 
          } 
          else 
          { 
            UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
          } 
          break; 
        case UsbUserSendAckn: 
          USB_EpWrite(CTRL_ENP_IN,NULL,0); 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
          break; 
        default : 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    // Vendor 
    case UsbTypeVendor: 
      if(UsbCoreUserFun[UsbUserVendor] != NULL) 
      { 
        switch((Int32U)UsbCoreUserFun[UsbUserClass](&UsbEp0Ctrl)) 
        { 
        case UsbUserNone: 
          break; 
        case UsbUserSendPacket: 
          if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word) 
          { 
            UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word; 
            UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE; 
          } 
          else 
          { 
            UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE; 
          } 
          UsbEp0SetupWrite(); 
          break; 
        case UsbUserReceivePacket: 
          if((UsbEp0Ctrl.Counter == UsbEp0SetupPacket.wLength.Word) && 
             (UsbCoreUserFun[UsbVendorEp0OutPacket] != NULL)) 
          { 
            UsbEp0Ctrl.EpStatus.Status = UsbEpVendorDataOut; 
          } 
          else 
          { 
            UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
          } 
          break; 
        case UsbUserSendAckn: 
          USB_EpWrite(CTRL_ENP_IN,NULL,0); 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
          break; 
        default : 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
      } 
      else 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    // Other 
    default: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
    } 
    break; 
  // Out Packet 
  case UsbDataOutPacket: 
    switch(UsbEp0Ctrl.EpStatus.Status) 
    { 
    case UsbEpSetupDataIn: 
    case UsbEpSetupLastIn: 
      // Clear output ep buffer 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStatusOut; 
      UsbEp0Ctrl.Counter = USB_EpRead(CTRL_ENP_OUT,(Int32U *)EpCtrlDataBuf,Ep0MaxSize); 
      if (UsbEp0Ctrl.Counter & 0x80000000) 
      { 
         goto setup_packet_overwrited; 
      } 
      break; 
    case UsbEpWaitStatusOut: 
      // Clear output ep buffer 
      UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket; 
      UsbEp0Ctrl.Counter = USB_EpRead(CTRL_ENP_OUT,(Int32U *)EpCtrlDataBuf,Ep0MaxSize); 
      if (UsbEp0Ctrl.Counter & 0x80000000) 
      { 
         goto setup_packet_overwrited; 
      } 
      break; 
    case UsbEpSetupDataOut: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      break; 
    case UsbEpClassDataOut: 
      PacketSize = USB_EpRead(CTRL_ENP_OUT,(Int32U *)UsbEp0Ctrl.pData,Ep0MaxSize); 
      if (UsbEp0Ctrl.Counter & 0x80000000) 
      { 
         goto setup_packet_overwrited; 
      } 
      UsbEp0Ctrl.pData += PacketSize; 
      UsbEp0Ctrl.Counter -= PacketSize; 
      if(UsbEp0Ctrl.Counter == 0) 
      { 
        switch((Int32U)UsbCoreUserFun[UsbClassEp0OutPacket](NULL)) 
        { 
        case UsbUserNone: 
          UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket; 
          break; 
        case UsbUserSendAckn: 
          USB_EpWrite(CTRL_ENP_IN,NULL,0); 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
          break; 
        default: 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
      } 
      else if (PacketSize != Ep0MaxSize) 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    case UsbEpVendorDataOut: 
      PacketSize = USB_EpRead(CTRL_ENP_OUT,(Int32U *)UsbEp0Ctrl.pData,Ep0MaxSize); 
      if (UsbEp0Ctrl.Counter & 0x80000000) 
      { 
         goto setup_packet_overwrited; 
      } 
      UsbEp0Ctrl.pData += PacketSize; 
      UsbEp0Ctrl.Counter -= PacketSize; 
      if(UsbEp0Ctrl.Counter == 0) 
      { 
        switch((Int32U)UsbCoreUserFun[UsbVendorEp0OutPacket](NULL)) 
        { 
        case UsbUserNone: 
          UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket; 
          break; 
        case UsbUserSendAckn: 
          USB_EpWrite(CTRL_ENP_IN,NULL,0); 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStatusIn; 
          break; 
        default: 
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
        } 
      } 
      else if (PacketSize != Ep0MaxSize) 
      { 
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
      } 
      break; 
    default: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
    } 
    break; 
  // In Packet 
  case UsbDataInPacket: 
    switch(UsbEp0Ctrl.EpStatus.Status) 
    { 
    case UsbEpStatusOut: 
    case UsbEpWaitStatusIn: 
    case UsbEpStatusIn: 
      UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket; 
      break; 
    case UsbEpSetupDataIn: 
      UsbEp0SetupWrite(); 
      break; 
    case UsbEpSetupLastIn: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpWaitStatusOut; 
      break; 
    case UsbEpStatusInSetAdd: 
      USB_SetAdd(UsbEp0SetupPacket.wValue.Lo); 
      UsbDevCtrl.DevAdd = UsbEp0SetupPacket.wValue.Lo; 
      if(UsbEp0SetupPacket.wValue.Lo) 
      { 
        UsbSetDevState(UsbDevStatusAddress); 
        UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket; 
      } 
      else 
      { 
        UsbSetDevState(UsbDevStatusDefault); 
        UsbCoreUserFun[UsbUserConfigure](NULL); 
      } 
      break; 
    default: 
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall; 
    } 
    break; 
  } 
  if (UsbEp0Ctrl.EpStatus.Status == UsbEpStall) 
  { 
    USB_SetStallEP(CTRL_ENP_OUT,TRUE); 
    USB_SetStallEP(CTRL_ENP_IN ,TRUE); 
    UsbEp0Ctrl.EpStatus.Status = UsbSetupPacket; 
  } 
}