Status: draft README for a demo that does not exist yet. This is the proposed
README.mdfor the Phase 4+ MCU replay demo, written ahead of implementation so the demo’s scope, claims, and vendor story are agreed before any board work starts. When the demo is built, this file moves tomcu/same54-replay-demo/README.md. Board selection follows eval-board-migration-matrix.md — a late, low-risk decision; this instantiates the matrix’s Microchip candidate.
This example demonstrates time-series decision inference on ride data: the
cue project’s portable C cue-policy kernel runs on a Microchip SAM E54
Curiosity Ultra v2 (ATSAME54P20A, Arm Cortex-M4F), streaming a
pre-recorded ride trace through cue_policy_step at the same 1 Hz cadence
the phone prototype uses. For each sample the kernel decides one of three
outcomes for an approaching road “squeeze zone” event: no action, emit a
single HEAD_UP attention cue, or suppress (cue budget already spent —
at most one cue per route event, NFR-001). The decision is indicated by
toggling onboard LEDs.
In this example the inference happens using the Cortex-M4F CPU itself and no hardware accelerator is used — nor the FPU, an RTOS, or any heap allocation: the kernel is integer-only C99 with a fixed-size state struct.
The decision to LED mapping is shown below:
NONEHEAD_UP — cue emitted with its computed lead timeIn the phone-side pipeline, map matching and squeeze-zone scoring run
against OpenStreetMap data and produce compact RouteEvents; only
normalized ride samples, those events, and the kernel itself migrate to
the MCU. There is no on-device learning: policy tuning is an offline loop
(design spec §13) in which exported ride traces replay deterministically
on a host through the same kernel (replay_cli), and config changes are
recorded in the trace’s policy_config. The build artifacts this example
consumes are: the kernel pair (cue_policy.c / cue_policy.h, compiled
unmodified from the repo root), and a generated header embedding one
checked-in replay trace — pre-parsed 20-byte binary sample records rather
than JSON, per the migration matrix’s on-target replay mode — with its
expected decisions. This makes the kernel easy to integrate with an
MPLAB X project.
The kernel is 100% vendor-neutral C99 — fixed-width types, no dynamic
allocation, no OS calls (NFR-004) — so migration changes only the ~4 glue
adapters: build integration, clock/timebase → t_ms, cue output GPIO,
and trace transport. See
eval-board-migration-matrix.md for the
board-neutral comparison against the other candidate targets (TI
LP-MSPM0G5187, Renesas EK-RA8M1) and the per-vendor glue table; the same
sources build for all three. Note the matrix caveat: verify
sizeof(CuePolicyState) under the actual vendor compiler — _Bool width
is a configurable option under IAR/ARMCC.
Terminate unused pins by configuring them as GPIO output-low or input with internal pull resistors; MPLAB Code Configurator / Harmony’s pin manager allows configuring unused pins directly. Because the decision loop runs at 1 Hz, the application can spend the inter-sample interval in STANDBY with an RTC wakeup; the kernel keeps all state in one caller-owned 420-byte struct, so nothing is lost across sleep.
cue_policy_step.replay/build/replay_cli --print — the decision sequences must be
identical. Because the kernel is integer-only and deterministic, any
divergence is a compiler/width bug, not noise (migration matrix,
Axis 3).#define CUE_TRACE in main.c to select a different
checked-in trace fixture.t_ms, speed_cmps,
heading, matched segment_id) and compact RouteEvents (20 B) —
trace schema v1, identical to the phone export and host replay formats
(FR-010).cue_policy_step — deterministic, integer-only, one
call per sample; measured footprint 1016 B Cortex-M0+ text + 420 B
state + 12 B/decision (arm-none-eabi-gcc -O3, from the Pico W
firmware build — see the migration matrix for the measurement).kernel/; replay harness and trace schema:
replay/