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

📄 xsusb.c

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