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

📄 usbhost.c

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

 *  ===== HISTORY of changes in //depot/misc/projects/tps/usb/usbhost.c
 *  
 *  1/Jul/04 #49 lee I forgot to run stdhdr; sorry.
 *  1/Jul/04 #48 lee Fixed window in power-on sequence where PictBridge could
 *  grab the job lock before a maintenance task had a change to run.
 *  30/Jun/04 #47 ebradsha Reinstated changes from #45.  But make sure we set *retCount in early
 *  return in PTP_USB_Read_Timed and _Write_Timed.
 *  30/Jun/04 #46 ebradsha Back out change #45.  May be related to recent hangs.
 *  30/Jun/04 #45 lee Make interrupt polling timing more accurate; fix bug.
 *  28/Jun/04 #44 lee Added 8-second delay before camera enumeration
 *  after printer is first powered on.
 *  23/Jun/04 #43 lee Fix for tracking transfer counts properly.
 *  18/Jun/04 #42 lee Fix issues with PB camera connected during printer power-on.
 *  10/Jun/04 #41 lee If printer is powered off, stop USB host communication.
 *  10/Jun/04 #40 lee Toggle DATAx after sending OUT null packet.
 *  9/Jun/04 #39 lee Return correct byte count for PTP_USB_Write_Timed()
 *  on incomplete transfer due to PTP_USB_NAK return; also, add zero-length
 *  packet if write size is integral multiple of packet size.
 *  28/May/04 #38 ebradsha Fix unsigned math error in PTP_USB_Write_Timed().
 *  28/May/04 #37 ebradsha Fix return math in PTP_USB_Write_Timed() for full packet.
 *  27/May/04 #36 bhebeise Return bytes actually sent by PTP_USB_Write_Timed(), commented-out PTP_USB_Write()
 *  19/May/04 #35 lee Fix return count for doGetEvent & doGetDeviceStatus
 *  19/May/04 #34 lee Fix doSICD_Class() so it will return command data.
 *  13/May/04 #33 lee PictBridge has to read device status before STALL is cleared.
 *  13/May/04 #32 lee Fix USB STALL code.
 *  13/May/04 #31 ebradsha PTP_SND_RCV_DBG for interrupt packet data.
 *  26/Apr/04 #30 lee Added versions of PTP read and write routines
 *  that return after a requested time, even if I/O doesn't take place.
 *  21/Apr/04 #29 lee Fix enumeration retry bug; reduce read failure timeout.
 *  21/Apr/04 #28 lee Fix NAKlimit setting for interrupt endpoint.
 *  21/Apr/04 #27 lee Fix MSCLASS_HOST_PASSTHROUGH array argument errors.
 *  13/Apr/04 #26 mrhines Fixed compiler errors when building with -DMSCLASS_HOST_PASSTHROUGH
 *  10/Apr/04 #25 ebradsha Retry after failing to enumerate (helps Canon Rebel).
 *  10/Apr/04 #24 ebradsha Slow down interrupt polling.  (Based on testing with Sanyo, Fuji cameras.)
 *  10/Apr/04 #23 ebradsha Now aborts PTP I/O if interrupt endpoint packet received.
 *  6/Apr/04 #22 lee Add interrupt poll to PTP reads/writes for Fuji
 *  30/Mar/04 #21 lee Added WriteProtected arg to CAMERA_GetMemoryCardStatus(),
 *                    fixed SetInterface[] value.
 *  26/Mar/04 #20 ebradsha Change PTP_USB_ReadInterrupt() to indicate NAK, separate from 0 length data.
 *  10/Mar/04 #19 lee Fix permissions (remove execute permission)
 *  10/Mar/04 #18 lee Fix compiler warnings: ptr argument agreement.
 *  23/Feb/04 #17 lee Add support for non-PictBridge device reporting.
 *  12/Feb/04 #16 lee Update Passthrough code for
 *  new ...GetMemoryCardStatus() routines.
 *  11/Feb/04 #15 lee Force DMA buffers into non-cachable memory address space.
 *  27/Jan/04 #14 lee Move immediately from LISR to HISR; add volatile
 *  to variables shared between ISR and task levels.
 *  26/Jan/04 #13 lee Detected unrecoverable NAK errors; fix reentrancy
 *  problem in MSCLASS_HOST_PASSTHROUGH mode.
 *  23/Jan/04 #12 lee Remove unused MEMORY_CARD_READER reference
 *  23/Jan/04 #11 lee Fix EOF errors by increasing SOF_THRESHOLD and
 *  ignoring EOF errors if they do occur.
 *  22/Jan/04 #10 dmerritt New build path.  Assume we're doing PictBridge.
 *  20/Jan/04 #9 lee Fix MSCLASS_HOST_PASSTHROUGH regression.
 *  22/Dec/03 #8 lee PictBridge fix.
 *  19/Dec/03 #7 dmerritt Local copy of mydoPictbridge should be static.
 *  19/Dec/03 #6 dmerritt Make builds work from the zipped archive.
 *  12/Dec/03 #5 lee Fixes for PictBridge
 *  11/Dec/03 #4 lee Handle USB errors properly.
 *  5/Dec/03 #3 emiller Allow external tuning of task stack sizes and priorities
 *  1/Dec/03 #2 lee Moved misplaced endif.
 *  26/Nov/03 #1 lee Created.
 *  
 *  End of Zoran Standard Header
 */
#ifndef BOOTCODE
#include "univ.gh"
#include "arch.h"
#include "util.h"
#include "pile.h"
#include "dbg.h"
#include "ts.h"
#include "bios.h"
#include "nucleus.h"
#include "oti4100.h"
#include "lstring.h"
#include "propman.h"
#include "usbhost.h"

#include "usb.h"
#include "usbh.h"
#include "usbmass.h"

#ifndef USBH_VERBOSE
#define USBH_VERBOSE 1
#endif

#if USBH_VERBOSE
#define VPRINT PSPRINTF
#else
#define VPRINT if(0)PSPRINTF
#endif

#define _CODE(_rs)    ((_rs >> 24) & 255)
#define _ISTATUS(_rs) ((_rs >> 16) & 255)
#define _ERROR(_rs)   ((_rs >>  8) & 255)
#define _STATUS(_rs)  (_rs & 255)

#ifndef USB_HOST_DEBUG_LOG
#define DEBUG_LOG(_a, _s)
#define DEBUG_DUMP(_a)
#define DUMP_CODE(_a)
#define DBPRINT if(0)PSPRINTF
#else

/******************************************************************************/
/* DEBUG CODE TO LOG INTERRUPTS - not required for normal operation           */

#define DBPRINT if(1)PSPRINTF

#define DCODE_CNT 250
Uint32 usb_debug_status[DCODE_CNT];
int usb_debuginx = 0, usb_debugoutx = 0;

static struct {
    char *name;
} cn[13] = {
    "NCODE ",   /* USBH_NOCODE 0 */
    "ERROR ",   /* USBH_ERROR  1 */
    "RESET ",   /* USBH_RESET  2 */
    "ATTCH ",   /* USBH_ATTACH 3 */
    "STALL ",   /* USBH_STALL  4 */
    "INTNAK",   /* USBH_INTNAK 5 */
    "DONE  ",   /* USBH_DONE   6 */
    "HCAN  ",   /* USBH_HCAN   7 */
    "NAK   ",   /* USBH_NAK    8 */
    "OUT   ",   /* USBH_OUT    9 */
    "IN    ",   /* USBH_IN    10 */
    "OUT0  ",   /* USBH_OUT0  11 */
    "IN0   "    /* USBH_IN0   12 */
};

static void DUMP_CODE(Uint32 rstatus)
{
    if (_CODE(rstatus) > 12) {
        PSPRINTF("***  %02x %02x %02x %02x\n", _CODE(rstatus),
                 _ISTATUS(rstatus), _ERROR(rstatus), _STATUS(rstatus));
    }
    else {
        PSPRINTF("%s", cn[_CODE(rstatus)].name);

        if (_ISTATUS(rstatus)) {
            PSPRINTF(", ISTAT %02x:", _ISTATUS(rstatus));
            if (_ISTATUS(rstatus) & 0x01) PSPRINTF(" RST");
            if (_ISTATUS(rstatus) & 0x02) PSPRINTF(" ERR");
            if (_ISTATUS(rstatus) & 0x04) PSPRINTF(" SOF");
            if (_ISTATUS(rstatus) & 0x08) PSPRINTF(" TDN");
            if (_ISTATUS(rstatus) & 0x10) PSPRINTF(" SLP");
            if (_ISTATUS(rstatus) & 0x40) PSPRINTF(" ATT");
            if (_ISTATUS(rstatus) & 0x80) PSPRINTF(" STL");
        }

        if (_ERROR(rstatus)) {
            PSPRINTF(",  ERROR %02x:", _ERROR(rstatus));
            if (_ERROR(rstatus) & 0x01) PSPRINTF(" PID ERR");
            if (_ERROR(rstatus) & 0x02) PSPRINTF(" EOF ERR");
            if (_ERROR(rstatus) & 0x04) PSPRINTF(" CRC ERR");
            if (_ERROR(rstatus) & 0x08) PSPRINTF(" ALG ERR");
            if (_ERROR(rstatus) & 0x10) PSPRINTF(" BUSTURN");
            if (_ERROR(rstatus) & 0x20) PSPRINTF(" DMA");
            if (_ERROR(rstatus) & 0x40) PSPRINTF(" OWN");
            if (_ERROR(rstatus) & 0x80) PSPRINTF(" STUFF");
        }

        PSPRINTF(" - EP%d %s %s\n", (_STATUS(rstatus) >> 4),
                 ((_STATUS(rstatus) & 8) ? "IN ":"OUT"),
                 ((_STATUS(rstatus) & 4) ? "ODD":"EVN"));
    }
}

#define DEBUG_LOG(_a, _s) \
    usb_debug_status[usb_debuginx] = (_a << 24) | _s; \
    if (++usb_debuginx == DCODE_CNT)                  \
        usb_debuginx = 0;                             \
    if (usb_debuginx == usb_debugoutx) {              \
        if (--usb_debuginx < 0)                       \
            usb_debuginx = DCODE_CNT - 1;             \
    }

static void DUMP_CODE_I(Uint32 rstatus)
{
    if (_CODE(rstatus) > 12) {
        PSPRINTF("***  %02x %02x %02x %02x\n", _CODE(rstatus),
                 _ISTATUS(rstatus), _ERROR(rstatus), _STATUS(rstatus));
    }
    else {
        PSPRINTF("%s", cn[_CODE(rstatus)].name);

        if (_ISTATUS(rstatus)) {
            PSPRINTF(", ISTAT %02x:", _ISTATUS(rstatus));
            if (_ISTATUS(rstatus) & 0x01) PSPRINTF(" RST");
            if (_ISTATUS(rstatus) & 0x02) PSPRINTF(" ERR");
            if (_ISTATUS(rstatus) & 0x04) PSPRINTF(" SOF");
            if (_ISTATUS(rstatus) & 0x08) PSPRINTF(" TDN");
            if (_ISTATUS(rstatus) & 0x10) PSPRINTF(" SLP");
            if (_ISTATUS(rstatus) & 0x40) PSPRINTF(" ATT");
            if (_ISTATUS(rstatus) & 0x80) PSPRINTF(" STL");
        }

        if (_ERROR(rstatus)) {
            PSPRINTF(",  ERROR %02x:", _ERROR(rstatus));
            if (_ERROR(rstatus) & 0x01) PSPRINTF(" PID ERR");
            if (_ERROR(rstatus) & 0x02) PSPRINTF(" EOF ERR");
            if (_ERROR(rstatus) & 0x04) PSPRINTF(" CRC ERR");
            if (_ERROR(rstatus) & 0x08) PSPRINTF(" ALG ERR");
            if (_ERROR(rstatus) & 0x10) PSPRINTF(" BUSTURN");
            if (_ERROR(rstatus) & 0x20) PSPRINTF(" DMA");
            if (_ERROR(rstatus) & 0x40) PSPRINTF(" OWN");
            if (_ERROR(rstatus) & 0x80) PSPRINTF(" STUFF");
        }

        PSPRINTF(" - EP%d %s %s\n", (_STATUS(rstatus) >> 4),
                 ((_STATUS(rstatus) & 8) ? "IN ":"OUT"),
                 ((_STATUS(rstatus) & 4) ? "ODD":"EVN"));
    }
}

static void DEBUG_DUMP(void)
{
    Uint32 rstatus;

    while (usb_debugoutx != usb_debuginx) {
        rstatus = usb_debug_status[usb_debugoutx];
        if (++usb_debugoutx == DCODE_CNT)
            usb_debugoutx = 0;
        DUMP_CODE_I(rstatus);
    }
}
#endif
/*                            end of debug code                               */
/******************************************************************************/

/* front-panel flag to tell if power is on or off */
extern int g_powerOn;
extern int g_powerWasOff;

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

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

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

#define FS_CTRL_PKCT_SIZE    64
#define FS_BULK_PKCT_SIZE    64

/*
 * Start-of-Frame byte-count-times threshold for starting a worst-case
 * transfer followed by ACK or NAK without colliding with next SOF.
 */
#define SOF_THRESHOLD  100

#define PIPECNT 4
#define BUFCOUNT (PIPECNT+1)    /* 1 buffer for each pipe + 1 control setup */
#define USB_BDT_PAGE    ( (Uint32) USB10BDT0REG0 )

#define MEM32_ALIGN(n)      (((Uint32)(n)) + (-((Uint32)(n)) & 31))

/* Insertion delay - 100ms. min USB spec.: 9.1.2, #3, pg. 243 */
#define USB_DEBOUNCE_DELAY          (105*1000)
static TimeVal debounce_delay = {0, USB_DEBOUNCE_DELAY};

/* Reset delay (TDRSTR) - 50ms. min, USB spec.: 7.1.7.5, pg. 153 */
#define USB_RESET_DELAY             (55*1000)
static TimeVal reset_delay   = {0, USB_RESET_DELAY};

/* Reset recovery time (TRSTRCY) - 10ms. min, USB spec.: 7.1.7.5, pg. 153 */
#define USB_RESET_RECOVERY_DELAY    (15*1000)
static TimeVal recover_delay = {0, USB_RESET_RECOVERY_DELAY};

/* usb_host.state values: */
#define CNTRL_SETUP 1
#define PROCESS_IN  2
#define PROCESS_OUT 3
#define PROCESS_NUL 4
#define CNTRL_LAST  5
#define NO_REQUEST  6

/* usb_host.code values: */
#define USBH_NOCODE 0
#define USBH_ERROR  1
#define USBH_RESET  2
#define USBH_ATTACH 3
#define USBH_STALL  4
#define USBH_INTNAK 5
#define USBH_DONE   6
#define USBH_HCAN   7
#define USBH_NAK    8
#define USBH_OUT    9
#define USBH_IN    10
#define USBH_OUT0  11
#define USBH_IN0   12
#define USBH_INTR  13

/* VUSB Buffer Descriptor Format */
typedef struct {
    Uint8 PID;      /* 7:own 6:data0/1 5-2:pid 1-0:bch bits */
    Uint8 BC;       /* Byte Count Low bits */
    Uint8 ADDRL;
    Uint8 ADDRH;
} BDT_STRUCT;

typedef struct {
    Uint8 pipe_type;
    Uint8 EP;
    Uint8 pksize;
    Uint8 type;
    Uint8 pid_ep;
    Uint8 DATAx;

    Uint8 *setup_bf;
    Uint8 *pipe_bf;

    Uint8 *io_bf;
    Uint32 length;
    Uint32 count;
    Uint32 NAKtime;
    Uint32 NAKstart;
    BDT_STRUCT *bdt;
} PIPE_STRUCT;

static PIPE_STRUCT pipe[PIPECNT];

#define PIPE_CTL 0
#define PIPE_IN  1
#define PIPE_OUT 2
#define PIPE_INT 3

static Uint32 ipoll_lasttime = 0;
static Uint32 usbhost_poll_msec = 50;

static Uint8 dev_request_buffer[256];

#define BFSIZE_ALLOC (2*(BUFCOUNT+1)*FS_BULK_PKCT_SIZE)
#define BFSIZE (BUFCOUNT*FS_BULK_PKCT_SIZE)

static Uint32 abuffers[(BFSIZE_ALLOC+3)/4];

#define CODE_CNT 4
typedef struct {
    volatile PIPE_STRUCT *cur_pipe;
    volatile Boolean even_odd_OUT;
    volatile Boolean even_odd_IN;
    volatile Uint32 state;
    volatile Boolean reset_required;
    volatile Uint32 USB_addr;
    volatile BDT_STRUCT nxt_bdt;
    volatile Uint32 code_status_error[CODE_CNT];

⌨️ 快捷键说明

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