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

📄 usbs_sa11x0.c

📁 Sa11的USB驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================////      usbs_sa11x0.c////      Device driver for the SA11x0 USB port.////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// 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:         2000-10-04//// This code implements support for the on-chip USB port on the SA11x0// family of processors. The code has been developed on the SA1110 and// may or may not work on other members of the SA11x0 family. There// have problems with the USB support on certain revisions of the silicon,// so the errata sheet appropriate to the specific processor being used// should be consulted. There also appear to be problems which do not// appear on any errata, which this code attempts to work around.////####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_arm.h>#include <pkgconf/devs_usb_sa11x0.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/hal/hal_sa11x0.h>#include <cyg/error/codes.h>#include <cyg/io/usb/usb.h>#include <cyg/io/usb/usbs.h>// Debugging support. By default this driver operates mostly at// DSR level, with the ISR doing a minimal amount of processing.// However is also possible to run most of the code at thread-level,// This is subject to some restrictions because the USB standard// imposes timing constraints, e.g. some control operations such// as SET-ADDRESS have to complete within 50ms. However it is// very useful for debugging, specifically it allows you to put// printf()'s in various places.//// Right now these configuration options are not exported to the// user because running at DSR level is likely to be good enough// for everybody not actively debugging this code. The options// could be exported if necessary.//#define CYGPKG_DEVS_USB_SA11X0_THREAD#undef CYGPKG_DEVS_USB_SA11X0_THREAD#ifdef CYGPKG_DEVS_USB_SA11X0_THREAD  // Default stack size should be CYGNUM_HAL_STACK_SIZE_TYPICAL# define CYGNUM_DEVS_USB_SA11X0_THREAD_STACK_SIZE       4096# define CYGNUM_DEVS_USB_SA11X0_THREAD_PRIORITY         7# include <cyg/kernel/kapi.h>#endif#if 0# define DBG(a) diag_printf a#else# define DBG(a)#endif#undef FAILURES#ifdef FAILURESstatic volatile int ep1_failure = 7;#endif#undef STATS#ifdef STATSint ep1_receives = 0;int ep1_errors = 0;int ep2_transmits = 0;int ep2_errors = 0;# define INCR_STAT(a) (a) += 1# define SET_STAT(a, b) (a) = (b)#else# define INCR_STAT(a)# define SET_STAT(a, b)#endif// ----------------------------------------------------------------------------// Serial port 0 on the SA11x0 provides a USB slave connection (aka a// USB device controller or UDC). The functionality is somewhat// limited, there are just three endpoints.//// Endpoint 0 can only be used for control messages. It has an 8 byte// fifo which cannot be connected to a DMA engine. Hence incoming// control packets have to be limited to 8 bytes by the enumeration// data. The endpoint has to be managed at a low-level, i.e. the// incoming request has to be extracted from the fifo, processed, and// any response put back into the fifo within the permitted USB// response times.//// Endpoint 1 can only be used for host->slave bulk OUT transfers. It// has a 20 byte receive fifo, and it can be hooked up to any of the// six DMA engines. Since bulk transfers will typically involve 64// byte packets, most applications will require the use of DMA.//// Endpoint 2 can only be used for slave-host bulk IN transfers. There// is a 16 byte transmit fifo so small messages can be transferred in// software. The fifo can also be hooked up to DMA, which is a more// likely scenario.//// Start with definitions of the hardware. The use of a structure and// a const base pointer should allow the compiler to do base/offset// addressing and keep the hardware base address in a register. This// is better than defining each hardware register via a separate// address. Although the registers are only a byte wide, the peripheral// bus only supports word accesses.//// The USBS_CONTROL etc. macros allow for an alternative way of// accessing the hardware if a better approach is presented, without// having to rewrite all the code. Macros that correspond to registers// are actually addresses, making it easier in the code to distinguish// them from bit values: the & and * operators will just cancel out.typedef struct usbs_sa11x0_hardware {    volatile int control;    volatile int address;    volatile int out_size;    volatile int in_size;    volatile int ep0_control;    volatile int ep1_control;    volatile int ep2_control;    volatile int ep0_data;    volatile int ep0_write_count;             int dummy1;    volatile int fifo;             int dummy2;    volatile int status;} usbs_sa11x0_hardware;static usbs_sa11x0_hardware* const usbs_sa11x0_base = (usbs_sa11x0_hardware* const) 0x80000000;#define USBS_CONTROL    (&(usbs_sa11x0_base->control))#define USBS_ADDRESS    (&(usbs_sa11x0_base->address))#define USBS_OUT_SIZE   (&(usbs_sa11x0_base->out_size))#define USBS_IN_SIZE    (&(usbs_sa11x0_base->in_size))#define EP0_CONTROL     (&(usbs_sa11x0_base->ep0_control))#define EP1_CONTROL     (&(usbs_sa11x0_base->ep1_control))#define EP2_CONTROL     (&(usbs_sa11x0_base->ep2_control))#define EP0_DATA        (&(usbs_sa11x0_base->ep0_data))#define EP0_WRITE_COUNT (&(usbs_sa11x0_base->ep0_write_count))#define EP1_DATA        (&(usbs_sa11x0_base->fifo))#define EP2_DATA        (&(usbs_sa11x0_base->fifo))#define USBS_STATUS     (&(usbs_sa11x0_base->status))#define CONTROL_DISABLE                 (1 << 0)#define CONTROL_ACTIVE                  (1 << 1)// The meaning of bit 2 changed, see errata#define CONTROL_RESUME_INTR             (1 << 2)#define CONTROL_EP0_INTR                (1 << 3)#define CONTROL_EP1_INTR                (1 << 4)#define CONTROL_EP2_INTR                (1 << 5)// The meaning of bit 6 also changed, see errata#define CONTROL_SUSPEND_INTR            (1 << 6)#define CONTROL_RESET_INTR              (1 << 7)// Getting the control register settings right is a little bit tricky.// Bit 0 is the disable bit so touching that is dangerous, and the// other bits have inverted meanings i.e. 0 enables interrupts. The// following macro encapsulates this.#define CONTROL_ALL_INTR                0x00FC#define CONTROL_INTR_ENABLE(bits)  ((~(bits)) & CONTROL_ALL_INTR)#define CONTROL_INTR_CLEAR(bits)   ((bits) & CONTROL_ALL_INTR)// All the endpoint interrupt numbers can be handled en masse,// but some of the endpoints may be disabled.#if defined(CYGPKG_DEVS_USB_SA11X0_EP1) && defined(CYGPKG_DEVS_USB_SA11X0_EP2)# define CONTROL_EP_INTR_BITS      (CONTROL_EP0_INTR | CONTROL_EP1_INTR | CONTROL_EP2_INTR)#elif defined(CYGPKG_DEVS_USB_SA11X0_EP1)# define CONTROL_EP_INTR_BITS      (CONTROL_EP0_INTR | CONTROL_EP1_INTR)#elif defined(CYGPKG_DEVS_USB_SA11X0_EP2)# define CONTROL_EP_INTR_BITS      (CONTROL_EP0_INTR | CONTROL_EP2_INTR)#else# define CONTROL_EP_INTR_BITS      (CONTROL_EP0_INTR)#endif#define EP0_OUT_READY                   (1 << 0)#define EP0_IN_READY                    (1 << 1)#define EP0_SENT_STALL                  (1 << 2)#define EP0_FORCE_STALL                 (1 << 3)#define EP0_DATA_END                    (1 << 4)#define EP0_SETUP_END                   (1 << 5)#define EP0_SERVICED_OPR                (1 << 6)#define EP0_SERVICED_SETUP_END          (1 << 7)#define EP1_FIFO_SERVICE                (1 << 0)#define EP1_PACKET_COMPLETE             (1 << 1)#define EP1_PACKET_ERROR                (1 << 2)#define EP1_SENT_STALL                  (1 << 3)#define EP1_FORCE_STALL                 (1 << 4)#define EP1_FIFO_NOT_EMPTY              (1 << 5)#define EP2_FIFO_SERVICE                (1 << 0)#define EP2_PACKET_COMPLETE             (1 << 1)#define EP2_PACKET_ERROR                (1 << 2)#define EP2_PACKET_UNDERRUN             (1 << 3)#define EP2_SENT_STALL                  (1 << 4)#define EP2_FORCE_STALL                 (1 << 5)#define STATUS_EP0_INTR                 (1 << 0)#define STATUS_EP1_INTR                 (1 << 1)#define STATUS_EP2_INTR                 (1 << 2)#define STATUS_SUSPEND_INTR             (1 << 3)#define STATUS_RESUME_INTR              (1 << 4)#define STATUS_RESET_INTR               (1 << 5)#define EP0_FIFO_SIZE                     8#define EP0_MTU                           8#define EP1_FIFO_SIZE                   20#ifdef CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL# define EP1_MTU                        64#else# define EP1_MTU                        16#endif#define EP2_FIFO_SIZE                   16#ifdef CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL# define EP2_MTU                        64#else# define EP2_MTU                        16#endif#if defined(CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL) || defined(CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL)typedef struct usbs_sa11x0_dma {    volatile int                address;    volatile int                control_set;    volatile int                control_clear;    volatile int                status;    volatile int                buf_a_address;  // Absolute, not remapped    volatile int                buf_a_size;    volatile int                buf_b_address;  // Absolute, not remapped    volatile int                buf_b_size;} usbs_sa11x0_dma;#define DMA_CONTROL_RUN                 (1 << 0)#define DMA_CONTROL_INTR_ENABLE         (1 << 1)#define DMA_STATUS_ERROR                (1 << 2)#define DMA_STATUS_DONE_A               (1 << 3)#define DMA_CONTROL_START_A             (1 << 4)

⌨️ 快捷键说明

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