bench: the stale-origin drill goes, drills report their verdict, the pgood gate follows the pin

The faultpos live-fire drill armed and commanded a cut at an origin it
called stale to test a refusal the design decided not to gate: its only
outcome was an emission at an unknown position. Removed from the script
and the bench page.

live_fire_drills.py discarded every drill's return value, so the bench
page recorded a failed live-fire drill as OK. The exit status is the
drill's.

laser_pgood is the supply's power-good, high on every healthy machine;
fire_test.py and the K3 drill aborted on it and pgood_probe.py inverted
it. The latch-unlock drills now gate on the safety chain holding HV off
(charge-pump watchdog dead, pulse engine idle), as the kernel suite
does, and the probe reports the pin as the kernel publishes it.

motion.deadman: the controller resumed from its hang recovers on $X and
moves again without a restart (the stream's fault acknowledgment).
This commit is contained in:
ScottW514
2026-09-02 08:08:19 -04:00
parent 8cf2212e63
commit a2bc4233d5
6 changed files with 59 additions and 46 deletions
+14 -3
View File
@@ -54,6 +54,17 @@ def rd(attr):
return f.read().strip()
# The safety chain asserts HV_ENABLE only while a run feeds the charge-pump
# watchdog: a dead watchdog and an idle pulse engine mean HV off. That is
# the gate for a latch unlock; laser_pgood is the supply's power-good,
# high on every healthy machine, and says nothing about HV.
def hv_off_reason():
alive = rd('cnc/charge_pump_alive')
state = rd('cnc/state')
if alive != '0' or state != 'idle':
return 'charge_pump_alive=%s state=%s' % (alive, state)
return None
def rd_pos():
with open('/sys/glowforge/cnc/position', 'rb') as f:
raw = f.read(32)
@@ -209,9 +220,9 @@ def drill_k2():
def drill_k3():
pgood = rd('cnc/laser_pgood')
if pgood != '0':
print('ABORT: laser_pgood=%s (HV supply reports good) - refusing latch unlock' % pgood)
why = hv_off_reason()
if why is not None:
print('ABORT: the safety chain is not holding HV off (%s) - refusing latch unlock' % why)
return 1
stream = POWER0 + FIRE * (3 * TICK_HZ) + PAD * (TICK_HZ // 2)
print('K3: %d bytes = %.1f s of FIRE bits; ramp_rate 10000 Hz/s '