Releases: angleto/phycommander
Release list
PhyCommander 2.1.2 — systemd notify fix for iso mode
Patch release: systemd readiness fix for iso-mode deployments. No protocol or wire-format changes; all 2.1.x clients and firmware interoperate.
Fixed
- physerver:
sd_notify(READY)and the watchdog kicker now fire in iso mode too. The systemd-integration block lived only in the bulk path ofmain(), so an iso-mode service running under theType=notifyunit (deploy/systemd/physerver.service) never reported readiness: systemd hitTimeoutStartSecand restart-looped the service every ~90 s even though the web server and iso transport were healthy. The block is nownotify_systemd_ready(), called from both transport paths.
Full changelog: CHANGELOG.md
PhyCommander 2.1.1 — scope smoothing & DAC fixes
Highlights
- Dashboard scope: smooth real-time waveform via WebSocket
adc_chunkstream with 150 ms playback buffer - Firmware DAC: WORD-mode buffered packing + HALF-mode manual DAC write fix
- Pin labels: dashboard rows for DAC/PWM/DOUT/fngen now show Due silkscreen pin
- Flash flow:
flash_firmware.shnow detects SAM-BA CDC after the 1200-baud trigger, not before
Other changes
README: clarified commercial use terms, replaced email with GitHub contactdocs/applications: added piezo Bode harvester, vision sorter, laser tracker concept docsweb: rustfmt nightly reflow ofwebsocket_connectiondoc comment (cosmetic)
Full changelog: https://github.com/$(gh repo view --json nameWithOwner -q .nameWithOwner)/compare/v2.1.0...v2.1.1
PhyCommander 2.1.0 — improvements and pin re-mapping
Bench-cycle release: hardware layout aligned with the assembled v2.0
unit (12 ADC + 8 PWM + 16 DOUT + 16 DIN + 2 DAC), JTAG-free firmware
update path, and a long list of dashboard / firmware fixes flushed
out by the new HTTP-driven loopback test suite.
protocol_version stays at 1; this is a feature release, not a
breaking-protocol release.
Added
- JTAG-free firmware update (
VREQ_FW_ENTER_BOOTLOADER 0x40).
The running firmware can now drop the SAM3X into ROM SAM-BA on
request: clearsGPNVM1via EEFCCGPB, then writes
RSTC_CR = KEY | PROCRST | PERRST | EXTRSTfor a full chip reset
including the USB peripheral. Exposed as
POST /api/firmware/enter-bootloaderon physerver. The legacy
1200-baud / ATmega16U2 trick remains as a fallback in
scripts/flash_firmware.sh(new--entry auto|fngen|1200baud
flag). End-to-end verified on the bench: api → SAM-BA → bossac →
RSTC_CR→ app, no J-Link required. See
docs/firmware/PROTOCOL.md§2.6 and
docs/firmware/FIRMWARE_UPLOAD.md. - HTTP-driven bench loopback test suite
(physerver/tests/bench_loopback.rs): DAC linearity, PWM duty
endpoints + monotonic sweep, GPIO walking-ones / walking-zeros
(auto-skip when no DOUT/DIN loopback wiring is present), ADC
idle-stability with stuck-0x800 regression detector. Gated by
PHYCMD_BENCH=1. 7/7 green on the v2.0 wiring. - Full-rate ADC capture endpoint + browser scope feed
(/api/adc/capture+ dashboard scope panel). - Reset button on D3 (PC28, 50 ms debounce →
RSTC_CR).
Changed — pin re-mapping & wire layout
- Wire protocol layout for v2.0 bench:
StatusMessage.adc[8]→
adc[12],reserved[30]→reserved[22]. CRC range bumped from
24 to 32 bytes; firmware and host both useoffset_of!/
CRC_OVER_STAT_BYTESto track the wire layout.Capabilities
now reportsnum_pwm = 8,num_adc = 12.protocol_version
stays at 1. - 8 PWM channels via mixed PWM peripheral + TC paths
(D9 / D8 / D7 / D6 / D10 / D11 / D5 / D2). PWM 4..7 use TC
modules; D11/D10 share TC2 channels by design. - Default outputs OFF at boot: physerver stops fngen on every
channel and zeros the streamingCommandat iso transport
startup, so the bench never comes up driving anything. - Dashboard PWM slider / fngen mutual exclusion removed —
last-action-wins now. Sliders no longer disable the function-row
Stop button; setting a duty firespwmSliderResetTo(ch, 0)on
the corresponding fngen lane. - Dashboard ADC scope panel + masonry layout, smoother poll loop
covering all 12 ADC channels, sliders sync from/api/command
at page load. enter_bootloader()host helper now treatsLIBUSB_ERROR_IO,
LIBUSB_ERROR_NO_DEVICE, andLIBUSB_ERROR_TIMEOUTall as
success — empirically the kernel returnsIO (-1)most often
when the firmware resets mid-status-stage, not the timeout we
initially mapped.
Fixed
- Firmware ADC: only enable channels we actually sample. The
earlier sparseCHER+ PDC race could leave late slots reading
a stale0x800, masquerading as silicon faults. Free-running
ADC with direct CDR reads now drives the canonical AD0..AD11
path. - Firmware TC-PWM
match_regclamp away from 0 so duty=1.0 stays
HIGH instead of glitching one cycle to LOW. - Bench-loopback default wiring map for pwm2/pwm3 (was inverted).
bench_adc_idle_stabilityno longer false-positives on floating
DAC/PWM pins: drives DAC mid-scale and PWM duty=0 before
measuring. Stuck-0x800 detection still fires unconditionally.- CI rustfmt +
-D warningstripwires (unused imports, dead code,
long lines).
Full changelog: v2.0.0...v2.1.0
PhyCommander 2.0.0 — copyleft era
PhyCommander 2.0.0 — copyleft era
First release under the new licensing stack:
- Rust server + crates + dashboard: AGPL-3.0-or-later
- Firmware + scripts + deploy plumbing: GPL-3.0-or-later
- Hardware designs (KiCad, panels, CAD): CERN-OHL-S v2
- Prose docs + photos: CC-BY-SA 4.0
- Name "PhyCommander" + logo: trademarked, see TRADEMARKS.md
Significant functional changes relative to the pre-2.0 history
(which was retired from origin along with this release):
- Fixed DAC reactive race (SHAPE_LUT/THRESHOLD/PID on DAC channels)
- Firmware watchdog enabled + host-side iso auto-reconnect
- CommandStaging::set_*_with_timeout bounded-wait API
- DMA-aligned (64 B) iso transfer buffers
- IPC shared-memory populated again + Send/Sync on IpcServer
- Per-channel reserved flag (PWM 4..7 on Arduino Due)
- Dashboard badge when host + firmware generators overlap
- scripts/rt_benchmark.py + docs/technical/XHCI_NOTES.md
Tested: cargo test --workspace passes 135/135, firmware make clean.