📄 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// endpoint control registers, thus avoiding unnecessary code// duplication. These will not work for the isochronous endpoints// because those are just too special.#define EPtx_CR_EpxEN (0x01 << 31)#define EPtx_CR_SSx (0x01 << 18)#define EPtx_CR_NAKx (0x01 << 16)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -