Fault | Detection | Containment |
|---|---|---|
RX overflow | Incoming item while FIFO cannot accept | Drop with sticky error or apply protocol backpressure |
TX underrun | Engine needs data while FIFO empty | Send idle/error symbol and stop safely |
Bus timeout | Accepted request exceeds response bound | Latch failure; one upstream error; retain/quarantine downstream ownership until drain or coordinated reset |
External protocol timeout | No expected edge/ack within programmed bound | Abort engine at safe pin boundary, report context; does not cancel bus ownership |
Illegal configuration | Start command with invalid fields | Reject start and set config error |
A bus watchdog does not cancel accepted downstream work. Keep A's tag/slot owned after issuing its one upstream timeout error; consume/discard a late A reply under that ownership and block reuse for B until drain completes or a coordinated isolation/reset establishes a fresh epoch. A still-stalled VALID offer cannot be withdrawn on timeout without that coordinated boundary. Keep separate ledgers: upstream accepted = completed responses + upstream owned; downstream accepted = drained replies + coordinated cancellations + downstream owned. An upstream timeout completion leaves downstream owned unchanged; a late discarded reply counts as drained, not another upstream response. Cancellation is counted only at the agreed reset boundary. Pin-level abort releases SPI resources but does not authorize bus-slot reuse.
Read the bars left to right against the numbered events below them.
Event 2: the watchdog answers the upstream master once. Upstream ownership ends here.
Events 2 to 4: the downstream slot is still owned. A late reply can still arrive and must not be mistaken for B's.
Event 5: only after the late reply drains does B get the slot.
Illustrative edge | Fault / software action | Observable state |
|---|---|---|
E0 | Legal START accepted | engine_busy=1, chip select active |
E1 | Protocol timeout at programmed bound | Latch context; timeout pending=1; irq=1 if enabled; begin pin-safe abort |
E2 | Abort boundary reached | chip select idle, engine_busy=0; pending remains 1 |
E3 | Software reads cause/context | Saved timeout diagnosis, no RC clear |
E4 | W1C timeout plus new timeout event | pending stays 1 (set wins) |
E5 | Service source then W1C, no new event | pending=0, irq drops if no other enabled cause |
E6 | Legal retry after bus ownership drain if needed | Exactly one new START; new transfer can complete |
Use this lesson as the harness destination: instantiate the planned adapter/CSR/engine/FIFO/DMA shell with a controllable SPI peer and clocked bus driver. Parameterize fault kind, trigger FSM state, response-stall length and recovery bound. Drive away from sampling edges; observe after NBA settlement. Scoreboard accepted TX/RX words, responses and reset cancellations separately; compare pin idle, saved context, sticky IRQ and W1C against the trace. Force a late A reply while attempting B and require zero B acceptance before drain. Bound every wait and fail fatally. Reuse the FIFO reference model and CSR adapter contract linked below.
The planned final review injects each fault while observing SPI pins, FIFOs, CSRs, DMA and IRQ. Recovery requires safe pins, resolved transaction ownership and successful acceptance of a later legal transfer.
Prove reset and abort from every FSM state.
Inject every error and confirm sticky status, interrupt, and W1C clear.
Run FIFO boundary and DMA backpressure tests.
Check pin-safe state during reset, clock gating, and power transitions.
Review address map, interrupts, clock/reset, DMA, and driver sequence with firmware.
One upstream completion, preserved diagnosis, safe pins and retained downstream ownership until drain or coordinated reset. Only then may a fresh transaction reuse the slot; local idle alone is insufficient.
The integration harness on this page is an exercise, not a supplied executable controller. The fault table and trace are a plan, and no results or pin-timing signoff are claimed.