May
2004, Issue 166
USB
in Embedded Design (Part 2):
HIDmaker
Converts an Application
SOFTWARE
CHANGES
Data
transmission via a serial port requires the conversion
of data through hardware or software into asynchronous
or synchronous bitstreams. The two devices are configured
for the same data format so that what goes in one end
comes out the other end. They may use hardware, software,
or no flow control. These factors must be agreed to
prior to any communication; for the most part, they
cannot be identified through the connection itself.
Data
transmission via parallel ports moves data in byte-sized
transfers using eight parallel data paths. Although
potentially 10 times faster than serial, hardware handshaking
is done on a byte-by-byte basis, which slows everything
down.
The
original parallel port is unidirectional and—discounting
the 5 bits of status inputs, which are often used for
inputting nibble data—is not meant to be a bidirectional
device. This led to the bidirectional port (SPP), the
enhanced parallel port (EPP) for speedier nonprinter
devices, and the extended capabilities port (ECP) for
speedier printing devices. Which do you have? Truth
be told, unless you are using an older system, you probably
have support for all of them, but it is still half-duplex.
Although
similar to synchronous serial, a USB host can obtain
everything it needs to know about a device through the
connection. Therefore, you don’t have to know anything
about a device just to make a connection to it. It’s
easy for you (as a user), but tough on the designer.
A
special device descriptor is the key to each device.
This is the biggest stumbling block for a designer.
The hardware handles much of the work. For the most
part, after putting together the device descriptors,
it is simply a mater of managing your data in and out
of the endpoint buffers.
Handling
this data takes some thought, however, particularly
because of the way USB operates. Your project may be
used to sending data whenever necessary to the application.
Under USB rules, the host must ask for data before a
device can send it. You’re in trouble unless you have
the resources to hold the data until it’s asked for.
Last
month I covered the designed data throughput of USB.
Now is a good time to cover the four types of transfers
(control, interrupt, bulk, and isochronous) because
each has different throughputs (see Table
1).
The
all-important enumeration process is handled with control
transfers. The host allocates between 10% and 20% of
a frame to control transfers. Although all enumeration
begins with endpoint 0, control transfers are not limited
to endpoint 0 or enumeration. A control transfer can
be used at any time as defined by any class (or vendor).
Don’t
be fooled by its name, the interrupt-type transfer does
not cause an interrupt; instead, it is guaranteed to
occur within a certain amount of time (more like interrupt
latency). The interrupt transfer is used where you don’t
want to miss a key press, mouse move, or any other real-time
interaction event. (The Windows predefined HID driver
supports this mode.) This type of transfer also requires
separate in and out pipes for data. Although attempts
by the host are guaranteed, it’s up to the device to
be ready and to ensure any throughput. The latency time
is defined in the device’s descriptor table.
Bulk
transfers are similar to interrupt transfers, except
there is no guarantee on when the data will start or
finish. They are plugged into frames whenever there
is room. This type of transfer also requires separate
in and out pipes for data. With no USB traffic, a bulk
transfer can fill the full frame. However, if other
USB transfers fill the frames, a bulk transmission is
held off. Bulk transfers are generally limited to functions
that aren’t time critical (e.g., printing and file transfers).
The
isochronous transfer is similar to an interrupt transfer
in that there is a guarantee. Here the isochronous transfer
requests a specific bandwidth. The host must calculate
what bandwidth it has to offer before it can accept
and configure an isochronous pipe. Success depends on
which other devices are already on the bus. This type
of transfer also requires separate in and out pipes
for data. You can see that allocating bandwidth ensures
the data gets there; however, there is no plan for resending
corrupted data. Therefore, this type of transfer is
used where the application can tolerate small errors
(streaming audio). The bandwidth requirements are defined
in the device’s descriptor table.
DEVICE
CLASSES
If
you could gather all the USB devices out there (as well
as those that haven’t been designed yet) and separate
them into groups with similar characteristics, you could
define classes of devices, which would include the following:
the HUB device, audio device, chip/smartcard interface
device, communication device, content security device,
device firmware upgrade, human interface device (HID),
IrDA bridge, mass storage, printer, and imaging. The
list is continually growing.
As
you can imagine, generic drivers don’t hack it for most
peripherals. There is the necessity for special drivers
to be written to handle each of these devices, even
those within the same class. After the host has received
a device descriptor table through enumeration, it can
search its .INF (or other files) for a matching class
and device driver. If necessary, the host asks you for
the appropriate drivers. (That’s if the device is new
to the system.)
Windows
has a generic driver for the HID class. (Try searching
for hiddev.inf; it can be viewed with Notepad.) Because
HIDs have a generic class driver, designers can make
their lives less complicated by trying to design for
this class.