Every creature has a little brain of its own. The firmware is the code that runs directly on the Creature Controller board — the custom RP2350B design tucked inside each creature. It lives in the firmware/ directory of the creature-controller repo on GitHub, right alongside the Linux controller software it talks to.
It’s written in pure C (C11) on top of the Pico SDK and FreeRTOS, and it’s deliberately dumb in the nicest possible way — it doesn’t make any decisions. It takes commands from the controller host over USB, drives the servos, reads the sensors, and reports back. All the thinking happens upstairs on the Linux host; the firmware just makes the hardware do what it’s told, as close to real-time as I can manage. There’s a critical ISR down here that updates every servo’s PWM on each counter wrap, so timing genuinely matters.
One codebase, several targets
The firmware isn’t a single program — it’s a suite of build targets that share a big pile of common code (the Dynamixel library, the USB stack, logging, the device drivers) but compile into different .uf2 files for different jobs. Flash whichever one you need by holding BOOTSEL, plugging the board in, and dragging the .uf2 onto the drive that appears.
Controller
The main event, and the whole reason the board exists. This is the firmware that actually runs the creature — it receives position frames from the host, drives the servos through the critical PWM ISR, watches power and temperature, and streams sensor data back. Everything else here is a bench tool by comparison.
I2C EEPROM Programmer
A little utility target that writes personality modules — the tiny I2C EEPROMs that give each creature its name, serial number, and USB identity. I plug the board into my Mac, it shows up as a serial port, and a shell running on the board itself does the rest.
Dynamixel Servo Tester
An interactive shell for poking at Dynamixel XC330 servos over Protocol 2.0 — ping them, scan the bus, change IDs and baud rates, and move them around. This is what I reach for when I’m setting up a fresh servo before it goes into a creature.
USB-C PD Tester
A small validation target I use when bringing up new boards. It exercises the USB-C Power Delivery negotiation so I can confirm the hardware is happy before I trust it with a creature.
Building
It’s a CMake + Pico SDK project, so you’ll need PICO_SDK_PATH pointing at your copy of the SDK. From inside the firmware directory:
cmake -B build .
cmake --build build --target controller-rp2350-arm-s-hw3
Swap the --target for whichever tool you want to build. The platform defaults to rp2350-arm-s and the hardware version defaults to 3 — that’s my current custom board (CC_VER3). The resulting .uf2 files will also run on off-the-shelf RP2040/RP2350 dev boards; you just lose the extended functionality (sensors, per-motor power control) that only my custom board has. Set USE_SENSORS to 0 to build for a generic board.