📄 usb.c
字号:
CurrentUsbbLength = Endpoint0.Rx[6];
}
else
if (UsbbRequest == SET_REPORT)
{
bmCopyRequest = bmRequest | 0x10; // Set bit 4 for SET_REPORT
bmRequest = 0;
CurrentUsbbLength = Endpoint0.Rx[6];
ClearEP0StatusOut(); // If StatusOut bit equal 1 there is no DataStageOut
}
}
if (ValBit(UsbbmRequestType, 7)) // xfer direction test
{
UsbCtrStatus = ((UsbCtrStatus & 0x80) | DATA_STAGE_IN); // a IN Data Stage will follow the Setup Stage
if ((UsbbmRequestType & TYPE) == CLASS)
{// Class requests
if (UsbbRequest == GET_REPORT)
return; // Don't go directly to DataStageIn
// We need time to prepare the data to send back
}
DataStageIn();
}
else
{
UsbCtrStatus = DATA_STAGE_OUT; // a OUT Data will follow the Setup Stage
Send0LengthData(); // Be ready to get an IN Token for Status In Stage
SetEP0RxStatus(VALID); // Endpoint0 Rx VALID for next data reception
}
}
// Add Class-Specific Requests processing
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : DataStageIn
INPUT/OUTPUT : None
DESCRIPTION : Data stage of a Control Read Transfer
-----------------------------------------------------------------------------*/
void DataStageIn(void)
{
if (ValBit(UsbbmRequestType, 7)) // xfer direction test (must be Device to Host)
{
if (CurrentUsbbLength <= MAXPACKETSIZE)
UsbCtrStatus = ((UsbCtrStatus & 0x80) | LAST_IN_TRANS);
if (CurrentUsbbLength == 0) // if the number of byte to send is
Send0LengthData(); // multiple of 8: send a 0 length data packet
else
if ((UsbbmRequestType & TYPE) == STANDARD)
{ // Standard requests
if (UsbbRequest == GET_STATUS)
GetStatus();
else
if (UsbbRequest == GET_DESCRIPTOR)
GetDescriptor();
else
if (UsbbRequest == GET_CONFIGURATION)
GetConfiguration();
else
if (UsbbRequest == GET_INTERFACE)
GetInterface();
}
else
if ((UsbbmRequestType & TYPE) == CLASS)
{// Class requests
if (UsbbRequest == GET_REPORT)
StatusOut();
else
if (UsbbRequest == GET_IDLE)
GetIdle();
else
if (UsbbRequest == GET_PROTOCOL)
GetProtocol();
}
}
else error(); // Stall endpoint
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : DataStageOut
INPUT/OUTPUT : None
DESCRIPTION : Data stage of a Control Write Transfer
-----------------------------------------------------------------------------*/
void DataStageOut(void)
{
if (!(ValBit(UsbbmRequestType, 7))) // xfer direction test (must be Host to Device)
{
if ((UsbbmRequestType & TYPE) == STANDARD)
{ // Standard requests
if (UsbbRequest == SET_DESCRIPTOR)
SetDescriptor();
}
else
if ((UsbbmRequestType & TYPE) == CLASS)
{// Class requests
if (UsbbRequest == SET_REPORT)
SetReport();
else
if (UsbbRequest == SET_IDLE)
SetIdle();
else
if (UsbbRequest == SET_PROTOCOL)
SetProtocol();
}
if (!CurrentUsbbLength) // this OUT Transaction is the last one
UsbCtrStatus = (LAST_OUT_TRANS | NO_MORE_DATA); // and the micro. will stall the next OUT
}
else error(); // Stall endpoint
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : UsbTransfer
INPUT/OUTPUT : None
DESCRIPTION : processing of the USB Transaction
-----------------------------------------------------------------------------*/
void UsbTransfer(void)
{
bmUsbIntFlag &= ~Int_Ctr; //Clear the Ctr Interrupt Flag
if (UsbEndpNumber == 0)
{
if (UsbDataTrDir == TP_SETUP) // Control Transfer (endpoint 0)
SetupStage();
else
if (UsbDataTrDir == TP_IN) // ACK received for IN Transaction (endpoint 0)
{
if ((UsbCtrStatus & DATA_STAGE_IN) == DATA_STAGE_IN) // Data Stage IN
DataStageIn();
else
if ((UsbCtrStatus & LAST_IN_TRANS) == LAST_IN_TRANS)
StatusOut();
else
if ((UsbCtrStatus & ADDRESS2SET) == ADDRESS2SET) // Device address must be written
SetAddress(); // after completion of Status Stage (ACK from Host)
else
if (((UsbCtrStatus & NO_DATA_STAGE) == NO_DATA_STAGE) ||
((UsbCtrStatus & LAST_OUT_TRANS) == LAST_OUT_TRANS) ||
((UsbCtrStatus & DATA_STAGE_OUT) == DATA_STAGE_OUT))//Host has terminated the Data Stage OUT
SetEP0RxStatus(VALID); // Set Endpoint0 Rx Valid for next reception
}
else
if (UsbDataTrDir == TP_OUT) // OUT Transaction (endpoint 0)
{
if ((UsbCtrStatus & LAST_IN_TRANS) == LAST_IN_TRANS) //End of Status Stage OUT
{
StatusOut();
}
else
if ((UsbCtrStatus & DATA_STAGE_IN) == DATA_STAGE_IN)
SetEP0RxStatus(VALID); // Host has terminated the Data Stage IN
else
if ((UsbCtrStatus & DATA_STAGE_OUT) == DATA_STAGE_OUT) // Data Stage OUT
{
if ((UsbCtrStatus & NO_MORE_DATA) == NO_MORE_DATA)
{
SetEP0TxStatus(STALL); // No more data to receive!! Stall Endpoint 0
}
else
{
DataStageOut();
if ((UsbCtrStatus & LAST_OUT_TRANS) == LAST_OUT_TRANS) // Status Stage IN
StatusIn(); //(possible check of the data PID; must be DATA1)
else
SetEP0RxStatus(VALID);
}
}
}
}
#ifdef USE_ENDPOINT1_OUT
else
if (UsbEndpNumber == 1)
{
}
#endif
#ifdef USE_ENDPOINT2_OUT
else
if (UsbEndpNumber == 2)
{
}
#endif
// if endpoint 1 and/or 2 are use only input interrupt in pipe
// we only clear the interrupt bit.
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : GetCtrInfos
INPUT/OUTPUT : None
DESCRIPTION : read token PID and endpoint number of the last Token
-----------------------------------------------------------------------------*/
void GetCtrInfos(void)
{
UsbDataTrDir = GetPid();
UsbEndpNumber = GetEndpointNumber();
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : UsbPolling
INPUT/OUTPUT : None
DESCRIPTION : checks if an USB interrupt has occured
-----------------------------------------------------------------------------*/
void UsbPolling(void)
{
if (!bmUsbIntFlag) ;
else
{
if (ValBit(bmUsbIntFlag,0))
UsbIntSof(); // Start Of Frame Int.
if (ValBit(bmUsbIntFlag,1))
UsbReset(); // USB reset Int.
if (ValBit(bmUsbIntFlag,2))
UsbEndSuspend(); // USB end of suspend mode Int.
if (ValBit(bmUsbIntFlag,5))
UsbTransfer(); // USB correct transfer Int.
if (ValBit(bmUsbIntFlag,7))
UsbSuspend(); // USB suspend Int.
}
}
/*-----------------------------------------------------------------------------
ROUTINE NAME : error
INPUT/OUTPUT : None
DESCRIPTION : Put the last used endpoint xx (0,1 or 2) and the direction (in/out)
to STALL status.
-----------------------------------------------------------------------------*/
void error()
{ Byte Endpoint, PID;
Endpoint = GetEndpointNumber();
if(!Endpoint) // Endpoint 0
{
PID = GetPid();
if(PID == TP_IN)
SetEP0TxStatus(STALL);
if(PID == TP_OUT)
SetEP0RxStatus(STALL);
}
else if(Endpoint == 1) // Endpoint 1
{
#ifdef USE_ENDPOINT1_IN
SetEP1TxStatus(STALL);
#endif
#ifdef USE_ENDPOINT1_OUT
SetEP1RxStatus(STALL);
#endif
}
else if(Endpoint == 2) // Endpoint 2
{
#ifdef USE_ENDPOINT2_IN
SetEP1TxStatus(STALL);
#endif
#ifdef USE_ENDPOINT2_OUT
SetEP1RxStatus(STALL);
#endif
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -