i
i
i
i
i
i
i
i
17.5. Interfacing Custom VR Hardware with the Applications 503
Not only does the embedded microcontroller program have to provide
correct enumeration of the USB descriptors for the device it is emulating, it
must also configure its own A /D converters and move the data from the input
registers to the RAM locations where the USB interface expects them to be.
This will differ from PIC to PIC, but typically the PIC program will provide
an interrupt handler to service an interrupt from the USB interface. In re-
sponse to the interrupt, either enumeration or data transfer from the internal
buffer to PC will take place. The PIC program will also go through an initial-
ization procedure to load the USB descriptors, configure its A/D converters
for input and then enter a n infinite loop to alternate between reading from
the A/D input and writing to the USB data transfer buffer. Examples of PIC
program design may be found in [4] and specifics of the Microchip 167865
from its datasheet [6].
17.5.3 Accessing the USB HID Directly from C/C++
Using the hardware described in the previous section as an illustration, it is
perfectly possible to read the emulated joystick status and position via the
DirectInput API. Indeed, we could read two, three or more attached joysticks
using DirectInput. Nevertheless, it may be that a custom interface which
can pick up the nine-byte data stream directly is more useful. This can be
done without having to resort to the trouble of writing a full Windows device
driver.
Any HID USB interface devices can be accessed directly from an appli-
cation program written in C/C++ by simply using the Win32 API functions
ReadFile(...) and WriteFile(...).
Listings 17.7 and 17.8 show how this is done for the pseudo-joystick
device discussed in Section 17.5.2. We will need a few components from
the Windows device driver development kit (DDK). Specifically, the header
files
hidusage.h, hidpi.h and setupapi.h need to be included in our ap-
plication code, since functions they define are called during initialization.
They themselves require the header file
pshpack4.h from the DDK, and
the application must be linked with the DDK stub libraries hid.lib and
setupapi.lib. We only need a few functions from these, but it is easer to
find the header and stub libraries than to make them up yourself. Microsoft
used to make the DDK freely available for download, but that has been with-
drawn. Nevertheless it is easy to find the necessary files with a Web search.
Reading from the device is done in a separate thread function (see List-
ing17.8),sothatitcanexecuteatahighpriority,justasthehapticservo