Data endpoints – Comtrol eCos User Manual

Page 712

Advertising
background image

Writing a USB Device Driver

state change to and from configured state cannot easily be handled by the device driver itself, instead higher-level
code such as the common USB slave package will take care of this.

Once the connection between host and peripheral has been established, the peripheral must be ready to accept
control messages at all times, and must respond to these within certain time constraints. For example, the standard
set-address control message must be handled within 50ms. The USB specification provides more information on
these constraints. The device driver is responsible for receiving the initial packet of a control message. This packet
will always be eight bytes and should be stored in the

control_buffer

field. Certain standard control messages

should be detected and handled by the device driver itself. The most important is set-address, but usually the get-
status, set-feature and clear-feature requests when applied to halted endpoints should also be handled by the driver.
Other standard control messages should first be passed on to the

standard_control_fn

callback (if any), and

finally to the default handler

usbs_handle_standard_control

provided by the common USB slave package.

Class, vendor and reserved control messages should always be dispatched to the appropriate callback and there is
no default handler for these.

Some control messages will involve further data transfer, not just the initial packet. The device driver must handle
this in accordance with the USB specification and the

buffer management strategy

. The driver is also responsible for

keeping track of whether or not the control operation has succeeded and generating an ACK or STALL handshake.

The polling support is optional and may not be feasible on all hardware. It is only used in certain specialised
environments such as RedBoot. A typical implementation of the polling function would just check whether or not
an interrupt would have occurred and, if so, call the same code that the interrupt handler would.

Data Endpoints

In addition to the control endpoint data structure, a USB device driver should also provide appropriate

data end-

point

data structures. Obviously this is only relevant if the USB support generally is desired, that is if the control

endpoint is provided. In addition, higher-level code may not require all the endpoints, so it may be useful to provide
configuration options that control the presence of each endpoint. For example, the intended application might only
involve a single transmit endpoint and of course control messages, so supporting receive endpoints might waste
memory.

Conceptually, data endpoints are much simpler than the control endpoint. The device driver has to supply
two functions, one for data transfers and another to control the halted condition. These implement the
functionality for

usbs_start_rx_buffer

,

usbs_start_tx_buffer

,

usbs_set_rx_endpoint_halted

and

usbs_set_tx_endpoint_halted

. The device driver is also responsible for maintaining the

halted

status.

For data transfers, higher-level code will have filled in the

buffer

,

buffer_size

,

complete_fn

and

com-

plete_data

fields. The transfer function should arrange for the transfer to start, allowing the host to send or

receive packets. Typically this will result in an interrupt at the end of the transfer or after each packet. Once the
entire transfer has been completed, the driver’s interrupt handling code should invoke the completion function. This
can happen either in DSR context or thread context, depending on the driver’s implementation. There are a number
of special cases to consider. If the endpoint is halted when the transfer is started then the completion function
can be invoked immediately with

-EAGAIN

. If the transfer cannot be completed because the connection is broken

then the completion function should be invoked with

-EPIPE

. If the endpoint is stalled during the transfer, either

because of a standard control message or because higher-level code calls the appropriate

set_halted_fn

, then

again the completion function should be invoked with

-EAGAIN

. Finally, the <

usbs_start_rx_endpoint_wait

and

usbs_start_tx_endpoint_wait

functions involve calling the device driver’s data transfer function with a

buffer size of 0 bytes.

608

Advertising