📄 usb_core.c
字号:
is Disabled*/
Status = _GetEPTxStatus(Related_Endpoint);
}
else
{
Status = _GetEPRxStatus(Related_Endpoint);
}
if (Related_Endpoint >= Device_Table.Total_Endpoint
|| pInformation->USBwValue != 0 || Status == 0
|| pInformation->Current_Configuration == 0)
{
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 : None.
* Output : None.
* Return : - Return USB_SUCCESS, if the request is performed.
* - Return USB_UNSUPPORT, if the request is invalid.
*******************************************************************************/
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 : None.
* Return : Address of a part of the descriptor pointed by the Usb_
* wOffset The buffer pointed by this address contains at least
* Length bytes.
*******************************************************************************/
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 : None.
* Output : None.
* Return : None.
*******************************************************************************/
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 : None.
* Output : None.
* Return : None.
*******************************************************************************/
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))
{
if(Data_Mul_MaxPacketSize == TRUE)
{
/* No more data to send and empty packet */
Send0LengthData();
ControlState = LAST_IN_DATA;
Data_Mul_MaxPacketSize = FALSE;
}
else
{
/* 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;
if (Length > save_wLength)
{
Length = save_wLength;
}
DataBuffer = (*pEPinfo->CopyData)(Length);
UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
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;
}
/*******************************************************************************
* Function Name : NoData_Setup0.
* Description : Proceed the processing of setup request without data stage.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void NoData_Setup0(void)
{
RESULT Result = USB_UNSUPPORT;
u32 RequestNo = pInformation->USBbRequest;
u32 ControlState;
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{
/* Device Request*/
/* SET_CONFIGURATION*/
if (RequestNo == SET_CONFIGURATION)
{
Result = Standard_SetConfiguration();
}
/*SET ADDRESS*/
else if (RequestNo == SET_ADDRESS)
{
if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0)
|| (pInformation->USBwIndex != 0)
|| (pInformation->Current_Configuration != 0))
/* Device Address should be 127 or less*/
{
ControlState = STALLED;
goto exit_NoData_Setup0;
}
else
{
Result = USB_SUCCESS;
}
}
/*SET FEATURE for Device*/
else if (RequestNo == SET_FEATURE)
{
if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP)
&& (pInformation->USBwIndex == 0)
&& (ValBit(pInformation->Current_Feature, 5)))
{
Result = Standard_SetDeviceFeature();
}
else
{
Result = USB_UNSUPPORT;
}
}
/*Clear FEATURE for Device */
else if (RequestNo == CLEAR_FEATURE)
{
if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
&& pInformation->USBwIndex == 0
&& ValBit(pInformation->Current_Feature, 5))
{
Result = Standard_ClearFeature();
}
else
{
Result = USB_UNSUPPORT;
}
}
}
/* Interface Request*/
else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
{
/*SET INTERFACE*/
if (RequestNo == SET_INTERFACE)
{
Result = Standard_SetInterface();
}
}
/* EndPoint Request*/
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 = USB_UNSUPPORT;
}
if (Result != USB_SUCCESS)
{
Result = (*pProperty->Class_NoData_Setup)(RequestNo);
if (Result == USB_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:
pInformation->ControlState = ControlState;
return;
}
/*******************************************************************************
* Function Name : Data_Setup0.
* Description : Proceed the processing of setup request with data stage.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Data_Setup0(void)
{
u8 *(*CopyRoutine)(u16);
RESULT Result;
u32 Request_No = pInformation->USBbRequest;
u32 Related_Endpoint, Reserved;
u32 wOffset, Status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -