?? usb_core.c
字號:
/******************** (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 + -