⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsusb.c

📁 这是一个USB的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
*
* 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 + -