Reviewd and fixed deadman architecture

This commit is contained in:
2026-09-10 23:53:27 +02:00
parent 31b3595ac0
commit f8d111ef5c
15 changed files with 304 additions and 305 deletions
+88 -74
View File
@@ -3,106 +3,120 @@
## Purpose
This module provides the hardware run-permission path for the engine outputs.
The steering-wheel dead-man switch must be held to assert permission. Two
electrically independent, normally-open switch contacts and two independent
harness signal paths are required. Releasing the switch, an open circuit,
one signal path shorted to the 5 V source, loss of a logic supply, or MCU reset
must place the engine outputs in their non-energising state independently of
firmware.
The steering wheel has two normally-open deadman switches wired in parallel.
Holding either switch closes the circuit; holding both also closes it. Their
outputs are tied together at the steering wheel and form **one shared deadman
signal entering the ECU**, not two independently monitored inputs.
This document defines the signal relationships and destinations only. Output
driver implementation is documented separately.
The existing active-high 5 V interface is retained: either switch connects the
protected 5 V source to `DEADMAN_IN`. Both switches must be released to remove
permission. The ECU conditions this one signal for hardware gating and MCU
observation. Output-driver implementation is documented separately.
## Logic domains
| Signal | Domain | Active state | Default/fault state |
| --- | --- | --- | --- |
| `DEADMAN_A_HELD` | Protected 5 V logic | High: deadman channel A observes its contact held | Low: released or fault |
| `DEADMAN_B_RELEASED` | Protected 5 V logic | High: deadman channel B does not observe its contact held | Low: contact held |
| `DEADMAN_OK` | Protected 5 V logic | High: channels have the valid held-state relationship | Low: released or fault |
| `MCU_RUN_PERMIT` | 3.3 V MCU logic | High: MCU permits engine operation | Low: no permission |
| `ENGINE_PERMIT` | 5 V logic | High: both hardware and MCU permit operation | Low: no permission |
| `MCU_INJECTOR_SIG` | 3.3 V MCU logic | High: requested injector on-time | Low: injector off |
| `SAFE_INJECTOR_SIG` | 5 V logic | High: permitted injector command | Low: injector off |
| `SAFE_IGNITION_INHIBIT` | 5 V logic | High: ignition output is inhibited | Low: ignition output is permitted |
| `DEADMAN_A_STATUS` | 3.3 V MCU input | High: channel A contact is observed held | Low: released or fault |
| `DEADMAN_B_STATUS` | 3.3 V MCU input | High: channel B contact is observed held | Low: released or fault |
| Signal | Domain | Meaning |
| --- | --- | --- |
| `DEADMAN_IN` | Harness-connected 5 V input | High when either parallel switch is held; ECU-side bias holds it low when both are released or the shared signal is open. |
| `DEADMAN_OK` | Conditioned 5 V logic | Active-high hardware observation of the single deadman input. It is not proof that a switch or harness fault is absent. |
| `DEADMAN_STATUS` | Protected 3.3 V MCU input | MCU observation of the same combined deadman state; high means asserted. |
| `MCU_RUN_PERMIT` | 3.3 V MCU logic | High permits engine operation; defaults low. |
| `ENGINE_PERMIT` | 5 V logic | High only when deadman and MCU permission are both asserted. |
| `MCU_INJECTOR_SIG` | 3.3 V MCU logic | Requested injector on-time; defaults low. |
| `SAFE_INJECTOR_SIG` | 5 V logic | Permitted injector command; low means off. |
| `SAFE_IGNITION_INHIBIT` | 5 V logic | High inhibits ignition; low permits it. The driver must default to inhibited when permission logic is unpowered. |
Each deadman contact has its own harness signal, connector pin, connector-side
protection, series/filter network, and default-low bias. The contacts may share
the protected 5 V source at the switch, but neither signal path may share a
pull-up, pull-down, connector pin, or post-contact conductor with the other.
Each contact closes to the protected 5 V source only while the driver holds the
switch. Thus an open signal path reads low; a short of only one signal path to
the source cannot create the valid two-channel state.
## Steering-wheel wiring and ECU input
Channel A is conditioned non-inverting to create `DEADMAN_A_HELD`. Channel B
is conditioned inverting to create `DEADMAN_B_RELEASED`. This complementary
encoding makes the sole valid held state `A = high`, `B = low`. Both raw,
conditioned contact observations also enter protected 3.3 V MCU inputs as
`DEADMAN_A_STATUS` and `DEADMAN_B_STATUS`; these are diagnostic observations,
not the safety-critical shutoff path.
The two switches share the protected 5 V source and the switched return signal.
The parallel connection is made before the ECU: only one `DEADMAN_IN` signal
conductor and one signal connector pin are required at the ECU, in addition to
the supply connection. No separate contact-status wires are provided.
## Signal tree
Use one dedicated connector-side protection, series/filter network, default-low
bias and non-inverting conditioning path. It produces the 5 V `DEADMAN_OK`
signal and a protected 3.3 V `DEADMAN_STATUS` observation for the MCU. Keep the
hardware gating independent of firmware; the MCU status input is observational.
Exact protection, filtering and connector assignments remain implementation
items. The generic digital-input module does not replace this dedicated path.
The permission gates operate from `+5V_MAIN` and accept 3.3 V MCU logic
levels. Their outputs are 5 V logic levels.
| Left switch held | Right switch held | Shared signal / `DEADMAN_OK` (healthy circuit) |
| --- | --- | --- |
| No | No | Low |
| Yes | No | High |
| No | Yes | High |
| Yes | Yes | High |
![Deadman inputs](../diagrams/deadman-inputs.svg)
## Hardware gating
![Deadman permit](../diagrams/deadman-permit.svg)
The permission gates operate from `+5V_MAIN`, accept 3.3 V MCU logic levels,
and produce 5 V logic outputs.
![Deadman outputs](../diagrams/deadman-outputs.svg)
![Parallel switches and single deadman input](../diagrams/deadman-inputs.svg)
The logic equations are:
![Single-input engine permission](../diagrams/deadman-permit.svg)
![Permitted injector command and ignition inhibit](../diagrams/deadman-outputs.svg)
The healthy-switch relationship is a physical parallel connection at the
steering wheel, not an OR gate or two channels inside the ECU:
```text
DEADMAN_OK = DEADMAN_A_HELD AND NOT(DEADMAN_B_RELEASED)
DEADMAN_IN asserted = LEFT_SWITCH_HELD OR RIGHT_SWITCH_HELD
DEADMAN_OK = conditioned active-high DEADMAN_IN
ENGINE_PERMIT = DEADMAN_OK AND MCU_RUN_PERMIT
SAFE_INJECTOR_SIG = ENGINE_PERMIT AND MCU_INJECTOR_SIG
SAFE_IGNITION_INHIBIT = NOT(ENGINE_PERMIT)
```
`LEFT_SWITCH_HELD` and `RIGHT_SWITCH_HELD` above describe physical switch
states only; they are not separately available ECU signals.
## Output destinations
| Logic output | Destination | Required behavior |
| --- | --- | --- |
| `ENGINE_PERMIT` | Hardware injection-command permission gate | Must prevent an injector command from reaching the injection output stage when low. |
| `SAFE_INJECTOR_SIG` | Dedicated injection output stage command input | The only injector on-command presented to the output stage. |
| `SAFE_IGNITION_INHIBIT` | Dedicated ignition output stage inhibit/enable input | Must inhibit the ignition output stage when high and permit it only when low. |
| `DEADMAN_A_STATUS`, `DEADMAN_B_STATUS` | STM32 digital inputs | Firmware observes both contacts, detects disagreement, clears schedules, and reports diagnostics. Neither input is the safety-critical shutoff path. |
| `ENGINE_PERMIT` | Injection command gate and ignition-permission inverter | Low removes permission from both engine-output paths. |
| `SAFE_INJECTOR_SIG` | Injector driver command input | The only injector on-command presented to the output stage. |
| `SAFE_IGNITION_INHIBIT` | Ignition driver inhibit input | High inhibits the ignition stage; low permits it. |
| `DEADMAN_STATUS` | One STM32 digital input | Firmware observes the combined deadman state and clears schedules when it deasserts. It cannot identify which switch is held. |
## Fail-safe behavior
## Release and fault behavior
- With the switch released, the valid relationship is
`DEADMAN_A_HELD = low` and `DEADMAN_B_RELEASED = high`; `DEADMAN_OK` is low.
- With the switch held, the only permissive relationship is
`DEADMAN_A_HELD = high` and `DEADMAN_B_RELEASED = low`; `DEADMAN_OK` is high.
- An open circuit, an open contact, or a short to the 5 V source on either one
signal path produces a non-permissive relationship. A short to ground on a
held path also removes permission.
- This architecture protects against one fault in one contact or signal path.
It does not claim to detect a common-mode fault that energises both input
paths, or simultaneous faults in both contacts/paths. Harness routing and
connector assignment shall minimise such common-mode faults; any remaining
risk requires explicit system-level acceptance.
- Releasing one switch while the other is held leaves permission asserted.
Releasing both switches deasserts `DEADMAN_OK` and removes `ENGINE_PERMIT`
through hardware, without waiting for firmware.
- An open shared signal conductor or loss of the switch supply deasserts the
input through the ECU-side default-low bias. A shared signal short to ground
also deasserts it; the protected source must tolerate the assigned fault.
- An open individual switch branch disables that switch only. The other
parallel switch can still assert the shared signal.
- A stuck-closed switch, a bridged contact or the shared signal shorted to the
asserted 5 V source can hold `DEADMAN_OK` high after both switches are
released. This single-input arrangement cannot distinguish those faults
from a legitimate held state. It provides no per-switch disagreement or
independent-channel fault detection.
- `MCU_RUN_PERMIT` and `MCU_INJECTOR_SIG` must default low during reset,
boot, brownout, or an unpowered MCU. External bias components shall provide
these states during power sequencing.
- If `ENGINE_PERMIT` becomes low during an injection command,
`SAFE_INJECTOR_SIG` becomes low and removes the command from the injection
output stage.
- If `ENGINE_PERMIT` becomes low during an ignition dwell,
`SAFE_IGNITION_INHIBIT` becomes high and commands the ignition output stage
into its non-sparking shutdown behavior.
- If the 5 V permission logic loses power, the injection command input must
be externally biased low and the ignition output stage's inhibit input must
default to its inhibited state.
boot, brownout or an unpowered MCU. External bias components establish these
states through power sequencing. The MCU can withdraw permission even when
the deadman signal is high.
- If `ENGINE_PERMIT` becomes low during injection, `SAFE_INJECTOR_SIG` becomes
low and removes the injector command.
- If `ENGINE_PERMIT` becomes low during ignition dwell,
`SAFE_IGNITION_INHIBIT` becomes high and requests the ignition driver's
documented non-sparking shutdown behavior.
- If the 5 V permission logic loses power, the injector command must be biased
low and the ignition driver must default to inhibited. Verify this behavior
in the completed input, gate and driver implementation.
## Firmware responsibilities
The hardware path is authoritative; firmware cannot override a released or
faulted deadman switch. Firmware shall sample both `DEADMAN_A_STATUS` and
`DEADMAN_B_STATUS`, clear pending injection and ignition schedules on a
released state or disagreement, report any disagreement, and keep
`MCU_RUN_PERMIT` low except while engine operation is intentionally enabled.
Firmware samples the single `DEADMAN_STATUS` input, clears pending injection
and ignition schedules when it deasserts, and keeps `MCU_RUN_PERMIT` low except
while engine operation is intentionally enabled. It has no individual switch
states to compare and must not claim to detect contact disagreement or a
stuck-high shared signal from this observation alone.
A firmware test mode may assert `MCU_RUN_PERMIT`, but cannot override a low
hardware deadman input. Bench operation requires a deliberate external test
arrangement that asserts the single `DEADMAN_IN` signal.
+2 -2
View File
@@ -7,9 +7,9 @@ NeoECU V1. It accepts externally driven 5 V, 12 V, and protected
battery-domain signals, plus dry-contact and open-collector sources when the
appropriate ECU bias option is fitted.
This is not the crank/cam trigger interface and is not either deadman
This is not the crank/cam trigger interface and is not the dedicated deadman
engine-permit input. Those functions retain their dedicated conditioning and,
for the deadman, its independent two-channel hardware safety path defined in
for the deadman, its single-input hardware permission path defined in
[DEAD_MAN.md](DEAD_MAN.md).
V1 provisionally allocates six generic digital-input channels. The allocation,
+1 -1
View File
@@ -43,7 +43,7 @@ temperature, and ignition noise.
SAFE_IGNITION_INHIBIT = NOT(ENGINE_PERMIT)
```
When `ENGINE_PERMIT` is removed by the two-channel deadman interlock or the
When `ENGINE_PERMIT` is removed by the single-input deadman interlock or the
MCU, `SAFE_IGNITION_INHIBIT` becomes high. If a dwell is active, this invokes
the VBG08H-E soft shutdown so coil current is removed without intentionally
generating a spark. The 1 kOhm resistors on `INP` and `EN` follow the
+2 -3
View File
@@ -29,7 +29,7 @@ low-impedance injector requires a different architecture.
## Command path
`INPUT` is active high. It receives only the hardware-permitted injector
command defined by the two-channel deadman interlock.
command defined by the single-input deadman interlock.
![Injector command](../diagrams/injector-command.svg)
@@ -51,8 +51,7 @@ pin.
When `ENGINE_PERMIT` is removed, `SAFE_INJECTOR_SIG` goes low and turns the
injector output off. This is the hardware shutoff path; firmware also clears
pending injection events when `DEADMAN_OK` becomes invalid or the two deadman
status inputs disagree.
pending injection events when the single `DEADMAN_STATUS` input deasserts.
## Status diagnostic