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

📄 usbhost.c

📁 printer usb
💻 C
📖 第 1 页 / 共 5 页
字号:
    while (i < length) {
        switch (bf[i+1]) {
        case CONFIGURATION_TYPE:
            ++Config_no;
            if (Config_no > DeviceDesc.bNumConfigurations) {
                VPRINT("More than %d many configurations\n",
                       DeviceDesc.bNumConfigurations);
                return FALSE;
            }
            BCOPY(&bf[i], (Uint8 *)&ConfigDesc, sizeof(CONFIG_DESC));
#if USBH_VERBOSE
            PSPRINTF("\nConfiguration no.: %d\n",
                     ConfigDesc.bConfigurationValue);
            PSPRINTF("  Total length of configuration: %d\n",
                     ConfigDesc.wTotalLength_high*256 +
                     ConfigDesc.wTotalLength_low);
            PSPRINTF("  No. of Interfaces: %d\n", ConfigDesc.bNumInterfaces);

            if (ConfigDesc.iConfiguration) {
                PSPRINTF("Configuration name: ");
                USB_PrintString(ConfigDesc.iConfiguration, lang_id);
            }
            PSPRINTF("  Configuration attributes: %02x\n  Max Power: %d mA.\n",
                ConfigDesc.bmAttributes, ConfigDesc.bMaxPower);
#endif
            break;

        case INTERFACE_TYPE:
            if (bf[i] != sizeof(INTERFACE_DESC)) {
                VPRINT("Bad Interface desc, size %d\n", bf[i]);
                return FALSE;
            }
            BCOPY(&bf[i], (Uint8 *)&InterfaceDesc, sizeof(INTERFACE_DESC));

            gotIface = TRUE;
            EndPointCount = 0;
#if USBH_VERBOSE
            PSPRINTF("\n  Interface Descriptor %02x Alt: %02x:\n",
                     InterfaceDesc.bInterfaceNumber,
                     InterfaceDesc.bAlternateSetting);
            if (InterfaceDesc.iInterface) {
                PSPRINTF("    Interface[%d]: ", InterfaceDesc.iInterface);
                USB_PrintString(InterfaceDesc.iInterface, lang_id);
            }
            PSPRINTF("    %d endpoints\n    Class    %02x ",
                     InterfaceDesc.bNumEndpoints,
                     InterfaceDesc.bInterfaceClass);
            switch (InterfaceDesc.bInterfaceClass) {
            case 3:
                PSPRINTF("HID Class\n");
                break;
            case 6:
                PSPRINTF("Still Image Capture Device Class\n");
                break;
            case 7:
                PSPRINTF("Printer Class\n");
                break;
            case 8:
                PSPRINTF("Mass Storage Class\n");
                break;
            case 0xff:
                PSPRINTF("Vendor specific\n");
                break;
            default:
                PSPRINTF("class unknown\n");
            }
            PSPRINTF("    Subclass %02x\n    Protocol %02x\n",
                     InterfaceDesc.bInterfaceSubClass,
                     InterfaceDesc.bInterfaceProtocol);
#endif
            if (InterfaceDesc.bInterfaceNumber >= ConfigDesc.bNumInterfaces) {
                VPRINT("ERROR: InterfaceNumber %d > NumInterfaces %d\n",
                       InterfaceDesc.bInterfaceNumber,
                       ConfigDesc.bNumInterfaces);
                gotIface = FALSE;
            }
            else if (MassStorage.needClass                 &&
                     InterfaceDesc.bInterfaceClass    == 8 &&
                     InterfaceDesc.bInterfaceSubClass == 6 &&
                     InterfaceDesc.bInterfaceProtocol == 0x50)
            {
                MassStorage.Config = Config_no;
                MassStorage.iface = InterfaceDesc.bInterfaceNumber;
                MassStorage.ifaceAlt = InterfaceDesc.bAlternateSetting;
                MassStorage.ep_in = 0;
                MassStorage.ep_out = 0;
                MassStorage.ep_intr = 0;
            }
            else if (StillImage.needClass                  &&
                     InterfaceDesc.bInterfaceClass    == 6 &&
                     InterfaceDesc.bInterfaceSubClass == 1 &&
                     InterfaceDesc.bInterfaceProtocol == 1)
            {
                StillImage.Config = Config_no;
                StillImage.iface = InterfaceDesc.bInterfaceNumber;
                StillImage.ifaceAlt = InterfaceDesc.bAlternateSetting;
                StillImage.ep_in = 0;
                StillImage.ep_out = 0;
                StillImage.ep_intr = 0;
            }
            break;

        case ENDPOINT_TYPE:
            if (bf[i] != sizeof(ENDPOINT_DESC)) {
                VPRINT("Bad Endpoint desc, size %d\n", bf[i]);
                return FALSE;
            }
            BCOPY(&bf[i], (Uint8 *)&EndpointDesc, sizeof(ENDPOINT_DESC));
            ++EndPointCount;
#if USBH_VERBOSE
            PSPRINTF("\n    Endpoint Descriptor[%d]%s: EP %d %s\n",
                     EndPointCount, (gotIface ? "" : " (ignored)"),
                     (EndpointDesc.bEPAddress & 15),
                     ((EndpointDesc.bEPAddress & 0x80) ? "IN":"OUT"));
            if ((EndpointDesc.bmAttributes & 3) == 0)
                PSPRINTF("      CNTRL");
            else if ((EndpointDesc.bmAttributes & 3) == 1)
                PSPRINTF("      ISO ");
            else if ((EndpointDesc.bmAttributes & 3) == 2)
                PSPRINTF("      BULK");
            else
                PSPRINTF("      INTR");

            PSPRINTF(", Packet Size %d, Interval %d\n",
                     EndpointDesc.wMaxPacketSize_high*256 +
                     EndpointDesc.wMaxPacketSize_low,
                     EndpointDesc.bInterval);

            if (EndPointCount > InterfaceDesc.bNumEndpoints) {
                PSPRINTF("End point no. %d > NumEndpoints %d\n",
                          EndPointCount, InterfaceDesc.bNumEndpoints);
            }
#endif
            if (MassStorage.needClass && MassStorage.Config) {
                if ((EndpointDesc.bmAttributes & 3) == 2) {
                    if (EndpointDesc.bEPAddress & 0x80) {
                        if (MassStorage.ep_in) {
                            VPRINT("multiple BULK IN endpoints\n");
                            MassStorage.Config = 0;
                        }
                        else {
                            MassStorage.ep_in = EndpointDesc.bEPAddress & 0x7f;
                            MassStorage.ep_in_pksize =
                                          EndpointDesc.wMaxPacketSize_low +
                                          256*EndpointDesc.wMaxPacketSize_high;
                        }
                    }
                    else {
                        if (MassStorage.ep_out) {
                            VPRINT("multiple BULK OUT endpoints\n");
                            MassStorage.Config = 0;
                        }
                        else {
                            MassStorage.ep_out = EndpointDesc.bEPAddress & 0x7f;
                            MassStorage.ep_out_pksize =
                                           EndpointDesc.wMaxPacketSize_low +
                                           256*EndpointDesc.wMaxPacketSize_high;
                        }
                    }
                }
                else if ((EndpointDesc.bmAttributes & 3) == 3 &&
                         (EndpointDesc.bEPAddress & 0x80))
                {
                    if (MassStorage.ep_intr) {
                        VPRINT("multiple INTERRUPT IN endpoints\n");
                        MassStorage.Config = 0;
                    }
                    else {
                        MassStorage.ep_intr = EndpointDesc.bEPAddress & 0x7f;
                        MassStorage.ep_intr_pksize =
                                       EndpointDesc.wMaxPacketSize_low +
                                       256*EndpointDesc.wMaxPacketSize_high;
                    }
                }
            }

            if (StillImage.needClass && StillImage.Config) {
                if ((EndpointDesc.bmAttributes & 3) == 2) {
                    if (EndpointDesc.bEPAddress & 0x80) {
                        if (StillImage.ep_in) {
                            VPRINT("multiple BULK IN endpoints\n");
                            StillImage.Config = 0;
                        }
                        else {
                            StillImage.ep_in = EndpointDesc.bEPAddress & 0x7f;
                            StillImage.ep_in_pksize =
                                          EndpointDesc.wMaxPacketSize_low +
                                          256*EndpointDesc.wMaxPacketSize_high;
                        }
                    }
                    else {
                        if (StillImage.ep_out) {
                            VPRINT("multiple BULK OUT endpoints\n");
                            StillImage.Config = 0;
                        }
                        else {
                            StillImage.ep_out = EndpointDesc.bEPAddress & 0x7f;
                            StillImage.ep_out_pksize =
                                           EndpointDesc.wMaxPacketSize_low +
                                           256*EndpointDesc.wMaxPacketSize_high;
                        }
                    }
                }
                else if ((EndpointDesc.bmAttributes & 3) == 3 &&
                         (EndpointDesc.bEPAddress & 0x80))
                {
                    if (StillImage.ep_intr) {
                        VPRINT("multiple INTERRUPT IN endpoints\n");
                        StillImage.Config = 0;
                    }
                    else {
                        StillImage.ep_intr = EndpointDesc.bEPAddress & 0x7f;
                        StillImage.ep_intr_pksize =
                                       EndpointDesc.wMaxPacketSize_low +
                                       256*EndpointDesc.wMaxPacketSize_high;
                        StillImage.ep_intr_pollms = EndpointDesc.bInterval;
                    }
                }
            }
            break;

        case HID_TYPE:
            if (bf[i] != 9) {
                VPRINT("Bad HID desc, size %d\n", bf[i]);
                return FALSE;
            }
            VPRINT("\n    HID Descriptor %s\n", (gotIface ? "" : "ignored"));
            break;

        default:
            VPRINT("\n  Descriptor type %d ignored.\n", bf[i+1]);
            gotIface = FALSE;
            break;
        }
        i += bf[i];
    }

#if USBH_VERBOSE
    PSPRINTF("****************************************************\n");
    if (StillImage.Config) {
        PSPRINTF("Still Image Class:\n");
        PSPRINTF("Configuration %d, interface %d [alternate %d]\n",
                 StillImage.Config, StillImage.iface, StillImage.ifaceAlt);
        PSPRINTF("IN EP%d [%d], OUT EP%d [%d], INTR EP%d [%d] %d msec. polling\n",
                 StillImage.ep_in, StillImage.ep_in_pksize,
                 StillImage.ep_out, StillImage.ep_out_pksize,
                 StillImage.ep_intr, StillImage.ep_intr_pksize,
                 StillImage.ep_intr_pollms);
    }

    if (MassStorage.Config) {
        PSPRINTF("Mass Storage Class:\n");
        PSPRINTF("Config %d, interface %d [a %d], in %d [%d], out %d [%d]\n",
                 MassStorage.Config, MassStorage.iface, MassStorage.ifaceAlt,
                 MassStorage.ep_in, MassStorage.ep_in_pksize,
                 MassStorage.ep_out, MassStorage.ep_out_pksize);
    }
#endif
    return TRUE;
}

static void reset_the_device(void)
{
    /* Disable and clear all interrupts */
    *regINT_ENB = 0;
    *regINT_STAT = 0xFF;

    /* Reset the device */
    usb_host.cur_pipe = NULL;
    pipe[0].pksize = FS_CTRL_PKCT_SIZE;
    usb_host.USB_addr = 0;
    *regADDR = 0;

    /* Assert reset on the USB */
    *regCTL = CTRL_HOST_NO_SOF | CTRL_RESET;

    /* Delay 55 msec. for the reset process to complete */
    TaskSleep(&reset_delay);

    /* Set the ODD/EVEN BDT to even */
    usb_host.even_odd_OUT = BDT_OUT_BIT;
    usb_host.even_odd_IN  = BDT_IN_BIT;

    /*
     * 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;

    /* End the reset , clear ODD bit and enable host */
    *regCTL = CTRL_ODD_RST | CTRL_HOST_SOF;

    /* Delay 15 msec. for the reset recovery period */
    TaskSleep(&recover_delay);

    usb_host.reset_required = FALSE;
}

static Uint8 USB_Request(Uint32 *rstatus)
{
    Sint32 sem_status, tick = 0;
    Boolean STALLflag;
    Uint8 code;

    STALLflag = FALSE;
    while (TRUE) {
        if (usb_host.reset_required || !g_powerOn) {
            *rstatus = (USBH_ERROR << 24);
            return USBH_ERROR;
        }

        /*
         * Stay suspended until awakened by the HISR (High Level Interrupt
         * Service Routine), but don't go to sleep if tick != usb_host.tick.
         * This means that an interrupt came in with more data after we
         * finished processing but, since we were awake at the time, the
         * interrupt routine did not signal the semaphore. So if we were
         * to go to sleep now we might not be reawakened for a long time,
         * if at all.
         */
        if (tick == usb_host.tick) {
            usb_host.sleeping = TRUE;

            /* Test again in case interrupt came in before setting sleep flag */
            if (tick == usb_host.tick) {
                sem_status = TaskSemWait(USBHSemaphore);
                ASSERT(sem_status >= 0);
            }
            usb_host.sleeping = FALSE;
        }
        tick = usb_host.tick;

        while (usb_host.outx != usb_host.inx) {
            DEBUG_DUMP();

            *rstatus = usb_host.code_status_error[usb_host.outx];
            code = _CODE(*rstatus);

            ARM_INTS_OFF
            if (++usb_host.outx == CODE_CNT)
                usb_host.outx = 0;
            ARM_INTS_ON

            if (code == USBH_STALL) {
                volatile PIPE_STRUCT *pipe;

                if (usb_host.cur_pipe) {
#ifdef MSCLASS_HOST_PASSTHROUGH
                    static Uint8 ClrFeatureEP[8] = {2, 1,  0, 0,  0, 0,  0, 0};
                    STALLflag = TRUE;

                    pipe = usb_host.cur_pipe;
                    if (pipe->EP) {
                        /* Send CLEAR_FEATURE */
                        ClrFeatureEP[wIndex_low] = pipe->EP;
                        if (pipe->pipe_type != PIPE_OUT)
                            ClrFeatureEP[wIndex_low] |= 0x80;
                        VPRINT("CLEAR STALL: %06x\n", (*rstatus & 0xffffff));
                        USB_device_request(ClrFeatureEP);
                    }
#else
                    pipe = usb_host.cur_pipe;
                    if (pipe->EP && pipe->EP != pipe[PIPE_INT].EP) {
                        /*
                         * Don't Clear Endpoint

⌨️ 快捷键说明

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