From fec48518c1e1ea1475a72a70eddbf2f4ab750e33 Mon Sep 17 00:00:00 2001 From: Aiden <68633820+awils27@users.noreply.github.com> Date: Tue, 26 May 2026 16:59:09 +1000 Subject: [PATCH] isolating lamp behaviour --- docs/pt2-shutter-display-trace.md | 55 +++- h8536/serial_scenario.py | 74 ++++-- scenarios/shutter-008f-evs-clear-control.json | 48 ++++ .../shutter-008f-evs-timeout-control.json | 36 +++ scenarios/shutter-0093-bit-isolation.json | 236 ++++++++++++++++++ scenarios/shutter-0093-gate-8000.json | 87 +++++++ scenarios/shutter-0093-gate-ffff.json | 87 +++++++ scenarios/shutter-adjacent-readback.json | 55 ++++ 8 files changed, 657 insertions(+), 21 deletions(-) create mode 100644 scenarios/shutter-008f-evs-clear-control.json create mode 100644 scenarios/shutter-008f-evs-timeout-control.json create mode 100644 scenarios/shutter-0093-bit-isolation.json create mode 100644 scenarios/shutter-0093-gate-8000.json create mode 100644 scenarios/shutter-0093-gate-ffff.json create mode 100644 scenarios/shutter-adjacent-readback.json diff --git a/docs/pt2-shutter-display-trace.md b/docs/pt2-shutter-display-trace.md index 24bdfeb..9ccc8df 100644 --- a/docs/pt2-shutter-display-trace.md +++ b/docs/pt2-shutter-display-trace.md @@ -11,7 +11,7 @@ The real panel responds to primary selector `0x008F`: | `00 01 0F 08 00 5C` | `E000[0x008F].11` | SHUTTER shows observed `EUS`, likely manual `EVS`; iris AUTO lamp on | | `00 01 0F 10 00 44` | `E000[0x008F].12` | SHUTTER shows literal `OFF`; iris AUTO lamp on | | `00 01 0F 18 00 4C` | bits 11 and 12 | likely `EVS` wins over `OFF`; iris AUTO lamp on | -| `00 01 0F 00 00 54` | clear candidate | not yet bench-confirmed | +| `00 01 0F 00 00 54` | live default/clear | in the short clear-control run, SHUTTER swapped to `OFF`, then back to `EVS` when bit 11 was restored | Manual correlation: @@ -19,7 +19,7 @@ Manual correlation: - The RCP-TX7 menu table lists `EVS/ECS` under OTHERS for DXC-D30/D30P. - A later CCU/RCP manual says the shutter display shows `EVS` when EVS is on and `OFF` when the shutter switch is off. -So `0x008F.11` is currently best labeled `shutter_evs_display_or_mode`, and `0x008F.12` is best labeled `shutter_off_display_or_mode`. +So `0x008F.11` is currently best labeled `shutter_evs_display_or_mode`. `0x008F.12` and `0x008F=0` both have `OFF` display evidence, so treat `OFF` as the live default/fallback shutter display unless a later bit-isolation run splits forced OFF from default OFF. ## Selector 0x008F ROM Path @@ -93,6 +93,14 @@ Candidate selectors: This cluster is a strong candidate for the numeric shutter speed / clear-scan frequency side of the display. It is not yet bench-confirmed. +ROM refinement: + +- `F6AE/F6AC` are sampled from the external panel bus in the IRQ3 `A8` branch (`H'3CCB`), from `F00C/F00A`. +- `F6AA/F6A8/F6A6/F6A4/F6A2` are sampled from the IRQ3 `A9` branch (`H'3C49`), from `F00C/F00A/F008/F006/F004`. +- Those IRQ3 branches set dirty bits in `F6F1`, then the `H'15E0` scanner fans changes into the selector reports above. +- Several lanes can OR bit 14 into the report selector when `F791` and `F404` feature bits are live. So emitted report traffic may carry a tagged variant of the base selector even though the table readback probes below use the base selector. +- This makes the adjacent selector family more likely to be live local-panel state than a simple CCU-write display latch. + ## Candidate Probe Frames Readback: @@ -120,3 +128,46 @@ Potential display probes after `CONNECT: OK`: ``` Use the value-lane selectors cautiously. They may represent shutter/clear-scan numeric values, but they are also part of the local control-report path, so bench probing should change one selector at a time and record LCD, shutter display, iris AUTO, and emitted report frames. + +Important methodology caveat: + +- `CONNECT:NOT ACT` globally clears volatile panel presentation. A blank LCD/segment result after a long wait is not evidence that a tested selector cleared the panel. +- For selector-display tests, record the visible state inside the short post-write window, before the session can fall back to `NOT ACT`. +- Use the timeout-control scenario below to measure the current bench's natural EVS-to-NOT-ACT cleanup time. Treat results after that point as timeout-contaminated. +- Re-seed `CONNECT: OK` immediately before gate writes when a prior readback sweep may have consumed enough time for the visible state to expire. + +## Adjacent Selector Bench Scenarios + +These JSON scenarios are set up for the current bench runner and default to `38400 8E1`: + +```text +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-adjacent-readback.json --parity E --log captures\shutter-adjacent-readback.txt --result-json captures\shutter-adjacent-readback-result.json +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-008f-evs-timeout-control.json --parity E --log captures\shutter-008f-evs-timeout-control.txt --result-json captures\shutter-008f-evs-timeout-control-result.json +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-008f-evs-clear-control.json --parity E --log captures\shutter-008f-evs-clear-control.txt --result-json captures\shutter-008f-evs-clear-control-result.json +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-gate-8000.json --parity E --log captures\shutter-0093-gate-8000.txt --result-json captures\shutter-0093-gate-8000-result.json +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-gate-ffff.json --parity E --log captures\shutter-0093-gate-ffff.txt --result-json captures\shutter-0093-gate-ffff-result.json +.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-bit-isolation.json --parity E --log captures\shutter-0093-bit-isolation.txt --result-json captures\shutter-0093-bit-isolation-result.json +``` + +Run order: + +1. `shutter-adjacent-readback.json`: read-only baseline for the adjacent shutter cluster after the selector-zero `CONNECT: OK` seed. +2. `shutter-008f-evs-timeout-control.json`: measures how long EVS survives before `CONNECT:NOT ACT` clears it with no explicit clear command. +3. `shutter-008f-evs-clear-control.json`: checks whether the EVS/OFF display selector can be cleared live inside the safe pre-timeout window. +4. `shutter-0093-gate-8000.json`: tests the ROM-observed `0x0093` high-bit gate without enabling every unknown bit. +5. `shutter-0093-gate-ffff.json`: broader gate test if the targeted high-bit run is uneventful. +6. `shutter-0093-bit-isolation.json`: isolates the `0x0093` bits after bench evidence showed this selector also controls white-balance and black/flare lamps. + +## Bench Observations 2026-05-26 + +Observed visible effects from the first adjacent-selector run set: + +| Scenario | Serial evidence | Observed panel result | Current interpretation | +| --- | --- | --- | --- | +| `shutter-adjacent-readback` | all read selectors returned value `0x0000` | no specific visible note | baseline cluster was clear | +| `shutter-0093-gate-8000` | `E000[0x0093]` read back as `0x8000` | white-balance PRESET lamp on, black/flare MANUAL lamp on | `0x0093.15` is a live panel-status/lamp bit, not just a shutter gate | +| `shutter-0093-gate-ffff` | `E000[0x0093]` read back as `0xFFFF` | white-balance PRESET lamp on, black/flare AUTO lamp on | another `0x0093` bit overrides/selects black/flare AUTO when all bits are set | +| `shutter-008f-evs-clear-control` | `0x008F` writes acknowledged as `0x0800`, `0x0000`, `0x0800` | SHUTTER swapped between EVS and OFF while iris AUTO lamp stayed on | `0x008F` is a packed shutter/display status word; clearing it does not simply mean "blank" | +| `shutter-008f-evs-timeout-control` | only `0x008F=0x0800` was sent after OK seed | EVS/iris AUTO, then `CONNECT:NOT ACT` | later blanking is timeout cleanup, not selector-clear evidence | + +This changes the local naming: the "adjacent shutter" group should be treated as a broader camera-status and panel-output word cluster. `0x008F` currently covers shutter EVS/OFF plus iris AUTO side effects; `0x0093` covers at least white-balance PRESET and black/flare manual/auto side effects, and still gates some ROM-observed shutter/clear-scan report lanes. diff --git a/h8536/serial_scenario.py b/h8536/serial_scenario.py index 25e146d..d1f3ebe 100644 --- a/h8536/serial_scenario.py +++ b/h8536/serial_scenario.py @@ -230,9 +230,13 @@ def _step_table_sweep(ctx: ScenarioContext, spec: dict[str, Any]) -> None: selectors = _selector_list(spec) gap = float(spec.get("gap", 0.080)) ack = _ack_config(spec.get("ack_on", {})) + ack_note = ( + "ack=disabled" + if not ack["enabled"] + else f"ack_targets={len(ack['targets'])} ack_frame={format_frame(ack['frame'])}" + ) ctx.logger.event( - f"TABLE_SWEEP selectors={len(selectors)} gap={gap:.3f}s " - f"ack_targets={len(ack['targets'])} ack_frame={format_frame(ack['frame'])}" + f"TABLE_SWEEP selectors={len(selectors)} gap={gap:.3f}s {ack_note}" ) for selector in selectors: if ctx.abort_requested: @@ -246,7 +250,10 @@ def _step_table_sweep(ctx: ScenarioContext, spec: dict[str, Any]) -> None: def _ack_config(raw: Any) -> dict[str, Any]: spec = raw if isinstance(raw, dict) else {} + enabled = bool(spec.get("enabled", True)) targets = _parse_frame_list(spec.get("frames", spec.get("frame", DEFAULT_ACK_TARGET))) + if not enabled: + targets = set() return { "targets": set(targets), "frame": _parse_optional_frame(spec.get("ack_frame"), DEFAULT_ACK_FRAME), @@ -254,7 +261,7 @@ def _ack_config(raw: Any) -> dict[str, Any]: "poll_interval": float(spec.get("poll_interval", 0.005)), "post_read": float(spec.get("post_ack_read", 0.250)), "once_per_selector": bool(spec.get("once_per_selector", True)), - "enabled": bool(spec.get("enabled", True)), + "enabled": enabled, "max_acks": _optional_int(spec.get("max_acks")), "max_target_hits": _optional_int(spec.get("max_target_hits")), "abort_on_limit": bool(spec.get("abort_on_limit", True)), @@ -452,23 +459,52 @@ def _print_dry_run(args: argparse.Namespace, scenario: dict[str, Any], log_path: for index, step in enumerate(_scenario_steps(scenario), start=1): action, spec = _normalize_step(step) print(f"step[{index}]={action}", file=stdout) - if action == "send": - frame = _parse_required_frame(spec.get("frame")) - print(f" frame={format_frame(frame)} checksum_ok={int(frame_checksum_ok(frame))}", file=stdout) - elif action == "table_sweep": - selectors = _selector_list(spec) - ack = _ack_config(spec.get("ack_on", {})) - if selectors: - first = selectors[0] - last = selectors[-1] - print(f" selectors={len(selectors)} first=0x{first:03X} last=0x{last:03X}", file=stdout) - else: - print(" selectors=0", file=stdout) - print(f" gap={float(spec.get('gap', 0.080)):.3f}", file=stdout) + _print_step_dry_run(action, spec, stdout) + + +def _print_step_dry_run(action: str, spec: dict[str, Any], stdout: TextIO, *, indent: str = " ") -> None: + if action == "send": + frame = _parse_required_frame(spec.get("frame")) + print(f"{indent}frame={format_frame(frame)} checksum_ok={int(frame_checksum_ok(frame))}", file=stdout) + if float(spec.get("listen", 0.0)) > 0: + print(f"{indent}listen={float(spec.get('listen', 0.0)):.3f}s", file=stdout) + elif action in {"drain", "listen", "wait"}: + print(f"{indent}seconds={float(spec.get('seconds', spec.get('value', 0.0))):.3f}", file=stdout) + elif action == "wait_ready": + print( + f"{indent}heartbeats={int(spec.get('heartbeats', 2))} " + f"timeout={float(spec.get('timeout', 10.0)):.3f}s " + f"require={int(bool(spec.get('require', False)))}", + file=stdout, + ) + elif action == "table_sweep": + selectors = _selector_list(spec) + ack = _ack_config(spec.get("ack_on", {})) + if selectors: + first = selectors[0] + last = selectors[-1] + print(f"{indent}selectors={len(selectors)} first=0x{first:03X} last=0x{last:03X}", file=stdout) + else: + print(f"{indent}selectors=0", file=stdout) + print(f"{indent}gap={float(spec.get('gap', 0.080)):.3f}", file=stdout) + if not ack["enabled"]: + print(f"{indent}ack=disabled", file=stdout) + else: for target in sorted(ack["targets"]): - print(f" ack_target={format_frame(target)}", file=stdout) - print(f" ack_frame={format_frame(ack['frame'])}", file=stdout) - print(f" max_acks={ack['max_acks']} max_target_hits={ack['max_target_hits']}", file=stdout) + print(f"{indent}ack_target={format_frame(target)}", file=stdout) + print(f"{indent}ack_frame={format_frame(ack['frame'])}", file=stdout) + print(f"{indent}max_acks={ack['max_acks']} max_target_hits={ack['max_target_hits']}", file=stdout) + elif action == "repeat": + count = max(0, int(spec.get("count", 1))) + steps = spec.get("steps", []) + step_count = len(steps) if isinstance(steps, list) else 0 + print(f"{indent}count={count} steps={step_count}", file=stdout) + if not isinstance(steps, list): + return + for child_index, child in enumerate(steps, start=1): + child_action, child_spec = _normalize_step(child) + print(f"{indent}child[{child_index}]={child_action}", file=stdout) + _print_step_dry_run(child_action, child_spec, stdout, indent=indent + " ") def _emit_summary(ctx: ScenarioContext, logger: BenchLogger) -> None: diff --git a/scenarios/shutter-008f-evs-clear-control.json b/scenarios/shutter-008f-evs-clear-control.json new file mode 100644 index 0000000..1832987 --- /dev/null +++ b/scenarios/shutter-008f-evs-clear-control.json @@ -0,0 +1,48 @@ +{ + "name": "shutter-008f-evs-clear-control", + "notes": [ + "Recover to CONNECT OK, force the likely EVS display via selector 0x008F, then clear selector 0x008F.", + "CONNECT NOT ACT globally clears the panel, so this scenario uses short observation windows to avoid mistaking timeout cleanup for selector clearing.", + "Record the panel within about one second of each write: EVS set, clear, and EVS set again." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.25 + }, + { + "action": "send", + "label": "e000_008f_likely_evs", + "frame": "00 01 0F 08 00 5C", + "listen": 0.85 + }, + { + "action": "send", + "label": "e000_008f_clear", + "frame": "00 01 0F 00 00 54", + "listen": 0.85 + }, + { + "action": "send", + "label": "e000_008f_likely_evs_again", + "frame": "00 01 0F 08 00 5C", + "listen": 0.85 + } + ] +} diff --git a/scenarios/shutter-008f-evs-timeout-control.json b/scenarios/shutter-008f-evs-timeout-control.json new file mode 100644 index 0000000..f72c9e4 --- /dev/null +++ b/scenarios/shutter-008f-evs-timeout-control.json @@ -0,0 +1,36 @@ +{ + "name": "shutter-008f-evs-timeout-control", + "notes": [ + "Recover to CONNECT OK, force likely EVS via selector 0x008F, then deliberately do not clear it.", + "This is the negative control for the adjacent-selector methodology: if the panel later blanks or falls to CONNECT NOT ACT, that is timeout cleanup, not proof that 0x008F clear worked.", + "Record the time from EVS visibility to blank/CONNECT NOT ACT." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.25 + }, + { + "action": "send", + "label": "e000_008f_likely_evs", + "frame": "00 01 0F 08 00 5C", + "listen": 4.0 + } + ] +} diff --git a/scenarios/shutter-0093-bit-isolation.json b/scenarios/shutter-0093-bit-isolation.json new file mode 100644 index 0000000..b73e9c5 --- /dev/null +++ b/scenarios/shutter-0093-bit-isolation.json @@ -0,0 +1,236 @@ +{ + "name": "shutter-0093-bit-isolation", + "notes": [ + "Recover to CONNECT OK, then isolate likely selector 0x0093 lamp/display bits with a clear and OK seed before each candidate.", + "Record white-balance PRESET, black/flare MANUAL, black/flare AUTO, shutter display, iris AUTO, and LCD state during each candidate window.", + "This follows the 0x0093=0x8000 and 0x0093=0xFFFF bench observations that affected lamps beyond the shutter cluster." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.25 + }, + { + "action": "repeat", + "count": 1, + "steps": [ + { + "action": "send", + "label": "e000_0093_clear_before_bit12", + "frame": "00 01 13 00 00 48", + "listen": 0.20 + }, + { + "action": "send", + "label": "selector_zero_ok_before_bit12", + "frame": "00 00 00 80 00 DA", + "listen": 0.10 + }, + { + "action": "send", + "label": "e000_0093_bit12_rom_gate", + "frame": "00 01 13 10 00 58", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x093" + ], + "gap": 0.20, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "e000_0093_clear_before_bit5", + "frame": "00 01 13 00 00 48", + "listen": 0.20 + }, + { + "action": "send", + "label": "selector_zero_ok_before_bit5", + "frame": "00 00 00 80 00 DA", + "listen": 0.10 + }, + { + "action": "send", + "label": "e000_0093_bit5_rom_gate", + "frame": "00 01 13 00 20 68", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x093" + ], + "gap": 0.20, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "e000_0093_clear_before_bits12_5", + "frame": "00 01 13 00 00 48", + "listen": 0.20 + }, + { + "action": "send", + "label": "selector_zero_ok_before_bits12_5", + "frame": "00 00 00 80 00 DA", + "listen": 0.10 + }, + { + "action": "send", + "label": "e000_0093_bits12_5", + "frame": "00 01 13 10 20 78", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x093" + ], + "gap": 0.20, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "e000_0093_clear_before_bit15", + "frame": "00 01 13 00 00 48", + "listen": 0.20 + }, + { + "action": "send", + "label": "selector_zero_ok_before_bit15", + "frame": "00 00 00 80 00 DA", + "listen": 0.10 + }, + { + "action": "send", + "label": "e000_0093_bit15_seen_wb_preset_blackflare_manual", + "frame": "00 01 13 80 00 C8", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x093" + ], + "gap": 0.20, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "e000_0093_clear_before_bits15_5", + "frame": "00 01 13 00 00 48", + "listen": 0.20 + }, + { + "action": "send", + "label": "selector_zero_ok_before_bits15_5", + "frame": "00 00 00 80 00 DA", + "listen": 0.10 + }, + { + "action": "send", + "label": "e000_0093_bits15_5", + "frame": "00 01 13 80 20 E8", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x093" + ], + "gap": 0.20, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "e000_0093_clear_before_bits15_12", + "frame": "00 01 13 00 00 48", + "listen": 0.20 + }, + { + "action": "send", + "label": "selector_zero_ok_before_bits15_12", + "frame": "00 00 00 80 00 DA", + "listen": 0.10 + }, + { + "action": "send", + "label": "e000_0093_bits15_12", + "frame": "00 01 13 90 00 D8", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x093" + ], + "gap": 0.20, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "e000_0093_clear_before_bits15_12_5", + "frame": "00 01 13 00 00 48", + "listen": 0.20 + }, + { + "action": "send", + "label": "selector_zero_ok_before_bits15_12_5", + "frame": "00 00 00 80 00 DA", + "listen": 0.10 + }, + { + "action": "send", + "label": "e000_0093_bits15_12_5", + "frame": "00 01 13 90 20 F8", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x093" + ], + "gap": 0.20, + "ack_on": { + "enabled": false + } + } + ] + }, + { + "action": "listen", + "seconds": 0.75 + } + ] +} diff --git a/scenarios/shutter-0093-gate-8000.json b/scenarios/shutter-0093-gate-8000.json new file mode 100644 index 0000000..9f03921 --- /dev/null +++ b/scenarios/shutter-0093-gate-8000.json @@ -0,0 +1,87 @@ +{ + "name": "shutter-0093-gate-8000", + "notes": [ + "Recover to CONNECT OK, read the shutter cluster, set primary selector 0x0093 to 0x8000, then read the cluster again.", + "ROM trace shows E000[0x0093] gates adjacent shutter/clear-scan value lanes, but the exact bit meaning is not bench-confirmed.", + "CONNECT NOT ACT can clear the panel, so a fresh selector-zero OK seed is sent immediately before the 0x0093 write.", + "Record visual changes during the short post-write window, then use the second sweep for table evidence." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.25 + }, + { + "action": "table_sweep", + "selectors": [ + "0x08F", + "0x093", + "0x0A3", + "0x0A4", + "0x0A5", + "0x0D8", + "0x080", + "0x0D9", + "0x0A6", + "0x0DA", + "0x081" + ], + "gap": 0.10, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed_before_gate", + "frame": "00 00 00 80 00 DA", + "listen": 0.15 + }, + { + "action": "send", + "label": "e000_0093_gate_high_bit", + "frame": "00 01 13 80 00 C8", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x08F", + "0x093", + "0x0A3", + "0x0A4", + "0x0A5", + "0x0D8", + "0x080", + "0x0D9", + "0x0A6", + "0x0DA", + "0x081" + ], + "gap": 0.12, + "ack_on": { + "enabled": false + } + }, + { + "action": "listen", + "seconds": 0.75 + } + ] +} diff --git a/scenarios/shutter-0093-gate-ffff.json b/scenarios/shutter-0093-gate-ffff.json new file mode 100644 index 0000000..2fc48ab --- /dev/null +++ b/scenarios/shutter-0093-gate-ffff.json @@ -0,0 +1,87 @@ +{ + "name": "shutter-0093-gate-ffff", + "notes": [ + "Recover to CONNECT OK, read the shutter cluster, set primary selector 0x0093 to 0xFFFF, then read the cluster again.", + "This enables both ROM-observed gate bits 12 and 5, plus unknown bits, so run after shutter-0093-gate-8000.", + "CONNECT NOT ACT can clear the panel, so a fresh selector-zero OK seed is sent immediately before the 0x0093 write.", + "Record visual changes during the short post-write window, then use the second sweep for table evidence." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.25 + }, + { + "action": "table_sweep", + "selectors": [ + "0x08F", + "0x093", + "0x0A3", + "0x0A4", + "0x0A5", + "0x0D8", + "0x080", + "0x0D9", + "0x0A6", + "0x0DA", + "0x081" + ], + "gap": 0.10, + "ack_on": { + "enabled": false + } + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed_before_gate", + "frame": "00 00 00 80 00 DA", + "listen": 0.15 + }, + { + "action": "send", + "label": "e000_0093_all_bits", + "frame": "00 01 13 FF FF 48", + "listen": 0.85 + }, + { + "action": "table_sweep", + "selectors": [ + "0x08F", + "0x093", + "0x0A3", + "0x0A4", + "0x0A5", + "0x0D8", + "0x080", + "0x0D9", + "0x0A6", + "0x0DA", + "0x081" + ], + "gap": 0.12, + "ack_on": { + "enabled": false + } + }, + { + "action": "listen", + "seconds": 0.75 + } + ] +} diff --git a/scenarios/shutter-adjacent-readback.json b/scenarios/shutter-adjacent-readback.json new file mode 100644 index 0000000..deab87e --- /dev/null +++ b/scenarios/shutter-adjacent-readback.json @@ -0,0 +1,55 @@ +{ + "name": "shutter-adjacent-readback", + "notes": [ + "Recover to CONNECT OK, then read the currently known shutter/clear-scan selector cluster.", + "This is read-only after the selector-zero CONNECT seed and should be the first adjacent-selector bench run.", + "CONNECT NOT ACT can clear the panel during/after the sweep, so treat visual state at the end as timeout-contaminated.", + "Use this primarily for table readback rows and non-heartbeat frames, not for proving display clearing." + ], + "steps": [ + { + "action": "power_cycle", + "off_seconds": 1.5 + }, + { + "action": "wait_ready", + "heartbeats": 2, + "timeout": 10.0, + "require": true + }, + { + "action": "drain", + "seconds": 0.25 + }, + { + "action": "send", + "label": "selector_zero_connect_ok_seed", + "frame": "00 00 00 80 00 DA", + "listen": 0.25 + }, + { + "action": "table_sweep", + "selectors": [ + "0x08F", + "0x093", + "0x0A3", + "0x0A4", + "0x0A5", + "0x0D8", + "0x080", + "0x0D9", + "0x0A6", + "0x0DA", + "0x081" + ], + "gap": 0.12, + "ack_on": { + "enabled": false + } + }, + { + "action": "listen", + "seconds": 0.75 + } + ] +}