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

📄 usbohci.c

📁 风河的vxworks-6.3 FOR amcc440epx BSP!
💻 C
📖 第 1 页 / 共 4 页
字号:
*
* ERRNO:
*   None.
* 
* \NOMANUAL
*/
LOCAL BOOLEAN usbOhciInitializeHostController
    (
    UINT8 uHostControllerIndex
    )
    {
   
    /* To hold the state of the OHCI Controller after reset */
    UINT32          uOhciControllerState = 0;

    /* To hold the value read from the registers */
    UINT32          uRegisterValue = 0;

    /* To hold the status of the operation */
    BUS_OPERATION_STATUS     uStatus = BUS_OPERATION_SUCCESS;

    /* To hold the status of initializing the root hub emulation module */
    USBHST_STATUS   nRootHubEmulationInit = FALSE;

    /* To hold the value of the HcFmInterval register */
    UINT32          uHcFmInterval = 0;

    /* To hold the temporary data */
    UINT32          uTemp = 0;
    
    UINT32          uTempEndpointDesc = 0;

    /* To hold the default control endpoint descriptor */
    USB_ENDPOINT_DESCRIPTOR controlEndpointDescriptor =
    	{
        7,                                      /* bLength */
        USB_OHCI_ENDPOINT_DESCRIPTOR_TYPE,      /* Endpoint Descritpor Type */
        0x00,                                   /* Endpoint Address */
        USB_OHCI_CONTROL_TRANSFER,              /* bmAttributes */
        USB_DEFAULT_DEVICE_MAXIMUM_PACKET_SIZE,	/* wMaxPacketSize */
        0                                       /* bInterval */
    	};


    /* To hold the pointer to the host controller information */
    PUSB_OHCI_INFORMATION   pOhciControllerInfo = NULL;

    /* Obtain the pointer to the host controller information */
    pOhciControllerInfo = &usbOhciControllerInfo[uHostControllerIndex];

    pOhciControllerInfo->uIrqNumber = pOhciBusInfo[uHostControllerIndex]->irq;
    pOhciControllerInfo->uBaseAddress =
                      (UINT32)pOhciBusInfo[uHostControllerIndex]->pBaseAddress;

    /* Initialize the OHCI Controller (BEGIN) */

    /*
     * The following initization steps should be followed to initialize
     * the OHCI Host Controller:
     *
     * a) Save the contents of the HcFmInterval register.
     * b) Issue a software reset to the host controller. It takes 1 micro
     *    second to complete the software reset.
     * c) Restore the contents of the HcFmInterval register.
     * d) Initialize the device data HCCA block to match the current
     *    device data state.
     * e) Initialize the Operational Registers to match the current device
     *    data state.
     * f) Program the HcHCCA register with the physical address of the
     *    HCCA block.
     * g) Set HcInterruptEnable to have all interrupt enabled except SOF
     *    detect.
     * h) Set HcControl to have "all queues on".
     * i) Set HcPeriodicStart to a value that is 90% of the value in
     *    FrameInterval field of HcFmInterval register.
     * j) Put the host control in Operation State.
     */

    OS_LOG_MESSAGE_LOW(
        OHCD,
        "Entering the function: usbOhciInitializeHostController().\n",
        0,
        0,
        0,
        0);


    /* Create the endpoint list access event */
    pOhciControllerInfo->endpointListAccessEvent =
        OS_CREATE_EVENT (OS_EVENT_SIGNALED);

    /* Check whether the event was created successfully */
    if (pOhciControllerInfo->endpointListAccessEvent == OS_INVALID_EVENT_ID)
    	{
        return FALSE;
    	}

    /*
     * Allocate memory for the Host Controller Communication Area.
     *
     * NOTE: This memory should be aligned to 256 bytes boundary.
     */
    pOhciControllerInfo->pHcca =
        (PUSB_OHCI_HCCA) OS_MALLOC (sizeof(USB_OHCI_HCCA) + 256);
    /* Check whether memory was allocated successfully */
    if (pOhciControllerInfo->pHcca == NULL)
    	{
        return FALSE;
    	}

    /* Reset the Host Controller Communication Area */
    OS_MEMSET ((PUCHAR) pOhciControllerInfo->pHcca,
              0,
              sizeof(USB_OHCI_HCCA) + 256);

    /*
     * Check whether the Host Controller Communication Area is aligned to
     * 256 bytes boundary.
     */
    uTemp = (UINT32) pOhciControllerInfo->pHcca;
    if ((uTemp % 256) != 0)
    	{
        /*
         * Align the Host Controller Communication Area to 256 bytes
         * boundary
         */
        pOhciControllerInfo->pHccaAligned =
            (PUSB_OHCI_HCCA) ((uTemp & (~0xFF)) + 256);
    	}
    else
    	{
        /* Initialize the Host Controller Communication Area pointer */
        pOhciControllerInfo->pHccaAligned = pOhciControllerInfo->pHcca;
    	}



    /* Create the pipe for the default control endpoint */

    uStatus = usbOhciCreatePipe (
				uHostControllerIndex,
				USB_DEFAULT_DEVICE_ADDRESS,
				USB_DEFAULT_DEVICE_SPEED,
				(PUCHAR) (&controlEndpointDescriptor),
				(UINT16) 0,
				(PUINT32) (&uTempEndpointDesc));

    pOhciControllerInfo->pDefaultEndpointDescriptor = (PUSB_OHCI_ENDPOINT_DESCRIPTOR)
                                                       uTempEndpointDesc;

    /*
     * Check whether the pipe for default control endpoint was created
     * successfully
     */
    if (uStatus != USBHST_SUCCESS)
    	{
        /* Return from the function */
        return FALSE;
    	}

    /* Read the contents of the HcFmInterval register */
    uHcFmInterval = USB_OHCI_REG_READ (uHostControllerIndex, 
                                       (pOhciControllerInfo->uBaseAddress + 
                                       USB_OHCI_FM_INTERVAL_REGISTER_OFFSET));

    /* Reset the OHCI Controller */
    USB_OHCI_REG_WRITE (uHostControllerIndex, 
                        (pOhciControllerInfo->uBaseAddress + 
                        USB_OHCI_COMMAND_STATUS_REGISTER_OFFSET),
                        USB_OHCI_COMMAND_STATUS_HCR);

    /*
     * Wait for the reset operation to complete. The reset operation should
     * be completed in 1 micro second. However, a delay of 1 milli second
     * is provided.
     *
     * NOTE: This extra delay will not create any performance issues.
     *       Since the host controller is being enabled, this delay is
     *       acceptable.
     */
    OS_DELAY_MS (USB_OHCI_WAIT_FOR_HOST_CONTROLLER_RESET_COMPLETION);

    /* Wait for the reset to be complete */
    while ((USB_OHCI_REG_READ (uHostControllerIndex,
                           (pOhciControllerInfo->uBaseAddress + 
                           USB_OHCI_COMMAND_STATUS_REGISTER_OFFSET)) & 
                           USB_OHCI_COMMAND_STATUS_HCR) != 
            0)
        {
        OS_DELAY_MS(1);
        }

    /* Check the status of the OHCI Controller */
    uOhciControllerState =
        USB_OHCI_REG_READ (uHostControllerIndex,
                           (pOhciControllerInfo->uBaseAddress + 
                           USB_OHCI_CONTROL_REGISTER_OFFSET));

    /* Check whether the OHCI Controller is in SUSPEND state */
    if ((uOhciControllerState & USB_OHCI_CONTROL_HCFS_USB_SUSPEND) != 
        USB_OHCI_CONTROL_HCFS_USB_SUSPEND)
        {
        /* Failed to reset the OHCI Controller */
        OS_LOG_MESSAGE_HIGH (
            OHCD,
            "Failed to reset the host controller ..... \n",
            0,
            0,
            0,
            0);

        return FALSE;
        }

    /*
     * Update the maximum packet size that can be transmitted by the host
     * controller without causing a schedule overrun. (BEGIN)
     */

    /* Update the largets packet size that can be transmitted in a frame */
    /* PENDING: Give proper explanation for this value */
    uHcFmInterval = uHcFmInterval | (0x2781 << 16);

    /*
     * Update the maximum packet size that can be transmitted by the host
     * controller without causing a schedule overrun. (END)
     */
     
    /* Restore the contents of the HcFmInterval register */
    USB_OHCI_REG_WRITE (uHostControllerIndex, 
                       (pOhciControllerInfo->uBaseAddress + 
                        USB_OHCI_FM_INTERVAL_REGISTER_OFFSET), 
                        uHcFmInterval);


    /* Flush the contents of the cache to the RAM */

    DMA_FLUSH(pOhciControllerInfo->pHccaAligned, sizeof(USB_OHCI_HCCA));

    /* Invalidate the cache */

    DMA_INVALIDATE(pOhciControllerInfo->pHccaAligned, sizeof(USB_OHCI_HCCA));

    /*
     * Program the Host Controller Communication Area into the HcHCCA
     * Register
     */

    USB_OHCI_REG_WRITE (uHostControllerIndex, 
                        (pOhciControllerInfo->uBaseAddress + 
                        USB_OHCI_HCCA_REGISTER_OFFSET),
              		(USB_OHCD_CONVERT_TO_BUS_MEM (uHostControllerIndex,
                        pOhciControllerInfo->pHccaAligned)));

    /*
     * Initialize the Host Controller Communication Area for interrupt and
     * isochronous transfers.
     *
     * NOTE: No initialization is required. The transfers will be queued
     *       based on the need.
     */

    /*
     * Initialize the head pointer for bulk transfers.
     *
     * NOTE: No initailization is required. The transfers will be queued
     *       based on the need.
     */

    /* Initialize the head pointer for control transfers (BEGIN) */


    /* Program the HcControlHeadED register */
    USB_OHCI_REG_WRITE (uHostControllerIndex, 
		(pOhciControllerInfo->uBaseAddress + 
                USB_OHCI_CONTROL_HEAD_ED_REGISTER_OFFSET),
                (USB_OHCD_CONVERT_TO_BUS_MEM (uHostControllerIndex,
                pOhciControllerInfo->pDefaultEndpointDescriptor)));

    /* Initialize the head pointer for control transfers (END) */

    /*
     * Enable the data transfers lists in the HcControl Register (BEGIN)
     *
     * The following lists are initialized.
     *
     * a) Control List Enable
     * b) Bulk List Enable
     * c) Periodic List Enable (Interrupt Only)
     * d) Isochronous List Enable
     */

    /* Read the contents of the HcControl register */
    uTemp = USB_OHCI_REG_READ (uHostControllerIndex, 
                               pOhciControllerInfo->uBaseAddress + 
                               USB_OHCI_CONTROL_REGISTER_OFFSET);

    /* Enable the processing of the endpoint descriptor list */
    uTemp |= (USB_OHCI_CONTROL_CLE | 
              USB_OHCI_CONTROL_BLE | 
              USB_OHCI_CONTROL_PLE | 
              USB_OHCI_CONTROL_IE);

    /* Update the contents of the HcControl register */
    USB_OHCI_REG_WRITE (uHostControllerIndex, 
		(pOhciControllerInfo->uBaseAddress + USB_OHCI_CONTROL_REGISTER_OFFSET), 
		uTemp);

    /* Enable the control list in the HcControl Register (END) */

    /* Update the HcPeriodicStart Register (BEGIN) */

    /* Read the contents of the HcFmInterval register */
    uTemp = USB_OHCI_REG_READ (uHostControllerIndex, 
 			       pOhciControllerInfo->uBaseAddress + 
                               USB_OHCI_FM_INTERVAL_REGISTER_OFFSET);
    /* Obtain the contents of the HcFmInterval::FrameInterval field */
    uRegisterValue = uTemp & 0x00003FFF;

    /* Compute the frame interval for starting the periodic transfers */
    uRegisterValue = (uRegisterValue *
                      USB_OHCI_PERCENTAGE_BANDWIDTH_FOR_PERIODIC_TRANSFERS);

    uRegisterValue = (uRegisterValue & 0x00003FFF);

    /*
     * Program the HcPeriodicStart register with the frame interval for
     * starting the periodic transfers.
     */
    USB_OHCI_REG_WRITE (uHostControllerIndex, 
		(pOhciControllerInfo->uBaseAddress + 
                USB_OHCI_PERIODIC_START_REGISTER_OFFSET),
		uRegisterValue);

    /* Update the HcPeriodicStart Register (END) */

    /*
     * Update the maximum periodic bandwidth available on this OHCI host
     * controller.
     */
    pOhciControllerInfo->uMaximumBandwidthAvailable =
        (UINT32) (USB_OHCI_MAXIMUM_USB11_BANDWIDTH *
                 USB_OHCI_PERCENTAGE_BANDWIDTH_FOR_PERIODIC_TRANSFERS);

    /* Set the OHCI Controller to operational state (BEGIN) */

    /*
     * NOTE: After host controller reset, the host controller enters the
     *       USB_SUSPEND state. The host controller should not remain in 
     *       this state for more than 2 ms. If not, the host controller 
     *       will enter USB_RESUME state and the host controller should
     *       remain in this state for the minimum duration specified in
     *       the USB specification (i.e. 5 ms).
     */

    /* Read the contents of the HC Control Register */
    uRegisterValue = USB_OHCI_REG_READ (uHostControllerIndex, 
		                        pOhciControllerInfo->uBaseAddress + 
                                        USB_OHCI_CONTROL_REGISTER_OFFSET);

    /* Clear the previous state */
    uRegisterValue &= (~USB_OHCI_CONTROL_HCFS_MASK);

    /* Set the OHCI Controller in operational state */
    uRegisterValue |= USB_OHCI_CONTROL_HCFS_USB_OPERATIONAL;

    /* Program the HC Control Register */
    USB_OHCI_REG_WRITE (uHostControllerIndex, 
		        (pOhciControllerInfo->uBaseAddress + 
                        USB_OHCI_CONTROL_REGISTER_OFFSET),
                        uRegisterValue);

    /* Set the OHCI Controller to operational state (END) */

    /*
     * Update the frame interval register (BEGIN) 
     *
     * NOTE: It is observed that some controllers like Opti OHCI card
     *       do not allow the HcFmInterval register to be updated when the 
     *       controller is in USB_SUSPEND state. Hence, the HcFmInterval 
     *       register is updated after the host controller is in 
     *       USB_OPERATIONAL state.
     */

	OS_DELAY_MS(2);

     /* Update the contents of the HcFmInterval register */
     USB_OHCI_REG_WRITE (uHostControllerIndex, 
                        (pOhciControllerInfo->uBaseAddress +
                             USB_OHCI_FM_INTERVAL_REGISTER_OFFSET),
                         uHcFmInterval);

    /* Update the frame interval register (END) */

    /* Initialize the root hub emulation module */
    nRootHubEmulationInit = usbOhciRootHubEmulationInit (uHostControllerIndex);

    /*
     * Check whether the root hub emulation module was initialize
     * successfully
     */
    if (nRootHubEmulationInit != USBHST_SUCCESS)
        {
        /* Failed to initialize the root hub emulation module */
        OS_LOG_MESSAGE_HIGH (
            OHCD,
            "Failed to initialize the root hub emulation module ..... \n",
            0,
            0,
            0,
            0);

        return FALSE;
        }


    /* Read the contents of the HcRhDescriptorA Register */
    uRegisterValue = USB_OHCI_REG_READ (uHostControllerIndex,
                           (pOhciControllerInfo->uBaseAddress + 
                           USB_OHCI_RH_DESCRIPTOR_A_REGISTER_OFFSET));


    uRegisterValue &= ~0x300;

⌨️ 快捷键说明

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