Raspberry Pi USB OTG Primer

This first page contains background information that you may or may not need. Remember the Dunning-Kruger effect, though : maybe you think you know, but do you really ? Read-on, just to make sure. You do not want to Dunning-Kruger.

The next page explains how to configure your SD Card to let the Pi Zero load the correct USB driver for USB gadget operation. It’s the exact same procedure no matter the gadget driver you need, so I put it there to avoid repetition. It’s a must-read.

1.1.         USB OTG and Connector Shapes

As you may be aware, USB isn’t a “bus” despite the B in its name. It’s a point-to-point connection that happens exclusively between a host port and a device port. So it was decided at the dawn of time. And to make sure people could tell hosts and devices apart, the USB specification introduced connectors with different shapes for each (A and B, easy). This way you could never be confused about what’s what.

USB being the hot mess it’s always been, that didn’t last long. Cellphones became popular and it was only a matter of time before that multibillion-dollar industry decided it wanted phones that could be both USB devices and hosts, but on the same connector. Even if it broke the USB design philosophy and even if it meant that a phone couldn’t act as host and be recharged at the same time. Anyone who’s cried over the disappearance of headphone jacks on smartphones will be able to relate. And to make sure we never forget where this aberration came from, they named it USB OTG, meaning “On The Go”, because, you know, cellphones… and lack of imagination.

And so, as tinier USB connectors (Mini– and Micro-USB) were introduced for pocket devices, a fifth pin appeared in addition to the traditional 5V (VBUS), ground and data pair : the ID pin. Also, a third shape of connector was added to the mix : the AB, which is both an A and a B. That’s right, the nightmare of every religious conservative : a socket that swings both ways.

The shield of the AB socket is designed in such a way that it’ll fit either an A or a B plug, whereas an A socket cannot fit a B plug and vice versa. The new ID pin, depending on how it is wired inside a cable, tells the USB port which type of connector (A or B) has been plugged in.

The three Micro-USB connectors look like this :

Interestingly, the color of the insulator is also normalized. For AB sockets, it’s grey instead of black.

The Pi Zero’s “USB” connector should have used the Micro-AB socket. But I’m guessing that, since it’s very uncommon compared to Micro-B, it’s a more expensive part. And the budget on the Pi Zero must be extremely tight considering the base model costs only five Euros.

Anyway, this explains why the Pi Zero need a special USB OTG cable : that cable, although it features a Micro-B plug, is wired inside as if it were a Micro-A plug. This tells the Broadcom SoC’s USB controller that it must operate as a host port.

However, despite using the wrong socket this is still electrically an OTG port. That means you are allowed to connect a Pi Zero to your PC using a typical “A to Micro-B” cable. In that configuration, the Pi’s USB controller will detect the cable’s plug as a type B and operate as a device port.

And that’s where things get interesting.

1.2.         The Linux USB Gadget API

We’ve just touched on the fact that a USB cable links a host to a device. Most of the time, the host is a computer and the device is a peripheral, be it a mouse, keyboard, printer, external hard drive, digital camera, coffee machine, you name it.

Because Linux is typically a computer operating system, it’s easy to assume that its USB drivers are all host-side drivers designed to control specific devices. However, in the embedded systems world, it’s also possible for a machine running Linux to have a USB device port, usually in a form of an OTG port. As we’ve just seen, it’s legal to connect a Pi Zero’s USB port to the USB port of a PC. It just requires the Pi Zero to behave as if it were a USB device.

This behavior is implemented, on Linux, by the USB Gadget API. To put it simply, Linux has a regular driver for the physical USB device interface, and then on top of that it also has so-called gadget drivers to implement the functionality of specific USB device classes. There are such drivers for the HID class (Human Interface Device), for example, which would enable a Pi to act as a keyboard or a mouse. There’s also a CDC (Communication Device Class) driver that will make your Pi appear as a USB to Serial converter.

There are many different gadget drivers, covering networking, audio / video, mass storage and more. This section will explore how to setup and use each one of those I have experience with.

This isn’t a new feature : it was introduced sometime during the Kernel 2.4 era, way back in the early 2000’s. Let’s call it a “hidden gem” of the Linux kernel.

1.3.         Hardware Prerequisites

For each gadget driver, I’ve done my best to come up with setup methods that do not require special or single-use hardware. You’ll just need what you should already have :

·       A Raspberry Pi Zero (any variant)

·       A microSD card

·       A microSD reader

·       And of course a Micro-USB cable (A to Micro-B)

All methods are headless, you won’t need a monitor and keyboard.

No power supply required : your PC will power the Pi through USB.

1.4.         Software Prerequisites

I’m going to assume that you’re starting a new project from a blank slate. Your microSD Card is empty. If you flash it with any version of Raspbian or Raspberry Pi OS released since 2017, then congratulations : you meet all the software perquisites to get this show on the road.

If you want to use USB gadget modes with an existing installation, you should also be fine as long as you’ve kept it up to date, though I won’t guarantee it. And you should definitely backup your data.

We’re going to modify the contents of your SD Card’s boot partition : if you’ve done modifications of your own, be on the look-out for conflicts.