Tools for developing APEX payload devices and validating their compliance with the APEX protocol — the UART payload-interface spoken between a Neros airframe (the host) and its payload (the device).
Two firmware images, both targeting the NUCLEO-G071RB (STM32G071, Cortex-M0+) — every signal lands on the Arduino headers, so the rig needs no soldering:
| Package | Role | What it's for |
|---|---|---|
//host_emulator |
Emulates the host (drone / flight controller) | Point it at your device to check conformance. REPL + verbose protocol log on the ST-Link VCP; walks the airframe flight stages and fires host conditions exactly like a real FC. |
//reference_device |
A known-good activation-class device | Worked example of a compliant device (3 preconditions: self-test, PROPS_WITH_THROTTLE, PROPS_ON_FLYING; GPIO bindings; motor-current ADC). Also the second half of the two-board self-test rig. |
bazel build //host_emulator:host_emulator_elf # or :host_emulator (.hex), :host_emulator_bin
bazel build //reference_device:reference_device_elfOpen the ST-Link VCP at 115200 8N1 and type help. The one-command
conformance pass is run: it waits for discovery, then walks
STANDBY → PROPS_ON_GND → +throttle → PROPS_ON_FLYING, starts each precondition
the device binds to a host condition, and on READY enables + triggers it.
Each package README documents its pinout, REPL commands, and internals.
Wire two NUCLEO-G071RB boards (Arduino headers only):
| Signal | Host board | Device board | Note |
|---|---|---|---|
| APEX UART | D1 = PC4 (USART1_TX) / D0 = PC5 (RX) | D0 = PC5 (RX) / D1 = PC4 (TX) | crossover (D1→D0 both ways) |
| Motor-current analog | A2 = PA4 (DAC1_OUT1) | A2 = PA4 (ADC1_IN4) | straight |
| Connector Pin 3 | D3 = PB3 (out) | D3 = PB3 (in) | straight |
| Connector Pin 4 | D4 = PB5 (out) | D4 = PB5 (in) | straight |
| GND | GND | GND | common ground |
The REPL/debug consoles need no wiring (USART2 → ST-LINK VCP on each board). The user button B1 (PC13, the device's hardware trigger) is active-low on the Nucleo-64.
Bring the host up first (or power-cycle both together). A device that was
already CONNECTED to a previous host session cannot be re-adopted by a rebooted
host — the protocol currently has no explicit re-enumeration (tracked
internally; the device's 5 s silence watchdog is held off by the new host's
1 Hz HOST_STATE broadcast).
This repo builds with no Neros infrastructure. ST's HAL/CMSIS come
straight from ST's public GitHub (pinned in MODULE.bazel, shim BUILD
overlays in third_party/stm32/) and the target
platform is defined locally in platforms/; nothing of ST's is
vendored here.
The toolchain rules are Neros's public
bazel_armclang
(wrapping the open-source Arm Toolchain for Embedded), and the APEX protocol
library itself comes from Neros's public
APEX release (pinned in
MODULE.bazel; --override_repository=apex=/path/to/apex builds against a
local checkout instead). Flashing is via any SWD programmer (STM32CubeProgrammer,
probe-rs, OpenOCD) against the plain .hex/.bin/.elf artifacts.
host_emulator/ APEX host emulator firmware (App/ = logic, Core/ = Cube-style bring-up)
reference_device/ Reference activation-class device firmware
third_party/apex/ BUILD overlay for the @apex protocol library
third_party/stm32/ BUILD overlays for ST's hal-driver / cmsis-device-g0 / cmsis-core repos
toolchains/ stm32g071 arm-none-eabi toolchain config + linker script
platforms/ local target-platform + MCU constraint definitions