📄 usbs_upd985xx.c
字号:
//==========================================================================
//
// 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 + -