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

📄 usbhost.c

📁 printer usb
💻 C
📖 第 1 页 / 共 5 页
字号:
            reset_the_device();

            while (!g_powerOn)
                TaskSleep(&delay_enum);
            TaskSleep(&delay_after_poweron);
            VPRINT("USB HOST: Printer powered on\n");
        }

        enumOK = FALSE;
        for (i = 0; g_powerOn && !g_powerWasOff && i < 10; i++) {
            enumOK = USB_enumerate();
            if (enumOK)
                break;
            VPRINT("USB_Host_Task: Failed to enumerate; retry %d...\n", i+1);
            TaskSleep(&delay_enum);
        }

        if (enumOK) {
            /*
             * New device detected and was assigned a USB address. Now set
             * configuration, interface, assign endpoints.
             */
            if (USB_GetConfiguration()) {
                if (StillImage.Config) {
                    Uint32 dpsConnect;

                    intcount = -1;

                    if (USB_DoConfiguration(&StillImage)) {
                        usb_host.DeviceReady = TRUE;
                        PASSTHROUGH_UNBLOCK
                        doPictbridge(StillImage.ep_in_pksize,
                                     StillImage.ep_out_pksize,
                                     StillImage.ep_intr_pksize,
                                     StillImage.ep_intr_pollms);
                    }

                    /*
                     * doPictbridge() should not return until either the
                     * device is disconnected (omDPSCONNECTED == DPSNONE)
                     * or the device does not support PictBridge
                     * (omDPSCONNECTED == DPSERROR).
                     */
                    OMgetEnum(omDPSCONNECTED, OMCURRENT, &dpsConnect);
                    if (dpsConnect != DPSNONE) {
                        if (g_powerOn || !g_powerWasOff) {
                            VPRINT("PTP device but not PictBridge\n");
                        }
                        USB_UnsupportedDevice();
                    }
                }
                else if (MassStorage.Config) {
#ifdef MSCLASS_HOST_PASSTHROUGH
                    if (USB_DoConfiguration(&MassStorage)) {
                        Uint32 rstatus;
                        Uint8 GetMaxLUN[8] = {0xA1, 0xFE,  0, 0,  3, 0,  1, 0};
                        static TimeVal poll_delay = {2, 0};

                        /* Enable interrupts */
                        *regINT_ENB = INTR_TOK_DNE | INTR_ERROR |
                                      INTR_STALL   | INTR_USB_RST;

                        GetMaxLUN[wIndex_low] = MassStorage.iface;
                        MassStorage.MaxLUN = 0;
                        if (!USB_device_request(GetMaxLUN)) {
                            PASSTHROUGH_UNBLOCK
                            return FALSE;
                        }
                        if (USB_Request(&rstatus) == USBH_DONE)
                            MassStorage.MaxLUN = dev_request_buffer[0];
                        else if (_CODE(rstatus) != USBH_STALL) {
                            VPRINT("bad return from GetMaxLUN\n");
                            PASSTHROUGH_UNBLOCK
                            return FALSE;
                        }
                        VPRINT("Max LUN %d, (code %s)\n",
                                MassStorage.MaxLUN,
                                (_CODE(rstatus)==USBH_STALL) ?"STALL" : "DONE");

                        *regINT_ENB = INTR_ERROR | INTR_USB_RST;
                        usb_host.DeviceReady = TRUE;
                        PASSTHROUGH_UNBLOCK

                        while (usb_host.DeviceReady) {
                            TaskSleep(&poll_delay);
                        }
                    }
                    else {
                        PASSTHROUGH_UNBLOCK
                    }
#else
                    if (g_powerOn || !g_powerWasOff) {
                        VPRINT("Mass Storage Class not supported\n");
                    }
                    USB_UnsupportedDevice();
#endif
                }
                else {
                    /* Device is none of above */
                    if (g_powerOn || !g_powerWasOff) {
                        VPRINT("Unknown device class not supported\n");
                    }
                    USB_UnsupportedDevice();
                }
            }
            else {
                /* Device had trouble after enumeration */
                if (g_powerOn || !g_powerWasOff) {
                    VPRINT("FAILED AFTER ENUMERATION, RESET\n");
                }
                USB_UnsupportedDevice();
                PASSTHROUGH_UNBLOCK
            }
        }
        else {
            /* Device is none of above (if printer powered on) */
            if (g_powerOn || !g_powerWasOff) {
                VPRINT("FAILED AFTER ENUMERATION, RESET\n");
            }
            USB_UnsupportedDevice();
            PASSTHROUGH_UNBLOCK
        }
    }
}

static Boolean USB_enumerate(void)
{
    Uint32 rstatus;
    int length, pksize;
    static Uint8 SetAddress[8] = {0, 5,  1, 0,  0, 0,  0, 0};

    VPRINT("USB_HOST READY:\n");

    usb_host.cur_pipe  = NULL;
    usb_host.USB_addr  = 0;
    usb_host.inx       = 0;
    usb_host.outx      = 0;
    usb_host.tick      = 0;
    usb_host.state     = NO_REQUEST;
    usb_host.reset_required = TRUE;
    usb_host.DeviceReady = FALSE;

    /* Disable ep0 */
    *regEP0CTL = ENDPT_DISABLE;

    /* Reset the device */
    reset_the_device();

    /* Enable attach interrupt */
    *regINT_ENB = INTR_ATTACH;

    /* Enable host mode but don't start generating SOFs */
    *regCTL = CTRL_HOST_NO_SOF;

    if (USB_Request(&rstatus) != USBH_ATTACH) {
        VPRINT("FAILED - NOT ATTACHED\n");
        return FALSE;
    }

    /* Get out if power was turned off or cycled waiting for ATTACH interrupt */
    if (!g_powerOn || g_powerWasOff)
        return FALSE;

    /* Reset the device a second time */
    reset_the_device();

    /* Device is now plugged in, enable all errors */
    *regERR_ENB = 0xff;

    /* Delay for the debounce interval */
    TaskSleep(&debounce_delay);

    /* Check if low-speed device */
    if ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) == 0) {
        USB_UnsupportedDevice();
        return FALSE;
    }

    /* Check if the device has detached */
    if ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) != CTRL_JSTATE) {
        VPRINT("process_attached NO DEVICE - ctrl_status %02x\n", *regCTL);
        return FALSE;
    }
    DBPRINT("ATTACHED\n");

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

    /*
     * Set SOF threshold so we are guaranteed to have enough time for
     * any transaction to complete (including ACK or NAK) without reaching
     * the time to send the next Start-of-frame packet.
     */
    *regSOF_THLD = SOF_THRESHOLD;

    /* Enable ep0 configured as CNTRL endpoint */
    *regEP0CTL = ENDPT_CNTL_0;

    /* Enable host mode and start generating SOFs */
    *regCTL = CTRL_HOST_SOF;

    /* Enable the token-done, error, STALL and RESET interrupts */
    *regINT_ENB = INTR_TOK_DNE | INTR_ERROR | INTR_STALL | INTR_USB_RST;

    /* Get first 8 bytes of the device descriptor */
    length = USB_GetDescriptor(DEVICE_TYPE, 0, &DeviceDesc, 8);
    if (length < 8)
        return FALSE;

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

    /* Reset the device */
    reset_the_device();

    /**************************************************************************/
    /* Validate size and descriptor type of device descriptor */
    pipe[0].pksize = pksize = dev_request_buffer[7];
    DBPRINT("Set CNTRL pksize %d\n", pipe[0].pksize);
    if (pipe[0].pksize <  8                     ||
        pipe[0].pksize > 64                     ||
        (pipe[0].pksize & (pipe[0].pksize - 1)) ||  /* must be power of 2 */
        dev_request_buffer[0] != 0x12           ||
        dev_request_buffer[1] != 1              )
    {
        VPRINT("GetDevDesc BAD\n");
        return FALSE;
    }
    /**************************************************************************/

    /* Enable attach interrupt */
    *regINT_ENB = INTR_ATTACH;

    if (USB_Request(&rstatus) != USBH_ATTACH) {
        VPRINT("FAILED - NOT ATTACHED (2)\n");
        return FALSE;
    }

    /* As above (restore after device reset) */
    *regSOF_THLD = SOF_THRESHOLD;
    *regEP0CTL = ENDPT_CNTL_0;
    *regCTL = CTRL_HOST_SOF;

    /* Enable the token done, error, stall and RESET interrupts */
    *regINT_ENB = INTR_TOK_DNE | INTR_ERROR | INTR_STALL | INTR_USB_RST;

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

    /* Set address to USB address 1 */
    DBPRINT("SET ADDRESS, threshold %d\n", *regSOF_THLD);
    if (!USB_device_request(SetAddress))
        return FALSE;
    if (USB_Request(&rstatus) != USBH_DONE) {
        VPRINT("bad return from SetAddress\n");
        return FALSE;
    }

    usb_host.USB_addr = 1;
    *regADDR = 1;
    DBPRINT("SET ADDRESS COMPLETE\n");
    return TRUE;
}

static void USB_UnsupportedDevice(void)
{
    static TimeVal delay_500msec = {0, 500*1000};

    /* If power is off (or printer powering down) don't report error */
    if (!g_powerOn || g_powerWasOff)
        return;

    /* Turn on front-panel message */
    OMsetEnum(omDPSCONNECTED, OMCURRENT, DPSERROR);

    /* Report Low Speed Device for debug purposes */
    if (!(*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE))) {
        VPRINT("LOW SPEED not supported - ctrl_status %02x\n", *regCTL);
    }

    while ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) != CTRL_SINGLE_END0) {
        TaskSleep(&delay_500msec);
    }

    VPRINT("Unsupported device unplugged %02x\n", *regCTL);

    /* Turn off front-panel message */
    OMsetEnum(omDPSCONNECTED, OMCURRENT, DPSNONE);
}

static Boolean USB_GetConfiguration(void)
{
    Uint16 length, i, config_length;
    Uint8 Config_no, EndPointCount;
    Uint8 bf[512];
    Boolean gotIface;
#if USBH_VERBOSE
    Uint16 lang_id;
#endif
    EndPointCount = 0;

    /* Get full 18 bytes of the device descriptor */
    DBPRINT("Get full DEVICE DESC addr %d\n", *regADDR);

    length = USB_GetDescriptor(DEVICE_TYPE, 0, &DeviceDesc, sizeof(DEVICE_DESC));
    if (length < 18)
        return FALSE;

    length = USB_GetDescriptor(CONFIGURATION_TYPE, 0, &ConfigDesc, sizeof(CONFIG_DESC));
    if (length < sizeof(CONFIG_DESC)) {
        VPRINT("CONFIG DESC FAILED: length %d\n", length);
        return FALSE;
    }

    /*********************/
    /* Device Descriptor */
    /*********************/
#if USBH_VERBOSE
    length = USB_GetString(0, 0);
    if (length < 2)
        return FALSE;
    lang_id = ((Uint16)dev_request_buffer[WLANGID0_HIGH] << 8) |
               (Uint16)dev_request_buffer[WLANGID0_LOW];

    if (DeviceDesc.bManufacturer) {
        PSPRINTF("\n\nManufacturer: ");
        USB_PrintString(DeviceDesc.bManufacturer, lang_id);
    }

    if (DeviceDesc.bProduct) {
        PSPRINTF("Product: ");
        USB_PrintString(DeviceDesc.bProduct, lang_id);
    }

    if (DeviceDesc.iSerialNumber) {
        PSPRINTF("Serial no.: ");
        USB_PrintString(DeviceDesc.iSerialNumber, lang_id);
    }

    PSPRINTF("Supports USB %x.%02x\n",
              DeviceDesc.bcdUSB_high, DeviceDesc.bcdUSB_low);
    PSPRINTF("Class: %02x, Subclass %02x, Protocol %02x\n",
              DeviceDesc.bDeviceClass, DeviceDesc.bDeviceSubclass,
              DeviceDesc.bDeviceProtocol);
    PSPRINTF("VID: %02x%02x, PID %02x%02x\n",
              DeviceDesc.idVendor_high, DeviceDesc.idVendor_low,
              DeviceDesc.idProduct_high, DeviceDesc.idProduct_low);
    PSPRINTF("Device release:  %x.%02x\n",
              DeviceDesc.bcdDevice_high, DeviceDesc.bcdDevice_low);

    PSPRINTF("No. of configurations: %d\n", DeviceDesc.bNumConfigurations);
#endif
    config_length = ConfigDesc.wTotalLength_high*256 +
                    ConfigDesc.wTotalLength_low;
    length = USB_GetDescriptor(CONFIGURATION_TYPE, 0, bf, config_length);
    if (length < config_length) {
        VPRINT("CONFIG DESC FAILED: length %d vs. expected %d\n",
               length, config_length);
        return FALSE;
    }

    gotIface = FALSE;
    i = 0;
    Config_no = 0;
    MassStorage.needClass = TRUE;
    MassStorage.Config = 0;
    StillImage.needClass = TRUE;
    StillImage.Config = 0;

⌨️ 快捷键说明

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