A USB keyboard to UART bridge. A Raspberry Pi Pico or Pico 2 receives keyboard input from a USB keyboard and translates the input into VT102 terminal output, which is transmitted using one of its two UARTs. Its second UART also transmits the terminal output along with debug messages. It was developed to enable stand-alone (i.e. no PC) use of my Palavo logic analyser project.
This project uses code from Raspberry Pi's Pico SDK USB Host (CDC MSC HID) Example, which uses Ha Thach's TinyUSB USB Host/Device stack for embedded systems.
A Raspberry Pi Pico or Pico 2 housed in a half-sized breadboard. The Pico's or Pico 2's USB port is attached to a USB keyboard via a special adapter cable, and its two UART TX pins are labelled as follows:
| Pico or Pico 2 Pin No | Pico or Pico 2 Pin Name | Function |
|---|---|---|
| 1 | GP0 | DEBUG_UART_TX |
| 3 | GND | GND |
| 11 | GP8 | TERMINAL_UART_TX |
| 13 | GND | GND |
This is the special adapter cable I use to connect a USB keyboard to the Pico or Pico 2.
Remove the special adapter cable from the Pico's or Pico 2's USB port, plug in a regular USB cable while holding down the BOOTSEL button, and copy the appropriate .uf2 file onto the device:
For the Pico use keybuart_on_pico.uf2.
For the Pico 2 use keybuart_on_pico2.uf2.
Alternatively, you can use the picotool utility:
For the Pico:
picotool load keybuart_on_pico.uf2 -fFor the Pico 2:
picotool load keybuart_on_pico2.uf2 -fFinally, remove the regular USB cable from the Pico or Pico 2 and reconnect the special adapter cable, USB keyboard etc.
Skip to Testing.
There may be a simpler way to build Keybuart's firmware, using Raspberry Pi's Pico Visual Studio Code Extension perhaps, but I haven't experimented with that enough yet (TODO). This is how I currently build the firmware on a Raspberry Pi 5 running Raspberry Pi OS:
Follow the instructions in Appendix C: Manual toolchain setup of Getting started with Raspberry Pi Pico-series.
Clone this repository (keybuart) to a suitable location on your PC:
git clone https://github.com/peterstansfeld/keybuart.gitEnter the keybuart directory:
cd keybuartCreate a build directory and, enter it:
mkdir build
cd buildCreate a directory for the board, and enter it.
For the Pico:
mkdir pico
cd picoFor the Pico 2:
mkdir pico2
cd pico2Specify where the pico-sdk directory can be found on your PC, e.g.:
export PICO_SDK_PATH=~/pico/pico-sdkRun cmake specifying where the top level CMakeLists.txt file can be found - in this case it's the grandparent directory ../../, and the board:
For the Pico:
cmake ../../ -DPICO_BOARD=picoFor the Pico 2:
cmake ../../ -DPICO_BOARD=pico2Then build the firmware:
makeThis should generate, among other files, a keybuart.uf2 and akeybuart.elf.
To program the Pico or Pico 2 with keybuart.uf2 remove the special adapter cable from the Pico's or Pico 2's USB port, plug in a regular USB cable while holding down the BOOTSEL button, and either copy the keybuart.uf2 onto the device, or use the picotool utility:
picotool load keybuart.uf2 -fFinally, remove the regular USB cable from the Pico or Pico 2 and reconnect the special adapter cable, USB keyboard etc.
To program the Pico or Pico 2 with keybuart.elf use openocd and a Raspberry Pi Debug Probe.
For the Pico:
openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "init; reset; program keybuart.elf verify reset exit"For the Pico 2:
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "init; reset; program keybuart.elf verify reset exit"Connect a USB to UART bridge, e.g. a Debug Probe, to Keybuart's TERMINAL_UART_TX pin and GND, and monitor the output with a serial communication program, e.g. minicom.
Here's a photo of my setup, which includes a second Debug Probe for flashing firmware onto the Pico 2, and for monitoring DEBUG_UART_TX output:
A Raspberry Pi Pico 2 housed in a half-sized breadboard with one end of a special adapter cable plugged into the Pico 2's USB port. Another end of the adapter cable is connected to a USB keyboard. The third and final end of the adapter cable is connected to a micro USB cable, which is plugged into a USB hub (not shown) to power both the USB keyboard and the Pico 2. The UART RX wire of one of two Raspberry Pi Debug Probes is connected to the Pico 2's DEBUG_UART_TX pin (GP0), the DEBUG wires of the same Debug Probe are connected to the Pico2's SWD port, and the UART RX wire of the second Debug Probe is connected to the Pico 2's TERMINAL_UART_TX pin (GP8). Finally, the currently unused UART TX wires of the two Debug Probes are plugged, safely out of harm's way, into unused parts of the breadboard.
