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

📄 usb20hw.c

📁 printer usb
💻 C
📖 第 1 页 / 共 4 页
字号:
                         * Transfer complete. Call the endpoint service function
                         * for the endpoint.
                         */
                        USBserviceEP[ep_index](ep_index, FALSE,
                                               dTD->LENGTH -
                                                 (dTD->SIZE_IOC_STS >> 16));

                        /*
                         * Get the address of the next dTD, if any, masking
                         * off the Terminal Flag in low-order bit, and update
                         * Endpoint dTD Head table entry.
                         */
                        next_dTD = (dDT_STRUCT *)(dTD->NEXT & ~DTD_TERM_BIT);
                        usb_state.EP_DTD_HEADS[ep_index] = next_dTD;

                        /* Move the dTD to the free dTD pool. */
                        dTD->NEXT = (Uint32)usb_state.DTD_POOL;
                        usb_state.DTD_POOL = dTD;

                        dTD = next_dTD;
                    }
                }
            }
        }
    }
}

/**************************************************************************
*
*  Function Name  : USB_ISR_process_reset
*  Returned Value : None
*  Comments       :
*    Services reset interrupt.
*
**************************************************************************/
static void USB_ISR_process_reset(void)
{
    Uint32 endpt_bits, lpcnt, i;
    dDT_STRUCT *dTD;

    /* Set the address back to zero. */
    usb_opreg->DEVICE_ADDR = 0;
    usb_state.DEVICE_ADDRESS = 0;
    usb_state.USB_STATE = USB_STATE_DEFAULT;

    /* Clear all the setup token semaphores. */
    endpt_bits = usb_opreg->ENDPT_SETUP_STAT;
    usb_opreg->ENDPT_SETUP_STAT = endpt_bits;

    /* Clear all the endpoint complete status bits. */
    endpt_bits = usb_opreg->ENDPTCOMPLETE;
    usb_opreg->ENDPTCOMPLETE = endpt_bits;

    for (lpcnt = 0; lpcnt < HW_LOOP_CNT; lpcnt++) {
        /* Wait until all ENDPTPRIME bits cleared. */
        if (usb_opreg->ENDPTPRIME == 0)
            break;
    }

    if (usb_opreg->ENDPTPRIME == 0) {
        /*
         * Flush all endpoints:
         * NOTE: There is a caveat in the manual that flushing may take a
         * large amount of time AND SHOULD NOT BE DONE AT INTERRUPT LEVEL!
         * Also, we are warned that a transfer may be in progress at the time
         * of the flush request and to avoid obvious problems, the flush is
         * ignored and must be repeated. This should not be an issue for
         * normal resets; only if something bad is happening.
         */
        /* Write 1s to the Flush register. */
        usb_opreg->ENDPTFLUSH = 0xFFFFFFFF;
        for (lpcnt = 0; lpcnt < HW_LOOP_CNT; lpcnt++) {
            /* Wait until all bits are reset. */
            if (usb_opreg->ENDPTFLUSH == 0) {
                /* All done, now reinitialize endpoints and dTD pool. */
                for (i = 0; i < 2 * USB_MAX_ENDPOINTS; i++) {
                    /* Initially no endpoints are initialized. */
                    usb_state.EP_INIT[i] = FALSE;

                    /* Initialize all device queue heads. */
                    usb_state.EP_QUEUE_HEAD_PTR[i].NEXT_DTD_PTR = DTD_TERM_BIT;
                    usb_state.EP_DTD_HEADS[i] = NULL;
                }

                /* Enqueue all the dTDs into the free pool. */
                usb_state.DTD_POOL = NULL;
                dTD = usb_state.DTD_ALIGNED_BASE_PTR;
                for (i = 0; i < DTD_POOL_CNT; i++, dTD++) {
                    /* Move the dTD to the free dTD pool. */
                    dTD->NEXT = (Uint32)usb_state.DTD_POOL;
                    usb_state.DTD_POOL = dTD;
                }
 
                USB_init_endpoint(EP0_RECV, EP0_PKT_SIZE,
                                  USB_CONTROL_ENDPOINT, 0);
                USB_init_endpoint(EP0_SEND, EP0_PKT_SIZE,
                                  USB_CONTROL_ENDPOINT, 0);
                return;
            }
        }
    }
    /* Not successful; defer to task reset. */
    USB_ForceReset = RESET_SW;
}

/**************************************************************************
*
*  Function Name  : USB_task_process_reset
*  Returned Value : None
*  Comments       :
*    Services reset interrupt at task level.
*
**************************************************************************/
void USB_task_process_reset(void)
{
    Uint32 endpt_bits, lpcnt, i;
    dDT_STRUCT *dTD;

    /* Let ISR know that reset is in progress so it won't try an ISR reset. */
    if (!USB_ForceReset)
        USB_ForceReset = RESET_SW;

    /* Set the address back to zero. */
    usb_opreg->DEVICE_ADDR = 0;
    usb_state.DEVICE_ADDRESS = 0;
    usb_state.USB_STATE = USB_STATE_DEFAULT;

    /* Clear all the setup token semaphores. */
    endpt_bits = usb_opreg->ENDPT_SETUP_STAT;
    usb_opreg->ENDPT_SETUP_STAT = endpt_bits;

    /* Clear all the endpoint complete status bits. */
    endpt_bits = usb_opreg->ENDPTCOMPLETE;
    usb_opreg->ENDPTCOMPLETE = endpt_bits;

    for (lpcnt = 0; lpcnt < HW_LOOP_LIMIT; lpcnt++) {
        /* Wait until all ENDPTPRIME bits cleared. */
        if (usb_opreg->ENDPTPRIME == 0)
            break;
    }

    if (USB_ForceReset != RESET_HW && usb_opreg->ENDPTPRIME == 0) {
        /*
         * Flush all endpoints:
         * NOTE: There is a caveat in the manual that flushing may take a
         * large amount of time AND SHOULD NOT BE DONE AT INTERRUPT LEVEL!
         * Also, we are warned that a transfer may be in progress at the time
         * of the flush request and to avoid obvious problems, the flush is
         * ignored and must be repeated.
         */
        for (lpcnt = 0; lpcnt < HW_LOOP_LIMIT; lpcnt++) {
            /* Write 1s to the Flush register. */
            usb_opreg->ENDPTFLUSH = 0xFFFFFFFF;
            for (i = 0; i < HW_LOOP_CNT; i++) {
                /* Wait until all bits are reset. */
                if (usb_opreg->ENDPTFLUSH == 0)
                    break;
            }
            if (usb_opreg->ENDPTFLUSH == 0) {
                /* All done, now reinitialize endpoints > 0 and dTD pool. */
                for (i = 2; i < 2 * USB_MAX_ENDPOINTS; i++) {
                    /* Initially no endpoints are initialized. */
                    usb_state.EP_INIT[i] = FALSE;
                }

                for (i = 0; i < 2 * USB_MAX_ENDPOINTS; i++) {
                    /* Initialize all device queue heads. */
                    usb_state.EP_QUEUE_HEAD_PTR[i].NEXT_DTD_PTR = DTD_TERM_BIT;
                    usb_state.EP_DTD_HEADS[i] = NULL;
                }

                /* Enqueue all the dTDs into the free pool. */
                usb_state.DTD_POOL = NULL;
                dTD = usb_state.DTD_ALIGNED_BASE_PTR;
                for (i = 0; i < DTD_POOL_CNT; i++, dTD++) {
                    /* Move the dTD to the free dTD pool. */
                    dTD->NEXT = (Uint32)usb_state.DTD_POOL;
                    usb_state.DTD_POOL = dTD;
                }
                USB_ForceReset = NO_RESET;
                return;
            }
        }
    }

    /* Hardware failed; try to reset it and reinitialize data base. */
    USB_chip_and_data_base_initialize();
}

/**************************************************************************
*
*  Function Name  : USB_shutdown
*  Returned Value : None
*  Comments       :
*    Shuts down the VUSB_HS Device.
*
**************************************************************************/
void USB_shutdown(void)
{
    /* Disable Device Mode. */
    usb_opreg->USB_MODE &= ~VUSB_MODE_CTRL_MODE_DEV;

    /* Disable interrupts. */
    usb_opreg->USB_INTR &= ~(VUSB_INTERRUPT_BITS);

    /* Reset the Run the bit in the command register to stop VUSB. */
    usb_opreg->USB_CMD &= ~VUSB_CMD_RUN_STOP;
}

/**************************************************************************
*
*  Function Name  : USB_ISR_set_address
*  Returned Value : None
*  Comments       :
*    Sets the newly assigned device address.
*
**************************************************************************/
void USB_ISR_set_address(Uint8 address)
{
    /* The address bits are passed in bits 31-25. Set the address. */
    usb_opreg->DEVICE_ADDR = ((Uint32)address << VUSB_ADDRESS_BIT_SHIFT);
}

/**************************************************************************
*
*  Function Name  : USB_ISR_get_endpoint_status
*  Returned Value : endpoint status  bit0 :: STALL
*  Comments       :
*    Gets the endpoint status.
*
**************************************************************************/
Uint8 USB_ISR_get_endpoint_status(Uint8 ep_num)
{
    ep_num &= 0xf;
    return ((usb_opreg->ENDPTCTRLX[ep_num] & VUSB_EPCTRL_EP_STALL) ? 1 : 0);
}

/**************************************************************************
*
*  Function Name  : USB_ISR_set_endpoint_status
*  Returned Value : None
*  Comments       :
*    Sets the endpoint registers, i.e., set/clear ENDPOINT_HALT.
*
**************************************************************************/
void USB_ISR_set_endpoint_status(Uint8 ep_num, Uint8 stall)
{
    Uint8 tx;

    tx = ep_num & 0x80;
    ep_num &= 0x0f;

    if (!ep_num) {
        if (stall)
            usb_opreg->ENDPTCTRLX[0] |= VUSB_EPCTRL_EP_STALL;
        else
            usb_opreg->ENDPTCTRLX[0] &= ~VUSB_EPCTRL_EP_STALL;
    }

    else if (stall) {
        if (tx)
            usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_TX_EP_STALL;
        else
            usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_RX_EP_STALL;
    }
    else {
        if (tx) {
            usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_TX_DATA_TOGGLE_RST;
            usb_opreg->ENDPTCTRLX[ep_num] &= ~VUSB_EPCTRL_TX_EP_STALL;
        }
        else {
            usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_RX_DATA_TOGGLE_RST;
            usb_opreg->ENDPTCTRLX[ep_num] &= ~VUSB_EPCTRL_RX_EP_STALL;
        }
    }
}

/**************************************************************************
*
*  Function Name  : USB_ISR_set_test_mode
*  Returned Value : None
*  Comments       :
*    Sets/resets the test mode.
*
**************************************************************************/
void USB_ISR_set_test_mode(Uint16 test_mode)
{
    usb_opreg->ENDPTCTRLX[0] |= VUSB_EPCTRL_TX_DATA_TOGGLE_RST;

    if (test_mode == USB_TEST_MODE_TEST_PACKET)
        USB_ISR_io_request(EP0_SEND, (void *)test_packet,
                           USB_TEST_MODE_PACKET_LENGTH);

    usb_opreg->PORTSCX[0] |= (Uint32)test_mode << 8;

    /* Hang up in ISR next time in. */
    TestModeLock = TRUE;
}

#ifdef NOT_IMPLEMENTED
/*
 * The following is for "documentation" purposes if there is some need in
 * the future.
 */

/**************************************************************************
*
*  Function Name  : USB_process_resume
*  Returned Value : None
*  Comments       :
*    Process Resume event.
*
**************************************************************************/
/* NOT CALLED and NOT COMPLETE - should not be called at interrupt level. */
void USB_assert_resume(void)
{
    Uint32 i, temp;

    /* Assert the Resume signal. */
    usb_opreg->PORTSCX[0] |= VUSB_PORTSCX_PORT_FORCE_RESUME;

    /* Keep it asserted for 20 ms. */
    for (i = 0; i < USB_RESUME_ASSERTION_PERIOD; i++) {
        temp = (usb_opreg->USB_FRINDEX & VUSB_FRINDEX_MS_MASK);
        while (temp == (usb_opreg->USB_FRINDEX & VUSB_FRINDEX_MS_MASK))
        {
        }
        /* 1 millisecond complete. */
    }

    /* Deassert the Resume. */
    usb_opreg->PORTSCX[0] &= ~VUSB_PORTSCX_PORT_FORCE_RESUME;
}

#endif

⌨️ 快捷键说明

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