📄 xsusb.c
字号:
break;
}
if (retry < 0)
{
// LOGERROR(ctxP->loggedError, ERR_L_XSFFUART,
// ERR_FLASH_NO_BUFFER, ERR_T_INVALIDACC, xsr, 0, 0);
return (ctxP->loggedError);
}
// Parse the data that is in the buffer
// Identify RequestType
tempReqType = (ReqData.bmRequestType & UDC_REQ_TYPE_MASK) >> 5;
if (tempReqType == StandardReq)
{
// Identify Standard Request type
switch (ReqData.bRequest)
{
case GetDescriptorId:
// Get the number of data bytes in the data stage that follows
// This is the maximum number, and the device can return this
// number of bytes or fewer.
DataLen = ReqData.wLength;
// Identify type of descriptor
switch (ReqData.wValue >> 8)
{
case UsbDescTypeDevice:
// Read the length of the device descriptor
// and compare with number of bytes in the data stage
tempDataLen = UsbDeviceDesc[0] + (UsbDeviceDesc[1] << 8);
if (DataLen > tempDataLen)
DataLen = tempDataLen;
// Initialize the buffer pointer
TxBuffEp0P = UsbDeviceDesc;
break;
case UsbDescTypeConfiguration:
// Read the total length of the configuration descriptor
// and compare with number of bytes in the data stage
tempDataLen = UDC_CONFIG_TOTAL;
if (DataLen > tempDataLen)
DataLen = tempDataLen;
// Initialize the buffer pointer
TxBuffEp0P = UsbConfigDesc;
}
// Preload EP0 FIFO to get ready for IN transaction that follows.
// Write up to sixteen bytes to the Endpoint 0 data buffer
for (count = 0; count < UDC_MAX_PACKET_SIZE_CTL; count++)
{
regsP->UDDR0 = *TxBuffEp0P++;
DataLen--;
if (DataLen == 0)
break;
}
// Set UDCCS0.IPR = 1
regsP->UDCCS0 |= UDC_UDCCS0_IPR;
// Set the status of the Endpoint 0 state machine to IN data
EP0Status = EP0_InDataState;
break;
case GetConfigurationId:
break;
case SetDescriptorId:
// Save descriptor index (lower byte of wValue)
DescIndex = ReqData.wValue & 0xff;
// Save descriptor type (upper byte of wValue)
DescType = ReqData.wValue >> 8;
// Get the number of data bytes in the data stage that follows
DataLen = ReqData.wLength;
// Initialize buffer pointer
RxBuffEp0P = EP0OutData;
// Set UDCCS0.IPR in case of premature STATUS IN stage
regsP->UDCCS0 |= UDC_UDCCS0_IPR;
// Set the status of the Endpoint 0 state machine to OUT data
EP0Status = EP0_OutDataState;
break;
case SetConfigurationId:
// Save configuration value and configure the endpoints
ctxP->configNum = ReqData.wValue;
XsUdcSetConfig (ctxP);
// Set the status of the Endpoint 0 state machine to idle state
EP0Status = EP0_IdleState;
}
}
// Process Vendor Request
// Note: Vendor Request are used to setup various types of the transfers.
// bmRequestType: bits 6 and 5 = 10 (vendor defined)
// bits 4 through 0 = 00010 (endpoint)
// bRequest: SETUP IN EP = 0x01
// SETUP OUT EP = 0x02
// SETUP INT EP = 0x03
// SETUP LOOPBACK = 0x04
// wValue: LSB - Rx(OUT) Endpoint number
// MSB - Tx(IN) Endpoint number
// wIndex: Not Used
// wLength: 4 bytes will be sent in the data stage to the UDC.
// Identify Vendor specified request type
else if (tempReqType == VendorReq)
{
// Get ready to process the data that would be sent in the data stage
RxBuffEp0P = (PCHAR)&VendorReqXferLength;
VendorReqType = ReqData.bRequest;
VendorReqEndpointNum = ReqData.wValue;
VendorReqComplete = TRUE;
// Get the number of data bytes in the data stage that follows
DataLen = ReqData.wLength;
// Set UDCCS0.IPR in case of premature STATUS IN stage
regsP->UDCCS0 |= UDC_UDCCS0_IPR;
// Set the status of the Endpoint 0 state machine to OUT data
EP0Status = EP0_OutDataState;
/*
DM_ControlWordsDebugPrintPutBit (DM_CW_USB_CLIENT, 1);
DM_CwDbgPrintf(DM_CW_USB_CLIENT, "ReqData: %02x %02x %04x %04x %04x",
ReqData.bmRequestType,
ReqData.bRequest,
ReqData.wValue,
ReqData.wIndex,
ReqData.wLength);
*/
}
else if (tempReqType == ClassReq)
{}
}
// Clear UDCCS0.OPR and UDCCS0.SA
regsP->UDCCS0 |= (UDC_UDCCS0_OPR | UDC_UDCCS0_SA);
return status;
}
/*
*******************************************************************************
*
* FUNCTION: XsUdcProcessOutData
*
* DESCRIPTION: This function services the data OUT state of Endpoint 0 state machine.
* There is the number of events happening on this stage. It should:
*
* INPUT PARAMETERS: ctxP is a pointer to UDC's context structure
*
* RETURNS: 0 if successful
* UINT32 error if not
*
* GLOBAL EFFECTS: none.
*
* ASSUMPTIONS: none.
*
*******************************************************************************
*/
static
UINT32 XsUdcProcessOutData (UdcContextT * ctxP)
{
volatile UdcRegsT * regsP = (UdcRegsT *)ctxP->regsP;
INT retry = 16;
UINT32 status = FALSE;
// Check UDCCS0.OPR and UDCCS0.SA
if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == UDC_SETUP)
{
// UDCCS0.OPR and UDCCS0.SA both are set,
// there is another SETUP transaction has been sent by the host
// Initialize Endpoint 0 state machine to the Idle state
EP0Status = EP0_IdleState;
status = JUMP_TO_IDLE;
}
else if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == 0)
{
// UDCCS0.OPR = 0 and UDCCS0.SA = 0 this is premature STATUS stage of
// the SETUP transaction.
// Initialize Endpoint 0 state machine to the Idle state
EP0Status = EP0_IdleState;
}
else if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == UDC_UDCCS0_OPR)
{
// Read data from Endpoint 0 data buffer
while (((regsP->UDCCS0 & UDC_UDCCS0_RNE) != 0) && (--retry > 0))
{
// Read data from Endpoint 0 FIFO
if (retry > 0)
{
*RxBuffEp0P = regsP->UDDR0;
RxBuffEp0P++;
DataLen--;
// Stop unloading the data
if (DataLen == 0)
break;
}
else
break;
}
if (retry < 0)
{
// LOGERROR(ctxP->loggedError, ERR_L_XSFFUART,
// ERR_FLASH_NO_BUFFER, ERR_T_INVALIDACC, xsr, 0, 0);
return (ctxP->loggedError);
}
// Clear UDCCS0.OPR
regsP->UDCCS0 |= UDC_UDCCS0_OPR;
// Set UDCCS0.IPR in case of premature STATUS IN stage
regsP->UDCCS0 |= UDC_UDCCS0_IPR;
}
return status;
}
/*
*******************************************************************************
*
* FUNCTION: XsUdcProcessInData
*
* DESCRIPTION: This function services the data IN state of Endpoint 0 state machine.
* There is the number of events happening on this stage. It should:
* - identify data IN of the data stage, premature STATUS stage
* or another SETUP transaction,
* - write data to Endpoint 0 data buffer.
* It set the status of the Endpoint 0 state machine to transition to
* the next "End of Transfer" state.
*
* INPUT PARAMETERS: ctxP is a pointer to UDC's context structure
*
* RETURNS: 0 if successful
* UINT32 error if not
*
* GLOBAL EFFECTS: none.
*
* ASSUMPTIONS: none.
*
*******************************************************************************
*/
static
UINT32 XsUdcProcessInData (UdcContextT * ctxP)
{
volatile UdcRegsT * regsP = (UdcRegsT *)ctxP->regsP;
INT count;
UINT32 status = FALSE;
// Check UDCCS0.OPR and UDCCS0.SA
if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == UDC_SETUP)
{
// UDCCS0.OPR and UDCCS0.SA both are set,
// there is another SETUP transaction has been sent by the host
// Initialize Endpoint 0 state machine to the Idle state
EP0Status = EP0_IdleState;
status = JUMP_TO_IDLE;
}
else if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == UDC_UDCCS0_OPR)
{
// UDCCS0.OPR = 1 and UDCCS0.SA = 0 this is premature STATUS stage of
// the SETUP transaction. Clear UDCCS0.OPR.
regsP->UDCCS0 |= UDC_UDCCS0_OPR;
// Empty transmit FIFO
regsP->UDCCS0 |= UDC_UDCCS0_FTF;
// Reset all state machine variables
DataLen = 0;
TxBuffEp0P = NULL;
RxBuffEp0P = NULL;
// Initialize Endpoint 0 state machine to the Idle state
EP0Status = EP0_IdleState;
}
else if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == 0)
{
// Write data to Endpoint 0 data buffer.
if (DataLen != 0)
{
// Write sixteen bytes to the Endpoint 0 data buffer
for (count = 0; count < UDC_MAX_PACKET_SIZE_CTL; ++count)
{
regsP->UDDR0 = *TxBuffEp0P++;
DataLen--;
// Stop loading the data, short packet.
if (DataLen == 0)
break;
}
}
// It needs more data to transmit,
// so on the next interrupt go back to the same state.
if (DataLen != 0)
EP0Status = EP0_InDataState;
// It ends on the short packet so force UDC to transmit a short packet.
// Set Endpoint 0 state machine to the End of transfer state
else if (count < UDC_MAX_PACKET_SIZE_CTL && DataLen == 0)
{
regsP->UDCCS0 |= UDC_UDCCS0_IPR;
EP0Status = EP0_EndXferState;
}
// No more data left, force UDC to send zero lenght packet.
// Set Endpoint 0 state machine to the End of transfer state
else if (count == 0 && DataLen == 0)
{
regsP->UDCCS0 |= UDC_UDCCS0_IPR;
EP0Status = EP0_EndXferState;
}
}
return status;
}
static
UINT32 XsUdcProcessEndXfer (UdcContextT * ctxP)
{
volatile UdcRegsT * regsP = (UdcRegsT *)ctxP->regsP;
UINT32 i = FALSE;
// Check UDCCS0.OPR and UDCCS0.SA
if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == UDC_SETUP)
{
// UDCCS0.OPR and UDCCS0.SA both are set,
// there is another SETUP transaction has been sent by the host
// Initialize Endpoint 0 state machine to the Idle state
EP0Status = EP0_IdleState;
i = JUMP_TO_IDLE;
}
else if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == UDC_UDCCS0_OPR)
{
// UDCCS0.OPR = 1 and UDCCS0.SA = 0 this is STATUS stage of
// the IN transaction. Clear UDCCS0.OPR.
regsP->UDCCS0 |= UDC_UDCCS0_OPR;
// Initialize Endpoint 0 state machine to the Idle state
EP0Status = EP0_IdleState;
}
return i;
}
/*
*******************************************************************************
*
* FUNCTION: XsUdcEP0IntHandler
*
* DESCRIPTION: This function is an interrupt handler for Endpoint 0 of UDC
* It dispatches the functions of the Endpoint 0 in according
* to the status of the Endpoint 0 state machine.
*
* INPUT PARAMETERS: ctxP is a pointer to UDC's context structure
*
* RETURNS: none
*
* GLOBAL EFFECTS: none
*
* ASSUMPTIONS: Endpoint 0 Interrupt is enabled
*
*******************************************************************************
*/
void XsUdcEP0IntHandler (UdcContextT * ctxP)
{
UINT32 i =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -