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

📄 usbch9.c

📁 printer usb
💻 C
📖 第 1 页 / 共 5 页
字号:
    volatile Uint32 index_done; /* index of data already sent */
} card_table;
static volatile Boolean card_active;

static volatile Boolean card_usingFIFO = FALSE;
static volatile Boolean card_needsFIFO = FALSE;

#endif /* MEMORY_CARD_READER */

#if SCANNER_EPS
static volatile Boolean USB_SCAN_TaskSleeping;
static volatile Uint32 USB_SCAN_TaskTick;
static volatile Boolean scan_usingFIFO = FALSE;
#endif

/* long_packet_pool: pool of long packets for sending data back to the host */
static OUT_PACKET *long_packet_pool;

/* short_packet_pool: pool of short packets for sending data back to the host */
static OUT_PACKET *short_packet_pool;

/* hid_packet_pool: pool of packets for sending HID data back to the host */
static OUT_PACKET *hid_packet_pool;

/* NOTE: MEMORY ALLOCATION IS CURRENTLY STATIC */
static Uint8 long_pool_memory[LONG_PACKET_CNT * sizeof(OUT_PACKET) + 4];
static Uint8 short_pool_memory[SHORT_PACKET_CNT * sizeof(OUT_PACKET_SHORT) + 4];
static Uint8 hid_pool_memory[HID_PACKET_CNT * sizeof(OUT_PACKET_HID) + 4];

static Uint8 prn_rbuff[USB_PRINT_BUFF_SIZE + 4];

#if SCANNER_EPS
static Uint8 scn_rbuff[USB_SCAN_BUFF_SIZE + 4];
#endif

#if DEBUG_EPS
static Uint8 dbg_rbuff[USB_DEBUG_BUFF_SIZE + 4];
#endif

#ifdef MEMORY_CARD_READER
static Uint8 mem_rbuff[USB_CARD_BUFF_SIZE + 4];
#endif

/*
 * Index of currently selected alternate interface; -1 if alternate interface
 * has not yet been negotiated.
 */
static volatile int alt_interface_no;

/* USB test mode flag (0 means test mode off) */
static volatile Uint16 test_mode_index;

static Boolean CableConnected = FALSE;

/******************************************************************************/
/* Local procedure prototypes:                                                */

static void service_ep0(Uint8 ep, Boolean setup, Uint32 length);
static void GetStatus(void);
static void ClearFeature(void);
static void SetFeature(Boolean setup);
static void SetAddress(Boolean setup);
static void GetDescriptor(void);
static void SetConfig(void);
static void GetInterface(void);
static void SetInterface(void);
static void SetIfaceNo(Uint8 alt_setting);

static void service_EPn_OUT(Uint8 ep_index, Boolean setup, Uint32 length);

static Uint8 GetPrinterStatus(void);

static Boolean ReadEPn(volatile Uint8 *ep_status, EP_RECV *ep, Uint8 ep_index,
                       Uint8 **ptr1, Uint32 *cnt1, Uint8 **ptr2, Uint32 *cnt2);
static void ConsumeEPn(EP_RECV *ep, Uint8 ep_index,
                       volatile Uint8 *ep_status, Uint32 nbytes);
static Boolean WriteEPn(volatile Uint8 *ep_status, Uint8 ep_index,
                        Uint8 *buffer, Uint16 nbytes);

/*
 * Default endpoint service routine - Should never be called.
 */
static void service_default(Uint8 ep, Boolean setup, Uint32 length)
{
    USB_ASSERT(0);
}

/******************************************************************************/
/*         U S B   I N T E R R U P T   S E R V I C E   R O U T I N E S        */
/******************************************************************************/

/**************************************************************************
*
*  Function Name: FlushOutput
*  Comments:
*    Return output packets to pools.
*
**************************************************************************/
static void FlushOutput(Uint8 ep_send)
{
    OUT_PACKET *packet;
    Uint8 ep_no = ep_send/2;

    packet = outpacketHead[ep_no];
    while (packet) {
        outpacketHead[ep_no] = packet->next;
        packet->next = *packet->home_pool;
        *packet->home_pool = packet;
        packet = outpacketHead[ep_no];
    }
}

/**************************************************************************
*
*  Function Name: USB_deconfigure_current_interface
*  Comments:
*    Called to deconfigure previously configured endpoints due to a "set
*    configuration" or "set interface" request, or a reset. This may also be
*    called from vusbd20.c due to a USB reset.
*
*    If at any step things are taking too long (hardware taking too long to
*    flush endpoints, and/or is hung), the USB_ForceReset flag is set and
*    USB_task is un-suspended to do the job without causing interrupt latencies.
*
**************************************************************************/
void USB_deconfigure_current_interface(void)
{
    if (alt_interface_no >= 0) {
        /* If read was in progress and partially complete, update inx index */
        if (prn_recv.request_active) {
            dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + PRN_RECV;
            if (qhead->CURR_DTD_PTR) {
                prn_recv.inx = prn_recv.request_index +
                               prn_recv.request_length -
                               (qhead->SIZE_IOC_INT_STS >> 16);
            }
        }
        USB_ISR_deinit_endpoint(PRN_RECV);
        USB_ISR_deinit_endpoint(PRN_SEND);

        /* Set status of all endpoints > 0 to inactive/unconfigured. */
        prn_status = EP_UNCONF; prn_recv.request_active = FALSE;
        prn_recv.full_flag = FALSE;
        prn_recv.limit = prn_recv.max_buff_size = USB_RCV_PRINT_LIMIT;

        /* Return any queued output buffers to their home pools. */
        FlushOutput(PRN_SEND);

#if SCANNER_EPS
        if (scn_recv.request_active) {
            dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + SCN_RECV;
            if (qhead->CURR_DTD_PTR) {
                scn_recv.inx = scn_recv.request_index +
                               scn_recv.request_length -
                               (qhead->SIZE_IOC_INT_STS >> 16);
            }
        }
        USB_ISR_deinit_endpoint(SCN_RECV);
        USB_ISR_deinit_endpoint(SCN_SEND);

        scn_status = EP_UNCONF; scn_recv.request_active = FALSE;
        scn_recv.full_flag = FALSE;
        scn_recv.limit = scn_recv.max_buff_size = USB_RCV_SCAN_LIMIT;

        /*
         * Scanner is special case since we don't own memory buffers.
         * if the scan application needs to know when the buffer has
         * been sent, supply the USBConsumeWriteScan() function and
         * enable this code to be compiled.
         */
        while (scan_outx != scan_inx) {
            CONSUME_WRITE_SCAN(scan_table[scan_outx].data);
            scan_table[scan_outx].length = 0;
            scan_table[scan_outx].data = NULL;
            scan_table[scan_outx].index_req = 0;
            scan_table[scan_outx].index_done = 0;
#if USB_ENA_SCN_FLUSH
            scan_table[scan_outx].null_req = FALSE;
#endif
            if (++scan_outx >= SCAN_TABLE_SIZE)
                scan_outx = 0;
        }
        scan_inx = scan_outx = 0;
        scan_active = FALSE;
#endif /* SCANNER_EPS */

#if DEBUG_EPS
        if (dbg_recv.request_active) {
            dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + DBG_RECV;
            if (qhead->CURR_DTD_PTR) {
                dbg_recv.inx = dbg_recv.request_index +
                               dbg_recv.request_length -
                               (qhead->SIZE_IOC_INT_STS >> 16);
            }
        }
        USB_ISR_deinit_endpoint(DBG_RECV);
        USB_ISR_deinit_endpoint(DBG_SEND);

        dbg_status = EP_UNCONF; dbg_recv.request_active = FALSE;
        dbg_recv.full_flag = FALSE;
        dbg_recv.limit = dbg_recv.max_buff_size = USB_RCV_DEBUG_LIMIT;
        FlushOutput(DBG_SEND);
#endif /* DEBUG_EPS */

        USB_ISR_deinit_endpoint(HID_SEND);
        hid_status = EP_UNCONF;
        FlushOutput(HID_SEND);

#ifdef MEMORY_CARD_READER
        if (mem_recv.request_active) {
            dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + MEM_RECV;
            if (qhead->CURR_DTD_PTR) {
                mem_recv.inx = mem_recv.request_index +
                               mem_recv.request_length -
                               (qhead->SIZE_IOC_INT_STS >> 16);
            }
        }
        USB_ISR_deinit_endpoint(MEM_RECV);
        USB_ISR_deinit_endpoint(MEM_SEND);

        mem_status = EP_UNCONF; mem_recv.request_active = FALSE;
        mem_recv.full_flag = FALSE;
        mem_recv.limit = mem_recv.max_buff_size = USB_RCV_CARD_LIMIT;

        /* memory card reader is also special case */
        card_active = FALSE;

        if (DoNotRemoveFlashMemory) {
            USB_TaskTick++;
            if (USB_TaskSleeping) {
                USB_TaskSleeping = FALSE;
                USB_WakeUpUSB_Task();
            }
        }

        TaskSemSignal(USB_CARD_Semaphore);
#endif /* MEMORY_CARD_READER */

#if SCANNER_EPS
        USB_SCAN_TaskTick++;
        if (USB_SCAN_TaskSleeping) {
            USB_SCAN_TaskSleeping = FALSE;
            TaskSemSignal(USB_SCAN_Semaphore);
        }
#endif /* SCANNER_EPS */

        alt_interface_no = -1;
    }
}

/**************************************************************************
*
*  Function Name: USB_speed_change
*  Comments:
*    Called if speed detection USB status bit set.
*
**************************************************************************/
void USB_speed_change(void)
{
    if (usb_state.SPEED == USB_DEV_HIGH_SPEED) {       /* 1 */
        USB_STATUS_MSK_SET(SPEED_MASK, HIGH_SPEED);
        USB20_HighSpeed = TRUE;
    }
    else if (usb_state.SPEED == USB_DEV_FULL_SPEED) {  /* 2 */
        USB_STATUS_MSK_SET(SPEED_MASK, FULL_SPEED);
        USB20_HighSpeed = FALSE;
    }
}

/**************************************************************************
*
*  Function Name: CheckEP
*  Comments:
*    Check if endpoint is valid and/or configured.  Stall if not.
*
**************************************************************************/
static Boolean CheckEP(Uint8 endpoint)
{
    Uint8 status = 0;

    /* stall if not configured */
    switch (endpoint & USB_STATUS_ENDPOINT_NUMBER_MASK) {
      case PRN_EP:
        status = prn_status;
        break;

#if SCANNER_EPS
      case SCN_EP:
        status = scn_status;
        break;
#endif

      case HID_EP:
        status = hid_status;
        break;

#ifdef MEMORY_CARD_READER
      case MEM_EP:
        status = mem_status;
        break;
#endif

#if DEBUG_EPS
      case DBG_EP:
        status = dbg_status;
        break;
#endif
    }

    if (status & EP_CONFIG)
        return FALSE;

    STALL_ENDPOINT_0;
    return TRUE;
}

/**************************************************************************
*
*  Function Name: ISRStartEndpointRead
*  Comments:
*    Called to start next read from endpoint from ISR routine.
*
**************************************************************************/
static void ISRStartEndpointRead(Uint8 ep_index, EP_RECV *ep)
{
    Uint32 length;

    USB_ASSERT(!ep->request_active);

    /* Compute space available left in input buffer (multiple of 512). */
    if (ep->outx <= ep->inx) {
        length = (ep->max_buff_size - ep->inx) & PACKET_SIZE_MASK;
        /*
         * If there is still room at the end, keep the limit at the
         * end so that outx won't turn the corner too soon.
         */
        if (length)
            ep->limit = ep->max_buff_size;
        else {
            /*
             * No more room at the end so mark this as the limit. But only
             * wrap inx back to the beginning if outx isn't at zero also.
             */
            ep->limit = ep->inx;
            if (ep->outx) {
                ep->inx = 0;
                length = (ep->outx - 1) & PACKET_SIZE_MASK;
            }
        }
    }
    else
        length = (ep->outx - ep->inx - 1) & PACKET_SIZE_MASK;

    /* If there is room, start next read. */
    if (length) {
        if (length > VUSB_EP_MAX_LENGTH_TRANSFER)
            length = VUSB_EP_MAX_LENGTH_TRANSFER;

        ep->request_index = ep->inx;
        ep->request_length = length;

        ep->full_flag = FALSE;
        ep->request_active = TRUE;
        USB_ISR_io_request(ep_index, &ep->buffer[ep->inx], length);
    }
    else {
        /* I/O must be restarted by task, set flag. */
        ep->full_flag = TRUE;
        ep->request_active = FALSE;
    }
}
/**************************************************************************
*
*  Function Name: service_ep0
*  Comments:
*    Called upon a completed endpoint 0 transfer. Setup data
*    have already been copied to the local setup buffer, "usb_setup".
*
**************************************************************************/
static void service_ep0(Uint8 ep, Boolean setup, Uint32 length)

⌨️ 快捷键说明

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