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

📄 drv_usb.c

📁 基于omap5912平台的usb设备驱动源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
       request = setup_Packet.bRequest; 
       
       if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,CSL_USBF_QUERY_IRQ_SRC,&irq_Src))
       {
            OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_IRQ_SRC:cmd failed \r\n"));
       }
    }

    /* Assume that the request is valid - and is to USB SPEC v1.1 */ 
    /* Perform any Requests */ 
    OS_DEBUGF(DEV_USB,(" request %2x \r\n",request));
    switch ( request )
    {
        /* ======== USB_GET_STATUS ======== */ 
        case USB_GET_STATUS:
            switch ( request_type & 0x3 )
            {
                case 0:
                    
                    /* Get Status for DEVICE */
                    if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,CSL_USBF_QUERY_DEVICE_STATUS,&devStatus))
                    {
                        OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_DEVICE_STATUS:cmd failed \r\n"));
                    }
                    
                    selfPwr = (Bool)(CSL_FEXT(hUsbf->regs->SYSCON1, USBF_SYSCON1_SELF_PWR));
                    response16 =  ( ( devStatus & 0x40 ) >> 5 )
                                | ( selfPwr  );
                    break;
                case 1:
                    /* Get Status for INTERFACE */
                    response16 = 0;
                    break;
                case 2:
                    /* Get Status for ENDPOINT */
                    if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,\
                                        CSL_USBF_QUERY_NONISO_EP_STATUS,&epStatus));
                    {
                        OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_NONISO_EP_STATUS:cmd failed \n"));
                    }
                    response16 = ( epStatus & \
                                      CSL_USBF_NONISO_EP_STATUS_EP_HALTED ) >> 6;
                    break;
                default:
                    stall( USB_DIR_IN );  /* Request ERROR */
                    return;
            }
            usbsend( 0, ( INT8U* )&response16, 2 );
            break;

        /* ======== USB_GET_DESCRIPTOR ======== */ 
        /* Determine which Descriptor to send */ 
        /* Action defined in USB Spec v1.1 */ 
        case USB_GET_DESCRIPTOR:
        

            switch ( ( value & 0xff00 ) >> 8 )
            {
                /* -------- Device Descriptor -------- */ 
                case USB_DEVICE_DESC:
                    /* Standard Device Descriptor */ 
                    if ( length == 18 )
                        usbsend( 0, dev_desc, 18 );

                    /* Dummy Device Descriptor - for Windows Compatiablity
                     * here length = 64 */ 
                    else
                        usbsend( 0, dev_desc, 64 );
                    break;

                /* -------- Config Descriptor -------- */ 
                /* Configuration Tree
                     * |--> Config Desc.
                     *      |--> Interface1 Desc.
                     *           |--> Endpt1 Desc.
                     *           |--> Endpt2 Desc.
                     *      |--> Interface2 Desc. :Optional Interfaces & Endpts 
                     *           |--> Endpt3 Desc.
                     *           |--> Endpt4 Desc.
                     */ 
                case USB_CONFIG_DESC:
                    /* Standard Interface Descriptor - */
                    if ( length == 9 )
                        usbsend( 0, cfg_desc, 9 );
	
                    /* Expanded Interface Descriptor:  Return Configuration Tree
                     * that corresponds to the order above
                     * here length >= Size of Config Tree */ 
                    else if ( length >= cfg_desc_size )
                    {
                        send_len = usbsend( 0, cfg_desc, cfg_desc_size );
                        ep0_send_ptr = cfg_desc + send_len;
                        ep0_send_len = cfg_desc_size - send_len;
                        ep0_post_send = 1;
                    }
                    break;

                /* -------- String Descriptor -------- */ 
                case USB_STRING_DESC:
                    value &= 0x00FF;

                    /* Lookup in the internal String Descriptor table using 
                     * "value" as the search key */ 
                    for ( i = 0 ; i < USB_STRING_INDEX_MAX ; i++ )
                        if ( string_desc_tbl[i].index == value )
                            break;

                    /* If NO String Desc. found - 
                     * Send Request Error = Stall Command */ 
                    if ( i == USB_STRING_INDEX_MAX )
                        stall( USB_DIR_IN );
                    /* Else send String Desc. */ 
                    else 
                    {
                        send_len = usbsend( 0, string_desc_tbl[i].ptr, length );
                        ep0_send_ptr = string_desc_tbl[i].ptr + send_len;
                        ep0_send_len = length - send_len;
                        ep0_post_send = 1;
                    }
                    break;
            }
            break;

        /* ======== USB_GET_CONFIGURATION ======== */ 
        case USB_GET_CONFIGURATION:
            if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,\
                                CSL_USBF_QUERY_DEVICE_STATUS,&devStatus))
            {
                OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_DEVICE_STATUS:cmd failed \n"));
            }
            /* [ 1 = Device configured ; 0 = NOT configured ] */ 
            response8 = ( devStatus & CSL_USBF_DEVICE_STATUS_CONFIGURED ) ? 0x01 : 0x00;
            usbsend( 0, &response8, 1 );
            break;

        /* ======== USB_SET_CONFIGURATION ======== */ 
        /*  Check: does HOST wants to clear or set configuration?
         *    value = [ 1: Set Config ; 0: Clear Config ] */ 
        case USB_SET_CONFIGURATION:
            hUsbf->regs->SYSCON2 = ( value ) ? 0x8 : 0x4;

            /* Respond with a zero-length data pkt - ACK */ 
            usbsend( 0, NULL, 0 );
            test_result = 1;
            break;

        /* ======== USB_GET_INTERFACE ======== */ 
        /* Respond with number of interfaces, currently 1 interface
         * { interface[0] }, therefore respond by send N-1 = 0 */ 
        case USB_GET_INTERFACE:
            response8 = 0;
            usbsend( 0, &response8, 1 );
            break;

        /* ======== USB_MASS_STORAGE_RESET ======== */ 
        /* Respond with no data */ 
        case USB_MASS_STORAGE_RESET:
            usbsend( 0, NULL, 0 );
            break;

        /* ======== USB_GET_MAX_LUN ======== */ 
        /* Respond by return N - 1 logical units */ 
        case USB_GET_MAX_LUN:
            response8 = 0;
            usbsend( 0, &response8, 1 );
            break;

        /* ======== default ======== */ 
        /* Request Error: use a USB Stall to indicate an Error */ 
        default:
            stall( USB_DIR_IN );
            return;
    }
}
/** ============================================================================
 *   @func   set_DeviceDesc
 *   @desc
 *     Sets the descriptor for the USB device
 *
 * =============================================================================
 */

void set_DeviceDesc( INT8U* device_desc )
{
    dev_desc = device_desc;
}


/** ============================================================================
 *   @func   set_ConfigDesc
 *   @desc
 *     Sets the configuration for the USB device
 *
 * =============================================================================
 */
void set_ConfigDesc( INT8U * config_desc )
{
    cfg_desc = config_desc;
    cfg_desc_size = *( INT16U* )&config_desc[2];
}
/** ============================================================================
 *   @func   addStringDesc
 *   @desc
 *      Adds a String Desc to the internal String table.  The index parameter
 *      will become the search key, when retrieving the String.
 * 
 * =============================================================================
 */

void addStringDesc( INT8U* string, INT8U index )
{
	INT16U i;
    for ( i = 0 ; i < USB_STRING_INDEX_MAX ; i++ )
        if ( ! string_desc_tbl[i].ptr )
        {
            string_desc_tbl[i].ptr = string;
            string_desc_tbl[i].index = index;
            return;
        }
}

/** @brief Sets up the USBF to a useful state as specified
 *
 * Configures the USBF using the values passed in through the
 * setup structure. 
 * 
 * <b> Usage Constraints: </b>
 * Both @a CSL_usbfInit() and @a CSL_usbfOpen() must be called
 * successfully in that order before this function can be called. The user
 * has to allocate space for & fill in the main setup structure 
 * 
 * @b Example:
 * @verbatim


     CSL_UsbfHandle hUsbf;
     CSL_UsbfHwSetup hwSetup = {
         <TODO>
     };
     
    ...         
    
    CSL_usbfHwSetup(hUsbf, &hwSetup);
   @endverbatim
 * 
 * @return Returns the status of the setup operation
 * 
 */

CSL_Status  CSL_usbfHwSetup(
    /** Pointer to the object that holds reference to the
     * instance of USBF requested after the Open call */
    CSL_UsbfHandle             hUsbf,
    /** Pointer to setup structure which contains the
     * information to program USBF to a useful state */
    CSL_UsbfHwSetup            *hwSetup
)
{
    if(hwSetup == NULL)
        return CSL_ESYS_INVPARAMS ;
    if(hUsbf == NULL)
        return CSL_ESYS_BADHANDLE ;
        
/*==============================================================================*/
    if(hwSetup->epSetup != NULL)
    {
        int epNum ;
        if(hwSetup->epSetup->ep0 != NULL)         
        {
            register INT16U _ep0 =  hUsbf->regs->EP0;
                           
            CSL_FINS(_ep0, USBF_EP0_SIZE, hwSetup->epSetup->ep0->size);
            CSL_FINS(_ep0, USBF_EP0_PTR, hwSetup->epSetup->ep0->ptr);
            
            hUsbf->regs->EP0  = _ep0;
        }
        
        for(epNum = 0; epNum < 15; epNum++)
        {
            if(hwSetup->epSetup->rxEp[epNum] != NULL)         
            {
                register INT16U _rx_ep = hUsbf->regs->RX_EP[epNum].RX_EP ;
                
                CSL_FINS(_rx_ep, USBF_RX_EP_VALID, hwSetup->epSetup->rxEp[epNum]->valid);
                
                CSL_FINS(_rx_ep, USBF_RX_EP_ISO, hwSetup->epSetup->rxEp[epNum]->type);

                /* Double buffering applies only if endpoint is of type Non-ISO */
                if((hwSetup->epSetup->rxEp[epNum]->type) == CSL_USBF_EPTYPE_NON_ISO)
                {
                    CSL_FINS(_rx_ep, USBF_RX_EP_SIZEDB, hwSetup->epSetup->rxEp[epNum]->doubleBuffered);
                    CSL_FINS(_rx_ep, USBF_RX_EP_SIZE, hwSetup->epSetup->rxEp[epNum]->size);
                }
                if((hwSetup->epSetup->rxEp[epNum]->type) == CSL_USBF_EPTYPE_ISO)
                {
                    /* Put MSB of 3 bit of 'size' into SIZEDB filed */
                    CSL_FINS(_rx_ep, USBF_RX_EP_SIZEDB, (hwSetup->epSetup->rxEp[epNum]->size) >> 2);
                    /* Put lower 2 bits of 'size' into SIZE filed */
                    CSL_FINS(_rx_ep, USBF_RX_EP_SIZE, (hwSetup->epSetup->rxEp[epNum]->size) & 0x3);
                }
                CSL_FINS(_rx_ep, USBF_RX_EP_PTR, hwSetup->epSetup->rxEp[epNum]->ptr);
                
                hUsbf->regs->RX_EP[epNum].RX_EP = _rx_ep ;
            }
        }
                
        for(epNum = 0; epNum < 15; epNum++)
        {
            if(hwSetup->epSetup->txEp[epNum] != NULL)         
            {
                register INT16U _tx_ep = hUsbf->regs->TX_EP[epNum].TX_EP ;
                
                CSL_FINS(_tx_ep, USBF_TX_EP_VALID, hwSetup->epSetup->txEp[epNum]->valid);
                
                CSL_FINS(_tx_ep, USBF_TX_EP_ISO, hwSetup->epSetup->txEp[epNum]->type);

                /* Double buffering applies only if endpoint is of type Non-ISO */
                if((hwSetup->epSetup->txEp[epNum]->type) == CSL_USBF_EPTYPE_NON_ISO)
                {
                    CSL_FINS(_tx_ep, USBF_TX_EP_SIZEDB, hwSetup->epSetup->txEp[epNum]->doubleBuffered);
                    CSL_FINS(_tx_ep, USBF_TX_EP_SIZE, hwSetup->epSetup->txEp[epNum]->size);
                }
                if((hwSetup->epSetup->txEp[epNum]->type) == CSL_USBF_EPTYPE_ISO)
                {
                    /* Put MSB of 3 bit of 'size' into SIZEDB filed */
                    CSL_FINS(_tx_ep, USBF_TX_EP_SIZEDB, (hwSetup->epSetup->txEp[epNum]->size) >> 2);
                    /* Put lower 2 bits of 'size' into SIZE filed */
                    CSL_FINS(_tx_ep, USBF_TX_EP_SIZE, (hwSetup->epSetup->txEp[epNum]->size) & 0x3);
                }
                CSL_FINS(_tx_ep, USBF_TX_EP_PTR, hwSetup->epSetup->txEp[epNum]->ptr);
                
                hUsbf->regs->TX_EP[epNum].TX_EP = _tx_ep ;
            }
        }
    }
    
/*==============================================================================*/        
    if(hwSetup->dmaSetup != NULL)
    {
        register INT16U _rxdma_cfg = hUsbf->regs->RXDMA_CFG ;

        register INT16U _txdma_cfg = hUsbf->regs->TXDMA_CFG ;
                
        CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RX_REQ, hwSetup->dmaSetup->rxRequestType) ;
        
        if(hwSetup->dmaSetup->rxChanSetup[2] != NULL)
        {        
            CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RXDMA2_EP, hwSetup->dmaSetup->rxChanSetup[2]->chanEpNum) ;
            CSL_FINS(hUsbf->regs->RXDMA2, USBF_RXDMA2_RX2_TC, hwSetup->dmaSetup->rxChanSetup[2]->transactionCount) ;
        }
        
        if(hwSetup->dmaSetup->rxChanSetup[1] != NULL)
        {        
            CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RXDMA1_EP, hwSetup->dmaSetup->rxChanSetup[1]->chanEpNum) ;
            CSL_FINS(hUsbf->regs->RXDMA1, USBF_RXDMA1_RX1_TC, hwSetup->dmaSetup->rxChanSetup[1]->transactionCount) ;
        }
    
        if(hwSetup->dmaSetup->rxChanSetup[0] != NULL)
        {        
            CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RXDMA0_EP, hwSetup->dmaSetup->rxChanSetup[0]->chanEpNum) ;
            CSL_FINS(hUsbf->regs->RXDMA0, USBF_RXDMA0_RX0_TC, hwSetup->dmaSetup->rxChanSetup[0]->transactionCount) ;
        }
        
        CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TX_REQ, hwSetup->dmaSetup->txRequestType) ;
        
        if(hwSetup->dmaSetup->txChanSetup[2] != NULL)
        {        
            CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TXDMA2_EP, hwSetup->dmaSetup->txChanSetup[2]->chanEpNum) ;
            CSL_FINS(hUsbf->regs->TXDMA2, USBF_TXDMA2_TX2_TSC, hwSetup->dmaSetup->txChanSetup[2]->txSize) ;
            CSL_FINS(hUsbf->regs->TXDMA2, USBF_TXDMA2_TX2_EOT, hwSetup->dmaSetup->txChanSetup[2]->txSizeType) ;
        }
        
        if(hwSetup->dmaSetup->txChanSetup[1] != NULL)
        {        
            CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TXDMA1_EP, hwSetup->dmaSetup->txChanSetup[1]->chanEpNum) ;
            CSL_FINS(hUsbf->regs->TXDMA1, USBF_TXDMA1_TX1_TSC, hwSetup->dmaSetup->txChanSetup[1]->txSize) ;
            CSL_FINS(hUsbf->regs->TXDMA1, USBF_TXDMA1_TX1_EOT, hwSetup->dmaSetup->txChanSetup[1]->txSizeType) ;
        }
        
        if(hwSetup->dmaSetup->txChanSetup[0] != NULL)
        {        
            CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TXDMA0_EP, hwSetup->dmaSetup->txChanSetup[0]->chanEpNum) ;
            CSL_FINS(hUsbf->regs->TXDMA0, USBF_TXDMA0_TX0_TSC, hwSetup->dmaSetup->txChanSetup[0]->txSize) ;
            CSL_FINS(hUsbf->regs->TXDMA0, USBF_TXDMA0_TX0_EOT, hwSetup->dmaSetup->txChanSetup[0]->txSizeType) ;
        }
                
        hUsbf->regs->RXDMA_CFG = _rxdma_cfg;

        hUsbf->regs->TXDMA_CFG = _txdma_cfg;        
        
    }       
    
/*=================

⌨️ 快捷键说明

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