?? usb_core.c
字號:
*/
LAST_OUT_DATA;
}
} /* DataStageOut */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
NAME: DataStageIn
INPUT: none
OUTPUT:
DESCRIPTION:
Data stage of a Control Read Transfer
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
void DataStageIn(void)
{
ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
WORD save_wLength = pEPinfo->Usb_wLength;
BYTE ControlState;
BYTE *DataBuffer;
WORD Length;
int i;
DWORD *pTxBuff;
WORD wTra;
union {
BYTE *bTra;
WORD *wTra;
}pBuf;
if (save_wLength == 0) {
/* if the number of byte to be sent is */
/* multiple of MaxPacketSize: send a 0 length data packet */
ControlState = WAIT_IN_ZERO;
Send0LengthData();
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 + (BYTE *)(_GetEPTxAddr(ENDP0)*2));
pBuf.wTra = &wTra;
for(i=0;i < Length;)
{
*(pBuf.bTra ) = *DataBuffer++;
i++;
*(pBuf.bTra+1) = *DataBuffer++;
i++;
*pTxBuff = wTra;
pTxBuff++;
}
_SetEPTxCount(ENDP0, Length);
pEPinfo->Usb_wLength -= Length;
pEPinfo->Usb_wOffset += Length;
vSetEPTxStatus(EP_TX_VALID);
Expect_Status_Out:
USB_StatusOut(); /* Expect the host to abort the data IN stage */
pInformation->ControlState = ControlState;
}/* DataStageIn */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
NAME: NoData_Setup0
INPUT:
OUTPUT: none
DESCRIPTION:
Proceed the processing of setup request without data stage
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
void NoData_Setup0()
{
DEVICE_INFO *pInfo = pInformation;
RESULT Result;
BYTE RequestNo = pInfo->USBbRequest;
BYTE ControlState;
if (RequestNo == CLEAR_FEATURE)
Result = Standard_ClearFeature();
else if (RequestNo == SET_FEATURE)
Result = Standard_SetFeature();
else if (RequestNo == SET_ADDRESS && Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT) )
Result = SUCCESS;
else
Result = UNSUPPORT;
if (Result != SUCCESS) {
Result = (*pProperty->Class_NoData_Setup)(RequestNo);
if (Result == NOT_READY) {
ControlState = PAUSE;
goto exit_NoData_Setup0;
}
}
if (Result != 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;
} /* NoData_Setup0 */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
NAME: Data_Setup0
INPUT:
OUTPUT: none
DESCRIPTION:
Proceed the processing of setup request with data stage
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
void Data_Setup0()
{
DEVICE_INFO *pInfo = pInformation;
DEVICE_PROP *pProp = pProperty;
BYTE *(*CopyRoutine)(WORD);
WORD wOffset;
RESULT Result;
BYTE Request_No = pInfo->USBbRequest;
BYTE *pbLen;
WORD wLen;
CopyRoutine = NULL;
wOffset = 0;
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;
} /* End of GET_DESCRIPTOR */
}
}
else if (Request_No == GET_STATUS) {
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)
|| Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) {
CopyRoutine = Standard_GetStatus;
}
}
/***************************************************************************
else if (Request_No == GET_CONFIGURATION) {
if ( Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT) )
CopyRoutine = Standard_GetConfiguration;
}
else if (Request_No == GET_INTERFACE) {
if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
CopyRoutine = Standard_GetInterface;
}
else if (Request_No == SET_DESCRIPTOR:) {
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) {
BYTE *SetDeviceDescriptor(WORD Length);
BYTE wValue1 = pInfo->USBwValue1;
if ( wValue1 == DEVICE_DESCRIPTOR)
CopyRoutine = SetDeviceDescriptor;
else if (wValue1 == CONFIG_DESCRIPTOR)
CopyRoutine = SetConfigDescriptor;
else if (wValue1 == STRING_DESCRIPTOR) {
CopyRoutine = SetStringDescriptor;
wOffset = pInfo->USBwValue0;
}
}
}
***************************************************************************/
if (CopyRoutine) {
pInfo->Ctrl_Info.Usb_wOffset = wOffset;
pInfo->Ctrl_Info.CopyData = CopyRoutine;
/* sb in the original the cast to word was directly */
/* now the cast is made step by step */
pbLen = (*CopyRoutine)(0);
wLen = (WORD)((DWORD)pbLen);
pInfo->Ctrl_Info.Usb_wLength = wLen;
Result = SUCCESS;
}
else {
Result = (*pProp->Class_Data_Setup)(pInfo->USBbRequest);
if (Result == NOT_READY) {
pInfo->ControlState = PAUSE;
return;
}
}
if (pInfo->Ctrl_Info.Usb_wLength == 0xffff) { /* 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;
/* SetEPRxCount(EPindex, STD_MAXPACKETSIZE); */
vSetEPRxStatus(EP_RX_VALID);
/* reenable for next data reception */
}
return;
} /* Data_Setup0 */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
NAME: Setup0_Process
INPUT:
OUTPUT: none
DESCRIPTION:
Get the device request data and dispatch to individual process
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
BYTE Setup0_Process()
{
DEVICE_INFO *pInfo = pInformation;
union {
BYTE* b;
WORD* w;
} pBuf;
/* sb pBuf.b = pProperty->RxEP_buffer; */
pBuf.b = PMAAddr + (BYTE *)(_GetEPRxAddr(ENDP0)*2); /* *2 for 32 bits addr */
if (pInfo->ControlState != PAUSE) {
pInfo->USBbmRequestType = *pBuf.b++; /* bmRequestType */
pInfo->USBbRequest = *pBuf.b++; /* bRequest */
pBuf.w++; /* sb word not accessed because of 32 bits addressing */
pInfo->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
pBuf.w++; /* word not accessed because of 32 bits addressing */
pInfo->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */
pBuf.w++; /* word not accessed because of 32 bits addressing */
/* sb pInfo->USBwLength = ByteSwap(*pBuf.w);*/ /* wLength */
pInfo->USBwLength = *pBuf.w; /* wLength */
}
pInfo->ControlState = SETTING_UP;
if (pInfo->USBwLength == 0)
{ /* No data statge processing */
NoData_Setup0();
}
else { /* Setup with data stage */
Data_Setup0();
}
return Post0_Process();
} /* Setup0_Process */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
NAME: In0_Process
INPUT:
OUTPUT: none
DESCRIPTION:
Process the IN token on all default endpoint
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
BYTE In0_Process()
{
DEVICE_INFO *pInfo = pInformation;
BYTE ControlState = pInfo->ControlState;
if (ControlState == IN_DATA)
{
DataStageIn();
/* sb questo e' un baco della libreria st9 */
ControlState = pInfo->ControlState; /* may be changed outside the function */
/* sb */
}
else if (ControlState == LAST_IN_DATA || ControlState == WAIT_IN_ZERO) {
ControlState = WAIT_STATUS_OUT;
USB_StatusOut();
}
else if (ControlState == WAIT_OUT_ZERO || ControlState == WAIT_STATUS_IN) {
if (pInfo->USBbRequest == SET_ADDRESS &&
Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT) ) {
/* Device address must be written */
/* after completion of Status Stage (ACK from Host) */
SetDeviceAddress(pInfo->USBwValue0);
}
(*pProperty->Process_Status_IN)();
ControlState = WAIT_SETUP;
}
else
ControlState = STALLED;
pInfo->ControlState = ControlState;
return Post0_Process();
} /* In0_Process */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
NAME: Out0_Process
INPUT:
OUTPUT: none
DESCRIPTION:
Process the OUT token on all default endpoint
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
BYTE Out0_Process()
{
DEVICE_INFO *pInfo = pInformation;
BYTE ControlState = pInfo->ControlState;
if (ControlState == OUT_DATA) {
DataStageOut();
if (pInfo->ControlState == LAST_OUT_DATA) {
ControlState = WAIT_STATUS_IN;
USB_StatusIn();
}
else {
/* Expecting another OUT token with 0 length data */
SetEPRxCount(ENDP0, 0);
vSetEPRxStatus(EP_RX_VALID);
/* Also expecting an IN token to finish the transaction */
USB_StatusIn();
}
}
else if (ControlState == WAIT_STATUS_OUT || ControlState == IN_DATA) {
/* host aborts the xfer before finish */
/* Clear_Status_Out(EPindex);*/ /* Clear ST_OUT bit of this EP */
vSetEPTxStatus(EP_TX_NAK);
/* This is to ensure that when the xfer is aborted,
close down the transmitter, in case the next IN
token comes in before I config the transmitter */
(*pProperty->Process_Status_OUT)();
ControlState = WAIT_SETUP;
}
else if (ControlState == WAIT_OUT_ZERO) {
ControlState = WAIT_STATUS_IN;
USB_StatusIn();
}
else {
/* Unexpect state, STALL the endpoint */
ControlState = STALLED;
}
pInfo->ControlState = ControlState;
return Post0_Process();
} /* Out0_Process */
/*============================================================================*/
/*============================================================================*/
BYTE Post0_Process()
{
SetEPRxCount(ENDP0, STD_MAXPACKETSIZE);
if (pInformation->ControlState == STALLED) {
vSetEPRxStatus(EP_RX_STALL);
vSetEPTxStatus(EP_TX_STALL);
}
/*
* Since the SIE will receive SETUP even in NAK state
* There is no need to enable the receiver again
*/
return (pInformation->ControlState == PAUSE);
} /* Post0_Process */
/***************************************************************************
BYTE DescriptorBuffer[128];
BYTE *SetDeviceDescriptor(WORD Length)
{
if (Length == 0)
return (BYTE*)sizeof(DescriptorBuffer);
return DescriptorBuffer + pInfomation->Ctrl_Info.Usb_rOffset;
}
***************************************************************************/
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void NOP_Process(void)
{
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -