📄 xsusb.c
字号:
*
* INPUT PARAMETERS: UdcContextT * ctxP is a pointer to UDC's context structure
* UdcEndpointsT epNum - endpoint number
* INT numBytes - used to allocate memory
* INT maxPacketSize - max. packet size for the endpoint
*
* RETURNS: 0 if successful
* UINT32 error if memory can not be allocated
*
* GLOBAL EFFECTS: none
*
* ASSUMPTIONS: none
*
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsUdcSetupInEndpoint (UdcContextT * ctxP,
* UdcEndpointsT epNum,
* INT numBytes,
* INT maxPacketSize);
*
*******************************************************************************
*/
static
UINT32 XsUdcSetupInEndpoint (UdcContextT * ctxP,
UdcEndpointsT epNum,
INT numBytes,
INT maxPacketSize)
{
void * physicalAddrP;
UINT error = FALSE;
// Enable the endpoint's interrupt
XsUdcEnableEndpointInt (ctxP, epNum);
// Allocate memory for the data buffer
if (ctxP->EPXferTable[epNum].enableLoopback == FALSE)
{
error = mallocx(numBytes,
(void**)&ctxP->EPXferTable[epNum].EPDataP,
(void**)&physicalAddrP);
if (error)
{
LOGERROR(ctxP->loggedError, ERR_L_XSUDC,
ERR_S_XSUDC_GET_MEM, ERR_T_UNSPECIFIED, error, 0, 0);
return (ctxP->loggedError);
}
}
// Fill buffer with the test data for INTERRUPT IN endpoint
if ((epNum == Endpoint5)||(epNum == Endpoint10)||(epNum == Endpoint15))
FillBufferSerial (ctxP->EPXferTable[epNum].EPDataP, numBytes, UDC_TEST_PATTERN);
ctxP->EPXferTable[epNum].xferLength = numBytes;
ctxP->EPXferTable[epNum].xferDataCounter = 0;
ctxP->EPXferTable[epNum].maxPacketSize = maxPacketSize;
ctxP->EPXferTable[epNum].xferComplete = FALSE;
// Load IN Endpoint's FIFO with data
XsUdcFillFifo (ctxP, epNum);
return error;
}
/*
*******************************************************************************
*
* FUNCTION: XsUdcSetupOutEndpoint
*
* DESCRIPTION: This function will setup BULK OUT and ISO OUT endpoints.
*
* INPUT PARAMETERS: UdcContextT * ctxP is a pointer to UDC's context structure
* UdcEndpointsT epNum - endpoint number
* INT numBytes - used to allocate memory
* INT maxPacketSize - max. packet size for the endpoint
*
* RETURNS: 0 if successful
* UINT32 error if memory can not be allocated
*
* GLOBAL EFFECTS: none
*
* ASSUMPTIONS: none
*
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsUdcSetupOutEndpoint (UdcContextT * ctxP,
* UdcEndpointsT epNum,
* INT numBytes,
* INT maxPacketSize);
*
*******************************************************************************
*/
static
UINT32 XsUdcSetupOutEndpoint (UdcContextT * ctxP,
UdcEndpointsT epNum,
INT numBytes,
INT maxPacketSize)
{
volatile UdcRegsT * regsP = (UdcRegsT *)ctxP->regsP;
void * physicalAddrP;
UINT error = FALSE;
// Enable the endpoint's interrupt
XsUdcEnableEndpointInt (ctxP, epNum);
// Clear UDCCS_OUT.DME bit
switch (epNum)
{
case Endpoint2:
regsP->UDCCS2 &= ~UDC_UDCCS_DME_OUT;
break;
case Endpoint4:
regsP->UDCCS4 &= ~UDC_UDCCS_DME_OUT;
break;
}
// Allocate memory for the data buffer
error = mallocx(numBytes,
(void**)&ctxP->EPXferTable[epNum].EPDataP,
(void**)&physicalAddrP);
if (error)
{
LOGERROR(ctxP->loggedError, ERR_L_XSUDC,
ERR_S_XSUDC_GET_MEM, ERR_T_UNSPECIFIED, error, 0, 0);
return (ctxP->loggedError);
}
ctxP->EPXferTable[epNum].xferLength = numBytes;
ctxP->EPXferTable[epNum].xferDataCounter = 0;
ctxP->EPXferTable[epNum].maxPacketSize = maxPacketSize;
return error;
}
/*
*******************************************************************************
*
* FUNCTION: XsUdcProcessVendorRequest
*
* DESCRIPTION: This function sets up Bulk, ISO, and Interrupt transactions.
* It enables or disables endpoints' interrupts based on the status
* ctxP->enableDma, sets up the Dma engine or preloads the endpoints'
* FIFO with the data for the IN transaction.
* Vendor Request are used to setup various types of the transfers.
* Vendor Request format:
* 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
* bRequest is passed in requestType
*
* wValue: LSB - Rx(OUT) Endpoint number
* MSB - Tx(IN) Endpoint number
* wValue is used to pass IN and/or OUT Endpoints
* wIndex: Not Used
* wLength: 4 bytes will be sent in the data stage to the UDC
* these bytes can be used to control various functions
*
* To setup loopback: 1. Send SETUP OUT EPx request
* 2. Send SETUP LOOPBACK on EPx and EPy
*
* INPUT PARAMETERS: UdcContextT * ctxP - a pointer to UDC's context structure
* UdcVendorReqTypeT requestType - a vendor request type
* UINT16 epNum - an endpoint number.
* INT numBytes - number of bytes to transfer (if zero, then
* a default length is used)
*
* RETURNS: None.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: Usb client is attached to Usb Host port.
*
* CALLS:
*
* CALLED BY: The menu system
*
* PROTOTYPE: VOID XsUdcProcessVendorRequest (UdcContextT * ctxP,
* UdcVendorReqTypeT requestType,
* UINT16 epNum,
* INT numBytes);
*
*******************************************************************************
*/
static
VOID XsUdcProcessVendorRequest (UdcContextT * ctxP,
UdcVendorReqTypeT requestType,
UINT16 epNum,
INT numBytes)
{
INT maxPacketSize;
INT inEpNum;
INT outEpNum;
// Get the endpoints numbers
inEpNum = (epNum >> 8) & 0x0f;
outEpNum = epNum & 0x0f;
// Determine the max. packet size of the endpoint
// Temp!!! I am planning to process the config. descriptors to get the data
switch (inEpNum)
{
case Endpoint1:
maxPacketSize = BULK_IN_LENGTH;
break;
case Endpoint3:
maxPacketSize = ISO_IN_LENGTH;
break;
case Endpoint5:
maxPacketSize = INT_IN_LENGTH;
break;
}
switch (outEpNum)
{
case Endpoint2:
maxPacketSize = BULK_OUT_LENGTH;
break;
case Endpoint4:
maxPacketSize = ISO_OUT_LENGTH;
break;
}
if (numBytes == 0)
numBytes = maxPacketSize * NUM_TEST_BLOCKS;
switch (requestType)
{
case UsbSetupInEp:
ctxP->EPXferTable[inEpNum].enableLoopback = FALSE;
if ((ctxP->enableDma == TRUE) && (maxPacketSize >= DMA_BUFF_SIZE_MIN))
{
XsUdcSetupInEndpointDma (ctxP, inEpNum, 0, numBytes, maxPacketSize);
}
else
{
XsUdcSetupInEndpoint (ctxP, inEpNum, numBytes, maxPacketSize);
}
break;
case UsbSetupOutEp:
if ((ctxP->enableDma == TRUE) && (maxPacketSize >= DMA_BUFF_SIZE_MIN))
{
XsUdcSetupOutEndpointDma (ctxP, outEpNum, numBytes, maxPacketSize);
}
else
{
XsUdcSetupOutEndpoint (ctxP, outEpNum, numBytes, maxPacketSize);
}
break;
case UsbSetupLoopback:
ctxP->EPXferTable[inEpNum].enableLoopback = TRUE;
if ((ctxP->enableDma == TRUE) && (maxPacketSize >= DMA_BUFF_SIZE_MIN))
{
XsUdcSetupInEndpointDma (ctxP, inEpNum, outEpNum, numBytes, maxPacketSize);
}
else
{
ctxP->EPXferTable[inEpNum].EPDataP = ctxP->EPXferTable[outEpNum].EPDataP;
XsUdcSetupInEndpoint (ctxP, inEpNum, numBytes, maxPacketSize);
}
break;
case UsbSetupIntEp:
ctxP->EPXferTable[inEpNum].enableLoopback = FALSE;
XsUdcSetupInEndpoint (ctxP, inEpNum, numBytes, maxPacketSize);
break;
}
}
/*
*******************************************************************************
*
* FUNCTION: XsUdcSetConfig
*
* DESCRIPTION: This function configures the endpoints based on the avalable
* configurations. It processes the configuration descriptors and
* sets up the table of the interfaces and the endpoints within
* the configuration.
*
* INPUT PARAMETERS: UdcContextT * ctxP - a pointer to UDC's context structure
*
* RETURNS: None.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: Usb client is attached to Usb Host port.
*
* CALLS:
*
* CALLED BY: The menu system
*
* PROTOTYPE: VOID XsUdcSetConfig (UdcContextT * ctxP);
*
*******************************************************************************
*/
static
VOID XsUdcSetConfig (UdcContextT * ctxP)
{
volatile UdcRegsT * regsP = (UdcRegsT *)ctxP->regsP;
// Enable Endpoint 0 interrupt and disable the interrupt requests from endpoints 1 - 7
regsP->UICR0 = UDC_DISABLE_ALL_INT & ~UDC_UICR0_IM0;
// Disable the interrupt requests from endpoints 8 - 15
regsP->UICR1 = UDC_DISABLE_ALL_INT;
// Process the descriptors and build the configuration table
//(ctxP->configNum)
}
/*
*******************************************************************************
*
* FUNCTION: XsUdcProcessIdle
*
* DESCRIPTION: This function is an entry point of Endpoint 0 state machine.
* There is the number of events happening on this stage. It should:
* - identify the SETUP transaction,
* - read data from Endpoint 0 data buffer,
* - parse the data and determine the request type,
* - identify the standard request type,
* - save the number of data bytes in the Data stage that follows.
* It set the status of the Endpoint 0 state machine to transition to
* the next "Data IN" or "Data OUT" states.
*
* INPUT PARAMETERS: ctxP is a pointer to UDC's context structure
*
* RETURNS: 0 if successful
* UINT32 error if not
*
* GLOBAL EFFECTS: none.
*
* ASSUMPTIONS:
*
*******************************************************************************
*/
static
UINT32 XsUdcProcessIdle (UdcContextT * ctxP)
{
volatile UdcRegsT * regsP = (UdcRegsT *)ctxP->regsP;
INT retry = 16;
PUCHAR rxBuffP;
UINT32 status = FALSE;
INT count;
UINT tempDataLen;
INT tempReqType;
rxBuffP = &ReqData.bmRequestType;
// Determine if UDCCS0.OPR and UDCCS0.SA both are set.
// It means that OUT packet in the Endpoint 0 buffer identifying SETUP transaction
if ((regsP->UDCCS0 & (UDC_UDCCS0_OPR | UDC_UDCCS0_SA)) == UDC_SETUP)
{
// Read data from Endpoint 0 data buffer
while (((regsP->UDCCS0 & UDC_UDCCS0_RNE) != 0) && (--retry > 0))
{
// Read data
if (retry > 0)
{
*rxBuffP++ = regsP->UDDR0;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -