Skip to content

Track B: STM32G0 wired-UART door sensor (bench/dev firmware)#13

Merged
avrabe merged 6 commits into
mainfrom
phase2/track-b-stm32g0-door
May 20, 2026
Merged

Track B: STM32G0 wired-UART door sensor (bench/dev firmware)#13
avrabe merged 6 commits into
mainfrom
phase2/track-b-stm32g0-door

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 20, 2026

Summary

Phase 2 Track B. New crates/wohl-fw-door-bench — the first firmware crate in the repo. STM32G031 + reed switch, emitting 14-byte CCSDS sensor packets over UART.

Bench tool, NOT a field sensor

This is explicitly a bench/development firmware. Point-to-point UART does not scale to a real home (one cable run per sensor). Its job: exercise the hub's --ccsds ingest path against real CCSDS framing without needing radio or bus hardware. It is the test fixture every future transport will be validated against.

The field door firmware — STM32WL55 sub-GHz (wireless) + CAN-FD (wired bus), both over a transport-agnostic CCSDS layer — is Phase 3, tracked in #10. The crate name (-bench), the AADL comments, and the board README all say this plainly so no one mistakes it for the product.

What's in it

  • crates/wohl-fw-door-bench/no_std, ARMv6-M (thumbv6m-none-eabi)
    • ccsds.rs — vendored 14-byte CCSDS encoder, golden-byte test cross-checks the relay-ccsds spec
    • debounce.rs — reed-switch edge debouncer (50 ms default)
    • door.rs — debounce → CCSDS packet state machine
    • main.rs — STM32G031 binary (GPIO + SysTick + USART1); collapses to a host stub off-target so cargo test works
    • HAL: stm32g0xx-hal (sync) — chosen over embassy for reviewability
  • boards/stm32g0/README.md — pin map, framing, clocking
  • AADL: DoorWindowNode.WiredG0 + processor STM32G031 + memories. Architect's call — keep both deployment shapes modelled (.WiredG0 bench, .Battery wireless field).
  • Fixed memory.x: STM32G031K8 is 64 KB flash, not 32 KB (the header said K8 but the linker LENGTH was 32K — corrected so part number, linker map, and AADL all agree).

Verification

  • cargo build -p wohl-fw-door-bench --target thumbv6m-none-eabi --release — OK
  • cargo test -p wohl-fw-door-bench — 16/16 (incl. proptests + CCSDS golden-byte cross-check)
  • cargo +1.85.0 clippy --all-targets -- -D warnings + fmt — clean

Notes / follow-ups

🤖 Generated with Claude Code

avrabe and others added 6 commits May 19, 2026 20:28
First firmware in the repo, matching the architect's STM32G0 + door
contact choice in spar/wohl_system.aadl and spar/wohl_firmware.aadl
(DoorFirmware thread). The crate is no_std/no_alloc and splits cleanly
into a pure-logic library (CCSDS encoder, debouncer, state machine —
host-testable) and a thin HAL binding to USART1/SysTick/GPIO on the
STM32G031K8 reference board.

Hardware notes (pin map, clocking, UART framing, linker memory) live
in boards/stm32g0/README.md so reviewers can audit them independently
of the Rust code. The CCSDS encoder is intentionally vendored — byte-
identical to relay-ccsds::sensor_wire::encode_packet, with a host-side
golden-byte test that locks the layout to spec — to keep the firmware
free of transitive deps like wit-bindgen.

HAL: stm32g0xx-hal 0.2.0 (synchronous embedded-hal 0.2 traits) over
embassy-stm32. Picked for reviewability on the first firmware: every
peripheral interaction is a plain function call, no executor, no
codegen magic. Async can replace this once the OTA bootloader thread
needs to share radio time.

Verification (gates that pass locally; CI integration is a follow-up):
  cargo build  -p wohl-fw-door --target thumbv6m-none-eabi --release
  cargo test   -p wohl-fw-door                          # 16/16 pass
  cargo fmt    -p wohl-fw-door --check
  cargo clippy -p wohl-fw-door --all-targets -- -D warnings

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Documents the exact Cargo.toml edit (one line in the workspace
members list) the orchestrator needs to apply when integrating the
new firmware crate, plus the rationale for deferring CI changes
until cross-compilation for thumbv6m-none-eabi has been scoped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The firmware in crates/wohl-fw-door targets an STM32G031K8 with a wired
UART link to the hub. The AADL only modelled DoorWindowNode.Battery
(nRF52840 + Thread mesh), so model and code disagreed on the door node.

Architect's call: keep BOTH deployment shapes modelled rather than
replacing the battery variant.

- wohl_hardware.aadl: new `processor STM32G031` (Cortex-M0+, UART, no
  radio) + `memory SRAM_STM32G031` (8 KB) + `memory Flash_STM32G031`
  (64 KB).
- wohl_nodes.aadl: new `system implementation DoorWindowNode.WiredG0`
  wiring the reed switch + STM32G031 + UART bus + DoorFirmwareProcess.

Also fixes crates/wohl-fw-door/memory.x: the header said "STM32G031K8"
but FLASH LENGTH was 32K. The K8 part is 64 KB flash — corrected so
the linker map, the AADL Flash_STM32G031 size, and the part number all
agree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The STM32G0 + wired-UART firmware is a bench/development tool, not a
field door sensor — point-to-point UART does not scale to a real home.
Field door nodes will use STM32WL55 (sub-GHz) or a CAN-FD bus with a
transport-agnostic CCSDS layer (tracked separately).

- Renamed crate wohl-fw-door -> wohl-fw-door-bench (package, [lib],
  [[bin]], doc comments, boot banner, .cargo/config comment).
- Root Cargo.toml: added crates/wohl-fw-door-bench to workspace members
  (applies the WORKSPACE_INTEGRATION.md handoff; that file is removed).
- boards/stm32g0/README.md: reframed as the bench board; fixed the
  STM32G031K8 flash size (it is 64 KB, not 32 KB — the K8 suffix
  denotes 64 KB; the linker-map example block was also wrong).
- spar AADL: DoorWindowNode.WiredG0 comment now states it is a
  bench/development node; processor STM32G031 comment updated. The
  wireless field shape stays modelled as DoorWindowNode.Battery.

Verified from the worktree:
  cargo build -p wohl-fw-door-bench --target thumbv6m-none-eabi --release  OK
  cargo test  -p wohl-fw-door-bench                                        16/16
  cargo +1.85.0 clippy -p wohl-fw-door-bench --all-targets -- -D warnings  clean
  cargo +1.85.0 fmt    -p wohl-fw-door-bench -- --check                    clean

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lockfile follow-up to the crate rename — the package entry is now
wohl-fw-door-bench. No dependency-version changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reviewer flagged that the processor declared Clock_Period => 15625 ps
(64 MHz) while the firmware boots on HSI16 at 16 MHz (main.rs leaves
the PLL off). Model the actual boot clock: 62500 ps / 16 MHz, with a
comment noting 64 MHz is the unused PLL ceiling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avrabe avrabe merged commit db8faa3 into main May 20, 2026
5 checks passed
@avrabe avrabe deleted the phase2/track-b-stm32g0-door branch May 20, 2026 05:39
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