firmware/src/evcore_safety.c and is the central gatekeeper between operator commands, measured inputs, and the output driver. This page describes its states, interlocks, fault types, and the rules for arming, enabling, and recovery.
States
The manager moves through five logical states. All transitions are explicit; nothing arms or enables automatically.
Arm does not enable anything. Reset does not arm or restore prior enables. Disarm cannot clear a fault. New faults accumulate until a successful reset. A zero output mask always turns outputs off, and the next tick still evaluates faults.
Interlocks
All nonzero enable requests require every interlock to be satisfied:- STOP is inactive
- Hardware safety permission is granted
- No HV conflict
- No overvoltage
- No overcurrent
- No reported watchdog fault
- Valid measurements and routing
- Valid output configuration and device profile
- Successful self-test
- Fresh inputs (within the configured age limit)
Fault flags
Faults are reported as bit flags and remain latched until an explicit healthy reset.EV_SafetyGetActiveFaults evaluates current conditions using the supplied time. EV_SafetyGetLatchedFaults reports retained history. Active faults can be zero while the state remains FAULT because the latch persists. EV_SafetyIsHealthy requires both current checks to pass and no latched faults.
E-stop and stale input behavior
An active STOP input latchesEV_FAULT_STOP and forces an immediate transition to FAULT with all outputs off. The fault remains latched after STOP is released, so the system stays in FAULT until an explicit reset is requested with all inputs healthy and fresh.
Stale inputs are detected when EV_SafetyTick is called with a timestamp strictly beyond the configured max_input_age_ms. The first check past the limit latches EV_FAULT_STALE, commands outputs off, and transitions to FAULT. You must call EV_SafetyTick periodically even when no new commands or inputs arrive, because shutdown on stale data happens at the tick boundary.
Overcurrent and reset rules
Overcurrent is treated like any other interlock violation: it latchesEV_FAULT_CURRENT, forces outputs off, and enters FAULT. While faulted, every tick reissues the off command, including after the physical condition clears. This means recovery is always explicit: the operator must request reset with all inputs healthy and fresh, and the Safety Manager verifies the snapshot before clearing the latch and returning to DISARMED with outputs off.
Reset without a fault returns false and does nothing. Reset during an active persistent fault (such as an un-released STOP) is denied because the input snapshot is not healthy.
Outputs default off
Initialization issues OFF through the supplied callback before modifying the manager state. A missing callback makes initialization fail and cannot command hardware. The callback receives zero on initialization, faults, reset, disarm, and off requests. A nonzero output mask is accepted only from ARMED; requests to change a valid mask while OUTPUT_ACTIVE are refused without changing the existing output. Disable and explicitly re-arm before requesting a new output mask. Unknown output bits are a configuration fault and shut down existing outputs.API summary
All public names use theEV_Safety prefix. The manager is single-owner and not thread-safe or ISR-safe.
Integration requirements
- Check successful initialization before using any other API.
- One task owns the manager and output driver. Queue commands from UI/USB and events from other tasks.
- Publish coherent snapshots with the original acquisition timestamp. Do not refresh a timestamp on cached data.
- Use the same monotonic uint32 millisecond clock for timestamps and API calls.
- Call
EV_SafetyTickperiodically even if no inputs or commands arrive. - The callback applies the full enable mask and must return promptly.
- These bits represent logical permissions, not physical pins or relay sequencing. Actual drivers must implement safe ordering, settling, break-before-make, output feedback, and fault handling before hardware use.
- The hardware safety chain must independently remove energy on STOP or latch events. Safe GPIO startup defaults and a hardware watchdog must cover boot, task starvation, crashes, and reset. This host module cannot do that.
Simulation and hardware status
The Safety Manager is fully implemented and host-testable. Thescripts/run-safety.ps1 suite validates startup denial, every interlock, simultaneous and accumulated faults, deliberate reset, no automatic restart, disarm, invalid output masks, freshness boundaries, future timestamps, and clock rollover. However, it does not verify welded relays, MCU timing, analog protections, output-driver failure, actual power removal, or board compliance. The callback has no physical feedback in v0.1; commanded_outputs is never proof of the electrical state. STM32H743 peripheral drivers and FreeRTOS integration are not implemented yet.