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

📄 usbhost.c

📁 printer usb
💻 C
📖 第 1 页 / 共 5 页
字号:

        Start_USB_Host_Task(USBH_DONE, rstatus);
    }

    else if (usb_host.state == CNTRL_LAST)
        Start_USB_Host_Task(USBH_DONE, rstatus);

    /* Didn't expect this */
    else
        Start_USB_Host_Task(USBH_ERROR, rstatus);
}

/***********************************************************************/
static void ProcessIN_ISR(Uint32 rstatus)
{
    int i, bytecnt, room_left;
    volatile PIPE_STRUCT *pipe;
    BDT_STRUCT *bdt;

    pipe = usb_host.cur_pipe;

    /* Toggle on success */
    pipe->DATAx ^= BDT_PID_DATA01;

    /* Get the number of bytes received */
    bdt = pipe->bdt;
    bytecnt = bdt->BC;

    /*
     * Transfer block of data just read from pipe->pipe_bf to io_bf.
     * If more data received that there is room for, ignore extra bytes
     * but maintain proper count. ("room_left" can go negative.)
     */
    room_left = pipe->length - pipe->count;
    if (room_left > bytecnt)
        room_left = bytecnt;

    if (room_left > 0) {
        Uint8 *to, *from;

        from = pipe->pipe_bf;
        to = &pipe->io_bf[pipe->count];
        for (i = 0; i < room_left; i++)
            *to++ = *from++;
    }

    /* Maintain count of total number of bytes received */
    pipe->count += bytecnt;

    if (bytecnt == pipe->pksize) {
        if ((pipe->count >= pipe->length) &&
            ((pipe->pipe_type == PIPE_INT) || MassStorage.Config))
        {
            /* All done if INTERRUPT endpoint or Mass-Storage-Class Device */
            Start_USB_Host_Task(USBH_DONE, rstatus);
            return;
        }

        /* More IN data coming; set up next transfer */
        bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_IN);
        pipe->bdt = bdt;
        usb_host.even_odd_IN ^= BDT_ODD_EVEN_BIT;

        usb_host.nxt_bdt.PID   = BDT_PID_OWN | pipe->DATAx;
        usb_host.nxt_bdt.BC    = pipe->pksize;
        usb_host.nxt_bdt.ADDRL = (Uint32)pipe->pipe_bf;
        usb_host.nxt_bdt.ADDRH = (Uint32)pipe->pipe_bf >> 8;

        //DEBUG_LOG(USBH_IN, rstatus);
    }
    else {
        /* Finished with IN transfer */
        if (pipe->EP) {
            /* All done if not CNTRL endpoint */
            Start_USB_Host_Task(USBH_DONE, rstatus);
            return;
        }

        /* Send status (no data OUT) transfer to finish Control */
        usb_host.state = CNTRL_LAST;
        bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_OUT);
        pipe[0].bdt = bdt;
        usb_host.even_odd_OUT ^= BDT_ODD_EVEN_BIT;

        usb_host.nxt_bdt.PID   = BDT_PID_OWN | BDT_PID_DATA01;
        usb_host.nxt_bdt.BC    = 0;
        usb_host.nxt_bdt.ADDRL = 0;
        usb_host.nxt_bdt.ADDRH = 0;
        pipe[0].pid_ep = VUSB_TOKEN_OUT;

        DEBUG_LOG(USBH_OUT0, rstatus);
    }

    /*
     * Read next packet (BULK or CNTRL) or send STATUS (zero length)
     * packet (CNTRL only - completes handshake)
     */
    bdt->PID   = usb_host.nxt_bdt.PID;
    bdt->BC    = usb_host.nxt_bdt.BC;
    bdt->ADDRL = usb_host.nxt_bdt.ADDRL;
    bdt->ADDRH = usb_host.nxt_bdt.ADDRH;

    *regEP0CTL = pipe->type;
    *regADDR = usb_host.USB_addr;
    *regTOKEN = pipe->pid_ep;
}

/***********************************************************************/
static void ProcessOUT_ISR(Uint32 rstatus)
{
    int i, left_to_send;
    volatile PIPE_STRUCT *pipe;
    BDT_STRUCT *bdt;

    pipe = usb_host.cur_pipe;

    /* Toggle on success */
    pipe->DATAx ^= BDT_PID_DATA01;

    pipe->count += pipe->pksize;
    if (pipe->count >= pipe->length)
        pipe->count = pipe->length;

    left_to_send = pipe->length - pipe->count;
    if (left_to_send > pipe->pksize)
        left_to_send = pipe->pksize;

    /*
     * Need to send another packet if more data left to send or
     * if non-control endpoint had transfer that was an exact multiple
     * of the packet size.
     */
    if (left_to_send ||
        (pipe->EP && (pipe->length % pipe->pksize) == 0))
    {
        if (left_to_send) {
            /* Transfer block of data from io_buff to pipe->pipe_bf */
            for (i = 0; i < left_to_send; i++)
                pipe->pipe_bf[i] = pipe->io_bf[pipe->count + i];
        }
        else {
            /* Final zero-length data packet to finish transfer */
            usb_host.state = PROCESS_NUL;
        }

        bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_OUT);
        pipe->bdt = bdt;
        usb_host.even_odd_OUT ^= BDT_ODD_EVEN_BIT;

        usb_host.nxt_bdt.PID   = BDT_PID_OWN | pipe->DATAx;
        usb_host.nxt_bdt.BC    = left_to_send;
        usb_host.nxt_bdt.ADDRL = (Uint32)pipe->pipe_bf;
        usb_host.nxt_bdt.ADDRH = (Uint32)pipe->pipe_bf >> 8;

        DEBUG_LOG(USBH_OUT, rstatus);
    }
    else {
        /* Finished with OUT transfer */
        if (pipe->EP || (pipe->length % pipe->pksize)) {
            /* Done if not CNTRL ep or final packet was not filled */
            Start_USB_Host_Task(USBH_DONE, rstatus);
            return;
        }

        /* Send status (no data IN) transfer to finish Control */
        usb_host.state = CNTRL_LAST;
        bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_IN);
        pipe[0].bdt = bdt;
        usb_host.even_odd_IN ^= BDT_ODD_EVEN_BIT;

        usb_host.nxt_bdt.PID   = BDT_PID_OWN | BDT_PID_DATA01;
        usb_host.nxt_bdt.BC    = 0;
        usb_host.nxt_bdt.ADDRL = 0;
        usb_host.nxt_bdt.ADDRH = 0;
        pipe[0].pid_ep = VUSB_TOKEN_IN;

        DEBUG_LOG(USBH_IN0, rstatus);
    }

    /*
     * Send next packet (BULK or CNTRL) or read STATUS (zero length)
     * packet (CNTRL only - completes handshake)
     */
    bdt->PID   = usb_host.nxt_bdt.PID;
    bdt->BC    = usb_host.nxt_bdt.BC;
    bdt->ADDRL = usb_host.nxt_bdt.ADDRL;
    bdt->ADDRH = usb_host.nxt_bdt.ADDRH;

    *regEP0CTL = pipe->type;
    *regADDR = usb_host.USB_addr;
    *regTOKEN = pipe->pid_ep;
}

/*************************************************************************/
/**************************************************************************
*
*  Function Name: Start_USB_Host_Task
*
**************************************************************************/
static void Start_USB_Host_Task(Uint8 code, Uint32 rstatus)
{
    STATUS ts_status;

    usb_host.state = NO_REQUEST;

    if (USBCancelHost) {
        code = USBH_HCAN;
        USBCancelHost = FALSE;
    }

    /* Mask off all USB interrupts */
    *regINT_ENB = 0;

    DEBUG_LOG(code, rstatus);

    usb_host.code_status_error[usb_host.inx] = ((Uint32)code << 24) | rstatus;
    if (++usb_host.inx == CODE_CNT)
        usb_host.inx = 0;
    ASSERT(usb_host.inx != usb_host.outx);

    usb_host.tick++;
    if (usb_host.sleeping) {
        /* Signal the USBH task semaphore. */
        ts_status = TaskSemSignal(USBHSemaphore);
        ASSERT(ts_status >= 0);
        usb_host.sleeping = FALSE;
    }
}

/**************************************************************************
*  Function Name  : USBHostPrologue
*
*  Initialize the USB 1.1 hardware and data structures.
**************************************************************************/
void USBHostPrologue(void)
{
    int i;
    Uint8 *bbase;
    Uint32 startHI, endHI;
    STATUS status;
    void (*old_lisr)(int);

    /*
     * I/O buffers must all be in the same 64K region of memory
     * since the high-order 16 bits can never change.  Over-allocate
     * and pick a safe region on a 32-byte boundary.
     */
    bbase = (Uint8 *)MEM32_ALIGN(abuffers);
    startHI = (Uint32)bbase >> 16;
    endHI = (Uint32)(&bbase[BFSIZE]) >> 16;
    if (startHI != endHI) {
        bbase = (Uint8 *)(endHI << 16);

        startHI = (Uint32)bbase >> 16;
        endHI = (Uint32)(&bbase[BFSIZE]) >> 16;
        ASSERT(startHI == endHI);
    }

    /* Lock in high 16-bits of address */
    *regBUFBASEL = (Uint32)bbase >> 16;
    *regBUFBASEH = (Uint32)bbase >> 24;

    /* Plug buffer address into pipe structures */
    for (i = 0; i < PIPECNT; i++) {
        pipe[i].setup_bf = NULL;
        pipe[i].pipe_bf = &bbase[i * FS_BULK_PKCT_SIZE];

        /* Force address into non-cachable memory region */
        pipe[i].pipe_bf = (Uint8 *)((Uint32)pipe[i].pipe_bf | 0x20000000);
        DBPRINT("pipe[%d].pipe_bf @ %x\n", i, (unsigned int)pipe[i].pipe_bf);
        pipe[i].pksize = FS_BULK_PKCT_SIZE;
    }

    /* Only pipe[0] is a CNTRL endpoint with SETUP buffer */
    pipe[0].setup_bf = &bbase[PIPECNT * FS_BULK_PKCT_SIZE];
    DBPRINT("pipe[0].setup_bf @ %x\n", (unsigned int)pipe[0].setup_bf);
    pipe[0].pksize = FS_CTRL_PKCT_SIZE;

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

    /* Create USB Host synchronization semaphore. */
    USBHSemaphore = TaskSemCreate(0);
    ASSERT(USBHSemaphore >= 0);

    /* Create the USBH task for task-level (vs. ISR) code. */
    TaskUSBH_ID = TASKCREATE(USB_Host_Task, USBHTASK_STACKSIZE, TaskUSBH_stack,
                             TaskUSBH_data, USBHTASK_PRIORITY, &TaskUSBH_arg,
                             "USB Host");
    ASSERT(TaskUSBH_ID >= 0);

    /* Register HISR */
    status = NU_Create_HISR(&usbh_hisr, "USBH_HISR", USBH_hisr, 2, pHISRStack,
                            HISR_STACKSIZE);
    ASSERT(status == NU_SUCCESS);

    /* Install the LISR (Low Interrupt Service Routine). */
    status = NU_Register_LISR(USB1_INTERRUPT_BIT, USBH_isr, &old_lisr);
    ASSERT(status == NU_SUCCESS);

    /* Initialize the USB hardware interface: disable EP0. */
    *regEP0CTL = ENDPT_DISABLE;

    /* Disable VUSB; mask and clear all interrupts */
    *regCTL = 0;
    *regINT_ENB = 0;
    *regINT_STAT = 0xFF;

    BZERO((Uint8 *)USB_BDT_PAGE, 16);

    /* Zero out BDT ODD ping/pong bits, USB address and frame number */
    *regCTL = CTRL_ODD_RST;
    *regADDR = 0;
    *regFRM_NUML = 0;
    *regFRM_NUMH = 0;

    usb_host.even_odd_OUT = BDT_OUT_BIT;
    usb_host.even_odd_IN  = BDT_IN_BIT;

    /* Turn on the power (if FIRE4 board) */
    ENABLE_USB_PWR

    /* Enable interrupt */
    *(volatile Uint32 *)EXMSK1A |= (1 << USB1_INTERRUPT_BIT);
}

/**************************************************************************
*  T A S K   L E V E L   C O D E
**************************************************************************/
/* The USBH task - runs at high priority but normally sleeps. */

#ifndef CALL_PICTBRIDGE
#define CALL_PICTBRIDGE 1
#endif

#if CALL_PICTBRIDGE == 0 /* We're doing something other than pictbridge. */
FORWARD void mydoPictbridge(int in_pk_size, int out_pk_size, int intr_pk_size, int msec);
#define doPictbridge mydoPictbridge
#endif

static Sint32 USB_Host_Task(void *arg)
{
    static TimeVal delay_enum = {1, 0};
    static TimeVal delay_after_poweron = {8, 0};
    int i, enumOK;

    usb_host.DeviceReady = FALSE;

    while (TRUE) {
        PASSTHROUGH_BLOCK

        /*
         * If the printer is powered down (or was powered down and
         * was just powered up) delay here to all maintenance task
         * to get a job lock first.
         */
        if (!g_powerOn || g_powerWasOff) {
            g_powerWasOff = 0;
            VPRINT("USB HOST: Printer powered off\n");

⌨️ 快捷键说明

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