XM10 Extension Module SDK v2.2.2¶
Release date: 2026-05-20 | Target HW: Rev 1.1 / Rev 2.0 | KIT H10 FW: v2.3.0+
At a Glance¶
This is a patch release focused on cleaning up example code across the SDK. It fixes confusing patterns and sloppy buffer/sign handling that users could trip over while following along. In addition, Ex.36 (OnDevice Kinesthetic Learning) now carries a clear Rev 2.0-only notice everywhere it is documented, since it does not build on Rev 1.1.
- Code cleanup in 9 examples
- Consistent Rev 2.0-only notice for Ex.36 in 4 locations: source header / README / tutorials roadmap / troubleshooting
- Example builds verified — Rev 2.0: all pass; Rev 1.1: all pass except Ex.36
- Build environment, API, and KIT H10 firmware are identical to v2.2.1 — just download and replace
Existing user code continues to work as-is. No API or behavior changes. If you are already working through v2.2.1, there is no urgent reason to upgrade; if you are starting fresh, use this ZIP.
Download¶
| File | Target board |
|---|---|
| Rev1.1.zip | XM10 Rev 1.1 (early development board) |
| Rev2.0.zip | XM10 Rev 2.0 (latest board — includes Ethernet / PSRAM / RTC) |
Extracting the archive produces a single folder. That folder is both the STM32CubeIDE import root and the Claude Code entry directory.
Download the ZIP that matches your board revision. If the board label is unclear, a quick visual check works: an RJ45 Ethernet port means Rev 2.0; no RJ45 means Rev 1.1. For a detailed comparison, see docs/hardware/README.md — Board Revision Comparison.
Release Attachments¶
The bootloader, KIT H10 firmware, and content files are identical to v2.2.0 / v2.2.1. If you already installed them from a previous release, you do not need to download them again. Download them only if this is your first time starting from v2.2.2.
| File | Description |
|---|---|
AGR_Bootloader.bin |
XM10 bootloader (v1.1.0). Flash once to 0x08000000. |
SUIT_FW_ContentsFiles_20260518.zip/SUIT_CM_APP_X_X_X.bin |
KIT H10 CM firmware. Update directly via USB-C memory stick. |
SUIT_FW_ContentsFiles_20260518.zip/SUIT_SAM10_APP_X_X_X.bin |
KIT H10 MD (SAM10) firmware. |
SUIT_FW_ContentsFiles_20260518.zip/SUIT_ESP32_FW_X_X_X.bin |
KIT H10 ESP32 firmware. |
SUIT_FW_ContentsFiles_20260518.zip/SUIT_ContentsFiles.zip |
KIT H10 content files. Replace the entire SD card folder. |
Update procedure: docs/kit-h10-firmware/.
Tools¶
| Tool | Link |
|---|---|
| PhAI Studio (real-time data monitoring, data collection) | studio.onephai.com |
| STM32CubeProgrammer (initial bootloader installation) | st.com |
| STM32CubeIDE (firmware development IDE) | st.com |
Example Code Cleanup — 9 Changes¶
These are patterns that commonly trip up users when they copy example code. Even as a minor patch, they were worth collecting into a release.
Patterns you should not copy as-is¶
- Ex.31 (Friction_Comp_DOB) —
MAX_TORQUE_NMwas#defined twice in the same file (8.0ffollowed by5.0f), causing a compilerredefinedwarning. The effective clamp was5.0fas intended, but the comment above pointed to8 Nm, leaving users wondering why the torque never reached 8. Consolidated to a single5.0 Nmdefinition. - Ex.08 (CDC_Sensor_Print) · Ex.13 (Resistive_Mode) — Both used bare
sprintf(...)into a 64-byte stack buffer. If the format string grows, this silently overflows the stack. Replaced withsnprintf(buf, sizeof(buf), ...). Ex.08 is the go-to reference for CDC debug printing, so users are very likely to copy it verbatim — it was fixed first.
Works, but was confusing¶
- Ex.15 (Inverted_Pendulum) — Negative signs were dropped in the debug serial output for fixed-point values. For example,
theta = -0.35would print as0.35, making it impossible to tell from the log whether the pelvis was tilting left or right — a real obstacle when tuning PD gains. Fixed by separating the sign as a%sprefix so-0.35prints correctly. - Ex.33 (Kinesthetic_Teaching) — The playback index advance timer reused a "loop-count macro" as a "millisecond threshold." Both happened to equal
10, so it worked by coincidence, but changing either value would silently break the other. Introduced a dedicatedREPLAY_STEP_MS = 10Umacro to separate the two meanings. - Ex.36 (OnDevice_Kinesthetic_Learning) — When re-entering the
Activestate, the example could fall back toSTANDBYon the very first cycle. The value is now explicitly reset inActive_Entry. Also added header comments explaining what to watch for when the learning task and the control loop exchange values — so that the question "why does Ex.38 use a mutex but this one doesn't?" has a visible answer in the code.
Easy to misread¶
- Ex.22 (CPG_Oscillator) — The AFO frequency adaptation formula used
sin(φ)evaluated after the phase advance, which is one step ahead of the documented Ronsse 2011 formula (which usesφ[k]). Pre-computedsin(φ[k]) / cos(φ[k])so that both update equations reference the phase at the same point in time. - Ex.24 (Virtual_Constraint) — The 5th-order Bézier basis called
powf12 times per 1 kHz loop iteration. Replaced with a chained multiply sequence (s2 = s*s,s3 = s2*s, ...), eliminating allpowfcalls and reducing the cost to approximately 14 multiplications. - Ex.26 (ILC) — The function is called once per gait cycle, not every millisecond, but the header gave no indication of this. Users could easily assume that the USB send inside was running at 1 kHz. Added a header comment stating the call frequency (≈ 1 Hz) and guidance for moving the call to a different rate.
- Ex.16 (TinyAI Sensor_Fusion) — The NN raw logit was multiplied by
× 100.0fand printed with aConf:%label, making it look like a probability percentage even though no softmax was applied. Changed the label toScore:, removed the× 100scaling, and added a header comment noting that this is a raw logit value.
Ex.36 (OnDevice Kinesthetic Learning) is Rev 2.0 only — marked in 4 places¶
Ex.36 uses the on-chip Flash storage API (XM_UserNV_Read/Write/Erase) to persist learned NN weights across power cycles. This API is included only in the Rev 2.0 libXM_Lib.a, so building on Rev 1.1 fails at link time with undefined reference to XM_UserNV_*.
Previously, neither the code nor the documentation disclosed this, leaving Rev 1.1 users stuck at Ex.36 with no obvious explanation. This release adds a consistent notice in 4 places.
| Location | Content |
|---|---|
examples/36_OnDevice_Kinesthetic_Learning/ondevice_kinesthetic_learning.c header |
@warning Rev 2.0 only + root cause + alternative for Rev 1.1 users (examples up to Ex.35) |
examples/36_OnDevice_Kinesthetic_Learning/README.md top |
🛑 Rev 2.0-only notice banner |
docs/troubleshooting.md new section |
undefined reference to XM_UserNV_* — symptom / cause / resolution |
docs/tutorials/README.md example roadmap |
"Rev 2.0 only" note on the Ex.36 row |
If you have a Rev 1.1 board, Ex.35 (Multi-Layer Transparent Control) is the final example for your board. If you want to study just the NN training and LQR portion of Ex.36, you can temporarily remove the BTN1 long-press (Flash save) path and run entirely from RAM as a learning exercise.
Compatibility¶
| Item | Impact |
|---|---|
User code (Control_Setup / Control_Loop) |
No change — v2.2.1 code builds without modification |
| API signatures | No change — no header changes |
| KIT H10 firmware | v2.3.0 unchanged — no accompanying firmware update required |
| Bootloader | v1.1.0 unchanged |
| User data (USB memory logs, etc.) | No change — data format is compatible |
If you are already working through v2.2.1, there is no need to switch to v2.2.2 (the changes are limited to example cleanup and the Ex.36 notice). If you are starting fresh, or if you were stuck at Ex.36 on a Rev 1.1 board, download this ZIP.