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

📄 usb20hw.c

📁 printer usb
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *  Start of Zoran Standard Header
 *  Copyright (c) 2003 - 2004 Zoran Corporation.
 *  
 *  
 *  All rights reserved.  Proprietary and confidential.
 *  
 *  DESCRIPTION for usb20hw.c
 *      USB 2.0 hardware-specific function calls.
 *  
 *  NEW HISTORY COMMENT (description must be followed by a blank line)
 *  <Enter change description here>

 *  ===== HISTORY of changes in //depot/misc/projects/tps/usb/usb20hw.c
 *
 *  15/Jun/04 #17 lee Remove no longer needed debug code.
 *  10/Jun/04 #16 imgeng ifdef DEBUG_USB_RESET_CAUSE 
 *  10/Jun/04 #15 imgeng ifdef DEBUG_USB_RESET_CAUSE
 *  4/Jun/04 #14 lee Increase hardware loop counts from 10 to 100 to fix USB1.1 problems.
 *  1/Jun/04 #13 lee Fix allocation of endpoint queue headers.
 *  3/May/04 #12 lee Protect USB_ISR_io_request() from reentrancy issue.
 *  19/Jan/04 #11 lee Change for USB Speed print out.
 *  19/Jan/04 #10 lee Put in "real" HW work-around for scanner/flash card conflict.
 *  8/Jan/04 #9 lee "USB suspend" code broke the loader build; now
 *  RESET_PWR_CYCLE always set to 0 for BOOTCODE.
 *  8/Jan/04 #8 lee Hardware workaround for scanner/flash card conflict is now in
 *  USB_ISR_io_request().  Also added code to do a "USB suspend" during
 *  reset if task-level reset occurs after USB connection is configured.
 *  19/Dec/03 #7 lee Forgot to run stdhdr last time.
 *  19/Dec/03 #6 lee Now immediately move to high-level ISR so scanner can interrupt.
 *  14/Oct/03 #5 lee Remove local definition of ASSERT.
 *  29/Sep/03 #4 lee Fixes to STALL code.
 *  18/Sep/03 #3 lee Fixed USB_ISR_set_endpoint_status() to STALL properly.
 *  27/Aug/03 #2 emiller Get rid of unnecessary nucleus.h, add util.h
 *  21/Aug/03 #1 lee Created
 *  
 *  End of Zoran Standard Header
 */

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

/*
 * If we do a task reset due to an unrecoverable error now we also go into
 * suspend state to get Windows to give us a fresh start. This can be disabled
 * by adding "-DRESET_PWR_CYCLE=0" to the compile flags.
 */
#ifndef RESET_PWR_CYCLE
#define RESET_PWR_CYCLE 1
#endif

#ifndef HW_LOOP_CNT
#define HW_LOOP_CNT 100
#endif

#ifdef BOOTCODE

/* This version is used by flash-ROM boot code */
#undef RESET_PWR_CYCLE
#define RESET_PWR_CYCLE 0

typedef unsigned char   uchar;   /* unsigned character     */
typedef unsigned char   Uint8;  /* 8-bit signed integer   */
typedef unsigned short  Uint16; /* 16-bit unsigned integer*/
typedef unsigned long   Uint32; /* 32-bit unsigned integer*/
typedef long            Sint32; /* 32-bit unsigned integer*/
typedef int             Boolean;

#include "usbpriv.h"
#include "oti4100.h"

#define USB_INTS_OFF {*(unsigned long *)EXMSK1A &= ~2;}
#define USB_INTS_ON  {*(unsigned long *)EXMSK1A |=  2;}
#define ARM_INTS_OFF
#define ARM_INTS_ON

#ifdef BZERO
#undef BZERO
#endif

static void BZERO(void *ptr, int n)
{
	Uint8 *p = (Uint8 *)ptr;
	
    while (n-- >= 0)
        *p++ = 0;
}

#else  /* not BOOTCODE */

#include "univ.gh"
#include "targmach.gh"

#include "arch.h"
#include "pile.h"
#include "util.h"
#include "oti4100.h"
#include "dbg.h"
#include "ts.h"
#include "nucleus.h"
#include "usbpriv.h"

/* prototype for interrupts off/on functions */
void armIntsOff(void);
void armIntsOn(void);

/* For protection over longer periods, only disable the USB interrupt. */
#define USB_INTS_OFF {armIntsOff();*(unsigned long *)EXMSK1A &= ~2;armIntsOn();}
#define USB_INTS_ON  {armIntsOff();*(unsigned long *)EXMSK1A |=  2;armIntsOn();}

/* Just turn off ARM chip interrupts for brief protection. */
#define ARM_INTS_OFF armIntsOff();
#define ARM_INTS_ON  armIntsOn();

#endif /* not BOOTCODE */

/* USB-disconnect flag (used to flash lights when reconnecting to JetDirect) */
Boolean USB_disconnect;

/* USB state structure */
USB_DEV_STATE_STRUCT usb_state;

/* Local copy of USB control packet setup array */
SETUP_STRUCT usb_setup;

/* Flag indicating that USB_task needs wake-up call for H/W reset */
volatile int USB_ForceReset;

#if RESET_PWR_CYCLE
static volatile Boolean USB_Hard_Reset;
#endif

/* Array of USB endpoint service routines */
extern void(*USBserviceEP[32])(Uint8, Boolean, Uint32);

/* Pointer to USB hardware registers */
static VUSB20_OPREG_STRUCT *usb_opreg;

/* Lock into Test Mode once requested by "set function" command from host */
static Boolean TestModeLock;

/* Test packet for sending during test mode */
static const Uint8 test_packet[53] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA,
    0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xEE, 0xEE, 0xEE,
    0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xDF,
    0xEF, 0xF7, 0xFB, 0xFD, 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7,
    0xFB, 0xFD, 0x7E
    /* CRC16      - generated by the hardware */
    /* EOP        - generated by the hardware */
};

static void USB_chip_and_data_base_initialize(void);
static void USB_ISR_process_tr_complete(void);
static void USB_ISR_process_reset(void);

/*
 * Task-level loop count: limit for loops on USB register values.
 * If hardware fails to respond it is assumed to be hung and reset.
 */
#define HW_LOOP_LIMIT 10000

/*
 * Allocate memory for the endpoint queue heads (with additional 2K
 * bytes so that we can align first queue head to a 2K boundary),
 * and for Device Transfer Descriptors (32-bytes aligned).
 */
static Uint8 ep_queue_head_mem[2*USB_MAX_ENDPOINTS*sizeof(dQH_STRUCT) + 2052];
static Uint32 dtd_base_ptr_mem[((DTD_POOL_CNT * sizeof(dDT_STRUCT)) + 36)/4];

/**************************************************************************
*
*  Function Name  : USB_init
*  Returned Value : USB_OK or error code
*  Comments       :
*    Initializes the USB device specific data structures and calls
*    the low-level device controller chip initialization routine.
*
**************************************************************************/
void USB_init(void)
{
    USB_ForceReset = NO_RESET;
    TestModeLock = FALSE;
#if RESET_PWR_CYCLE
    USB_Hard_Reset = FALSE;
#endif

    /* Zero out the internal USB state structure. */
    BZERO(&usb_state, sizeof(USB_DEV_STATE_STRUCT));

    usb_opreg = (VUSB20_OPREG_STRUCT *)USB20USBCMD;
    usb_state.USB_STATE = USB_STATE_POWER_ON;
    usb_state.USB_DEVICE_STATE = USB_SELF_POWERED;
    usb_state.USB_SUSPEND = 0;
    usb_state.SPEED = 0;
    usb_state.USB_CURR_CONFIG = 0;

    /*
     * Align the endpoint queue head to 2K boundary. Additionally, the
     * dDT structure size must be exactly 32 bytes (or a multiple of 32,
     * a hardware requirement).
     */
    usb_state.EP_QUEUE_HEAD_PTR =
       (dQH_STRUCT *)(Uint32)USB_MEM2048_ALIGN((dQH_STRUCT *)ep_queue_head_mem);
    USB_ASSERT(sizeof(dDT_STRUCT) == 32);

    /* Align the dTD base to 32 byte boundary. */
    usb_state.DTD_ALIGNED_BASE_PTR =
                  (dDT_STRUCT *)USB_MEM32_ALIGN((dDT_STRUCT *)dtd_base_ptr_mem);

    /* Initialize the VUSB_HS controller and USB data base. */
    USB_chip_and_data_base_initialize();

    usb_state.USB_STATE = USB_STATE_DEFAULT;
}

/**************************************************************************
*
*  Function Name  : USB_lisr
*  Returned Value : None
*  Comments       :
*    Services all the VUSB_HS interrupt sources.
*
**************************************************************************/
#ifdef BOOTCODE
/*
 * BOOTCODE version doesn't include nucleus so no HISR possible
 */
void USB_lisr(int interruptBit)
{
    Uint32 status;
    Uint8 new_speed;

    for (;;) {
        status = usb_opreg->USB_STS;

        if (!(status & usb_opreg->USB_INTR))
            break;

        /* Clear all the interrupts that occured. */
        usb_opreg->USB_STS = status;

        /*
         * Only process interrupt bits if we have not already invoked
         * the reset task, otherwise let it proceed without interference.
         */
        if (!USB_ForceReset && usb_state.USB_STATE != USB_STATE_POWER_ON) {
            /* Process reset. */
            if (status & VUSB_STS_RESET) {
                /* Deconfigure interface before reset. */
                USB_deconfigure_current_interface();

                /*
                 * Only reset in Interrupt Service Routine if deconfigure
                 * went OK.
                 */
                if (!USB_ForceReset)
                    USB_ISR_process_reset();
            }

            /* Process change of speed (if not also reset). */
            else if (status & VUSB_STS_PORT_CHANGE) {
                if (usb_opreg->PORTSCX[0] & VUSB_PORTSCX_PORT_HIGH_SPEED)
                    new_speed = USB_DEV_HIGH_SPEED;
                else
                    new_speed = USB_DEV_FULL_SPEED;

                if (usb_state.SPEED != new_speed) {
                    usb_state.SPEED = new_speed;
                    usb_state.USB_STATE = USB_STATE_DEFAULT;
                    USB_speed_change();
                }
            }

            /* Error count not currently used for anything. */
            if (status & VUSB_STS_ERR)
                usb_state.ERRORS++;

            /* I/O transfer complete. */
            if (status & VUSB_STS_INT)
                USB_ISR_process_tr_complete();

            /* Monitor change of suspend/resume. */
            if (usb_state.USB_SUSPEND != (status & VUSB_STS_SUSPEND)) {
                usb_state.USB_SUSPEND = status & VUSB_STS_SUSPEND;
                /*
                 * Call to "suspend/resume" routine can go here.
                 */
            }

            /* Start of USB frame: not currently enabled in VUSB_INTERRUPT_BITS */
            if (status & VUSB_STS_SOF) {
                /*
                 * Call to "Start of Frame" routine can go here; frame
                 * number is in "usb_opreg->USB_FRINDEX".
                 */
            }
        }
    }
    /*
     * Wake up USB reset/1248.4 task if appropriate.
     */
    if (USB_ForceReset)
        USB_WakeUpUSB_Task();

    /* Clear bit in exception register. */
    *(Uint32 *)EXCLRA = (1 << USB_INTERRUPT_BIT);
}
#else
NU_HISR usbHISR;

void USB_lisr(int interruptBit)
{
    /* Mask off USB interrupts because we're moving to HISR */
    *(unsigned long *)EXMSK1A &= ~2;

    NU_Activate_HISR(&usbHISR);

    /* Clear bit in exception register. */
    *(Uint32 *)EXCLRA = (1 << USB_INTERRUPT_BIT);
}

/* High Interrupt Service Routine: Just wakes up USB task. */
void USB_hisr(void)
{
    Uint32 status;
    Uint8 new_speed;

    /* Once test mode is entered, hang here until power cycle. */
    while (TestModeLock)
    {
    }

    for (;;) {
        status = usb_opreg->USB_STS;

        if (!(status & usb_opreg->USB_INTR))

⌨️ 快捷键说明

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