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

📄 xsudc.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 2 页
字号:
        XllpUdcClearInterrupt (pUdcHandle, INT_ENDPOINT_0, PACKET_COMPL_INT);
        // Update statistics
        ++pUdcHandle->interruptStat.EpIntCount[INT_ENDPOINT_0];
    }

    // Check if this is Endpoint 0 FIFO error interrupt
    if (statusISR0 & XLLP_UDC_UDCISR0_IR0_1)
    {
        PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 2);
        // Clear the Endpoint 0 Interrupt
        XllpUdcClearInterrupt (pUdcHandle, INT_ENDPOINT_0, FIFO_ERROR_INT);
    }

    // Process the pending interrupts from the Endpoints in active configuration
    while (pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum > 0)
    {
        udcEndpointNum = pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum;
        // Get Endpoint's packet complete interrupt status
        XllpUdcGetStatusInterrupt (pUdcHandle, 
                                  udcEndpointNum,
                                  PACKET_COMPL_INT,
                                  &packetComplIntStatus);
        if (packetComplIntStatus)
        {
            // Determine the direction of the Endpoint
            if (pRegs->UDCCRZ[udcEndpointNum] & XLLP_UDC_UDCCRZ_ED)
            {
                // This is IN Endpoint
                PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 3);
                XllpUdcFillFifo (pUdcHandle, udcEndpointNum, XLLP_TRUE); 
            }
            else
            {
                // This is OUT Endpoint
                PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 4);
                XllpUdcUnloadFifo (pUdcHandle, udcEndpointNum);  
            }
            // Clear the Interrupt
            XllpUdcClearInterrupt (pUdcHandle, udcEndpointNum, PACKET_COMPL_INT);
            // Update statistics
            ++pUdcHandle->interruptStat.EpIntCount[udcEndpointNum];
        }
      
        // Get Endpoint's FIFO error interrupt status
        XllpUdcGetStatusInterrupt (pUdcHandle,
                                  udcEndpointNum,
                                  FIFO_ERROR_INT,
                                  &fifoErrorIntStatus);
        if (fifoErrorIntStatus)
        {
            // If this is IN Endpoint, the FIFO underrun happened,
            // The UDC will issue NAK to the host for Bulk and Interrupt transfers,
            // and sends zero-length packet for Iso 
            // if this is OUT Endpoint, the FIFO overrun happened,
            // The UDC will issue NAK to the host for Bulk and Interrupt OUT tokens.
            PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 5);
            
            // Clear the Endpoint FIFO Interrupt
            XllpUdcClearInterrupt (pUdcHandle, udcEndpointNum, FIFO_ERROR_INT);
        }
        ++i;
    }
}

XLLP_STATUS_T XllpUdcRegisterFirstLevelInterrupt(P_XLLP_UDC_T pUdcHandle)
{
    UINT32 error = FALSE;
    
    // Register the UDC interrupt handler    
    error = XsIcRegisterHandler (XSIC_USB_SGNL, (XsIcL1IntHandlerFnPT)XsUdcInterruptHandler, 
                                    (void*)pUdcHandle);
    if (error)
    {
        LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_INT_HANDLER, 1, ERR_T_ILLPARAM, 0, 0, 0);
    }
    
    return error;
}

XLLP_STATUS_T XllpUdcUnRegisterFirstLevelInterrupt(void)
{
    UINT32 error = FALSE;
    
    // Register the UDC interrupt handler    
    error = XsIcUnRegisterHandler (XSIC_USB_SGNL);
    if (error)
    {
        LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_INT_HANDLER, 2, ERR_T_ILLPARAM, 0, 0, 0);
    }
    
    return error;

}


XLLP_STATUS_T XllpUdcEnableFirstLevelInterrupt(void)
{
    UINT32 error = FALSE;
    
    // Enable first level UDC interrupt
    error = XsIcEnableIrqDeviceInt (XSIC_USB_SGNL);
    if (error)
    {
        LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_ENABLE_INT, 1, ERR_T_NO_HANDLER, 0, 0, 0);
    }

    return error;
}

XLLP_STATUS_T XllpUdcDisableFirstLevelInterrupt(void)
{
    UINT32 error = FALSE;
    
    // Enable first level UDC interrupt
    error = XsIcDisableIrqDeviceInt (XSIC_USB_SGNL);
    if (error)
    {
        LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_ENABLE_INT, 2, ERR_T_NO_HANDLER, 0, 0, 0);
    }

    return error;
}

/******************************************************************************

  Function Name: 
    XsUdcSend

  Description:
    This function is used to transfer the data via the USB Endpoint 
    
  Global Register Modified: 
    None. 

  Input Arguments:
    P_XLLP_UDC_T pUdcHandle             - pointer to the UDC's handle
    XLLP_UDC_USB_EP_T usbEndpointNum    - the USB endpoint number
    P_XLLP_UINT32_T pTxBuff             - pointer to the transmit buffer
    XLLP_UINT32_T xferLength            - length of the transfer

  Output Arguments:
    P_XLLP_UINT32_T pXferCompleteFlag   - notifies the caller that transfer was completed or failed
          
  Return Value: 
    None

*******************************************************************************/

void XsUdcSend (P_XLLP_UDC_T pUdcHandle, 
                XLLP_UDC_USB_EP_T usbEndpointNum,
                P_XLLP_UINT32_T pTxBuff,
                XLLP_UINT32_T xferLength,
                P_XLLP_UINT32_T pXferCompleteFlag)
{
    XLLP_UDC_EP_T udcEndpointNum, i = 0;
    XLLP_VUINT32_T statusTxComplete = 0;

    // Get the UDC endpoint number that is correspond to the USB Endpoint number
    // from the list of active endpoints
    while (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum > 0)
    {
        if (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum == usbEndpointNum)
        {
            udcEndpointNum = pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum;
            break;
        }
        ++i;
    }

    if (pUdcHandle->enableDma == XLLP_TRUE)
    {
        // Disable endpoint's packet complete interrupt
        XllpUdcDisableInterrupt (pUdcHandle, 
                                udcEndpointNum,
                                PACKET_COMPL_INT);
        
        // Disable endpoint's FIFO error interrupt
        XllpUdcDisableInterrupt (pUdcHandle, 
                                udcEndpointNum,
                                FIFO_ERROR_INT);

        // Initilize the UDC's endpoint xfer structure and setup DMA
        XsUdcSetupInEndpointDma (pUdcHandle, udcEndpointNum, pTxBuff, xferLength);
    }
    else
    {
        // Initilize the UDC's endpoint xfer structure
        XsUdcSetupInEndpoint (pUdcHandle, udcEndpointNum, pTxBuff, xferLength);
        
        // Load Endpoint's FIFO with the first packet
        XllpUdcFillFifo (pUdcHandle, udcEndpointNum, XLLP_TRUE);
        
        // Enable endpoint's packet complete interrupt
        XllpUdcEnableInterrupt (pUdcHandle, 
                                udcEndpointNum,
                                PACKET_COMPL_INT);

        // Enable endpoint's FIFO error interrupt
        XllpUdcEnableInterrupt (pUdcHandle, 
                                udcEndpointNum,
                                FIFO_ERROR_INT);
    }

    // Wait for data to be sent
    while (!statusTxComplete)  
        statusTxComplete=pUdcHandle->EpXferTable[udcEndpointNum].TxXferComplete; 

        // Disable endpoint's packet complete interrupt
        XllpUdcDisableInterrupt (pUdcHandle, 
                                udcEndpointNum,
                                PACKET_COMPL_INT);
        
    // Notify caller that transfer was completed or failed
    *pXferCompleteFlag = pUdcHandle->EpXferTable[udcEndpointNum].TxXferComplete;
    pUdcHandle->EpXferTable[udcEndpointNum].TxXferComplete = XLLP_FALSE;
} 

/******************************************************************************

  Function Name: 
    XsUdcRead

  Description:
    This function is used to receive the data from the USB Endpoint 
    
  Global Register Modified: 
    None. 

  Input Arguments:
    P_XLLP_UDC_T pUdcHandle             - pointer to the UDC's handle
    XLLP_UDC_USB_EP_T usbEndpointNum    - the USB Endpoint number
    P_XLLP_UINT32_T pRxBuff             - pointer to the receive buffer

  Output Arguments:
    P_XLLP_UINT32_T pNumBytes           - total number of bytes being received
          
  Return Value: 
    None

*******************************************************************************/

void XsUdcRead (P_XLLP_UDC_T pUdcHandle, 
                 XLLP_UDC_USB_EP_T usbEndpointNum,
                 P_XLLP_UINT32_T pRxBuff,
                 P_XLLP_UINT32_T pNumBytes)
{
    UINT32 udcEndpointNum, i = 0;

    // Get the UDC endpoint number that is correspond to the USB Endpoint number
    // from the list of active endpoints
    while (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum > 0)
    {
        if (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum == usbEndpointNum)
        {
            udcEndpointNum = pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum;
            break;
        }
        ++i;
    }
    
    // Reset OUT Endpoint and get ready for the transfer
    XllpUdcSetupOutEndpoint (pUdcHandle, udcEndpointNum);
    
    do 
    {
        if (pUdcHandle->EpXferTable[udcEndpointNum].RxXferComplete == XLLP_TRUE)
        {
            memcpy (pRxBuff, pUdcHandle->EpXferTable[udcEndpointNum].pDataEp, 
                                    pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter);
            *pNumBytes = pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter;
            // Disable endpoint's packet complete interrupt
            XllpUdcDisableInterrupt (pUdcHandle, 
                                    udcEndpointNum,
                                    PACKET_COMPL_INT);
        
            // Disable endpoint's FIFO error interrupt
            XllpUdcDisableInterrupt (pUdcHandle, 
                                    udcEndpointNum,
                                    FIFO_ERROR_INT);
            break;
        }
        else if (pUdcHandle->EpXferTable[udcEndpointNum].RxBlockXferComplete == XLLP_TRUE)
        {
            // We need to notify upper layer to request more memory, 
            // the transfer has not been completed yet
            memcpy (pRxBuff, pUdcHandle->EpXferTable[udcEndpointNum].pDataEp, 
                                    pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter);
            *pNumBytes = pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter;
            break;
        }
    }while (1);
}


UINT32 XsUdcHWSetup (void)
{
    UINT32 status = FALSE;
    UINT32 error = FALSE;

    status = XllpUdcHWSetup (&UsbDeviceController);
    if (status)
    {
        LOGERROR(error, ERR_L_XSUDC, ERR_S_XSUDC_HWSETUP, ERR_T_NODEVICE, 0, 0, 0);  
    }

    return error;
}

UINT32 XsUdcHWShutdown (void)
{
    P_XLLP_UDC_T pUdcHandle = &UsbDeviceController;
    volatile P_XLLP_UDC_REGISTERS_T pRegs = (P_XLLP_UDC_REGISTERS_T)pUdcHandle->pRegsBase;    
    XLLP_UINT32_T i;
    UINT32 status = FALSE;
    UINT32 error = FALSE;

    status = XllpUdcHWShutdown (pUdcHandle);
    if (status)
    {
        LOGERROR(error, ERR_L_XSUDC, ERR_S_XSUDC_SHUT, ERR_T_NODEVICE, 0, 0, 0);
    }

    // Free memory allocated for temp. Rx buffers
    for (i = 1; i < XLLP_UDC_MAX_EP_NUM; ++i)
    {
        // Check if this is OUT endpoint
        if (!(pRegs->UDCCRZ[i] & XLLP_UDC_UDCCRZ_ED))
        {
            // Free alocated memory
            if (pUdcHandle->EpXferTable[i].pDataEp != NULL) 
              free((PVOID)pUdcHandle->EpXferTable[i].pDataEp);
        }
    }

    // Clear Endpoints' Xfer table
    memset (&pUdcHandle->EpXferTable[0], 0, (sizeof(XLLP_UDC_XFER_T) * XLLP_UDC_MAX_EP_NUM));

    return error;
}

void XsUdcSWInit (void)
{
	XllpUdcSWInit (&UsbDeviceController, (P_XLLP_UDC_REGISTERS_T)XLLP_UDC_REGISTERS_BASE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -