⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_core.c

📁 程序演示了一个USB鼠标的应用。 运行时用USB线连接开发板与PC机
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************** (C) COPYRIGHT 2006 STMicroelectronics ********************
* File Name          : usb_core.c
* Author             : MCD Application Team
* Date First Issued  : 2/6/2006
* Description        : USB protocol state machine functions
********************************************************************************
* History:
* 2/6/2006 :  Beta Version V0.1
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
* CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS
* A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
* OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

#include "USB_lib.h"

#define ValBit(VAR,Place)    (VAR & (1<<Place))
#define SetBit(VAR,Place)    ( VAR |= (1<<Place) )
#define ClrBit(VAR,Place)    ( VAR &= ((1<<Place)^255) )

WORD_BYTE StatusInfo;
#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */
#define StatusInfo1 StatusInfo.bw.bb0
BYTE *Standard_GetStatus(WORD Length);
RESULT Standard_ClearFeature(void);

#define Send0LengthData() { \
  SetEPTxCount(ENDP0, 0); \
  vSetEPTxStatus(EP_TX_VALID);  \
  }

/* cells saving status during interrupt servicing */
WORD SaveRState;
WORD SaveTState;
#define vSetEPRxStatus(st)  (SaveRState = st)
#define vSetEPTxStatus(st)  (SaveTState = st)
#define USB_StatusIn()  Send0LengthData()
#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID)

/*******************************************************************************
* Function Name  : Standard_GetConfiguration
* Description    : This routine is called to Get the configuration value
* Input          : Length
* Output         : None
* Return         : -Return a pointer on Current_Configuration value if
*                  the "Length" is not 0.
*******************************************************************************/
BYTE *Standard_GetConfiguration(WORD Length)
{
  if (Length == 0)
  return (BYTE *)sizeof(pInformation->Current_Configuration);
  return (BYTE *)&pInformation->Current_Configuration;
} /* Standard_GetConfiguration */

/*******************************************************************************
* Function Name  : Standard_SetConfiguration
* Description    : This routine is called to set the configuration value
* Input          : None
* Output         : None
* Return         : Return USB_SUCCESS, if the request is performed
*                  Return UNSUPPORT, if the request is invalid
*******************************************************************************/
RESULT Standard_SetConfiguration(void)
{
  if (pInformation->USBwValue0 <= Device_Table.Total_Configuration
  && pInformation->USBwValue1==0 && pInformation->USBwIndex==0)
  {
    pInformation->Current_Configuration = pInformation->USBwValue0;
    return USB_SUCCESS;
  }
  else
  return UNSUPPORT;
} /* Standard_SetConfiguration */

/*******************************************************************************
* Function Name  : Standard_GetInterface
* Description    : Return the Alternate Setting of the current interface
* Input          : Length
* Output         : None
* Return         : Return a pointer on Current_AlternateSetting value
*                  if length is not 0
*******************************************************************************/
BYTE *Standard_GetInterface(WORD Length)
{
  if (Length == 0)
  return (BYTE *)sizeof(pInformation->Current_AlternateSetting);
  return (BYTE *)&pInformation->Current_AlternateSetting;
} /* Standard_GetInterface */

/*******************************************************************************
* Function Name  : Standard_SetInterface
* Description    : This routine is called to set the interface alternate settings
* Input          : None
* Output         : None
* Return         : USB_SCCESS or UNSUPPORT
*******************************************************************************/
RESULT Standard_SetInterface(void)
{
  DEVICE_INFO   *pInfo = pInformation;
  DEVICE_PROP   *pProp = pProperty;
  RESULT                  Re;

  /*test if the specified Interface and Alternate Setting
  are supported by the application Firmware*/
  Re = (*pProp->Class_Get_Interface_Setting)(pInfo->USBwIndex0,pInfo->USBwValue0);
  if(pInfo->Current_Configuration==0 )
  return UNSUPPORT;
  else
  {
    if (Re!= USB_SUCCESS || pInfo->USBwIndex1!=0 || pInfo->USBwValue1!=0)
    return  UNSUPPORT;
    else if ( Re == USB_SUCCESS)
    {
      pInfo->Current_Interface = pInfo->USBwIndex0;
      pInfo->Current_AlternateSetting = pInfo->USBwValue0;
      return USB_SUCCESS;
    }
    else return  UNSUPPORT;
  }
} /* Standard_SetInterface */


/*******************************************************************************
* Function Name  : Standard_GetStatus
* Description    : GetStatus request processing (device, interface or endpoint)
* Input          : None
* Output         : None
* Return         : pointer on StatusInfo
*******************************************************************************/

BYTE *Standard_GetStatus(WORD Length)
{
  DEVICE_INFO *pInfo = pInformation;
  if (Length == 0)
  return (BYTE *)2;
  StatusInfo.w = 0;
  /* Reset Status Information */
  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
  {
    /*Get Device Status */
    BYTE  Feature = pInfo->Current_Feature;
    if (ValBit(Feature, 5))
    SetBit(StatusInfo0, 1); /* Remote Wakeup enabled */
    if (ValBit(Feature, 7))
    ClrBit(StatusInfo0, 0);  /* Bus-powered */
    else if (ValBit(Feature, 6))
    SetBit(StatusInfo0, 0);  /* Self-powered */
  }
  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))/*Interface Status*/
  return (BYTE *)&StatusInfo;
  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
  {
    /*Get EndPoint Status*/
    BYTE  Related_Endpoint;
    BYTE  wIndex0 = pInfo->USBwIndex0;
    Related_Endpoint = (wIndex0 & 0x0f);
    if (ValBit(wIndex0, 7))
    {
      /* IN endpoint */
      if (_GetTxStallStatus( Related_Endpoint ))
      SetBit(StatusInfo0, 0); /* IN Endpoint stalled */
    }
    else
    {
      /* OUT endpoint */
      if (_GetRxStallStatus( Related_Endpoint ))
      SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */
    }
  }
  else
  return NULL;
  return (BYTE *)&StatusInfo;
} /* Standard_GetStatus */


/*******************************************************************************
* Function Name  : Standard_ClearFeature
* Description    : Clear (or disable) a specific feature (device or endpoint)
* Input          : None
* Output         : None
* Return         : USB_SUCCESS or UNSUPPORT
*******************************************************************************/
RESULT Standard_ClearFeature(void)
{
  DEVICE_INFO *pInfo = pInformation;
  BYTE  Type_Rec = Type_Recipient;
  WORD    Status;
  if ( Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT) )
  {
     if (pInfo->USBwValue !=  DEVICE_REMOTE_WAKEUP)
     return UNSUPPORT;
    /*Device Clear Feature*/
    ClrBit(pInfo->Current_Feature, 5);
    return USB_SUCCESS;
  }
  else if ( Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT) )
  {
    /*EndPoint Clear Feature*/
    DEVICE* pDev;
    BYTE  Related_Endpoint;
    BYTE  wIndex0;
    BYTE  rEP;
    if (pInfo->USBwValue != ENDPOINT_STALL || pInfo->USBwIndex1!=0)
    return UNSUPPORT;
    pDev = &Device_Table;
    wIndex0 = pInfo->USBwIndex0;
    rEP = wIndex0 & ~0x80;
    Related_Endpoint = ENDP0 + rEP;
    if (ValBit(pInfo->USBwIndex0, 7))
    Status =_GetEPTxStatus(Related_Endpoint);
    /*get Status of endpoint & stall the request if the related_ENdpoint is Disabled*/
    else Status =_GetEPRxStatus(Related_Endpoint);
    if (rEP >= pDev->Total_Endpoint || Status==0 || pInfo->Current_Configuration==0)
    return UNSUPPORT;
    if (wIndex0 & 0x80)
    {
      /* IN endpoint */
      if (_GetTxStallStatus(Related_Endpoint ))
      _SetEPTxStatus(Related_Endpoint, EP_TX_NAK);
    }
    else
    {
      /* OUT endpoint */
      if (_GetRxStallStatus(Related_Endpoint))
      {
        if (Related_Endpoint == ENDP0)
        {
          /* After clear the STALL, enable the default endpoint receiver */
          _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
        }
        else
        _SetEPRxStatus(Related_Endpoint, EP_RX_NAK);
      }
    }
    return USB_SUCCESS;
  }
  return UNSUPPORT;
} /* Standard_ClearFeature */


/*******************************************************************************
* Function Name  : Standard_SetEndPointFeature
* Description    : Sets endpoint feature
* Input          : None
* Output         : None
* Return         : USB_SUCCESS or UNSUPPORT
*******************************************************************************/
RESULT Standard_SetEndPointFeature(void)
{
  DEVICE_INFO *pInfo = pInformation;
  BYTE  wIndex0;
  BYTE    Related_Endpoint;
  BYTE  rEP;
  WORD    Status;
  wIndex0 = pInfo->USBwIndex0;
  rEP = wIndex0 & ~0x80;
  Related_Endpoint = ENDP0 + rEP;
  if (ValBit(pInfo->USBwIndex0, 7))
  Status =_GetEPTxStatus(Related_Endpoint);// get Status of endpoint & stall the request if
  //the related_ENdpoint is Disable
  else Status =_GetEPRxStatus(Related_Endpoint);
  if (Related_Endpoint >= Device_Table.Total_Endpoint || pInfo->USBwValue !=0 || Status==0 ||
  pInfo->Current_Configuration==0 /*&& Related_Endpoint!=ENDP0)*/)
  return UNSUPPORT;
  else
  {
    if (wIndex0 & 0x80)
    {
      /* IN endpoint */
      _SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
    }
    else
    {
      /* OUT endpoint */
      _SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
    }
  }
  return USB_SUCCESS;
} /*Standard_SetEndPointFeature */


/*******************************************************************************
* Function Name  : Standard_SetDeviceFeature
* Description    : Set or enable a specific feature of Device
* Input          : None
* Output         : None
* Return         : USB_SUCCESS
*******************************************************************************/
RESULT Standard_SetDeviceFeature(void)
{
      SetBit(pInformation->Current_Feature, 5);
      return USB_SUCCESS;

} /*Standard_SetDeviceFeature */

/*******************************************************************************
* Function Name  : Standard_GetStringDescriptor
* Description    : GetStringDescriptor
* Input          :
* Output         : None
* Return         : Pointer
*******************************************************************************/

BYTE *Standard_GetStringDescriptor(WORD Length, ONE_DESCRIPTOR *pDesc)
{
  int   len, offset, wOffset;
  wOffset = pInformation->Ctrl_Info.Usb_wOffset;
  if (Length == 0)
  {
    offset = 0;
    do
    {
      len = (int)*(pDesc->Descriptor + offset);
      if (wOffset >= 0 && wOffset < len)
      {
        len -= wOffset;
        if (len > 0)
        return (BYTE*)len;
        break;
      }
      wOffset -= len;
      offset += len;
    }
    while (offset < pDesc->Descriptor_Size);
    return 0;
  }
  return pDesc->Descriptor + wOffset;
}/* Standard_GetStringDescriptor */

/*******************************************************************************
* Function Name  : Standard_GetDescriptorData
* Description    : GetDescriptorData
* Input          :
* Output         : None
* Return         : Return pointer on string descriptor if length is not 0
*                  Return string descriptor length if length is 0
*******************************************************************************/

BYTE *Standard_GetDescriptorData(WORD Length, ONE_DESCRIPTOR *pDesc)
{
  int   len, wOffset;
  wOffset = pInformation->Ctrl_Info.Usb_wOffset;
  if (Length == 0)
  {
    len = pDesc->Descriptor_Size - wOffset;
    if (len <= 0)
    return 0;
    return (BYTE *)len;
  }
  return pDesc->Descriptor + wOffset;
} /* Standard_GetDescriptorData */

/*******************************************************************************
* Function Name  : DataStageOut
* Description    : Data OUT stage of a control transfer
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void DataStageOut()
{
  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
  WORD  save_rLength;
  save_rLength = pEPinfo->Usb_rLength;
  if (pEPinfo->CopyData && save_rLength)
  {
    BYTE *Buffer;
    WORD Length;
    WORD wBuffer;
    WORD *Source;
    Length = pEPinfo->PacketSize;
    if (Length > save_rLength)
    Length = save_rLength;
    Buffer = (*pEPinfo->CopyData)(Length);
    pEPinfo->Usb_rLength -= Length;
    pEPinfo->Usb_rOffset += Length;
    Source = (WORD*)(PMAAddr + GetEPRxAddr(ENDP0));
    while (Length)
    {
      wBuffer = *Source;
      Source++;
      *Buffer = wBuffer&0x00FF;
      *(Buffer+1) = ((wBuffer&0xFF00)>>8);
      Buffer++;
      Buffer++;
      Length--;
      if(Length == 0) break; /* odd counter */
      Length--;
    }
  }
  if(pEPinfo->Usb_rLength !=0)
  {
    vSetEPRxStatus(EP_RX_VALID);/* reenable for next data reception */
    SetEPTxCount(ENDP0, 0);
    vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */
  }
  /* Set the next State*/
  if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize)
  pInformation->ControlState = OUT_DATA;
  else
  {
    if (pEPinfo->Usb_rLength >0)
    pInformation->ControlState = LAST_OUT_DATA;
    else if (pEPinfo->Usb_rLength == 0)
    {
      pInformation->ControlState = WAIT_STATUS_IN;
      USB_StatusIn();
    }
  }
} /* DataStageOut */

/*******************************************************************************
* Function Name  : DataStageIn
* Description    : Data IN stage of a Control Transfer
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void DataStageIn(void)
{
  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
  WORD  save_wLength = pEPinfo->Usb_wLength;
  BYTE  ControlState;
  BYTE  *DataBuffer;
  WORD  Length;
  DWORD    tmp;
  int i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -