This repository hosts the firmware of the Ultimate Hacking Keyboard.
If you want to use the latest firmware version for your UHK, then instead of going through the pain of building the firmware, simply download the latest release of Agent and update to the latest firmware version within Agent with a click of a button.
- Agent smart macro pane - covers commands that configure your UHK.
- user guide tries to give a a basic understanding of how macro commands can be combined, and describe common usecases.
- reference manual is a dry and rather formal list of all the commands and features.
If you're one of the brave few who wants to hack the firmware then read on.
uhk-workspace
- west workspace that manages both uhk firmware repository and third party componentszephyr, c2usb, bootloader, nrf
- third party componentsfirmware
- the actual uhk repositorylib/agent
- Agent as a git submodule.nvmrc
- expected Node.js versionpackages/usb
various development scripts to communicate with the UHK over USB
scripts
make-release.mjs
- script to build a full release tarball
- git
- pip3
- ninja
- cmake
- nodejs (and optionally nvm for version management, then (e.g.)
nvm install 22; nvm use 22
) - west and some other python packages (
pip3 install -r scripts/requirements.txt
after you have cloned the repository) - (UHK60 and modules) gcc-arm-none-eabi (sometimes also called arm-none-eabi-gcc) toolchain:
after it is installed, set an environment variable in the default shell, e.g.
export ARM_GCC_DIR="/usr"
for Linux or WSL in ~/.bashrcexport ARM_GCC_DIR="/opt/homebrew"
for macOS in ~/.zshrc
- (UHK80) nrfutil and nrf commandline tools:
- (release, might work without it)
- (flashing over USB) Agent built in
lib/agent
(see bellow also seelib/agent/README.md
): - (optional, used by build.sh) jq, tmux
Following uses the build.sh
helper script. I use it with Ubuntu linux. If they don't work for you, see the manual instructions below.
Initial setup:
mkdir uhk-workspace
cd uhk-workspace
git clone --recurse-submodules [email protected]:UltimateHackingKeyboard/firmware.git
cd firmware
./build.sh setup
(Optional) Update and build Agent (we don't update the submodule reference as often as we should):
cd lib/agent
git fetch origin && git checkout origin/master
npm ci && npm run build
cd ../..
Pick UHK60 environment:
./build.sh switchMcux
Or UHK80 environment:
./build.sh switchZephyr
Full build and flash of UHK80:
./build.sh right left dongle build flashUsb
Full build and flash of UHK60v2:
./build.sh rightv2 build flashUsb
Valid targets:
- UHK80:
right
,left
,dongle
- UHK60:
rightv1
,rightv2
,left
,keycluster
,trackball
,trackpoint
Basic actions (see help for more):
build
- full pristine buildmake
- incremental buildflash
- flash via debug probe, consider setting up.devices
file. See./build.sh help
.flashUsb
- flash via USBrelease
- build full release tarball
Release:
./build.sh release
Note: this and following sections are redundant If you have successfully completed above build.sh procedure.
Unlike most common workflows, where the git repository is the top level directory, this firmware uses the west workspace structure. This means that you should first create a wrapping directory, which will store the firmware git repository, and the west workspace with the third-party SW components.
Here is the initial checkout and installation of required Python packages:
mkdir uhk-workspace
cd uhk-workspace
git clone --recurse-submodules [email protected]:UltimateHackingKeyboard/firmware.git
west init -l firmware --mf west_nrfsdk.yml
west config build.cmake-args -- "-Wno-dev"
cd firmware
Note that there are two parallel development paths, that exist side by side.
UHK80 left, right and dongle use nRF Connect SDK, while the UHK60 and the modules use McuXpresso SDK.
If you intend to develop on the latter, use west init -l firmware --mf west_mcuxsdk.yml
command instead.
(You can also switch later on with west config manifest.file west_mcuxsdk.yml
.)
For the rest of the command line instructions, we assume the pwd
to be firmware
, the git repo root directory.
The nRF Connect SDK or McuXpresso SDK (depending on the manifest file selection) and additional third-party libraries must be fetched to their up-to-date state with the following command:
west update && west patch
This must be performed for each SDK independently, after manifest file selection. While the setup must only be done once, the external software components change during development, so this command is highly recommended to execute after checking out a new branch.
For UHK80 development, it is recommended to use Nordic's nrf shell environment:
- (Install nRF Util if you haven't done yet).
- Install the nRF Connect Toolchain Manager with
nrfutil install toolchain-manager
- Enter the Toolchain Manager shell with
nrfutil toolchain-manager launch --shell --ncs-version v2.8.0
Before you start a build, ensure that you have the correct west manifest selected (check with west config manifest.file
),
and that the external software components are available.
For UHK80 device targets (uhk-80-right
, uhk-80-left
, or uhk-dongle
), the basic command is this:
DEVICE=uhk-80-right; west build --build-dir device/build/$DEVICE device -- --preset $DEVICE
A debug build can be produced by appending DEVICE name with -debug
, e.g. DEVICE=uhk-80-right-debug
.
For UHK60 device and module targets (right
, left
, keycluster
, trackball
or trackpoint
), the basic command is this:
(Note that only right
has v1
and v2
options, all other devices are simply release
presets.)
DEVICE=right; west build -f --build-dir $DEVICE/build/v2-release $DEVICE -- --preset v2-release
A debug build can be produced by replacing release
with debug
in the preset.
The empty --
separates the west command line arguments from the arguments that are forwarded to cmake.
A full, clean rebuild can be performed by adding -p
or --pristine
before this separator.
Using the --build-dir
parameter of the build (e.g. device/build/uhk-80-right
or right/build/v2-release
),
the flashing command is as follows:
BUILD_DIR=device/build/uhk-80-right; west flash --build-dir $BUILD_DIR
-
(Install node.js and build Agent
cd lib/agent && npm ci && npm run build
or see seelib/agent/README.md
.) -
Use the
west agent
command just likewest flash
, with the--build-dir
parameter to flash the new firmware over USB.
It is recommended to start development in the IDE once a successful build is available, as the build parameters
aren't trivial to pass to the IDE, but it does pick up existing build configurations.
To get started, choose Open Workspace from File..., then select the firmware.code-workspace
file.
Install the recommended extensions or pick the one for your single device depending on the SDK.
Note that using MCUXpresso for VS Code extension currently overwrites the
mcux_includes.json
file, these modifications shall not be committed into the git repository!
If you encounter any issues, let us know via a github ticket and we will try to help asap.
Places to reference if build fails:
scripts/make-release.mjs
- script that handles building the release, thus should contain correct build commands.github/workflows/ci.yml
- github actions script that builds the firmware on every push, so contains a working dev environment setupbuild.sh
- a linux helper script that tries to automate above steps
For UHK60 and modules, the McuXpresso SDK extention is the starting point for a debugging session. On a first try, this error might manifest:
Could not start GDB. Check that the file exists, and it can be manually started. Error: Error: spawn $env{ARM_GCC_DIR}/bin/arm-none-eabi-gdb ENOENT
There are two problems to solve:
- The arm-none-eabi package doesn't ship with gdb by default. You can follow this guide to get a full toolchain installed.
- The extension doesn't expand the environment variable, so you'll need to modify the
.vscode/mcuxpresso-tools.json
file, to have a hardcodedtoolchainPath
variable. (Don't push this change into the repository, obviously.)
Release pack can be built either from system shell or from Nordic's nrf shell. As a rule of thumb, if one fails, try the other.
To build a full firmware tarball:
- Run
npm install
inscripts
. - Either:
- To build from system shell, make sure you have zephyr sdk installed: https://docs.zephyrproject.org/latest/develop/toolchains/zephyr_sdk.html
- To build from nrf shell, etner
nrfutil toolchain-manager launch --shell --ncs-version v2.8.0
.
- Run
scripts/make-release.mjs
. (Orscripts/make-release.mjs --allowSha
for development purposes.) - Now, the created tarball
scripts/uhk-firmware-VERSION.tar.gz
can be flashed with UHK Agent.
Want to contribute? Let us show you how.