Skip to content

feat(seq): hardware-sequencer engine core (native-tested, not yet wired)#580

Open
hongquanli wants to merge 8 commits into
masterfrom
feat/firmware-v2
Open

feat(seq): hardware-sequencer engine core (native-tested, not yet wired)#580
hongquanli wants to merge 8 commits into
masterfrom
feat/firmware-v2

Conversation

@hongquanli

Copy link
Copy Markdown
Contributor

Summary

Phase A of the firmware v2 modernization program (design + plan in AI-docs, 2026-07-04-firmware-v2-{design,plan}.md — see design §5 for the timing semantics this implements).

Adds the hardware-sequenced acquisition engine as a pure C++11 module (firmware/controller/src/sequencer/) with no Arduino dependencies and no serial/hardware wiring yet — that lands in later phases (protocol v2 Phase B/C, hardware binding Phase D). The firmware's runtime behavior is unchanged by this PR; the new files compile into the teensy41 target but nothing calls them.

What the engine does (once wired)

One uploaded program = one multichannel z-stack executed autonomously: per (layer, channel) step it moves the stack axis (stepper or piezo DAC) and filter wheel, pre-arms the intensity DAC, waits for settle + filter-in-position + camera trigger-ready (input line or timing model), schedules µs-timestamped trigger/illumination edges (level or edge mode, keeping the v1 electrical contract: level pulse width = strobe_delay + exposure), and — the core time-saver — launches the next step's filter/z moves at exposure end, during camera readout. Rolling-shutter cameras can opt out via readout_overlap_safe=0. Cancel never truncates an exposure; faults abort with specific error codes.

Files

  • src/sequencer/seq_types.{h,cpp} — acquisition program structs (future SEQ_UPLOAD_PROGRAM wire format) + validation
  • src/sequencer/seq_hal.h — hardware interface (ExposurePlan µs edge schedule; Phase D binds TMC/DAC/GPIO)
  • src/sequencer/seq_engine.{h,cpp} — the timing state machine
  • test/test_seq_types/, test/test_seq_engine/ — 22 Unity tests incl. a scripted fake HAL + virtual clock

Testing

  • pio test -e native: 102/102 (16 engine-timing scenarios: readout overlap, WAIT gating, ready-line + timeout abort, rolling-shutter opt-out, cancel semantics, min trigger period, whole-run invariants: frames == Nz×Nch, exposures never overlap, no motion command inside any exposure window)
  • pio run -e teensy41: SUCCESS (target build unaffected)

🤖 Generated with Claude Code

hongquanli and others added 8 commits July 4, 2026 21:17
Phase A Task A1 of the firmware-v2 plan (AI-docs 2026-07-04-firmware-v2-plan.md).
Pure C++11, no Arduino deps; structs are the future SEQ_UPLOAD_PROGRAM wire format.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lock tests

Phase A Task A2: SeqHal + ExposurePlan (µs-timestamped edges owned by the HAL),
FakeHal scripted test harness, engine state machine passing single-frame and
piezo-settle scenarios.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase A Task A3. Engine already used the explicit settle_armed_ latch the plan's
refactor step targets; tests lock the behavior in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-channel z offsets

Phase A Task A4. Locks in the core time-saving behavior: PREP(k+1) launches at
exposure end (readout start), and the next exposure waits for readout AND moves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase A Task A5.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rlap opt-out

Phase A Task A6. readout_overlap_safe=0 defers PREP(k+1) until that camera's
readout completes (no motion during rolling-shutter readout); ready-line and
timeout paths locked by tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase A Task A7. Cancel never truncates an exposure and honors return_to_start;
min_trigger_period_us spacing enforced; whole-run invariants: frames == Nz*Nch,
exposures never overlap, no motion/DAC command inside any exposure window.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant