Skip to content

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_NM was #defined twice in the same file (8.0f followed by 5.0f), causing a compiler redefined warning. The effective clamp was 5.0f as intended, but the comment above pointed to 8 Nm, leaving users wondering why the torque never reached 8. Consolidated to a single 5.0 Nm definition.
  • 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 with snprintf(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.35 would print as 0.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 %s prefix so -0.35 prints 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 dedicated REPLAY_STEP_MS = 10U macro to separate the two meanings.
  • Ex.36 (OnDevice_Kinesthetic_Learning) — When re-entering the Active state, the example could fall back to STANDBY on the very first cycle. The value is now explicitly reset in Active_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-computed sin(φ[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 powf 12 times per 1 kHz loop iteration. Replaced with a chained multiply sequence (s2 = s*s, s3 = s2*s, ...), eliminating all powf calls 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.0f and printed with a Conf:% label, making it look like a probability percentage even though no softmax was applied. Changed the label to Score:, removed the × 100 scaling, 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.