The Raspberry Pi RP2040 specifications only list one USB 1.1 Host/Device hardware interface, but developer’s Sekigon Gonnoc decided to leverage the microcontroller’s programmable I/Os (PIO) to add an extra USB port that also works in host or device mode.
While the C library is still supposed to be a work in progress Sekigon implemented full-speed (12 Mbps) and slow-speed (1.5Mbps) host, full-speed device, USB hub, and multi-port support. There’s even a demo with three “Pico Pico USB” keyboards acting as USB hubs and HID plus a wireless mouse to show the results.
The implementation uses one PIO for the USB transmitter using 22 instructions and one state machine and another PIO for the USB receiver using 31 instructions and two state machines, as well as one 1ms loop timer for the host, and one PIO interrupt for the receiver.
You’ll find the code to implement the extra USB port on RP2040 MCU through PIO on the Pico-PIO-USB Github repository including two samples:
- capture_hid_report.c USB host sample program that prints HID reports received from a device.
- usb_device.c HID USB FS device sample which moves mouse cursor every 0.5s.
Another more advanced sample is the QMK firmware for the Pico Pico USB board. The hardware keyboard also appears to be designed by Sekigon Gonnoc, but I could not find any information about it. Having said that, he previously designed the Pico Micro RP2040 board and sold it through Booth.pm, a “creator market” for the Japanese market that looks somewhat similar to Tindie to me, except it also works for artists.
Via Hackster.io.
Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.
Support CNX Software! Donate via cryptocurrencies, become a Patron on Patreon, or purchase goods on Amazon or Aliexpress
I didn’t notice the capabilities of PIO, that’s super interesting. I’m currently thinking about making a USB-audio input device that directly converts SPDIF input data to digital audio. It sounds easy to do once you have the suitable device, but there are considerations such as USB speed, signal rate and buffering that limit the choices. From what I’m seeing here, there could be some real possibilities with this chip.
There’s some discussion on SPDIF conversion in the forum’s !
Ah cool, thanks for letting me know! I was amazed to see how complicated it is to find such solutions nowadays compared to how simple it ought to be at the protocol level!
I’d really like an SBC with multiple USB-device ports. I want to play at building a KVM. I guess that this lets the Pico have two device ports but perhaps only one can be device (not sure).
One problem is that most SBCs put a USB hub chip between their USB ports and the SoC. A USB hub port cannot be a device, only a host.
Some or all models of the Raspberry Pi 0 provide one bare USB port that can be host or device.
The Raspberry Pi 4 has one USB 2 port that can act as a device. It is also the power supply port so you need a circuit to break it out.
There are many SBC’s that have a USB Device Controller (UDC), including the Pi 4 and Pi Zero, but also Allwinner and RockChip-based devices too. There are a few microcontrollers with more than one device port, but the most I have seen is two, I think, and even then, you probably still want one port to manage the physical keyboard and mouse.
The alternative is to use an SBC with a USB host port(s) for the keyboard/mouse, and connect multiple microcontrollers via e.g. SPI to act as devices to the various computers. An example here is the Maxim MAX3420 and MAX3421 chips, but really, any microcontroller with a UDC would work. The Maxim chips are particularly expensive, although they do have native support in the Linux kernel, which could be attractive.
The problem then becomes accurately replicating multiple independent USB devices (a physical keyboard, a mouse/trackpad/whatever) using a single USB gadget. In other words, amalgamating two or more independent USB device descriptors into a single one.
It’s not impossible, by any means. The LUFA stack for Atmel microcontrollers provides examples of combined Keyboard and Mouse devices, and it would then require translating the reports received from independent devices into reports coming from the combined one.
One of the most interesting chips I have encountered in this area is http://www.wch.cn/products/CH9374B.html?from=list which is advertised as a 4-port host, 4-port device chip explicitly for KVMs. But actually getting a datasheet for it, and making sense of it may be tricky.