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

📄 usb_core.c

📁 程序演示了一个USB鼠标的应用。 运行时用USB线连接开发板与PC机
💻 C
📖 第 1 页 / 共 2 页
字号:
  DWORD *pTxBuff;



  if (save_wLength == 0)
  {
    /* no more data to send so STALL the TX Status*/
    ControlState = WAIT_STATUS_OUT;
    vSetEPTxStatus(EP_TX_STALL);
    goto Expect_Status_Out;
  }
  Length = pEPinfo->PacketSize;
  ControlState = (save_wLength < Length) ? LAST_IN_DATA : IN_DATA;

  /* Same as UsbWrite */
  if (Length > save_wLength)
  Length = save_wLength;
  DataBuffer = (*pEPinfo->CopyData)(Length);
  /* transfer data from buffer to PMA */
  pTxBuff = (DWORD *)(PMAAddr + GetEPTxAddr(ENDP0));
  for(i=0;i < Length;)
  {
    tmp = *DataBuffer;
    tmp|=*(DataBuffer+1)<<8;
    tmp|=*(DataBuffer+2)<<16;
    tmp|=*(DataBuffer+3)<<24;
    DataBuffer = DataBuffer+4;
    i=i+4;
    *pTxBuff=tmp;
    pTxBuff++;
  }
  SetEPTxCount(ENDP0, Length);
  pEPinfo->Usb_wLength -= Length;
  pEPinfo->Usb_wOffset += Length;
  vSetEPTxStatus(EP_TX_VALID);
  USB_StatusOut();/* Expect the host to abort the data IN stage */

Expect_Status_Out:  pInformation->ControlState = ControlState;

}/* DataStageIn */

/*******************************************************************************
* Function Name  : NoData_Setup0
* Description    : Proceed the processing of setup request without data stage
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NoData_Setup0()
{
  DEVICE_INFO *pInfo = pInformation;
  RESULT  Result;
  BYTE  RequestNo = pInformation->USBbRequest;
  BYTE  ControlState;

  /*Standard Device Requests*/
  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
  {
    /*SET_CONFIGURATION*/
    if (RequestNo == SET_CONFIGURATION)
    Result = Standard_SetConfiguration();

    /*SET ADDRESS*/
    else if (RequestNo == SET_ADDRESS)
    {
      if(pInfo->USBwValue0 > 127 || pInfo->USBwValue1!=0
      ||pInfo->USBwIndex!=0 || pInfo->Current_Configuration!=0)
      {
        ControlState = STALLED;
        goto exit_NoData_Setup0;
      }
      else Result = USB_SUCCESS;
    }

    /*SET FEATURE*/
    else if (RequestNo == SET_FEATURE)
    {
      if (pInfo->USBwValue0==DEVICE_REMOTE_WAKEUP && pInfo->USBwIndex==0
      && ValBit(pInfo->Current_Feature,5))
      Result = Standard_SetDeviceFeature();
      else
      Result = UNSUPPORT;
    }

    /*Clear FEATURE */
    else if (RequestNo == CLEAR_FEATURE)
    {
      if (pInfo->USBwValue0==DEVICE_REMOTE_WAKEUP && pInfo->USBwIndex==0
      &&ValBit(pInfo->Current_Feature,5))
      Result = Standard_ClearFeature();
      else
      Result = UNSUPPORT;
    }
  }

  /*Standard Interface Requests*/
  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
  {
    /*SET INTERFACE*/
    if (RequestNo == SET_INTERFACE)
    Result = Standard_SetInterface();
  }

  /*Standard EndPoint Requests*/
  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
  {
    /*CLEAR FEATURE for EndPoint*/
    if (RequestNo == CLEAR_FEATURE)
    Result = Standard_ClearFeature();

    /*SET FEATURE for EndPoint*/
    else if (RequestNo == SET_FEATURE)
    {
      Result = Standard_SetEndPointFeature();
    }
  }

  else Result = UNSUPPORT;
  if (Result != USB_SUCCESS)
  {
    /*Check and Process possible Class_NoData_Setup Requests*/
    Result = (*pProperty->Class_NoData_Setup)(RequestNo);
    if (Result == NOT_READY)
    {
      ControlState = PAUSE;
      goto exit_NoData_Setup0;
    }
  }
  if (Result != USB_SUCCESS)
  {
    ControlState = STALLED;
    goto exit_NoData_Setup0;
  }
  ControlState = WAIT_STATUS_IN; /* After no data stage SETUP */
  USB_StatusIn();

exit_NoData_Setup0:
  pInfo->ControlState = ControlState;
  return;
} /* NoData_Setup0 */

/*******************************************************************************
* Function Name  : Data_Setup0
* Description    : Processing Setup Requests with data stage
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Data_Setup0()
{
  DEVICE_INFO   *pInfo = pInformation;
  DEVICE_PROP   *pProp = pProperty;
  BYTE  *(*CopyRoutine)(WORD);
  RESULT  Result;
  BYTE Request_No = pInfo->USBbRequest;
  BYTE *pbLen;
  BYTE Related_Endpoint,Reserved;
  WORD  wOffset,wLen,Status;

  CopyRoutine = NULL;
  wOffset = 0;

  /*GET_DESCRIPTOR*/
  if (Request_No == GET_DESCRIPTOR)
  {
    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
    {
      BYTE wValue1 = pInfo->USBwValue1;
      if (wValue1 == DEVICE_DESCRIPTOR)
      CopyRoutine = pProp->GetDeviceDescriptor;
      else if (wValue1 == CONFIG_DESCRIPTOR)
      CopyRoutine = pProp->GetConfigDescriptor;
      else if (wValue1 == STRING_DESCRIPTOR)
      {
        wOffset = pInfo->USBwValue0;
        CopyRoutine = pProp->GetStringDescriptor;
      }
    }
  }

  /*GET STATUS*/
  else if (Request_No == GET_STATUS && pInfo->USBwValue==0
  && pInfo->USBwLength == 0x0002 && pInfo->USBwIndex1==0)
  {
    /* GET STATUS for Device*/
    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT) && pInfo->USBwIndex==0)
    {
      CopyRoutine = Standard_GetStatus;
    }

    /* GET STATUS for Interface*/
    else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
    {
      if ((*pProp->Class_Get_Interface_Setting)(pInfo->USBwIndex0,0)==USB_SUCCESS
      && pInfo->Current_Configuration!=0)
      CopyRoutine = Standard_GetStatus;
    }

    /* GET STATUS for EndPoint*/
    else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
    {
      Related_Endpoint = (pInfo->USBwIndex0 & 0x0f);
      Reserved= pInfo->USBwIndex0 & 0x70;
      if (ValBit(pInfo->USBwIndex0, 7))
      Status =_GetEPTxStatus(Related_Endpoint);
      else Status =_GetEPRxStatus(Related_Endpoint);
      if(Related_Endpoint < Device_Table.Total_Endpoint && Reserved==0 && Status != 0)
      CopyRoutine = Standard_GetStatus;
    }
  }

  /*GET CONFIGURATION*/
  else if (Request_No == GET_CONFIGURATION)
  {
    if ( Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT) )
    CopyRoutine = Standard_GetConfiguration;
  }

  /*GET INTERFACE*/
  else if (Request_No == GET_INTERFACE)
  {
    if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)
    && pInfo->Current_Configuration!=0 && pInfo->USBwValue==0
    && pInfo->USBwIndex1==0 && pInfo->USBwLength == 0x0001
    && (*pProperty->Class_Get_Interface_Setting)(pInfo->USBwIndex0,0)==USB_SUCCESS)
    CopyRoutine = Standard_GetInterface;
  }

  if (CopyRoutine)
  {
    pInfo->Ctrl_Info.Usb_wOffset = wOffset;
    pInfo->Ctrl_Info.CopyData = CopyRoutine;
    pbLen = (*CopyRoutine)(0);
    wLen = (WORD)((DWORD)pbLen);
    pInfo->Ctrl_Info.Usb_wLength = wLen;
    Result = USB_SUCCESS;
  }
  else
  {
    /*check and process possible Class_Data_Setup request*/
    Result = (*pProp->Class_Data_Setup)(pInfo->USBbRequest);
    if(Result == NOT_READY)
    {
      pInfo->ControlState = PAUSE;
      return;
    }
  }
  if (pInfo->Ctrl_Info.Usb_wLength == -1)
  {
    /* Data is not ready, wait it */
    pInfo->ControlState = PAUSE;
    return;
  }
  if (Result == UNSUPPORT || pInfo->Ctrl_Info.Usb_wLength == 0)
  {
    /* Unsupported request */
    pInfo->ControlState = STALLED;
    return;
  }
  if (ValBit(pInfo->USBbmRequestType, 7))
  {
    /* Device ==> Host */
    WORD  wLength = pInfo->USBwLength;
    /* Restrict the data length to be the one host asks */
    if (pInfo->Ctrl_Info.Usb_wLength > wLength)
    pInfo->Ctrl_Info.Usb_wLength = wLength;
    pInfo->Ctrl_Info.PacketSize = pProp->MaxPacketSize;
    DataStageIn();
  }
  else
  {
    pInfo->ControlState = OUT_DATA;
    vSetEPRxStatus(EP_RX_VALID);/* enable for next data reception */
  }
  return;
} /* Data_Setup0 */

/*******************************************************************************
* Function Name  : Setup0_Process
* Description    : Setup Token processing (entry point)
* Input          : None
* Output         : None
* Return         : (see Post0_Process)
*******************************************************************************/
BYTE Setup0_Process()
{
  DEVICE_INFO *pInfo = pInformation;
  WORD*    pBuf;

  pBuf= (WORD *)(GetEPRxAddr(ENDP0)+PMAAddr);
  if (pInfo->ControlState != PAUSE)
  {
    pInfo->USBbmRequestType = (*pBuf)&0xFF; /* bmRequestType */
    pInfo->USBbRequest = ((*pBuf)&0xFF00)>>8; /* bRequest */
    pInfo->USBwValue = ByteSwap(*(pBuf+1)); /* wValue */
    pInfo->USBwIndex = ByteSwap(*(pBuf+2)); /* wIndex */
    pInfo->USBwLength = *(pBuf+3);  /* wLength */
  }
  pInfo->ControlState = SETTING_UP;
  if (pInfo->USBwLength == 0)
  {
    /* Setup with no data stage */
    NoData_Setup0();
  }
  else
  {
    /* Setup with data stage */
    Data_Setup0();
  }
  return Post0_Process();
} /* Setup0_Process */

/*******************************************************************************
* Function Name  : In0_Process
* Description    : Process the IN tocken on control endpoint
* Input          : None
* Output         : None
* Return         : (see Post0_Process)
*******************************************************************************/
BYTE In0_Process()
{
  DEVICE_INFO *pInfo = pInformation;
  BYTE  ControlState = pInfo->ControlState;
  if (ControlState == IN_DATA || ControlState == LAST_IN_DATA)
  {
    DataStageIn();
    ControlState = pInfo->ControlState;
  }
  else if (ControlState == WAIT_STATUS_IN)
  {
    if (pInfo->USBbRequest == SET_ADDRESS &&
    Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT) )
    {
      SetDeviceAddress(pInfo->USBwValue0);
    }
    (*pProperty->Process_Status_IN)();
    ControlState = STALLED;
  }
  else
  ControlState = STALLED;
  pInfo->ControlState = ControlState;
  return Post0_Process();
} /* In0_Process */

/*******************************************************************************
* Function Name  : Out0_Process
* Description    : Process the OUT token on control endpoint
* Input          : None
* Output         : None
* Return         : (see Post0_Process)
*******************************************************************************/
BYTE Out0_Process()
{
  DEVICE_INFO *pInfo = pInformation;
  BYTE  ControlState = pInfo->ControlState;
  if(ControlState == OUT_DATA || ControlState == LAST_OUT_DATA)
  DataStageOut();
  else if (ControlState == WAIT_STATUS_OUT)
  {
    (*pProperty->Process_Status_OUT)();
    ControlState = STALLED;
  }
  else if (ControlState == IN_DATA || ControlState == LAST_IN_DATA)
  {
    /* host aborts the transfer before finish */
    ControlState = STALLED;
  }
  /* Unexpect state, STALL the endpoint */
  else
  {
    ControlState = STALLED;
  }
  pInfo->ControlState = ControlState;
  return Post0_Process();
} /* Out0_Process */

/*******************************************************************************
* Function Name  : Post0_Process
* Description    : Stalls ENDPOINT0 if ControlState = STALLED
* Input          : None
* Output         : None
* Return         : 0: if ControlState is not " PAUSE "
*                  1: if ControlState is "PAUSE"
*******************************************************************************/
BYTE Post0_Process()
{
  _SetEPRxCount(ENDP0, STD_MAXPACKETSIZE);
  if (pInformation->ControlState == STALLED)
  {
    vSetEPRxStatus(EP_RX_STALL);
    vSetEPTxStatus(EP_TX_STALL);
  }
  return (pInformation->ControlState == PAUSE);
} /* Post0_Process */


/*******************************************************************************
* Function Name  : SetDeviceAddress
* Description    : Set Device Address
* Input          : Val: Device Address
* Output         : None
* Return         : None
*******************************************************************************/
void SetDeviceAddress(BYTE Val)
{
	int i;
  DEVICE *pDevice = &Device_Table;
  /*  BYTE	EP0 = pDevice->EP0;	*/
  int	nEP = pDevice->Total_Endpoint;
  /* set address in every used endpoint */
	for(i=0;i<nEP;i++)
	{
		_SetEPAddress((BYTE)i, (BYTE)i);
	} /* for */
	_SetDADDR(Val|DADDR_EF); /* set device address and enable function */
} /* SetDeviceAddress */


/*******************************************************************************
* Function Name  : NOP_Process
* Description    : Do Nothing
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NOP_Process(void)
{
}

⌨️ 快捷键说明

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