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

📄 usbs_upd985xx.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================
//
//      usbs_upd985xx.c
//
//      Driver for the NEC uPD985xx USB device
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 2002 Bart Veer
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    bartv
// Contributors: bartv
// Date:         2001-05-22
//
// This code implements support for the on-chip USB port on the NEC
// uPD985xx family of processors. The code has been developed on the
// uPD98503 and may or may not work on other members of the uPD985xx
// family.
//
//####DESCRIPTIONEND####
//==========================================================================

#include <cyg/infra/cyg_type.h>
#include <cyg/infra/cyg_ass.h>
#include <cyg/infra/cyg_trac.h>
#include <cyg/infra/diag.h>

#include <pkgconf/hal_mips_upd985xx.h>
#include <pkgconf/devs_usb_upd985xx.h>

#include <cyg/hal/drv_api.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_io.h>
#include <cyg/hal/hal_cache.h>
#include <cyg/error/codes.h>

#include <cyg/io/usb/usb.h>
#include <cyg/io/usb/usbs.h>

// For memcpy()
#include <string.h>

// ----------------------------------------------------------------------------
// Toplevel FIXME's.
//
// The device supports remote wakeups, but this driver does not. Note that
// the device GET_STATUS, SET_FEATURE and CLEAR_FEATURE operations are 
// affected by remote wakeup support.

// ----------------------------------------------------------------------------
// Debugging-related odds and ends.
#if 0
# define DBG(a) diag_printf a
#else
# define DBG(a)
#endif

// ----------------------------------------------------------------------------
// Hardware definitions.
//
// The NEC uPD985Xx on-chip USB device provides the following:
//
// endpoint 0   - control messages only
// endpoint 1   - isochronous transmits
// endpoint 2   - isochronous receives
// endpoint 3   - bulk transmits
// endpoint 4   - bulk receives
// endpoint 5   - interrupt transmits
// endpoint 6   - interrupt receives

// All acess to the USB controller registers goes via the IBUS, which
// always runs little-endian. Hence when the CPU is running
// little-endian no extra work is needed, but when running big-endian
// all register updates involve swapping.
#ifdef CYGPKG_HAL_MIPS_LSBFIRST
# define IBUS_SWAP32(_a_)               (_a_)
# define IBUS_SWAPPTR(_type_, _a_)      (_a_)
#else
# error IBUS_SWAP32() needs to be defined and tested
#endif

// Move an address to kseg1. Or'ing in the relevant bits means
// that this macro will work even if the specified address is
// already in kseg1
#define MIPS_TO_UNCACHED(_a_)  ((void*)(((cyg_uint32)(_a_)) | MIPS_KSEG1_BASE))

// For now access the various registers directly. A structure might
// be marginally more inefficient in that if a function accesses
// several registers this could be handled by a single base plus
// offsets, rather than by separate addresses.
#define USBS_REGISTER(_a_)              ((volatile cyg_uint32*)(MIPS_IO_BASE + UPD985XX_SYSUSB_OFF + (_a_)))
#define USBS_ADDRREG(_type_, _a_)       ((_type_* volatile*)(MIPS_IO_BASE + UPD985XX_SYSUSB_OFF + (_a_)))

#define USBS_GMR                USBS_REGISTER(0x0000)
#define USBS_VER                USBS_REGISTER(0x0004)
#define USBS_GSR1               USBS_REGISTER(0x0010)
#define USBS_IMR1               USBS_REGISTER(0x0014)
#define USBS_GSR2               USBS_REGISTER(0x0018)
#define USBS_IMR2               USBS_REGISTER(0x001C)
#define EP0_CR                  USBS_REGISTER(0x0020)
#define EP1_CR                  USBS_REGISTER(0x0024)
#define EP2_CR                  USBS_REGISTER(0x0028)
#define EP3_CR                  USBS_REGISTER(0x002C)
#define EP4_CR                  USBS_REGISTER(0x0030)
#define EP5_CR                  USBS_REGISTER(0x0034)
#define EP6_CR                  USBS_REGISTER(0x0038)
#define USBS_CMR                USBS_REGISTER(0x0040)
#define USBS_CA                 USBS_ADDRREG(void, 0x0044)
#define USBS_TEPSR              USBS_REGISTER(0x0048)
#define USBS_RP0IR              USBS_REGISTER(0x0050)
#define USBS_RP0AR              USBS_ADDRREG(RxBufferDescriptor, 0x0054)
#define USBS_RP1IR              USBS_REGISTER(0x0058)
#define USBS_RP1AR              USBS_ADDRREG(RxBufferDescriptor, 0x005C)
#define USBS_RP2IR              USBS_REGISTER(0x0060)
#define USBS_RP2AR              USBS_ADDRREG(RxBufferDescriptor, 0x0064)
#define USBS_TMSA               USBS_ADDRREG(TxMailbox, 0x0070)
#define USBS_TMBA               USBS_ADDRREG(TxMailbox, 0x0074)
#define USBS_TMRA               USBS_ADDRREG(TxMailbox, 0x0078)
#define USBS_TMWA               USBS_ADDRREG(TxMailbox, 0x007C)
#define USBS_RMSA               USBS_ADDRREG(RxMailbox, 0x0080)
#define USBS_RMBA               USBS_ADDRREG(RxMailbox, 0x0084)
#define USBS_RMRA               USBS_ADDRREG(RxMailbox, 0x0088)
#define USBS_RMWA               USBS_ADDRREG(RxMailbox, 0x008C)

// There are additional counter registers from offset 0x100 onwards.
// These registers are not used by the driver, and anyway may not be
// available on all hardware.

// The General Mode register USBS_GMR
#define USBS_GMR_VT                     (0x01 << 23)
#define USBS_GMR_FA_MASK                (0x7F << 16)
#define USBS_GMR_FA_SHIFT               16
#define USBS_GMR_SOFINTVL_MASK          (0x00FF << 8)
#define USBS_GMR_SOFINTVL_SHIFT         8
#define USBS_GMR_SOFINTVL_DEFAULT_VALUE (0x18 << 8)
#define USBS_GMR_AU                     (0x01 << 2)
#define USBS_GMR_LE                     (0x01 << 1)
#define USBS_GMR_RR                     (0x01 << 0)

// The Frame Number/Version register
#define USBS_VER_UVER_MASK              (0x0FFFF << 16)
#define USBS_VER_UVER_SHIFT             16
#define USBS_VER_UFNR_MASK              (0x03FF << 0)
#define USBS_VER_UFNR_SHIFT             0

// General status register 1
#define USBS_GSR1_GSR2                  (0x01 << 31)
#define USBS_GSR1_TMF                   (0x01 << 23)
#define USBS_GSR1_RMF                   (0x01 << 22)
#define USBS_GSR1_RPE2                  (0x01 << 21)
#define USBS_GSR1_RPE1                  (0x01 << 20)
#define USBS_GSR1_RPE0                  (0x01 << 19)
#define USBS_GSR1_RPA2                  (0x01 << 18)
#define USBS_GSR1_RPA1                  (0x01 << 17)
#define USBS_GSR1_RPA0                  (0x01 << 16)
#define USBS_GSR1_DER                   (0x01 << 10)
#define USBS_GSR1_EP2FO                 (0x01 << 9)
#define USBS_GSR1_EP1FU                 (0x01 << 8)
#define USBS_GSR1_EP6RF                 (0x01 << 7)
#define USBS_GSR1_EP5TF                 (0x01 << 6)
#define USBS_GSR1_EP4RF                 (0x01 << 5)
#define USBS_GSR1_EP3TF                 (0x01 << 4)
#define USBS_GSR1_EP2RF                 (0x01 << 3)
#define USBS_GSR1_EP1TF                 (0x01 << 2)
#define USBS_GSR1_EP0RF                 (0x01 << 1)
#define USBS_GSR1_EP0TF                 (0x01 << 0)

// The Interrupt mask 1 bits correspond to the GSR1 bits above

// General status register 2
#define USBS_GSR2_FW                    (0x01 << 21)
#define USBS_GSR2_IFN                   (0x01 << 20)
#define USBS_GSR2_IEA                   (0x01 << 19)
#define USBS_GSR2_URSM                  (0x01 << 18)
#define USBS_GSR2_URST                  (0x01 << 17)
#define USBS_GSR2_USPD                  (0x01 << 16)
#define USBS_GSR2_EP2OS                 (0x01 << 7)
#define USBS_GSR2_EP2ED                 (0x01 << 6)
#define USBS_GSR2_EP2ND                 (0x01 << 5)
#define USBS_GSR2_EP1NT                 (0x01 << 4)
#define USBS_GSR2_EP1ET                 (0x01 << 3)
#define USBS_GSR2_EP1ND                 (0x01 << 2)
#define USBS_GSR2_ES                    (0x01 << 1)
#define USBS_GSR2_SL                    (0x01 << 0)

// Interrupt mask 2 bits correspond to GSR2

// Endpoint control registers.
// EP0 - control messages
#define EP0_CR_EP0EN                    (0x01 << 31)
#define EP0_CR_ISS                      (0x01 << 20)
#define EP0_CR_INAK                     (0x01 << 19)
#define EP0_CR_OSS                      (0x01 << 18)
#define EP0_CR_NHSK0                    (0x01 << 17)
#define EP0_CR_ONAK                     (0x01 << 16)
#define EP0_CR_MAXP0_MASK               (0x7F << 0)
#define EP0_CR_MAXP0_SHIFT              0

// EP1 - isochronous transmits
#define EP1_CR_EP1EN                    (0x01 << 31)
#define EP1_CR_TM1                      (0x01 << 19)
#define EP1_CR_TM1_MASK                 (0x01 << 19)
#define EP1_CR_TM1_SZLP                 (0x00 << 19)
#define EP1_CR_TM1_NZLP                 (0x01 << 19)
#define EP1_CR_MAXP1_MASK               (0x3FF << 0)
#define EP1_CR_MAXP1_SHIFT              0

// EP2 - isochronous receives
#define EP2_CR_EP2EN                    (0x01 << 31)
#define EP2_CR_RM2_MASK                 (0x03 << 19)
#define EP2_CR_RM2_NORMAL               (0x00 << 19)
#define EP2_CR_RM2_ASSEMBLE             (0x02 << 19)
#define EP2_CR_RM2_SEPARATE             (0x03 << 19)
#define EP2_CR_MAXP2_MASK               (0x3FF << 0)
#define EP2_CR_MAXP2_SHIFT              0

// EP3 - bulk transmits
#define EP3_CR_EP3EN                    (0x01 << 31)
#define EP3_CR_TM3                      (0x01 << 19)
#define EP3_CR_TM3_MASK                 (0x01 << 19)
#define EP3_CR_TM3_SZLP                 (0x00 << 19)
#define EP3_CR_TM3_NZLP                 (0x01 << 19)
#define EP3_CR_SS3                      (0x01 << 18)
#define EP3_CR_NAK3                     (0x01 << 16)
#define EP3_CR_MAXP3_MASK               (0x7F << 0)
#define EP3_CR_MAXP3_SHIFT              0

// EP4 - bulk receives
#define EP4_CR_EP4EN                    (0x01 << 31)
#define EP4_CR_RM4_MASK                 (0x03 << 19)
#define EP4_CR_RM4_NORMAL               (0x00 << 19)
#define EP4_CR_RM4_ASSEMBLE             (0x02 << 19)
#define EP4_CR_RM4_SEPARATE             (0x03 << 19)
#define EP4_CR_SS4                      (0x01 << 18)
#define EP4_CR_NHSK4                    (0x01 << 17)
#define EP4_CR_NAK4                     (0x01 << 16)
#define EP4_CR_MAXP4_MASK               (0x7F << 0)
#define EP4_CR_MAXP4_SHIFT              0

// EP5 - interrupt transmits
#define EP5_CR_EP5EN                    (0x01 << 31)
#define EP5_CR_FM                       (0x01 << 19)
#define EP5_CR_SS5                      (0x01 << 18)
#define EP5_CR_NAK5                     (0x01 << 16)
#define EP5_CR_MAXP5_MASK               (0x7F << 0)
#define EP5_CR_MAXP5_SHIFT              0

// EP6 - interrupt receives
#define EP6_CR_EP6EN                    (0x01 << 31)
#define EP6_CR_SS6                      (0x01 << 18)
#define EP6_CR_NHSK6                    (0x01 << 17)
#define EP6_CR_NAK6                     (0x01 << 16)
#define EP6_CR_MAXP6_MASK               (0x7F << 0)
#define EP6_CR_MAXP6_SHIFT              0

// Some bits which can be applied to multiple transmit or receive

⌨️ 快捷键说明

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