This repository documents the reverse-engineering path from a closed Unitree motor driver to a future custom firmware target.
All information in this repository was obtained by deduction, hardware inspection, public documentation, bus observation, and live debugging of owned hardware. The content is provided for research and documentation purposes. I am not responsible for how the information, scripts, or procedures in this repository are used.
The project started from a practical goal: understand the Go2 motor driver well enough to write our own motor-control code for it. The Go2 motor appears to be the same motor family as the Unitree GO-M8018-6, so the public GO-M8018-6 manuals and Unitree actuator SDK are used as references when they match the observed hardware.
The high-level actuator protocol is already documented by Unitree:
https://github.com/unitreerobotics/unitree_actuator_sdk
That public interface covers normal actuator commands such as kp, kd,
position, velocity, and torque. This repository focuses on the layer below
that interface: the driver board electronics, the protected firmware, the RS485
bootloader workflow, and the path to replacing the stock application with
custom code.
The hardware reverse engineering has identified the motor driver as a
CMSEMICON CMS32M57xx-based design, most likely using CMS32M5733Q048. SWD is
available on the board, but direct flash reads return zeroes, so readout
protection appears to be enabled.
The bootloader path is now understood well enough to explain the firmware
update flow. The motor can be put into bootloader mode over RS485, and Unitree's
unisp workflow uploads packetized firmware images. Those firmware images are
not plain Cortex-M0 code. Live SRAM inspection during the bootloader workflow
showed where to recover a local 128-bit key candidate. With that key and a
custom Python TEA script, available Unitree update images decrypt to clear
Cortex-M0 firmware. A public version of that helper is included at
tools/decrypt_firmware_tea.py; the key itself
is intentionally not published.
Because TEA is symmetric, the same locally recovered key also works in the
other direction: a custom clear Cortex-M0 image can be encrypted locally and
sent through the existing RS485 unisp bootloader path.
The first custom firmware bring-up now lives in go2_motor_custom_firmware. It builds a CMS32M57xx Cortex-M0 APROM image, packages it for the Unitree bootloader, drives early PWM/ADC/FOC experiments, and streams telemetry over RS485. It depends on the external CMSEMICON/Keil CMS32-Series device support pack, which is documented in the firmware folder. It is still research firmware, not a production-safe actuator controller.
Read the repository as a sequence:
- Hardware reverse engineering: starts from the physical board, SWD header, x-rays, pin tracing, and chip identification.
- Bootloader analysis: follows the RS485 firmware update workflow, bootloader entry paths, encrypted firmware format, and decryption result.
- Custom firmware plan: describes what the first firmware should prove and why custom firmware is useful.
The bootloader chapter has one supporting lab note: Firmware key extraction, which documents the SRAM/OpenOCD method used to locate the key candidate. The key itself is intentionally not published.
The motivation is not just to identify parts. The goal is to make the motor usable as an open, configurable actuator platform:
- Add command timeout behavior so the motor does not keep applying stale commands when communication is lost.
- Tune or replace the FOC loops.
- Adapt communication to custom protocols.
- Run autonomous motor behavior directly on the driver, where motion commands or control sequences are generated inside the motor for a specific project.
- Support operating modes that are awkward or unavailable in the stock firmware, including infinite-turn use.
- Keep the firmware fully customizable for experiments and application-specific motor behavior.
Erase/program operations may permanently remove the factory firmware. Any firmware work should assume that the original application cannot be recovered unless it has already been backed up or reconstructed.