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

📄 usb_core.c

📁 基于ST ARM处理器的USB通信的演示
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************** (C) COPYRIGHT 2006 STMicroelectronics ********************
* File Name          : main.c
* Author             : wuyuhuai
* Date First Issued  : 4/40/2008 : V1.0
* Description        : str training demo main file
********************************************************************************
* History:
* 09/18/2006 : V3.0
* 09/01/2006 : V2.0
* 10/27/2003 : V1.0
********************************************************************************
* 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.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_mem.h"
#include "usb_conf.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ValBit(VAR,Place)    (VAR & (1<<Place))
#define SetBit(VAR,Place)    ( VAR |= (1<<Place) )
#define ClrBit(VAR,Place)    ( VAR &= ((1<<Place)^255) )

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

#define vSetEPRxStatus(st)	(SaveRState = st)
#define vSetEPTxStatus(st)	(SaveTState = st)

#define USB_StatusIn()	Send0LengthData()
#define USB_StatusOut()	vSetEPRxStatus(EP_RX_VALID)

#define StatusInfo0 StatusInfo.bw.bb1	/* Reverse bb0 & bb1 */
#define StatusInfo1 StatusInfo.bw.bb0
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u16_u8 StatusInfo;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/*******************************************************************************
* Function Name  : Standard_GetConfiguration
* Description    : Return the current configuration variable address
* Input          : Length - How many bytes are needed.
* Output         : If "Length" is 0, return the length of configuration value
		   If "Length" is not 0, return the data buffer address.
* Return         : Return 1 , if the request is invalid when "Length" is 0
		   Return "Buffer" if the "Length" is not 0
*******************************************************************************/
u8 *Standard_GetConfiguration(u16 Length)
{
  if (Length == 0){
    pInformation->Ctrl_Info.Usb_wLength = sizeof(pInformation->Current_Configuration);
		return 0;
  }
        pUser_Standard_Requests->User_GetConfiguration();
	return (u8 *)&pInformation->Current_Configuration;
}
/*******************************************************************************
* Function Name  : Standard_SetConfiguration
* Description    : This routine is called to set the configuration value
		   Then each class should configure device themself
* Input          :
* Output         :
* Return         : Return USB_SUCCESS, if the request is performed
		   Return USB_UNSUPPORT, if the request is invalid
*******************************************************************************/
RESULT Standard_SetConfiguration(void)
{

	if (pInformation->USBwValue0 <= Device_Table.Total_Configuration && pInformation->USBwValue1==0
	    && pInformation->USBwIndex==0) /*call Back usb spec 2.0*/
	{
		pInformation->Current_Configuration = pInformation->USBwValue0;
                pUser_Standard_Requests->User_SetConfiguration();
		return USB_SUCCESS;
	}
	else
	return USB_UNSUPPORT;
}
/*******************************************************************************
* Function Name  : Standard_GetInterface
* Description    : Return the Alternate Setting of the current interface
* Input          : Length - How many bytes are needed
* Output         : If "Length" is 0, return the length of interface value
		   If "Length" is not 0, return the data buffer address
* Return         : Return 0, if the request is invalid when "Length" is 0
		   Return "Buffer" if the "Length" is not 0
*******************************************************************************/
u8 *Standard_GetInterface(u16 Length)
{
  if (Length == 0){
	pInformation->Ctrl_Info.Usb_wLength =	sizeof(pInformation->Current_AlternateSetting);
    return 0;
  }
        pUser_Standard_Requests->User_GetInterface();
	return (u8 *)&pInformation->Current_AlternateSetting;
}
/*******************************************************************************
* Function Name  : Standard_SetInterface
* Description    : This routine is called to set the interface
		   Then each class should configure the interface them self
* Input          :
* Output         :
* Return         : Return USB_SUCCESS, if the request is performed
		   Return USB_UNSUPPORT, if the request is invalid
*******************************************************************************/
RESULT Standard_SetInterface(void)
{
	RESULT                  Re;
  	/*Test if the specified Interface and Alternate Setting are supported by the application Firmware*/
	Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0,pInformation->USBwValue0);

	if(pInformation->Current_Configuration!=0 )
	{
		if (Re!= USB_SUCCESS || pInformation->USBwIndex1!=0 || pInformation->USBwValue1!=0)
				return  USB_UNSUPPORT;
		else if ( Re == USB_SUCCESS)
                {
                 pUser_Standard_Requests->User_SetInterface();
                 pInformation->Current_Interface = pInformation->USBwIndex0;
		 pInformation->Current_AlternateSetting = pInformation->USBwValue0;
		 return USB_SUCCESS;
		}
			
	}

 return USB_UNSUPPORT;
}
/*******************************************************************************
* Function Name  : Standard_GetStatus
* Description    : Copy the device request data to "StatusInfo buffer"
* Input          : Length - How many bytes are needed
* Output         : If "Length" is 0, return the length of status data
		   If "Length" is not 0, return number of bytes have been copied
* Return         : Return 0, if the request is at end of data block,
		   or is invalid when "Length" is 0
*******************************************************************************/
u8 *Standard_GetStatus(u16 Length)
{
  if (Length == 0){
          pInformation->Ctrl_Info.Usb_wLength =2;
		return 0;
  }

	StatusInfo.w = 0;
 				/* Reset Status Information */
	
	if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) {/*Get Device Status */
		u8	Feature = pInformation->Current_Feature;

		if (ValBit(Feature, 5))
			SetBit(StatusInfo0, 1); /* Remote Wakeup enabled */

		
		if (ValBit(Feature, 6))
			SetBit(StatusInfo0, 0);  /* Self-powered */
		else
			ClrBit(StatusInfo0, 0); /* Bus-powered */
	}
	else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))/*Interface Status*/
			return (u8 *)&StatusInfo;

	else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) {/*Get EndPoint Status*/
		u8	Related_Endpoint;
		u8	wIndex0 = pInformation->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;
        pUser_Standard_Requests->User_GetStatus();
	return (u8 *)&StatusInfo;
}
/*******************************************************************************
* Function Name  : Standard_ClearFeature
* Description    : Clear or disable a specific feature
* Input          :
* Output         :
* Return         :
*******************************************************************************/
RESULT Standard_ClearFeature(void)
{
	
	u32     Type_Rec = Type_Recipient;
	u32     Status;

	
	if ( Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT) ) {/*Device Clear Feature*/
		ClrBit(pInformation->Current_Feature, 5);
		return USB_SUCCESS;
	}
	else if ( Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT) ) {/*EndPoint Clear Feature*/
		DEVICE* pDev;
		u32	Related_Endpoint;
		u32	wIndex0;
		u32	rEP;

		if (pInformation->USBwValue != ENDPOINT_STALL || pInformation->USBwIndex1!=0)
			return USB_UNSUPPORT;

		pDev = &Device_Table;
		wIndex0 = pInformation->USBwIndex0;
		rEP = wIndex0 & ~0x80;
		Related_Endpoint = ENDP0 + rEP;

		if (ValBit(pInformation->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 || pInformation->Current_Configuration==0)
			return USB_UNSUPPORT;

	
		if (wIndex0 & 0x80) {		/* IN endpoint */
                  if (_GetTxStallStatus(Related_Endpoint )){
                                ClearDTOG_TX(Related_Endpoint);
				SetEPTxStatus(Related_Endpoint, EP_TX_VALID);
      		  }
                }
		else {							/* OUT endpoint */
			if (_GetRxStallStatus(Related_Endpoint)){
				if (Related_Endpoint == ENDP0) {
					/* After clear the STALL, enable the default endpoint receiver */
					SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize);
					_SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
				}
				else
                                {
                                        ClearDTOG_RX(Related_Endpoint);
					_SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
                                }
			}
		}
                pUser_Standard_Requests->User_ClearFeature();
		return USB_SUCCESS;
	}

	return USB_UNSUPPORT;
}
/*******************************************************************************
* Function Name  : Standard_SetEndPointFeature
* Description    : Set or enable a specific feature of EndPoint
* Input          :
* Output         :
* Return         :
*******************************************************************************/
RESULT Standard_SetEndPointFeature(void)
{
	u32    wIndex0;
	u32    Related_Endpoint;
	u32    rEP;
	u32   Status;

		wIndex0 = pInformation->USBwIndex0;
		rEP = wIndex0 & ~0x80;
		Related_Endpoint = ENDP0 + rEP;

		if (ValBit(pInformation->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 (Related_Endpoint >= Device_Table.Total_Endpoint || pInformation->USBwValue !=0 || Status==0 ||
			pInformation->Current_Configuration==0 /*&& Related_Endpoint!=ENDP0)*/)
			return USB_UNSUPPORT;
		else {

			if (wIndex0 & 0x80) {		/* IN endpoint */
				_SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
			}
			 	
			else {				/* OUT endpoint */
				_SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
			}
		}
        pUser_Standard_Requests->User_SetEndPointFeature();
	return USB_SUCCESS;
}
/*******************************************************************************
* Function Name  : Standard_SetDeviceFeature
* Description    : Set or enable a specific feature of Device
* Input          :
* Output         :
* Return         :
*******************************************************************************/
RESULT Standard_SetDeviceFeature(void)
{
			SetBit(pInformation->Current_Feature, 5);
                        pUser_Standard_Requests->User_SetDeviceFeature();
			return USB_SUCCESS;

}

/*******************************************************************************
* Function Name  : Standard_GetDescriptorData
* Description    : Standard_GetDescriptorData is used for descriptors transfer
*                : This routine is used for the descriptors resident in Flash or RAM
		  pDesc can be in either Flash or RAM
		  The purpose of this routine is to have a versatile way to response
		  descriptors request. It allows user to generate certain descriptors
		  with software or read descriptors from external storage part by part.
* Input          : Length - Length of the data in this transfer
		   pDesc - A pointer points to descriptor struct.
		          The structure gives the initial address of the
                          descriptor and its original size
* Output         : Address of a part of the descriptor pointed by the Usb_wOffset
		   The buffer pointed by this address contains at least Length bytes
* Return         :
*******************************************************************************/

u8 *Standard_GetDescriptorData(u16 Length, ONE_DESCRIPTOR *pDesc)
{
	u32	 wOffset;

	wOffset = pInformation->Ctrl_Info.Usb_wOffset;
	if (Length == 0) {
		pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
                return 0;
	}

	return pDesc->Descriptor + wOffset;
}
/*******************************************************************************
* Function Name  : DataStageOut
* Description    : Data stage of a Control Write Transfer
* Input          :
* Output         :
* Return         :
*******************************************************************************/
void DataStageOut(void)
{
	ENDPOINT_INFO	*pEPinfo = &pInformation->Ctrl_Info;
	u32	save_rLength;

	save_rLength = pEPinfo->Usb_rLength;

	if (pEPinfo->CopyData && save_rLength) {
		u8 *Buffer;
		u32 Length;

		Length = pEPinfo->PacketSize;
		if (Length > save_rLength)
			Length = save_rLength;

                Buffer = (*pEPinfo->CopyData)(Length);
                pEPinfo->Usb_rLength -= Length;
		pEPinfo->Usb_rOffset += Length;

                PMAToUserBufferCopy(Buffer,GetEPRxAddr(ENDP0), Length);
  	}

	if(pEPinfo->Usb_rLength !=0){
		vSetEPRxStatus(EP_RX_VALID);/* re-enable 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();
				}
		}

}
/*******************************************************************************
* Function Name  : DataStageIn
* Description    : Data stage of a Control Read Transfer
* Input          :
* Output         :
* Return         :
*******************************************************************************/
void DataStageIn(void)
{
	ENDPOINT_INFO	*pEPinfo = &pInformation->Ctrl_Info;
	u32	save_wLength = pEPinfo->Usb_wLength;
	u32	ControlState = pInformation->ControlState;

	u8	*DataBuffer;
	u32	Length;

     	if ((save_wLength == 0) && (ControlState == LAST_IN_DATA))
        { /* 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;

⌨️ 快捷键说明

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