📄 usbs.h
字号:
#ifndef CYGONCE_USBS_H
# define CYGONCE_USBS_H
//==========================================================================
//
// include/usbs.h
//
// The generic USB slave-side support
//
//==========================================================================
//####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
// Purpose:
// Description: USB slave-side support
//
//
//####DESCRIPTIONEND####
//==========================================================================
# include <pkgconf/system.h>
# include <cyg/infra/cyg_type.h>
# include <cyg/io/usb/usb.h>
#ifdef __cplusplus
extern "C" {
#endif
// The USB slave-side eCos support involves a number of different
// components:
//
// 1) a hardware-specific package to drive a specific chip implementation.
// This provides access to the endpoints. All the hardware-specific
// packages implement a common interface.
//
// 2) a common package (this one). This defines the interface implemented
// by the hardware-specific packages. It also provides support for
// the various generic control messages, using information provided
// by higher-level code and invoking callbacks as appropriate.
//
// 3) some number of support packages for particular types of
// application, for example ethernet or mass-storage.
//
// Typically there will only be one USB slave device, although the design
// does allow for multiple devices. Each device should provide a
// usbs_control_endpoint structure and zero or more usbs_data_endpoint
// structures. Each usbs_data_endpoint structure supports uni-directional
// transfers on a single endpoint. If an endpoint can support multiple
// types of transfer then there will be some control operation to switch
// between bulk, interrupt and isochronous.
//
// Access to the USB endpoints can go either via usbs_ calls which
// take a usbs_endpoint structure, or via open/read/write calls. The
// latter is more likely to be used in application code since it
// involves a familiar interface. The former is more appropriate for
// eCos packages layered on top of the USB code. The difference is
// synchronous vs. asynchronous: the open/read/write model involves
// blocking operations, implying a need for extra threads; the usbs_
// calls involve start operations and a completion callback. In
// practice the read and write calls are implemented using the
// lower-level code.
// Enumeration data. This requires information about the hardware,
// specifically what endpoints are available and what they get used
// for. It also requires information about the application class
// packages that are in the configuration, and quite possibly about
// things in application space. Some of the enumeration info such as
// the vendor id is inherently application-specific. Hence there is no
// way of generating part or all of the the enumeration information
// automatically, instead it is up to application code to supply this.
//
// The intention is that application provides all the data via const
// static objects, allowing the data to live in ROM. Alternatively the
// data structures can go into the .data section as normal, allowing
// them to be edited at run-time.
//
// There can be only one device descriptor, so that is part of the
// main enumeration data structure. There can be an unknown number of
// configurations so application code has to initialize an array of
// these. Ditto for interfaces and endpoints. The first x interfaces
// in the array correspond to the first configuration, the next y
// interfaces to the second configuration, etc. The endpoints array
// works in the same way.
//
// In the initial implementation multiple languages are not supported
// so a simple array of strings suffices. The first entry of these
// is still special in that it should define a single supported
// LANGID. All strings should be encoded as per the USB standard:
// a length field, a type code of USB_STRING_DESCRIPTOR_TYPE,
// and data in unicode format. In future multiple language support
// may be supported via configury with the default case remaining
// a single language, thus avoiding incompatibility problems.
typedef struct usbs_enumeration_data {
usb_device_descriptor device;
int total_number_interfaces;
int total_number_endpoints;
int total_number_strings;
const usb_configuration_descriptor* configurations;
const usb_interface_descriptor* interfaces;
const usb_endpoint_descriptor* endpoints;
const unsigned char** strings;
} usbs_enumeration_data;
// The current state of a USB device. This involves a bit to mark
// whether or not the device has been suspended, plus a state machine.
// On some hardware it may not be possible to distinguish between the
// detached, attached and powered states. If so then the initial state
// will be POWERED.
#define USBS_STATE_DETACHED 0x01
#define USBS_STATE_ATTACHED 0x02
#define USBS_STATE_POWERED 0x03
#define USBS_STATE_DEFAULT 0x04
#define USBS_STATE_ADDRESSED 0x05
#define USBS_STATE_CONFIGURED 0x06
#define USBS_STATE_MASK 0x7F
#define USBS_STATE_SUSPENDED (1 << 7)
// State changes. Application code or higher-level packages should
// install an appropriate state change function which will get
// invoked with details of the state change.
typedef enum {
USBS_STATE_CHANGE_DETACHED = 1,
USBS_STATE_CHANGE_ATTACHED = 2,
USBS_STATE_CHANGE_POWERED = 3,
USBS_STATE_CHANGE_RESET = 4,
USBS_STATE_CHANGE_ADDRESSED = 5,
USBS_STATE_CHANGE_CONFIGURED = 6,
USBS_STATE_CHANGE_DECONFIGURED = 7,
USBS_STATE_CHANGE_SUSPENDED = 8,
USBS_STATE_CHANGE_RESUMED = 9
} usbs_state_change;
typedef enum {
USBS_CONTROL_RETURN_HANDLED = 0,
USBS_CONTROL_RETURN_UNKNOWN = 1,
USBS_CONTROL_RETURN_STALL = 2
} usbs_control_return;
typedef struct usbs_control_endpoint {
// The state is maintained by the USB code and should not be
// modified by anything higher up.
int state;
// The enumeration data should be supplied by higher level code,
// usually the application. Often this data will be constant.
const usbs_enumeration_data* enumeration_data;
// This function pointer is supplied by the USB device driver.
// Application code should invoke it directly or via the
// usbs_start() function when the system is ready. Typically it
// will cause the USB lines to switch from tristate to active,
// and the USB host/hub should detect this.
void (*start_fn)(struct usbs_control_endpoint*);
// This function is used for polled operation when interrupts
// are disabled. This can happen in some debugging contexts.
// Higher-level code may also need to know about the interrupt
// number(s) used.
void (*poll_fn)(struct usbs_control_endpoint*);
int interrupt_vector;
// When a new control message arrives it will be in this buffer
// where the appropriate callback functions can examine it. The
// USB code will not modify the buffer unless a new control
// message arrives. The control_buffer can also be re-used
// by handlers to maintain some state information, e.g.
// for coping with complicated IN requests, but this is only
// allowed if they actually handle the request.
unsigned char control_buffer[8];
// This callback will be invoked by the USB code following a
// change in USB state, e.g. to SUSPENDED mode. Higher-level code
// should install a suitable function. There is some callback data
// as well. This gets passed explicitly to the callback function,
// in addition to the control endpoint structure. The reason is
// that the actual state change callback may be some sort of
// multiplexer inside a multifunction peripheral, and this
// multiplexer wants to invoke device-specific state change
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -