Tuesday 12 February 2013

Library: USBMouse implementation

Today I'm going to show you how to implement USB mouse emulation using InputStick library. In order to understand what's going on you need to have at least some basic knowledge about USB and HID (Human Interface Device) class. At this moment I'm not going to explain every detail, although I think about writing detailed tutorial at some point in the future. My goal for today is to show, that using InputStick library, which takes care of many USB related details, it is possible to implement simple USB device in approximately 100 lines  of code. If you want to learn more about USB and HID there are many good materials available on the Internet:

At this moment InputStick library is still under development. Current version has some limitations:
  • only HID class is supported.
  • only 1 device configuration supported.
  • only 1 interface supported.
  • total size of all descriptors must be lass than 512 bytes.

In final release I hope to solve at least some of this problems. Adding support for more interfaces and additional USB classes has highest priority. 512 bytes limit may be hard to overcome, due to memory limitations of microcontroller used in InputStick device, however it should be more than enough for most cases.
Brief description of Java classes used in this example:
  • USBDevice - every USB device must inherit from this class, which stores device related data and takes care of communication with InputStick device.
  • USBDeviceData - stores data describing the USB device.
  • USBDescriptor - abstract class used as a base class for specific USB descriptors (Device, Configuration, Interface, etc.). Descriptors are a data structures containing information about USB device, what allows USB host to learn about devices capabilities.
  • EndpointConfig - stores USB endpoint configuration: type, direction, size etc.
  • EndpointBuffer - FIFO data buffer for a USB endpoint.
Before going to implementation I will briefly describe USB mouse protocol. USB mouse uses one IN endpoint (data goes from device to USB host). Mouse sends data to host using USB reports. In most simple case, which is presented here (mouse with two buttons), report consists of 3 data bytes: state of buttons, change in X coordinate, change in Y coordinate. Some examples:
{0x00, 0x0A, 0x00} - moves pointer 10 pixels right.
{0x00, 0x00, 0x05} - moves pointer 5 pixels down.
{0x01, 0x00, 0x00} - left button pressed.
{0x02, 0x00, 0x00} - right button pressed.
{0x03, 0x00, 0x00} - both buttons pressed.
{0x00, 0x00, 0x00} - all buttons released.
Now let's take a look at the implementation:

If you're familiar with USB and HID, comments should more less explain everything what's happening. If not, well, take a look at sites linked at the beginning of this post, USB is not as difficult as it may seem :)

No comments:

Post a Comment