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

📄 usb_core.c

📁 arm(str710)usb功能的实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************** (C) COPYRIGHT 2003 STMicroelectronics ********************
* File Name          : usb_core.c
* Author             : MCD Application Team
* Date First Issued  : 27/10/2003
* Description        : standard protocol processing (USB v1.1)
*
********************************************************************************/

#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) )

BYTE *Standard_GetStatus(WORD Length);
RESULT Standard_ClearFeature(void);
RESULT Standard_SetFeature(void);

#define Send0LengthData() {	\
	_SetEPTxCount(ENDP0, 0);	\
	vSetEPTxStatus(EP_TX_VALID);	\
	}
#define Sendn0LengthData(ep) {	\
	_SetEPTxCount(ep, 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_StatusInn(ep)	Sendn0LengthData(ep)
#define USB_StatusIn()	Send0LengthData()
#define USB_StatusOut()	vSetEPRxStatus(EP_RX_VALID)


/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_GetConfiguration
	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 0, if the request is invalid when "Length" is 0
			Return "Buffer" if the "Length" is not 0
	DESCRIPTION:
		Return the current configuration variable address

	NOTICE:
		This routine is used for devices with only one configuration,
		User should write their own routine to process GET_CONFIGURATION
		if their device has more than one configuration.
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
BYTE *Standard_GetConfiguration(WORD Length)
{
	int cnf;
	if (Length == 0)
		return (BYTE *)sizeof(pInformation->Current_Configuration);
	cnf=pInformation->Current_Configuration;
	uart_printf("Standard_GetConfiguration %d call",cnf);
	return (BYTE *)&pInformation->Current_Configuration;
} /* Standard_GetConfiguration */

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_SetConfiguration
	INPUT:
	OUTPUT:
	RETURN:	Return SUCCESS, if the request is performed
			Return UNSUPPORT, if the request is invalid
	DESCRIPTION:
		The class calls this routine to get the configuration value
		Then each class should configure device themself

	NOTICE:
		This routine is used for devices with only one configuration.
		User should write their own routine to process SET_CONFIGURATION
		if their device has more than one configuration.
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
RESULT Standard_SetConfiguration(void)
{
	int cnf;
	BYTE wValue0 = pInformation->USBwValue0;
	if (1)//wValue0 <= Device_Table.Total_Configuration) 
	{
		/* If the number of configuration is within the range */
		pInformation->Current_Configuration = wValue0;
		cnf = wValue0;
		uart_printf("Standard_SetConfiguration  call  %d ",cnf);
		return SUCCESS;
	}
	else
		return UNSUPPORT;
} /* Standard_SetConfiguration */
BYTE* Standard_GetMaxLun(WORD Length)
{
if (Length == 0)
		return (BYTE*)1;
	uart_printf("Standard_GetMaxLun call",pInformation->Current_Interface++);

	return (BYTE*)&pInformation->Current_Interface;

} /* Standard_SetConfiguration */

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_GetInterface
	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
	DESCRIPTION:
		Return the current interface variable address

	NOTICE:
		This routine is used for devices with only one configuration and one interface,
		User should write their own routine to process GET_INTERFACE
		if their device has more than one configuration or one interface
		or one alternative setting.
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
BYTE *Standard_GetInterface(WORD Length)
{
	if (Length == 0)
		return (BYTE *)sizeof(pInformation->Current_Interface);
	uart_printf("Standard_GetInterface call",0);

	return (BYTE *)&pInformation->Current_Interface;
} /* Standard_GetInterface */

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_SetInterface
	INPUT:
	OUTPUT:
	RETURN:	Return SUCCESS, if the request is performed
			Return UNSUPPORT, if the request is invalid
	DESCRIPTION:
		The class calls this routine to get the interface value
		Then each class should configure the interface themself

	NOTICE:
		This routine is used for devices with only one configuration and
		one interface with one alternative setting.
		User should write their own routine to process SET_INTERFACE
		if their device has more than one configuration or one interface
		or one alternative setting.
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
RESULT Standard_SetInterface(void)
{
	DEVICE_INFO		*pInfo = pInformation;
	if (pInfo->USBwValue0 != 0 || pInfo->USBwIndex0 != 0)
		return UNSUPPORT;
	uart_printf("Standard_SetInterface call",0);

	/* I have only one interface & one alternative setting */
	pInfo->Current_Interface = 0;
	return SUCCESS;
} /* Standard_SetInterface */

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_GetStatus
	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
	DESCRIPTION:

	  Copy the device request data to "StatusInfo buffer"
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
WORD_BYTE StatusInfo;
#define StatusInfo0 StatusInfo.bw.bb1	/* Reverse bb0 & bb1 */
#define StatusInfo1 StatusInfo.bw.bb0
BYTE *Standard_GetStatus(WORD Length)
{
	DEVICE_INFO	*pInfo = pInformation;
	BYTE	Type_Rec;

	if (Length == 0)
		return (BYTE *)2;
	uart_printf("Standard_GetStatus call",0);
	StatusInfo.w = 0;	/* Reset Status Information */

	Type_Rec = Type_Recipient;
	if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) {
		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_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) {
		BYTE	Related_Endpoint;
		BYTE	wIndex0 = pInfo->USBwIndex0;

		Related_Endpoint = ENDP0 + (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 */

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_ClearFeature
	INPUT:
	OUTPUT:	none
	DESCRIPTION:
		Clear or disable a specific feature
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
RESULT Standard_ClearFeature(void)
{
	DEVICE_INFO	*pInfo = pInformation;
	BYTE	Type_Rec = Type_Recipient;
	BYTE	wValue0 = pInfo->USBwValue0;
	uart_printf("Standard_ClearFeature call",0);

	if ( Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT) ) {
		if (wValue0 != DEVICE_REMOTE_WAKEUP)
			return UNSUPPORT;

		ClrBit(pInfo->Current_Feature, 5);
		return SUCCESS;
	}
	else if ( Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT) ) {
		DEVICE* pDev;
		BYTE	Related_Endpoint;
		BYTE	wIndex0;
		BYTE	rEP;

		if (wValue0 != ENDPOINT_STALL)
			return UNSUPPORT;

		pDev = &Device_Table;
		wIndex0 = pInfo->USBwIndex0;
		rEP = wIndex0 & ~0x80;
		if (rEP >= pDev->Total_Endpoint)
			return UNSUPPORT;

				/* EPindex should be equal to Device_Table.EP0 */
		Related_Endpoint = ENDP0 + rEP;

		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 */
					SetEPRxCount(Related_Endpoint, STD_MAXPACKETSIZE);
					_SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
				}
				else
					_SetEPRxStatus(Related_Endpoint, EP_RX_NAK);
			}
		}
		return SUCCESS;
	}

	return UNSUPPORT;
} /* Standard_ClearFeature */

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_SetFeature
	INPUT:
	OUTPUT:	none
	DESCRIPTION:
		Set or enable a specific feature
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
RESULT Standard_SetFeature(void)
{
	DEVICE_INFO	*pInfo = pInformation;
	BYTE	Type_Rec = Type_Recipient;
	BYTE	wValue0 = pInfo->USBwValue0;
	uart_printf("Standard_SetFeature call",0);

	if ( Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT) ) {
		if (wValue0 != DEVICE_REMOTE_WAKEUP)
			return UNSUPPORT;

		SetBit(pInfo->Current_Feature, 5);

		/****************************************/
		return SUCCESS;
	}
	else if ( Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT) ) {
		DEVICE* pDev;
		BYTE	Related_Endpoint;
		BYTE	wIndex0;
		BYTE	rEP;

		if (wValue0 != ENDPOINT_STALL)
			return UNSUPPORT;

		pDev = &Device_Table;
		wIndex0 = pInfo->USBwIndex0;
		rEP = wIndex0 & ~0x80;
		if (rEP >= pDev->Total_Endpoint)
			return UNSUPPORT;

		Related_Endpoint = ENDP0 + rEP;
		if (wIndex0 & 0x80) {		/* IN endpoint */
			_SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
		}
		else {							/* OUT endpoint */
			_SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
		}

		return SUCCESS;
	}

	return UNSUPPORT;
} /* Standard_SetFeature */

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	NAME:	Standard_GetDescriptorData
			Standard_GetStringDescriptor
	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
	DESCRIPTION:
		These 2 routines only used for the descriptors resident in ROM or RAM
		pDesc can be in either ROM or RAM

		Standard_GetStringDescriptor is used for transfer string descriptor

		The purpose of these 2 routines 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.
 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
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;

⌨️ 快捷键说明

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