This software is firmware for the Raspberry Pi Pico W. It allows you to use a single BLE or Bluetooth Classic HID device, such as a keyboard or mouse, as a wired USB device, even on PCs without Bluetooth functionality. It operates as a Bluetooth Host, forwarding input data from the connected device to the host PC via USB. Since it is recognized as a standard USB HID device by the PC, it can also be used in UEFI environments. *For the reverse (USB to BLE) bridge, please see this repository.
-
Connect Pico W
- Connect the Pico W to the PC's USB port.
- In the standby state where BLE connection is not complete, the LED on the Pico W will blink.
-
Pairing
- Put the BLE or Bluetooth Classic HID device (keyboards, mice, and other peripherals) you want to connect into pairing mode.
- Refer to the manual of each BLE device for how to enter pairing mode.
- If a keyboard requests a pairing code, type
000000on the keyboard and press Enter. - Bluetooth Classic keyboards using legacy PIN pairing use
0000; type0000and press Enter when requested.
-
Connection Complete
- When the Pico W detects the device and the connection is complete, the LED changes to steady on.
- It will be recognized as a USB input device on the PC side, and operation becomes possible.
- Reconnection: Once paired (bonded), you do not need to put the BLE device into pairing mode next time. It will automatically reconnect just by turning on the power.
- Keyboard Behavior: Some BLE keyboards (with power-saving features, etc.) may not enter reconnection mode unless a key is pressed to wake them from sleep. If it does not connect, try pressing a random key a few times.
- Firmware Update: Hold the Pico W's BOOTSEL button continuously for at least 5 seconds to reset into USB BOOTSEL mode. The firmware can then be flashed with
make flashor by copying a UF2 file to the mounted drive.
The firmware requires Raspberry Pi Pico SDK 2.2.0, an Arm GNU toolchain, CMake,
Make, and picotool. If SDK 2.2.0 is already installed, set PICO_SDK_PATH to
that directory. Otherwise, CMake downloads the pinned SDK automatically. Run
the build from the repository root:
makeThe generated firmware is build-sdk-2.2/picow_ble_usb_hid_bridge.uf2.
To build and flash a connected Pico W:
make flashmake flash uses picotool and works when the board is in BOOTSEL mode or is
running firmware that permits picotool -f to reboot it. To use a different
build directory, pass BUILD_DIR, for example make BUILD_DIR=build-release.
Each received 8-byte keyboard press or release report is also sent as a 15-byte CH9350 packet at 115200 baud over UART0 TX on GPIO 0 (physical pin 1). Connect GPIO 0 to the CH9350 UART RX and connect the two boards' grounds. UART debug output is disabled so diagnostic text cannot corrupt CH9350 packets. Pairing and discovery traffic is not forwarded.
When forwarding is compiled in, the Pico selects its USB role at startup. If VBUS is present, it assumes an upstream USB host is connected, retains its normal USB HID device behavior, and does not forward keys to UART. Without VBUS, it enables CH9350 forwarding and operates as a USB host, allowing a boot-protocol keyboard connected through a micro-USB-to-USB-A OTG adapter to be forwarded along with Bluetooth keyboard reports. The keyboard still needs powered USB VBUS; the stock Pico board does not source VBUS from VSYS through its micro-USB connector.
Forwarding is enabled by default. To disable it and restore the original UART diagnostic output and USB HID device behavior, configure a separate build directory with:
cmake -S src_fw/picow_ble_usb_hid_bridge -B build-no-ch9350 \
-DCH9350_UART_FORWARDING=OFF
cmake --build build-no-ch9350 --parallelOperation has been verified with the following devices:
- Mouse: Sanwa Supply MA-SBB314
- Keyboard: ELECOM TK-FBM119
The bridge supports both BLE HID-over-GATT (HOGP) devices and Bluetooth Classic HID devices, including devices marketed as Bluetooth 3.0. Discovery alternates between BLE scanning and Bluetooth Classic inquiry until a supported device is found.
To achieve a comfortable operational feel as an input device, the following optimizations are performed:
- Multi-core Distributed Processing:
- Core 0: Handles communication processing as a USB device.
- Core 1: Handles communication processing as a BLE Host (Central).
- By operating these in parallel, processing delay from BLE reception to USB transmission is minimized.
- High-Speed Polling:
- The USB endpoint polling interval (
bInterval) is set to1(1ms), configured to transfer reports to the PC at the fastest speed.
- The USB endpoint polling interval (
- HID Report Descriptor:
- Upon completion of the BLE connection, a USB reconnection is triggered to pass the "HID Report Descriptor" acquired from the BLE device directly to the PC (USB host). This ensures that device-specific features, such as multimedia keys, are correctly recognized by the PC.
- HID Input Report:
- After the BLE connection is established, the "HID Input Report" received from the BLE device is passed through to the PC (USB host) without modification.
- Smart Scan:
- Operates by automatically switching between reconnection to known devices (bonded devices) and scanning for new devices every few seconds.
This software is developed and integrated based on sample code from the following open source projects:
- TinyUSB:
dev_hid_compositesample - BTstack:
hog_host_demosample
For license details of this software, please refer to LICENSE.TXT.