Writing a usb device driver, Name, Introduction – Comtrol eCos User Manual
Page 711: The control endpoint

Writing a USB Device Driver
Name
Writing a USB Device Driver
— USB Device Driver Porting Guide
Introduction
Often the best way to write a USB device driver will be to start with an existing one and modify it as necessary.
The information given here is intended primarily as an outline rather than as a complete guide.
Note: At the time of writing only one USB device driver has been implemented. Hence it is possible, perhaps
probable, that some portability issues have not yet been addressed. One issue involves the different types
of transfer, for example the initial target hardware had no support for isochronous or interrupt transfers, so
additional functionality may be needed to switch between transfer types. Another issue would be hardware
where a given endpoint number, say endpoint 1, could be used for either receiving or transmitting data, but
not both because a single fifo is used. Issues like these will have to be resolved as and when additional USB
device drivers are written.
The Control Endpoint
A USB device driver should provide a single
data structure for every USB device. Typical
peripherals will have only one USB port so there will be just one such data structure in the entire system, but
theoretically it is possible to have multiple USB devices. These may all involve the same chip, in which case a
single device driver should support multiple device instances, or they may involve different chips. The name or
names of these data structures are determined by the device driver, but appropriate care should be taken to avoid
name clashes.
A USB device cannot be used unless the control endpoint data structure exists. However, the presence of USB
hardware in the target processor or board does not guarantee that the application will necessarily want to use
that hardware. To avoid unwanted code or data overheads, the device driver can provide a configuration op-
tion to determine whether or not the endpoint 0 data structure is actually provided. A default value of
CY-
GINT_IO_USB_SLAVE_CLIENTS
ensures that the USB driver will be enabled automatically if higher-level code
does require USB support, while leaving ultimate control to the user.
The USB device driver is responsible for filling in the
start_fn
,
poll_fn
and
interrupt_vector
fields.
Usually this can be achieved by static initialization. The driver is also largely responsible for maintaining the
state
field. The
control_buffer
array should be used to hold the first packet of a control message. The
buffer
and other fields related to data transfers will be managed
by higher-level code and the device
driver. The remaining fields are generally filled in by higher-level code, although the driver should initialize them
to NULL values.
Hardware permitting, the USB device should be inactive until the
start_fn
is invoked, for example by tristating
the appropriate pins. This prevents the host from interacting with the peripheral before all other parts of the system
have initialized. It is expected that the
start_fn
will only be invoked once, shortly after power-up.
Where possible the device driver should detect state changes, such as when the connection between host and
peripheral is established, and
these to higher-level code via the
state_change_fn
callback, if any. The
607