Hacking USB HID for Easy Tethered Ubicomp

At this years Sketching in Hardware conference, I gave a talk on the general approach I used to create LinkM, ThingM’s USB-to-I2C adapter for programming and controlling BlinkMs. I called it “Hacking USB HID for Easy Tethered Ubicomp” (4.8MB PDF) to give it a form that fit within some of the larger issues I’ve been dealing with in creating easily usable ubiquitous computing devices.

USB has many different (and confusing) aspects to it. I’ve long advocated the creation of a set of libraries and patterns to make “driverless” USB a reality. A sort of training wheels for USB. At the time I called this USB on Rails”, poking fun at RoR.

To me the key to this ease-of-use was the HID class in USB. No driver is needed when plugging in something like a mouse or keyboard. Other built-in device class drivers include CDC (modems), Mass storage, audio (headset), and video (webcam).

While researching HID, trying to make LinkM a “USB on Rails” project, I found that the biggest hurdle was a consistent host-side USB API that would let one write one set of code that could easily be ported to Mac OS X, Windows, and Linux. Libusb works well enough for Unix-like OSes like Linux and Mac OS X, but the Windows variant libusb-win32 required a driver install. So I put HID away.

For many months I investigated using CDC instead of HID because it maps down to a serial port on modern operating systems. Unfortunately, CDC has two main problems. For the “serial port emulation” mode, mapping to serial port semantics is problematic for a USB device that can be removed at will. If a device is removed while it is still “connected”, the OS and application can get confused or crash. Also, the CDC driver implementation seems brittle on Mac OS X. Some CDC devices can work fine, others wouldn’t. I can see now why FTDI and similar vendors use a custom driver for their USB-to-serial chips.

When looking back into HID after the frustration with CDC, I discovered that V-USB, the software-only USB firmware stack for AVR microcontrollers, had two interesting HID-based projects in them with a cross-platform host-side library for talking HID. The first was BootloadHID, a HID-based bootloader, and the second was “hid-data”, one of the examples. And there was a nice discussion of the platform differences on the V-USB wiki.

With that, I took both of those projects, generalized them slightly, then specialized them for LinkM and made them the core of the LinkM project. You can view the resulting source at the LinkM Googlecode project.

Leave a Reply

Your email address will not be published. Required fields are marked *