Nowadays if you want to interact with an electronic device over a serial line, all you can find is a WebSerial page: open browser, click Connect, grant it the serial port, click Flash. But it needs a graphical environment, a browser and a mouse… and I live in a terminal.
So I designed uvktool, a small dependency-light Python CLI that talks to the radio directly over the serial port: pip install, plug in a cable, run a command.
$ uvktool info -p /dev/ttyACM0
bootloader 7.03.01 (modern / UV-K1, UV-K5 V3)
$ uvktool flash -p /dev/ttyACM0 firmware.bin
It covers the two things I actually need a serial cable for: flashing firmware, and backing up/restoring the radio’s RF calibration data (easy to lose track of when you reflash a radio a few times in an evening).
I built this with Claude Code doing most of the typing, but none of the protocol work is mine — this project is just gluing other people’s reverse-engineering into a CLI I actually wanted to use:
- k5prog by Jacek Lipkowski (SQ5BPF) — the classic UV-K5 V1/V2 DFU protocol and the normal-mode EEPROM protocol, straight from
k5prog.c. - Multi-UVTools and the deployed uvstudio app by Armel (F4HWN) — the modern UV-K1/UV-K5 V3 DFU protocol and the calibration-address logic. Armel also maintains the custom firmware this tool is usually flashing in the first place.
- qs-uvk5-firmware-modder by Mikhail Yudin (fagci) — Quansheng’s OEM firmware XOR encryption format, used to auto-decrypt classic UV-K5 release files.
Verified end to end on real hardware: flashed Armel’s official release to a UV-K1 and confirmed TX/RX against a local relay, flashed a classic UV-K5 V1 (via an AIOC) between two firmware editions including auto-decrypting an actual encrypted release file, and did a full calibration dump/restore/re-dump round trip on both radios.
Code and full protocol notes are on my Forgejo: forge.chach.org/francois/UVKtool.
Still on the list:
- logo dump/restore,
- real hardware testing on a UV-K5 V2 (only tested V1 and V3/K1 so far). If you use my program with this HT, let me know in the comments!
