Skip to main content

StereoPi used as USB device

  • StereoPi USB gadget (RNDIS device)

The Raspberry Pi Compute Module powering the StereoPi has the ability to operate as an USB device thanks to an USB-OTG hardware within the processor. This means that we can connect it to the PC and make it appear as an USB stick, a serial interface, or – as exposed in this article – as an external network interface. It is very powerful but it comes with a few limitations due to the architecture of the Raspberry ecosystem followed by the StereoPi. Let’s see how it works.

Overview of the hardware

Appearing as a device requires a special hardware. Fortunately, in the case of the Raspberry Pi Compute module, the processor has one USB port which has the OTG functionality. It means that it can act either as a host (like a PC) or as a slave (like a USB device). Notice that the StereoPi can be entirely powered through the micro USB connector in the case it is used as a device.

The processor has only one USB port, which is problematic because the norm precises that it is not possible to connect multiple devices per port. Furthermore, the processor do not have any Ethernet controller internally. To circumvent these two facts, a special chip named LAN9513 is connected to the USB port of the processor and acts both as a USB extender providing 3 USB host ports (two of which have a USB connector on the StereoPi while the third is available on a pin connector) and as an external network interface with the associated Ethernet port on the board.

On the StereoPi, there is an additional component: an electronic switch named FSUSB42UMX, which allows to choose to connect the LAN9513 or the micro-USB connector to the USB port of the processor. The switch to the micro-USB connector is automatically done when the cable connected to it is under power.

Let’s draw a synopsis to visualize this architecture:

StereoPi USB synopsys

Legend: Synopsis of the hardware of the StereoPi focused on the USB subpart.

As we can see, the limitation is clearly that we will lost Ethernet and USB connectivity when using the USB device mode, because they will not be connected to the processor anymore. Fortunately, we can create a network through the USB cable to connect to the StereoPi as we will see afterwards.

If you tried to plug the board into your computer now, you would see that Ethernet and USB devices would cease to function. However, no device would appear on the PC because of the lack of software part in the StereoPi.

Overview of the software

To appear as a USB device, we have to enable the USB port in slave mode and then make the board behave as a device thanks to the kernel's USB gadget functionality. We will also have to enable a service to give an IP address to the PC automatically for convenience.

Unfortunately, because the usage of the device mode removes Ethernet and other USB capabilities of the board, and with them the ability to communicate easily with the board, we will have to prepare all the software stack in one run without progressive steps.

USB gadgets are kernel drivers that allow a Linux system (with appropriate hardware) to act as USB device. A specific API allows developers to write such drivers, but fortunately, there exist some generic drivers with common functionalities, already written in the Linux sources. These drivers allow the board to be discovered as serial link, human interface device, USB stick, etc. In our case, we will use an USB gadget which will transform the StereoPi to an Ethernet-over-USB device.

Notice that only one gadget driver can be loaded at the time. In the SLP distribution provided with the StereoPi, the gadgets are compiled as kernel modules, so that they are ready to be used without compiling anything.

When built as modules, the drivers are not included into the kernel binary image. They become auxiliary binary files (.ko extension is used for kernel objects) that can be dynamically loaded into the kernel at runtime. These files must be present in the target's filesystem to be used. In the case of our gadgets, they are located in /lib/modules/[kernel version]/kernel/drivers/usb/gadget/legacy/. As you can see by listing the directory, there are a lot of possibilities. In our case, the g_ether module is the one we want to use: it provides both CDC-Ethernet for Linux/Mac/FreeBSD and RNDIS for Windows.

After the network device interface is created, we will need the PC and the StereoPi to have an IP address so that they can discuss together. We can force the addresses manually but there is a more convenient way. When they detect a new network connection, most operating system send a DHCP request, which is a standard way to retrieve a valid IP address if there is a server to respond to it. We will run a DHCP server on the StereoPi so that the PC will automatically get the right network configuration. The StereoPi will have a static address though to make it easier to reach.

Preparing the future network interface

We will lost the other connections (Ethernet or WiFi dongle connected to USB) as soon as the USB port will be configured in slave mode, so we have to prepare the future network interface before doing any configuration on the USB subsystem. To do so, unlock the filesystem and create a new file named

/etc/network/interfaces.d/usb0

with the following content:

 

auto usb0 
allow-hotplug usb0 
iface usb0 inet static 
    address 192.168.3.1 
    netmask 255.255.255.0 
    network 192.168.3.0 
    broadcast 192.168.3.255

This will allow the system to automatically configure a static IP on the usb0 network interface when available. This interface will be created on the StereoPi by the g_ether module.

Additionally, we will use dnsmasq already installed on SLP as a DHCP server. We just have to create a new file named

/etc/dnsmasq.d/usb0

with the following content:

interface=usb0 
dhcp-range=192.168.3.10,192.168.3.250 

This will allow the system to automatically attribute an IP in a valid range for our case to the computer which will send a DHCP request on the USB network interface.

 

Enabling device mode (and revert)

These manipulation require to modify some files in the boot partition of the SD card. You can power off the StereoPi, remove its SD and edit the files on your computer for example.

We need to enable the slave mode in the OTG driver thanks to a device-tree overlay. A device-tree overlay (DTBO) is a set of configurations for the kernel, in binary form, that we can load at startup to indicate which peripherals to use. Here, we will load the “dwc2” DTBO which describes the configuration of the USB-OTG hardware in the raspberry pi module, and we will set its dual role mode as “peripheral”.

To do this, open the config.txt file in the boot partition and add the following line in it (there might be several lines starting with “dtoverlay=”):

dtoverlay=dwc2,dr_mode=peripheral

We will now add a second configuration which will ask the kernel to load some modules at startup. This time, it is done by changing the command line used to start the kernel.

To do this, open the cmdline.txt file in the boot partition and add the following arguments at the end of the unique line (do not forget to separate this parameter from the old last one with a space):

modules-load=dwc2,g_ether

And voilà!

To return to the host mode (with Ethernet and USB ports), you can simply remove these two additions.

For a quick switch between the two modes, you can even only comment the added “dtoverlay=” line in config.txt because, in this case, the remaining configuration in cmdline.txt will only give a warning message in kernel log indicating that g_ether cannot be used without a USB port in device mode and usb0 network interface will not be created. In the absence of usb0 interface, the other configurations will not have effect.

Benefit from your new feature

If you correctly modified the 4 files cited on this article, plug a USB cable in the micro-USB connector of the StereoPi (with the board powered off) and plug the other end in your PC. After a little time necessary for the StereoPi to boot and for your system to negotiate the IP address, you will be connected to the StereoPi through USB. The usual test is obviously to ping the peer. The IP of the StereoPi is fixed to 192.168.3.1, so we can send pings from the PC:

$ ping -c 5 192.168.3.1

PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.

64 bytes from 192.168.3.1: icmp_seq=1 ttl=64 time=0.157 ms

64 bytes from 192.168.3.1: icmp_seq=2 ttl=64 time=0.223 ms

64 bytes from 192.168.3.1: icmp_seq=3 ttl=64 time=0.291 ms

64 bytes from 192.168.3.1: icmp_seq=4 ttl=64 time=0.218 ms

64 bytes from 192.168.3.1: icmp_seq=5 ttl=64 time=0.244 ms

--- 192.168.3.1 ping statistics ---

5 packets transmitted, 5 received, 0% packet loss, time 4064ms

rtt min/avg/max/mdev = 0.157/0.226/0.291/0.043 ms

Perfect! Let’s try to access the web interface of SLP with our browser:

StereoPi SLP admin panel access over USB

Legend: Visit the web interface of the StereoPi with the browser using http://192.168.3.1/ address. The page passes through the USB network interface.

It works.

You can also access the board with SSH or get the video stream through this network established over USB. If you want to access the Internet from the board, you have to share your connection on the PC and configure a default route on the StereoPi, but it is out of the scope of this article.

Now, you have fully access to the StereoPi without a need to an Ethernet switch nor a WiFi dongle. On the other hand, you do not have access to the Ethernet nor USB ports while using this method. Whether or not this solution is interesting will totally depends on your usage.

To revert to a classical usage, just remove (or comment) the line added in config.txt, or revert all the changes seen here (2 files created, additions in 2 files) and of course power the StereoPi with the power connector.

Troubleshooting

1. USB power

If you connect StereoPi to the USB 2.0 port on your desktop/notebook, power provided by this port might not be sufficient to feed up StereoPi (as USB 2.0 current is limited by 500 mA). Please use USB 3.0 port.

2. Dnsmasq

Dnsmasq is already installed on Raspbian S.L.P. image, but not installed by default on a stock Raspbian. To install it, use this command:

sudo apt-get install dnsmasq

3. Windows RNDIS driver problem

Under MacOS and Linux, the StereoPi will be detected and automatically configured. But with Windows 10 you can get a situation, when StereoPi is detected as a COM port. This is a known problem (for RPi and other single board computers), mentioned in a lot of places like Microsoft support forum. To say briefly, you can install this driver manually according to this guide (French), and it works.

 

Author: Stereomaton