FIGURE 5. PIC32
chip USB peripheral.
provide a set of data structures called descriptors
that give details to the host about how to use it.
In general terms, the USB descriptors can be
thought of as belonging to one of three different
groups: those describing the overall device,
those describing possible device configurations,
and those providing user-readable information.
Each USB device has one and only one
descriptor in the first group — the device descriptor. It
uniquely identifies the device and gives the number
of possible configurations. Each configuration (the
second group) has its own set of descriptors
describing the details of that configuration. User-readable information is kept in the string descriptors,
making up the third group. All descriptors are already
pre-defined using the Microchip firmware stack.
3. The Application
Since most of the CDC USB related code is
already in place within the Microchip framework,
our user focus will be on the main function code.
To begin with, the main function must call
Finally, to service the user-specific defined I/O for the
end application, we need to call the C function ProcessIO ()
(see Figure 7). This is the flow chart that the USB framework
uses for Main code and is the one we will be following
throughout the demos. This arrangement is described as
cooperative multitasking and is implemented using a
continuous loop in C code. For this loop, the user has to
insure that the ProcessIO() does not unduly occupy
significant CPU processing time. This occurs when the CPU
delays service during ProcessIO() from the USB for greater
than 1.8 milliseconds. While ProcessIO() is executing, it
cannot consume CPU operations beyond 1.8 milliseconds.
If this is done, it will cause an inadequate update service to
the USB. When the ProcessIO() operates in this manner, it
is designated to be a "blocking function." They are not
allowed because they can cause USB functional problems.
To prevent this, Microchip recommends that the
ProcessIO() be implemented as a “state machine design.”
This means that ProcessIO() is broken down into a number
of discrete steps where each step consumes only a limited
amount of loop time. This state machine is “non-blocking”
and keeps track of what steps have been done and which
ones still remain, during every pass through the main loop.
To help us visually understand blocking during the
ProcessIO, a blink LED function is called. The blink
FIGURE 6. Microchip USB stack.
FIGURE 7. Generic Main function flow.
Note that the peripheral uses the USB bus supply voltage
of +5V to sense the USB bus connection and to regulate
and drive its data lines which are a + 3.3V differential level.
A key hardware component within the USB peripheral is
the SIE or Serial Interface Engine. The SIE off-loads the
PIC32 CPU by directly handling all USB activity. The SIE
communicates to the PIC32 through internal RAM. It
automatically does conversions from serial to parallel
between serial USB bits and parallel CPU memory, and
performs USB communications error checking.
2. The Microchip USB Stack
The Microchip USB framework is similar for all USB
applications and it is the second consideration for the
virtual serial port. A project view from MPLAB is captured
for the USB to PS/2 keyboard USB demo. There are Main,
Keyboard (PS2T4), and USB descriptor files and associated
header files, including usb_config.h. Most of what we’ll be
concerned with is the Main file.
Let’s discuss USB descriptors. Every USB device must
46 February 2012