bench: head-accel crash-detector de-risk drill (item 6, first step)

accel_crash_probe.py arms the head LIS2HH12's on-chip interrupt
generator (IG_CFG1/IG_THS/IG_DUR1) and polls the latched IG_SRC1 for a
strike, reporting the axes and raw magnitude. It settles the bench fact
the crash detector rides on: coexist mode reaches the IG registers over
i2c-dev with I2C_SLAVE_FORCE while st_accel stays bound, so it proves
whether the detector can be forgectrl-only with the liveness path
untouched, or whether the accel must move under glowforge.ko. It touches
only the IG registers (0x30-0x35) plus the CTRL7 latch bit, never the
full scale, so st_accel's raw scaling is undisturbed; no emission, no
commanded motion by default.

Registered on the bench page (dry, board) and in the bench README.
BRINGUP item 6 now stages the drill as the committed first step, with
the readout path, per-state thresholds and the two-tier wiring owed
after it. Tooling only: no shipped component source changed, so no
acceptance-catalog consequence (the detector feature gets its case when
it is built); the bench registry test and coverage lint pass.
This commit is contained in:
ScottW514
2026-08-31 17:56:53 -04:00
parent 18104a0e51
commit 765521455d
4 changed files with 305 additions and 10 deletions
+13
View File
@@ -75,6 +75,19 @@ TOOLS = [
_arg("feed", "int", 120, "creep feed"), _arg("segment_mm", "float", 15.0, "jog segment"),
_arg("max_mm", "float", 200.0, "travel bound")],
"desc": "Creeps toward a rail in bounded jog segments, detects the contact jolt, jog-cancels and backs off."},
{"id": "accel-crash-probe", "title": "Head accel crash-detector probe", "script": "accel_crash_probe.py",
"safety": "dry", "where": "board", "ported": True,
"args": [_arg("seconds", "float", 20.0, "arm-and-watch window"),
_arg("mode", "choice", "coexist", "coexist keeps st_accel bound (forgectrl up); unbind frees it",
["coexist", "unbind"], flag="--mode"),
_arg("ths", "int", 40, "per-axis threshold register value 0..255", flag="--ths"),
_arg("dur", "int", 0, "IG_DUR1 duration counter (ODR samples)", flag="--dur"),
_arg("axes", "str", "xyz", "axes to arm for high events", flag="--axes"),
_arg("jog", "str", None, "optional one jog at t=2 s, e.g. $J=G91X5F1000 (+X only)", flag="--jog")],
"desc": "Arms the head LIS2HH12's on-chip interrupt generator (IG1) and polls IG_SRC1 for a latched strike. "
"coexist mode reaches the IG registers over i2c-dev with st_accel still bound (the forgectrl-only "
"path proof); provoke a trip by hand or with --jog. Touches only the IG registers, no emission, "
"no full-scale change. CSV to /tmp/accel_crash.csv."},
# -- board-side, takeover / scope ------------------------------------------
{"id": "pwm-sweep", "title": "LASER_PWM scope sweep", "script": "pwm_sweep.py",
"safety": "scope", "where": "board", "ported": True,