Compare commits
13 Commits
c0e3aaddee
...
0d099235c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d099235c5 | ||
|
|
57547fb6ed | ||
|
|
a187214e06 | ||
|
|
c007f2180c | ||
|
|
566b4ab108 | ||
|
|
8d98beb6aa | ||
|
|
fb282fea49 | ||
|
|
de992c6087 | ||
|
|
99946170cf | ||
|
|
fec48518c1 | ||
|
|
11b6a2dc3b | ||
|
|
3e1d30527f | ||
|
|
d9a9dade41 |
@@ -62,7 +62,7 @@ To start the current emulator harness:
|
|||||||
|
|
||||||
The real-device bench helper uses `pyserial`; install repo dependencies with `.\.venv\Scripts\python.exe -m pip install -r requirements.txt` if needed.
|
The real-device bench helper uses `pyserial`; install repo dependencies with `.\.venv\Scripts\python.exe -m pip install -r requirements.txt` if needed.
|
||||||
|
|
||||||
The current PT2/protocol reconstruction is documented in [docs/pt2-protocol.md](docs/pt2-protocol.md).
|
The current PT2/protocol reconstruction is documented in [docs/pt2-protocol.md](docs/pt2-protocol.md), with focused mini-notes for [COPY state](docs/pt2-copy-state-machine.md) and [menu state](docs/pt2-menu-state-machine.md).
|
||||||
|
|
||||||
## Real Bench Serial Format
|
## Real Bench Serial Format
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ Current serial observations:
|
|||||||
- Bench serial-format finding: real hardware talks `38400 8E1`. Earlier `8N1` captures primarily exercised SCI1 parity/error handling and retry echoes, not the normal command path. After switching bench scripts to even parity, the selector-zero CONNECT path can reach `CONNECT: OK`.
|
- Bench serial-format finding: real hardware talks `38400 8E1`. Earlier `8N1` captures primarily exercised SCI1 parity/error handling and retry echoes, not the normal command path. After switching bench scripts to even parity, the selector-zero CONNECT path can reach `CONNECT: OK`.
|
||||||
- Bench CONNECT recovery finding: `CONNECT:NOT ACT` is recoverable without a power cycle. This makes it a normal no-active-session/cleared-state display rather than a terminal latch; tests can now probe from the idle NOT ACT state directly, then separately check whether OK is held or needs periodic CCU-like refresh traffic.
|
- Bench CONNECT recovery finding: `CONNECT:NOT ACT` is recoverable without a power cycle. This makes it a normal no-active-session/cleared-state display rather than a terminal latch; tests can now probe from the idle NOT ACT state directly, then separately check whether OK is held or needs periodic CCU-like refresh traffic.
|
||||||
- Bench CONNECT cadence finding: the `40 -> 80 -> C0` sequence stayed at `CONNECT:NOT ACT` with 10 ms, 50 ms, and 150 ms gaps, but produced `CONNECT: OK` then returned to `CONNECT:NOT ACT` with 700 ms and 1.5 s gaps. At 700 ms, single `40`/`80`/`C0` frames did not work, but all tested two-frame pairs did. Repeated `80 -> 80` at about 700 ms also worked, so the values do not need to differ. The no-power-cycle NOT ACT recovery capture produced repeated `02 00 02 00 00 5A` OK-path responses before heartbeat traffic resumed.
|
- Bench CONNECT cadence finding: the `40 -> 80 -> C0` sequence stayed at `CONNECT:NOT ACT` with 10 ms, 50 ms, and 150 ms gaps, but produced `CONNECT: OK` then returned to `CONNECT:NOT ACT` with 700 ms and 1.5 s gaps. At 700 ms, single `40`/`80`/`C0` frames did not work, but all tested two-frame pairs did. Repeated `80 -> 80` at about 700 ms also worked, so the values do not need to differ. The no-power-cycle NOT ACT recovery capture produced repeated `02 00 02 00 00 5A` OK-path responses before heartbeat traffic resumed.
|
||||||
- Bench special-selector finding: in the CONNECT OK advance sweep, command-5 selector `0x006C` (`05 00 6C 00 00 33`) produced `CONNECT OK` then a blank LCD with the CAM POWER lamp still on, while selector `0x006D` (`05 00 6D 00 00 32`) produced `CONNECT OK` then `COPY IN PROGRESS` then `CONNECT NOT ACT`. A later fresh isolated `ack-006d` run in `captures/connect-ok-advance-special-20260526-153339.txt` reproduced the copy path after a relay power-cycle. Forced ROM decoding confirms `0x006C -> H'2FAF` and `0x006D -> H'3015`; the `0x006D` path sets display selector `F732=H'1903`, a long `F798` countdown, and the ROM contains the `COPY IN PROGRESS` LCD string. LCD dispatch now traces through `493E[0x19] -> H'930A`, with local table entry `H'9F6A` building `COPY IN PROGRESS` and entry `H'9FDA` building `COPY COMPLETED`; `0x006C` appears to be the completion/exit sibling only after `0x006D` has set the `F795.6/F795.7` copy flags. The RCP-TX7 manual identifies `COPY IN PROGRESS` as the multi-camera `COPY TO SLAVES` transfer state over the RS232C command-link system, with controls locked until `COPY COMPLETED`.
|
- Bench special-selector finding: in the CONNECT OK advance sweep, command-5 selector `0x006C` (`05 00 6C 00 00 33`) produced `CONNECT OK` then a blank LCD with the CAM POWER lamp still on, while selector `0x006D` (`05 00 6D 00 00 32`) produced `CONNECT OK` then `COPY IN PROGRESS` then `CONNECT NOT ACT`. A later fresh isolated `ack-006d` run in `captures/connect-ok-advance-special-20260526-153339.txt` reproduced the copy path after a relay power-cycle. Forced ROM decoding confirms `0x006C -> H'2FAF` and `0x006D -> H'3015`; the `0x006D` path sets display selector `F732=H'1903`, a long `F798` countdown, and the ROM contains the `COPY IN PROGRESS` LCD string. LCD dispatch now traces through `493E[0x19] -> H'930A`, with local table entry `H'9F6A` building `COPY IN PROGRESS` and entry `H'9FDA` building `COPY COMPLETED`; `0x006C` appears to be the completion/exit sibling only after `0x006D` has set the `F795.6/F795.7` copy flags. The RCP-side menu trace now also identifies page `0x01` table entry `H'6FF0` as `OTHERS / COPY TO SLAVES`; it is gated by `E400[0x0015]`, and its local copy-start branch also requires `F791.7` before setting `F76E.6`, `F795.7`, `F731.7`, `F798=H'C8`, `F711.7`, and `F726=H'64`. The RCP-TX7 manual identifies `COPY IN PROGRESS` as the multi-camera `COPY TO SLAVES` transfer state over the RS232C command-link system, with controls locked until `COPY COMPLETED`.
|
||||||
- ROM report-source finding: the active `02/01 ...` frames exposed during CONNECT OK attempts are autonomous `F870 -> BAF2 -> BA26` report-queue transmissions, not ordinary command-1 readbacks. The ROM sets `FAA2.3/FAA3.7` after sending them, so the CCU probably needs to answer in that continuation window with command `4`, `5`, or `6` to consume the report queue and keep the session alive.
|
- ROM report-source finding: the active `02/01 ...` frames exposed during CONNECT OK attempts are autonomous `F870 -> BAF2 -> BA26` report-queue transmissions, not ordinary command-1 readbacks. The ROM sets `FAA2.3/FAA3.7` after sending them, so the CCU probably needs to answer in that continuation window with command `4`, `5`, or `6` to consume the report queue and keep the session alive.
|
||||||
- Board/P9 finding: traced MCU pin 62 `P91` reaches X24164 pin 6 `SCL`, and MCU pin 68 `P97` reaches the shared X24164 pin 5 `SDA` node. The emulator now treats the ROM's `C121/C08B/C0DB/C10C/C142` P9 routines as an X24164-style two-wire EEPROM bus, with ROM logical addresses `0x000-0x7FF` on the `H'A0/H'A1` control-byte family and `0x800-0xFFF` on `H'E0/H'E1`.
|
- Board/P9 finding: traced MCU pin 62 `P91` reaches X24164 pin 6 `SCL`, and MCU pin 68 `P97` reaches the shared X24164 pin 5 `SDA` node. The emulator now treats the ROM's `C121/C08B/C0DB/C10C/C142` P9 routines as an X24164-style two-wire EEPROM bus, with ROM logical addresses `0x000-0x7FF` on the `H'A0/H'A1` control-byte family and `0x800-0xFFF` on `H'E0/H'E1`.
|
||||||
- EEPROM role finding: `loc_40BB` checks `P7DR.7` and the `F402 == H'6B6F` signature before defaulting EEPROM/shadow tables; `loc_4103` writes ROM default words through `BFE0`, `loc_41D2` reads sixteen 8-byte records into `F7B0-F82F`, and the command-4 path at `BD2B-BD5F` can persist serial table writes when `F76E.7` is set.
|
- EEPROM role finding: `loc_40BB` checks `P7DR.7` and the `F402 == H'6B6F` signature before defaulting EEPROM/shadow tables; `loc_4103` writes ROM default words through `BFE0`, `loc_41D2` reads sixteen 8-byte records into `F7B0-F82F`, and the command-4 path at `BD2B-BD5F` can persist serial table writes when `F76E.7` is set.
|
||||||
|
|||||||
4263
build/rom_others_menu.asm
Normal file
4263
build/rom_others_menu.asm
Normal file
File diff suppressed because it is too large
Load Diff
219643
build/rom_others_menu.json
Normal file
219643
build/rom_others_menu.json
Normal file
File diff suppressed because it is too large
Load Diff
4219
build/rom_others_menu_deep.asm
Normal file
4219
build/rom_others_menu_deep.asm
Normal file
File diff suppressed because it is too large
Load Diff
220100
build/rom_others_menu_deep.json
Normal file
220100
build/rom_others_menu_deep.json
Normal file
File diff suppressed because it is too large
Load Diff
4295
build/rom_others_menu_gate.asm
Normal file
4295
build/rom_others_menu_gate.asm
Normal file
File diff suppressed because it is too large
Load Diff
221410
build/rom_others_menu_gate.json
Normal file
221410
build/rom_others_menu_gate.json
Normal file
File diff suppressed because it is too large
Load Diff
4642
build/rom_others_page1.asm
Normal file
4642
build/rom_others_page1.asm
Normal file
File diff suppressed because it is too large
Load Diff
239015
build/rom_others_page1.json
Normal file
239015
build/rom_others_page1.json
Normal file
File diff suppressed because it is too large
Load Diff
125
docs/pt2-copy-state-machine.md
Normal file
125
docs/pt2-copy-state-machine.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
# PT2 Copy State Machine
|
||||||
|
|
||||||
|
This is a focused reference for the COPY behavior seen on the RCP LCD and traced in the ROM.
|
||||||
|
|
||||||
|
## Known Entry Points
|
||||||
|
|
||||||
|
### Serial Start / Progress
|
||||||
|
|
||||||
|
Frame:
|
||||||
|
|
||||||
|
```text
|
||||||
|
05 00 6D 00 00 32
|
||||||
|
```
|
||||||
|
|
||||||
|
ROM path:
|
||||||
|
|
||||||
|
- Command 5 accepts selector `0x006D` at `BD80-BDBF`.
|
||||||
|
- The selector is queued through `BE70`.
|
||||||
|
- Selector `0x006D` dispatches to `H'3015`.
|
||||||
|
|
||||||
|
Observed effects from forced decode:
|
||||||
|
|
||||||
|
- Sets `F731.7`.
|
||||||
|
- Sets `F795.6/F795.7`.
|
||||||
|
- Loads `F798=H'C8`.
|
||||||
|
- Sets display selector `F732=H'1903`.
|
||||||
|
- Sets `FB02=H'64`.
|
||||||
|
- Calls the display/report bridge at `48FA`.
|
||||||
|
- Sets `F76E.6`.
|
||||||
|
|
||||||
|
LCD dispatch:
|
||||||
|
|
||||||
|
- `F732` high byte `0x19` selects `493E[0x19] -> H'930A`.
|
||||||
|
- The local table at `H'931C` maps substate `0x03` to `H'9F6A`.
|
||||||
|
- `H'9F6A` builds `COPY` / `IN PROGRESS`.
|
||||||
|
|
||||||
|
### Serial Complete / Exit
|
||||||
|
|
||||||
|
Frame:
|
||||||
|
|
||||||
|
```text
|
||||||
|
05 00 6C 00 00 33
|
||||||
|
```
|
||||||
|
|
||||||
|
ROM path:
|
||||||
|
|
||||||
|
- Command 5 accepts selector `0x006C` at `BD80-BDBF`.
|
||||||
|
- The selector is queued through `BE70`.
|
||||||
|
- Selector `0x006C` dispatches to `H'2FAF`.
|
||||||
|
|
||||||
|
Observed effects from forced decode:
|
||||||
|
|
||||||
|
- Manipulates `F76E`, `F795`, `F797`, and `F799`.
|
||||||
|
- Can set display selector `F732=H'1904`.
|
||||||
|
- Sets `FB02=H'14`.
|
||||||
|
- Calls the display/report bridge at `48FA`.
|
||||||
|
|
||||||
|
LCD dispatch:
|
||||||
|
|
||||||
|
- `F732` high byte `0x19` selects `493E[0x19] -> H'930A`.
|
||||||
|
- The local table at `H'931C` maps substate `0x04` to `H'9FDA`.
|
||||||
|
- `H'9FDA` builds `COPY` / `COMPLETED`.
|
||||||
|
|
||||||
|
### RCP-Side Menu Start
|
||||||
|
|
||||||
|
ROM path:
|
||||||
|
|
||||||
|
- OTHERS menu page: `493E[0x01] -> H'631C`.
|
||||||
|
- Local page table: `H'632E`.
|
||||||
|
- `COPY TO SLAVES` entry handler: `H'6FF0`.
|
||||||
|
|
||||||
|
Required gates:
|
||||||
|
|
||||||
|
- The entry descriptor before `H'6FF0` requires `E400[0x0015] != 0`.
|
||||||
|
- The local COPY action branch requires `F770.2` and `F791.7`.
|
||||||
|
|
||||||
|
Local branch effects:
|
||||||
|
|
||||||
|
- Sets `F76E.6`.
|
||||||
|
- Sets `F795.7`.
|
||||||
|
- Sets `F731.7`.
|
||||||
|
- Loads `F798=H'C8`.
|
||||||
|
- Sets `F711.7`.
|
||||||
|
- Loads `F726=H'64`.
|
||||||
|
- Calls `loc_5500`.
|
||||||
|
- Displays `COPY TO SLAVES`.
|
||||||
|
|
||||||
|
If `F770.2` is set while `F791.7` is clear, the ROM diverts through `H'704C` to a `SET RCP` / `MASTER` display path instead of starting copy.
|
||||||
|
|
||||||
|
## Working State Model
|
||||||
|
|
||||||
|
| State | Likely indicators | Entry | Exit |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Idle / no copy | `F731.7` clear | Boot, timeout, or completion cleanup | `0x006D` or local COPY branch |
|
||||||
|
| Copy in progress | `F731.7`, `F795.6/F795.7`, `F798` live, `F732=H'1903` | `05 00 6D 00 00 32` or local COPY branch | `0x006C` in the live window, or timer expiry |
|
||||||
|
| Copy completed | `F732=H'1904` | `05 00 6C 00 00 33` while copy flags are live | Display/session timeout or next state update |
|
||||||
|
| Timeout / not active | `F731.7` cleared by timer path | `F797` or `F798` reaches zero | Normal CONNECT recovery traffic |
|
||||||
|
|
||||||
|
## Bench Results
|
||||||
|
|
||||||
|
Observed on the real panel:
|
||||||
|
|
||||||
|
```text
|
||||||
|
006C alone -> CONNECT OK -> blank
|
||||||
|
006D alone -> CONNECT OK -> COPY IN PROGRESS -> CONNECT NOT ACT
|
||||||
|
006D -> 006C after 250 ms -> COPY IN PROGRESS -> COPY COMPLETED
|
||||||
|
006D -> 006C after 1.0-1.5 s -> COPY IN PROGRESS -> COPY COMPLETED
|
||||||
|
006D -> 006C after 2.0-2.5 s -> COPY IN PROGRESS -> CONNECT NOT ACT
|
||||||
|
006D repeated, then 006C -> COPY IN PROGRESS held longer -> COPY COMPLETED
|
||||||
|
006D repeated without 006C -> COPY IN PROGRESS -> CONNECT NOT ACT
|
||||||
|
```
|
||||||
|
|
||||||
|
Current interpretation:
|
||||||
|
|
||||||
|
- `0x006D` is a copy-start/progress-window refresh selector.
|
||||||
|
- `0x006C` is a completion/exit selector that only behaves cleanly while the copy window is live.
|
||||||
|
- The copy window is transient and timer-controlled.
|
||||||
|
- The panel does not treat `0x006C` as a stateless "show completed" command.
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
- What sets `F791.7` during normal CCU/RCP operation?
|
||||||
|
- What exact official PT2 name belongs to selectors `0x006C`, `0x006D`, and `0x006E`?
|
||||||
|
- Whether `0x006E` is a copy cancel/error sibling or an unrelated special selector.
|
||||||
|
- Whether the CCU sends repeated progress refreshes during a real COPY TO SLAVES operation.
|
||||||
175
docs/pt2-knee-rom-trace.md
Normal file
175
docs/pt2-knee-rom-trace.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
# PT2 KNEE ROM Trace
|
||||||
|
|
||||||
|
Date: 2026-05-26
|
||||||
|
|
||||||
|
## Short Version
|
||||||
|
|
||||||
|
KNEE is not a simple held selector bit. The ROM has a dedicated local panel-input handler at `loc_1795`, reached when the panel input word at `F104` changes. That handler uses CCU-side selector state as gates, then either shows a short timed KNEE page or reports a KNEE value change on selector `0x00BC`.
|
||||||
|
|
||||||
|
This explains the bench pattern where KNEE AUTO can light or flash and then clear even while serial traffic remains healthy: one ROM path is a timed display/page override, not a maintained lamp value.
|
||||||
|
|
||||||
|
## Input Path
|
||||||
|
|
||||||
|
The local panel path is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
F104 changes -> F692 updated -> F6F0.1 set -> main dispatcher calls loc_1795
|
||||||
|
```
|
||||||
|
|
||||||
|
The important code anchors are:
|
||||||
|
|
||||||
|
```text
|
||||||
|
3B33 MOV:G.W @H'F104, R0
|
||||||
|
3B37 CMP:G.W @H'F692, R0
|
||||||
|
3B3D BSET.B #1, @H'F6F0
|
||||||
|
3B41 MOV:G.W R0, @H'F692
|
||||||
|
|
||||||
|
1630 BCLR.B #1, @H'F6F0
|
||||||
|
1636 JSR @loc_1795
|
||||||
|
```
|
||||||
|
|
||||||
|
So serial writes can prepare the state table, but the main KNEE control branch appears to require the panel-side input lane to change.
|
||||||
|
|
||||||
|
## Handler Decision Table
|
||||||
|
|
||||||
|
`loc_1795` reads two words from the primary selector table:
|
||||||
|
|
||||||
|
| ROM read | Selector meaning |
|
||||||
|
| --- | --- |
|
||||||
|
| `@H'E172` | `E000[0x00B9]` |
|
||||||
|
| `@H'E220` | `E000[0x0110]` |
|
||||||
|
|
||||||
|
The branch is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1795 if F731 > 2: skip
|
||||||
|
179C if E000[0x00B9].13 == 0: loc_2127()
|
||||||
|
17A7 else if E000[0x0110].15 == 1: loc_2127()
|
||||||
|
17B2 else:
|
||||||
|
delta = F692 - F6B2
|
||||||
|
report/update selector 0x00BC via loc_19A2
|
||||||
|
17C0 F6B2 = F692
|
||||||
|
```
|
||||||
|
|
||||||
|
Practical interpretation:
|
||||||
|
|
||||||
|
| Condition | ROM effect | Current meaning |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `0x00B9.13 = 0` | timed KNEE page via `loc_2127` | KNEE value reporting not enabled |
|
||||||
|
| `0x00B9.13 = 1`, `0x0110.15 = 1` | timed KNEE page via `loc_2127` | override/inhibit mode |
|
||||||
|
| `0x00B9.13 = 1`, `0x0110.15 = 0` | value delta reported as selector `0x00BC` | likely live KNEE control/report lane |
|
||||||
|
|
||||||
|
This downgrades the earlier bench label that treated `0x00B9.15` as the main KNEE gate. The ROM gate for the panel-input handler is `0x00B9.13`.
|
||||||
|
|
||||||
|
## Timed KNEE Page
|
||||||
|
|
||||||
|
`loc_2127` is the timed page path:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2127 set FB03.7
|
||||||
|
212D save old F732 into F734, if this is a fresh override
|
||||||
|
2135 F732 = 0x1C03
|
||||||
|
213B FB02 = 0x14
|
||||||
|
2140 call loc_48FA
|
||||||
|
```
|
||||||
|
|
||||||
|
The timer path later decrements `FB02`; when it expires, `loc_48EF` restores `F732` from `F734` and redraws. That is the likely cause of "lights, then falls away" observations.
|
||||||
|
|
||||||
|
The LCD dispatcher confirms `F732=0x1C03` is a KNEE page:
|
||||||
|
|
||||||
|
```text
|
||||||
|
493E[0x1C] -> 0x92CC
|
||||||
|
0x92DE[3] -> 0x95CE
|
||||||
|
0x960B prints "KNEE"
|
||||||
|
```
|
||||||
|
|
||||||
|
On that KNEE page, the second line is selected like this:
|
||||||
|
|
||||||
|
```text
|
||||||
|
if E000[0x0110].15: "DL"
|
||||||
|
else if E000[0x00B9].15: "PRESET"
|
||||||
|
else: "AUTO"
|
||||||
|
```
|
||||||
|
|
||||||
|
So `0x00B9.15` still matters, but it appears to choose the KNEE page label (`PRESET` versus `AUTO`) rather than enabling the report path. `0x0110.15` selects the `DL` label and also forces the timed page path from `loc_1795`.
|
||||||
|
|
||||||
|
## Bench Implications
|
||||||
|
|
||||||
|
Useful frames to test this model:
|
||||||
|
|
||||||
|
| Purpose | Frame |
|
||||||
|
| --- | --- |
|
||||||
|
| clear `0x00B9` | `00 01 39 00 00 62` |
|
||||||
|
| set `0x00B9.13` gate | `00 01 39 20 00 42` |
|
||||||
|
| set `0x00B9.15` label bit | `00 01 39 80 00 E2` |
|
||||||
|
| set `0x00B9.15` and `.13` | `00 01 39 A0 00 C2` |
|
||||||
|
| clear `0x0110` | `00 01 90 00 00 CB` |
|
||||||
|
| set `0x0110.15` override | `00 01 90 80 00 4B` |
|
||||||
|
| read `0x00BC` | `01 01 3C 00 00 66` |
|
||||||
|
|
||||||
|
The most direct live-control test is:
|
||||||
|
|
||||||
|
1. Reach `CONNECT: OK`.
|
||||||
|
2. Send `00 01 39 20 00 42` to set `0x00B9.13`.
|
||||||
|
3. Send `00 01 90 00 00 CB` to clear `0x0110.15`.
|
||||||
|
4. Move or exercise the physical KNEE-related control, if available.
|
||||||
|
5. Watch for TX/report traffic around selector `0x00BC`.
|
||||||
|
|
||||||
|
If no physical KNEE input is moved, the ROM may not enter `loc_1795`, because the trigger is the `F104` panel input change path rather than the serial write itself.
|
||||||
|
|
||||||
|
## Bench Observation: DTL / KNEE
|
||||||
|
|
||||||
|
The first `knee-rom-gate-and-value-probe` bench run produced a new LCD state with `DTL` on the left and `KNEE` on the right. That is an important confirmation: page `0x1C` contains both a KNEE entry and a DETAIL entry.
|
||||||
|
|
||||||
|
Relevant ROM text and page entries:
|
||||||
|
|
||||||
|
```text
|
||||||
|
0x92DE[3] -> 0x95CE KNEE page entry
|
||||||
|
0x92DE[7] -> 0x97C8 DETAIL page entry
|
||||||
|
0x960B prints "KNEE"
|
||||||
|
0x9805 prints "DETAIL"
|
||||||
|
```
|
||||||
|
|
||||||
|
The bench display probably shows the page-0x1C menu neighborhood, with DETAIL abbreviated as `DTL` and KNEE as the selected/right-side item. The log does not encode LCD pixels, but the serial timing around the observation is consistent with the KNEE probe:
|
||||||
|
|
||||||
|
```text
|
||||||
|
00 01 39 20 00 42 ; set 0x00B9.13 gate
|
||||||
|
00 01 39 A0 00 C2 ; set 0x00B9.15 + 0x00B9.13
|
||||||
|
00 01 90 80 00 4B ; set 0x0110.15 timed KNEE/DL override
|
||||||
|
```
|
||||||
|
|
||||||
|
Next isolation target: determine whether `DTL/KNEE` appears from `0x00B9.13`, `0x00B9.A0`, `0x0110.15`, or only the combined sequence.
|
||||||
|
|
||||||
|
## Panel Correlation
|
||||||
|
|
||||||
|
The physical panel has both DETAIL and KNEE buttons near the LCD. That matches the ROM page-`0x1C` neighborhood and makes the observed `DTL/KNEE` state likely to be a local menu/button context rather than a generic lamp status.
|
||||||
|
|
||||||
|
Practical implication: once the CCU-side selector gates are prepared, pressing the physical DETAIL/KNEE buttons may be the missing `F104` panel-input transition that calls `loc_1795`. If so, the useful evidence should be:
|
||||||
|
|
||||||
|
- visible LCD movement between DETAIL and KNEE entries,
|
||||||
|
- possible KNEE timed page redraws,
|
||||||
|
- TX/report traffic for selector `0x00BC` when KNEE input movement is accepted,
|
||||||
|
- or other page-`0x1C` selector reports from neighboring DETAIL/KNEE controls.
|
||||||
|
|
||||||
|
## Follow-Up: Lamp Without LCD Movement
|
||||||
|
|
||||||
|
The follow-up run after discovering the DETAIL/KNEE buttons did not reproduce an LCD page change. The observed result was:
|
||||||
|
|
||||||
|
- only the later KNEE cases/windows illuminated the KNEE AUTO lamp,
|
||||||
|
- none of those cases changed the LCD.
|
||||||
|
|
||||||
|
Current interpretation:
|
||||||
|
|
||||||
|
- `0x0110.15` is still the strongest KNEE AUTO lamp/status source.
|
||||||
|
- Serial table writes can light KNEE AUTO without necessarily entering the LCD DETAIL/KNEE page.
|
||||||
|
- The LCD path probably needs an additional local-display/menu condition, not just the CCU-side selector bits.
|
||||||
|
- The physical DETAIL/KNEE buttons may be scanned by the local panel path, but in this test they did not create a visible LCD transition or new serial report evidence.
|
||||||
|
|
||||||
|
This separates two related but distinct paths:
|
||||||
|
|
||||||
|
```text
|
||||||
|
KNEE AUTO lamp/status: mostly selector/table driven, strongest source 0x0110.15
|
||||||
|
DETAIL/KNEE LCD page: local page/menu context, likely page 0x1C plus panel/menu state
|
||||||
|
```
|
||||||
|
|
||||||
|
Next ROM target: trace the DETAIL and KNEE button scan bits through the page-`0x1C` menu dispatcher, not just the `loc_1795` KNEE value handler.
|
||||||
166
docs/pt2-lamp-selector-map.md
Normal file
166
docs/pt2-lamp-selector-map.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# PT2 Lamp And Panel Output Selector Map
|
||||||
|
|
||||||
|
This note tracks bench-visible lamp/readout effects from CCU-to-RCP selector writes.
|
||||||
|
|
||||||
|
## Current Model
|
||||||
|
|
||||||
|
The panel lamps and seven-segment displays are driven by selector-table state, not by one monolithic "connected" flag. Command 0 writes into the primary/current tables, and several selectors immediately affect visible panel outputs while `CONNECT: OK` is alive.
|
||||||
|
|
||||||
|
Known active-state foundation:
|
||||||
|
|
||||||
|
- `E000[0x0000] = 0x8080` wakes/holds `CONNECT: OK`.
|
||||||
|
- `E000[0x008F]` drives shutter `EVS`/`OFF` style display state and iris AUTO side effects.
|
||||||
|
- `E000[0x0093]` drives at least white-balance and black/flare lamp state.
|
||||||
|
|
||||||
|
## Bench Observations 2026-05-26
|
||||||
|
|
||||||
|
### `lamp-0093-lowbyte-sweep`
|
||||||
|
|
||||||
|
Result: no new visible behavior beyond the already-known `0x0093` family.
|
||||||
|
|
||||||
|
Interpretation:
|
||||||
|
|
||||||
|
- The earlier `0x0093` mapping still stands.
|
||||||
|
- Individual low-byte probes inside a streamed `0x90xx` context did not reveal a new lamp in this run.
|
||||||
|
- Keep `0x9020` as a useful manual/baseline context and `0x90FF` / `0xFFFF` as black/flare AUTO positive controls.
|
||||||
|
|
||||||
|
### `lamp-known-button-selector-probe`
|
||||||
|
|
||||||
|
Visible result:
|
||||||
|
|
||||||
|
- CAM button/lamp flashed on/off.
|
||||||
|
- CALL lamp flashed on/off.
|
||||||
|
- BARS and MASTER lamps flashed on/off.
|
||||||
|
- Camera tally changed red, then later green.
|
||||||
|
- Each visible output illuminated by itself, not as a broad all-lamps blast.
|
||||||
|
|
||||||
|
Serial result:
|
||||||
|
|
||||||
|
- The run stayed in normal `CONNECT: OK` response cadence.
|
||||||
|
- Each command-0 write produced an immediate `04 ...` readback-style frame and repeated `02 00 02 00 00 5A` active responses.
|
||||||
|
|
||||||
|
Candidate mapping:
|
||||||
|
|
||||||
|
| Selector/value pair | Current meaning |
|
||||||
|
| --- | --- |
|
||||||
|
| `0x0007 = 0x8000/0x0000` | CAM POWER lamp blink confirmed by isolated run |
|
||||||
|
| `0x0015 = 0x8000/0x0000` | CALL lamp blink confirmed; red tally also blinked in the same phase |
|
||||||
|
| `0x0012`, `0x0013`, `0x0016`, `0x0017`, `0x0018`, `0x001A` | ordered candidates for SLAVE, green tally, BARS, MASTER, and neighboring lamp states |
|
||||||
|
|
||||||
|
Follow-up `lamp-isolate-cam-call` result:
|
||||||
|
|
||||||
|
- First phase blinked CAM POWER.
|
||||||
|
- Second phase blinked CALL and red tally.
|
||||||
|
|
||||||
|
Follow-up `lamp-isolate-known-neighbors` result:
|
||||||
|
|
||||||
|
- Visible order was SLAVE, then green tally, then BARS.
|
||||||
|
- The pattern repeated, and at one point SLAVE and BARS were visible together.
|
||||||
|
- Treat the ordered mapping as likely but not final until a fresh-boot single-selector run separates latch/persistence effects from the selector under test.
|
||||||
|
|
||||||
|
Follow-up `lamp-isolate-neighbor-single-boot` result:
|
||||||
|
|
||||||
|
| Fresh-boot candidate | Visible result |
|
||||||
|
| --- | --- |
|
||||||
|
| `0x0012 = 0x8000/0x0000` | no visible change reported |
|
||||||
|
| `0x0013 = 0x8000/0x0000` | SLAVE lamp |
|
||||||
|
| `0x0016 = 0x8000/0x0000` | camera tally green |
|
||||||
|
| `0x0017 = 0x8000/0x0000` | BARS lamp |
|
||||||
|
| `0x0018 = 0x8000/0x0000` | no visible result reported yet |
|
||||||
|
| `0x001A = 0x8000/0x0000` | no visible result reported yet |
|
||||||
|
|
||||||
|
This confirms that the host/CCU can directly drive panel lamps through selector-table writes. It also validates using the ROM dispatch-neighbor list around `0x0007` and `0x0015` as a high-value lamp map.
|
||||||
|
|
||||||
|
### `lamp-broad-status-selector-sweep`
|
||||||
|
|
||||||
|
Visible result:
|
||||||
|
|
||||||
|
- KNEE AUTO lamp flashed a few times.
|
||||||
|
- No other new visible result was reported.
|
||||||
|
- Follow-up isolation saw KNEE AUTO toward the end of the run, then blinking.
|
||||||
|
|
||||||
|
Candidate selectors in that run:
|
||||||
|
|
||||||
|
`0x0003`, `0x0040`, `0x0081`, `0x0092`, `0x00A7`, `0x00B7`, `0x00B9`, `0x0110`
|
||||||
|
|
||||||
|
Interpretation:
|
||||||
|
|
||||||
|
- KNEE AUTO is likely in this broader status cluster.
|
||||||
|
- Because the visible change happened toward the end, strongest next candidates are `0x00A7`, `0x00B7`, `0x00B9`, and `0x0110`, with `0x0092` kept as a guard candidate.
|
||||||
|
- Exact selector/value still needs isolation because the broad sweep changed several selectors in sequence.
|
||||||
|
|
||||||
|
Follow-up `lamp-isolate-knee-tail-single-boot` result:
|
||||||
|
|
||||||
|
| Fresh-boot candidate | Visible result |
|
||||||
|
| --- | --- |
|
||||||
|
| `0x0092` | iris AUTO/OFF behavior |
|
||||||
|
| `0x00A7` | no visible result reported |
|
||||||
|
| `0x00B7` | no visible result reported |
|
||||||
|
| `0x00B9` | KNEE AUTO |
|
||||||
|
| `0x0110` | KNEE AUTO |
|
||||||
|
|
||||||
|
Interpretation:
|
||||||
|
|
||||||
|
- `0x00B9` and `0x0110` are real KNEE-related selectors, but a ROM trace now shows they are not a simple OR-held lamp pair.
|
||||||
|
- `loc_1795` is the local KNEE/panel-input handler. It is reached from `F104 -> F692 -> F6F0.1`, then reads `E000[0x00B9]` and `E000[0x0110]`.
|
||||||
|
- The ROM gate for the live KNEE value/report branch is `0x00B9.13`, not `0x00B9.15`.
|
||||||
|
- `0x0110.15` forces a timed KNEE page/display override. That fits the observed "lights, then clears" behavior.
|
||||||
|
- `0x00B9.15` still matters on the timed KNEE LCD page: it selects the `PRESET` label when `0x0110.15` is clear. With both clear, the same page labels KNEE as `AUTO`.
|
||||||
|
- When `0x00B9.13` is set and `0x0110.15` is clear, the ROM computes `F692 - F6B2` and reports/updates selector `0x00BC`. That is now the strongest candidate for the KNEE control value lane.
|
||||||
|
|
||||||
|
Follow-up `lamp-knee-or-precedence` result:
|
||||||
|
|
||||||
|
- Case 1 (`0x00B9.15` set, then `0x0110.15` set, then `0x00B9` cleared) kept KNEE AUTO on until near the end, when `0x0110` was cleared.
|
||||||
|
- Case 2 (`0x0110.15` set, then `0x00B9.15` set, then `0x0110` cleared) turned KNEE AUTO off well before the end, even though `0x00B9` had been set.
|
||||||
|
- This argues against a simple OR model. Current best interpretation: `0x0110.15` is the stronger live display/control source for KNEE AUTO; `0x00B9.15` is related, but may be a transient, secondary status source, or only meaningful with another gate active.
|
||||||
|
|
||||||
|
Follow-up `lamp-knee-sustain-compare` result:
|
||||||
|
|
||||||
|
- Repeated `0x00B9.15` refresh never lit KNEE AUTO.
|
||||||
|
- Repeated `0x0110.15` refresh lit KNEE AUTO, but it turned off again around the middle of the repeated-refresh window.
|
||||||
|
- This makes `0x00B9.15` look like a context-sensitive or stale interpretation rather than a maintained lamp source.
|
||||||
|
- `0x0110.15` remains the best KNEE AUTO source, but it is not sufficient by itself to hold the lamp. It likely needs a surrounding CCU status refresh, or another selector periodically clears/rebuilds the visible lamp bank.
|
||||||
|
|
||||||
|
Follow-up `lamp-knee-context-hold` result:
|
||||||
|
|
||||||
|
- Pairing `0x00B9.15` with the known `0x0093=0x9020` active refresh did not light KNEE AUTO.
|
||||||
|
- Pairing `0x0110.15` with `0x0093=0x9020` did light KNEE AUTO, but it still turned off around the middle of the run.
|
||||||
|
- The serial log stayed clean: repeated table readbacks and `02 00 02 00 00 5A` active responses continued, with no resync or NOT ACT-style serial collapse.
|
||||||
|
- Current best hypothesis: `0x0110.15` behaves more like an edge/pulse or consumed display request than a pure level-held lamp bit. Repeating the same high value may not retrigger it after the display task has consumed the state.
|
||||||
|
|
||||||
|
ROM follow-up:
|
||||||
|
|
||||||
|
- Detailed notes: `docs/pt2-knee-rom-trace.md`.
|
||||||
|
- The timed path sets `F732=0x1C03`, `FB02=0x14`, calls `loc_48FA`, and later restores the previous page through `loc_48EF`.
|
||||||
|
- `F732=0x1C03` dispatches to a KNEE LCD page. Its second line is `DL` when `0x0110.15` is set, `PRESET` when `0x0110.15` is clear and `0x00B9.15` is set, otherwise `AUTO`.
|
||||||
|
- `knee-rom-gate-and-value-probe` produced a new bench LCD state with `DTL` on the left and `KNEE` on the right. This matches the ROM page-0x1C neighborhood: KNEE entry at `0x95CE`, DETAIL entry at `0x97C8`.
|
||||||
|
- The panel physically has DETAIL and KNEE buttons near the LCD, so this is likely a local menu/button context. Pressing those buttons during the prepared gate window may supply the `F104` transition that the ROM needs before it calls `loc_1795`.
|
||||||
|
- Follow-up isolation lit KNEE AUTO in the later KNEE cases/windows but did not change the LCD. Treat the KNEE AUTO lamp and the DETAIL/KNEE LCD page as related but separate paths: `0x0110.15` remains the strongest lamp/status source, while LCD movement likely needs an additional local menu/display gate.
|
||||||
|
- Next bench retest should include `0x00B9.13` (`00 01 39 20 00 42`) and the `0x00BC` report/read lane, not only the older `0x00B9.15` / `0x0110.15` pair.
|
||||||
|
|
||||||
|
## Follow-Up Isolation Scenarios
|
||||||
|
|
||||||
|
Run these with the console visible and record the exact label shown when each lamp changes:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-isolate-cam-call.json --parity E --log captures\lamp-isolate-cam-call.txt --result-json captures\lamp-isolate-cam-call-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-isolate-known-neighbors.json --parity E --log captures\lamp-isolate-known-neighbors.txt --result-json captures\lamp-isolate-known-neighbors-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-isolate-knee-status-selectors.json --parity E --log captures\lamp-isolate-knee-status-selectors.txt --result-json captures\lamp-isolate-knee-status-selectors-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-isolate-neighbor-single-boot.json --parity E --log captures\lamp-isolate-neighbor-single-boot.txt --result-json captures\lamp-isolate-neighbor-single-boot-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-isolate-knee-tail-single-boot.json --parity E --log captures\lamp-isolate-knee-tail-single-boot.txt --result-json captures\lamp-isolate-knee-tail-single-boot-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-isolate-knee-bit-scan.json --parity E --log captures\lamp-isolate-knee-bit-scan.txt --result-json captures\lamp-isolate-knee-bit-scan-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-knee-or-precedence.json --parity E --log captures\lamp-knee-or-precedence.txt --result-json captures\lamp-knee-or-precedence-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-knee-sustain-compare.json --parity E --log captures\lamp-knee-sustain-compare.txt --result-json captures\lamp-knee-sustain-compare-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-knee-context-hold.json --parity E --log captures\lamp-knee-context-hold.txt --result-json captures\lamp-knee-context-hold-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\lamp-knee-edge-refresh.json --parity E --log captures\lamp-knee-edge-refresh.txt --result-json captures\lamp-knee-edge-refresh-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\knee-rom-gate-and-value-probe.json --parity E --log captures\knee-rom-gate-and-value-probe.txt --result-json captures\knee-rom-gate-and-value-probe-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\knee-rom-dtl-knee-isolation.json --parity E --log captures\knee-rom-dtl-knee-isolation.txt --result-json captures\knee-rom-dtl-knee-isolation-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\knee-detail-physical-button-watch.json --parity E --log captures\knee-detail-physical-button-watch.txt --result-json captures\knee-detail-physical-button-watch-result.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Method notes:
|
||||||
|
|
||||||
|
- Record visible changes immediately during each labeled hold. Later `CONNECT: NOT ACT` cleanup is not selector evidence.
|
||||||
|
- If a selector causes a latch or unexpected mode, stop and keep the log instead of continuing the whole sweep.
|
||||||
|
- Prefer exact notes like `selector_0018_high -> tally red`, because the logs already preserve send timestamps and readback frames.
|
||||||
|
- For the single-boot follow-ups, each candidate gets a fresh power cycle. That is deliberate: it tests whether a lamp is truly driven by that selector rather than retained from a previous write.
|
||||||
193
docs/pt2-menu-state-machine.md
Normal file
193
docs/pt2-menu-state-machine.md
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
# PT2 Menu State Machine
|
||||||
|
|
||||||
|
This is a focused reference for the ROM menu/display selection machinery that drives LCD pages and panel soft-key activity.
|
||||||
|
|
||||||
|
## Page Dispatch
|
||||||
|
|
||||||
|
Primary display selector:
|
||||||
|
|
||||||
|
- `F732` holds the current display/page selector.
|
||||||
|
- The high byte of `F732` selects a page wrapper through `493E`.
|
||||||
|
- The low byte is used as a page-local substate/selection, commonly through `F733`.
|
||||||
|
|
||||||
|
Important dispatcher:
|
||||||
|
|
||||||
|
- `48FA` bridges table/report state into LCD page dispatch.
|
||||||
|
- `493E[page]` points at a wrapper.
|
||||||
|
- Wrappers pass a local table pointer to `5FD2`.
|
||||||
|
|
||||||
|
For COPY status:
|
||||||
|
|
||||||
|
- `F732=H'1903` selects page `0x19`, substate `0x03`, `COPY IN PROGRESS`.
|
||||||
|
- `F732=H'1904` selects page `0x19`, substate `0x04`, `COPY COMPLETED`.
|
||||||
|
|
||||||
|
For OTHERS:
|
||||||
|
|
||||||
|
- `493E[0x01] -> H'631C`.
|
||||||
|
- Local table `H'632E` includes the OTHERS pages.
|
||||||
|
|
||||||
|
## Local Entry Selection
|
||||||
|
|
||||||
|
`loc_5FD2` is the local menu chooser.
|
||||||
|
|
||||||
|
Important RAM:
|
||||||
|
|
||||||
|
| RAM | Role |
|
||||||
|
| --- | --- |
|
||||||
|
| `F72C` | visible/selectable entry bitmask |
|
||||||
|
| `F72E` | count of visible/selectable entries |
|
||||||
|
| `F72F` | cached page high byte |
|
||||||
|
| `F733` | selected local entry index |
|
||||||
|
| `FB03.7` | no-entry/error/display suppression flag |
|
||||||
|
| `FB02` | display/session timer or message timer |
|
||||||
|
|
||||||
|
Observed algorithm shape:
|
||||||
|
|
||||||
|
1. If the page changed, clear `F72C/F72E` and cache the new page in `F72F`.
|
||||||
|
2. Walk the page-local handler table from the last entry down.
|
||||||
|
3. For each handler, read descriptor words immediately before the handler.
|
||||||
|
4. Compare the entry state descriptor against `F731`.
|
||||||
|
5. If the entry has required selector descriptors, test `E400 + selector*2`.
|
||||||
|
6. If requirements pass, set the entry bit in `F72C` and increment `F72E`.
|
||||||
|
7. Clamp or reset `F733` so it points at a visible entry.
|
||||||
|
8. If no entries are visible, set `FB03.7`, set `FB02=H'14`, clear `F72F`, and return `R4=H'FFFE`.
|
||||||
|
|
||||||
|
Practical meaning:
|
||||||
|
|
||||||
|
- A page can exist in ROM but be invisible/inactive until the CCU seeds the right `E400` feature/status selector.
|
||||||
|
- Command 6 writes the `E400-E7FF` secondary table, but only on the continuation side of the protocol.
|
||||||
|
|
||||||
|
## OTHERS / COPY TO SLAVES Gates
|
||||||
|
|
||||||
|
OTHERS page map:
|
||||||
|
|
||||||
|
| Local entry | Handler | Visible text | Required secondary selector |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1 | `H'6FF0` | `OTHERS` / `COPY TO SLAVES` | `E400[0x0015] != 0` |
|
||||||
|
| 2 | `H'70F6` | `OTHERS` / `CAM ID SET` | `E400[0x0043] != 0` |
|
||||||
|
| 3 | `H'7188` | `OTHERS` / `CAM ID IND` | `E400[0x0037] != 0` |
|
||||||
|
| 4 | `H'7258` | `OTHERS` / `CAM BARS` | `E400[0x0038] != 0` |
|
||||||
|
| 5-6 | `H'7328/H'73D8` | marker/percentage pages | `E400[0x0027] != 0` |
|
||||||
|
|
||||||
|
COPY TO SLAVES local action gate:
|
||||||
|
|
||||||
|
- Handler `H'6FF0` watches `F770.2`.
|
||||||
|
- If `F770.2` is clear, it only displays the OTHERS/COPY page.
|
||||||
|
- If `F770.2` is set and `F791.7` is set, it enters the local copy-start branch.
|
||||||
|
- If `F770.2` is set and `F791.7` is clear, it diverts to `SET RCP` / `MASTER`.
|
||||||
|
|
||||||
|
Root OTHERS soft-key bits:
|
||||||
|
|
||||||
|
- Root handler `H'6EE4` tests `E000[0x008F]` at `H'E11E`.
|
||||||
|
- Bit 11 sets `F711.6`.
|
||||||
|
- Bit 12 sets `F711.4`.
|
||||||
|
|
||||||
|
These bits are not only OTHERS soft-key enables. Bench tests show `E000[0x008F]` directly changes the shutter seven-segment display and iris AUTO lamp, so treat it as a packed camera/display status selector that also feeds the OTHERS root handler.
|
||||||
|
|
||||||
|
## Button / Lamp Masks
|
||||||
|
|
||||||
|
Important RAM:
|
||||||
|
|
||||||
|
| RAM | Role |
|
||||||
|
| --- | --- |
|
||||||
|
| `F711-F718` | panel output masks used by external panel chips |
|
||||||
|
| `F711.4-F711.7` | soft-key/menu-related bits seen around OTHERS/COPY |
|
||||||
|
| `F726` | countdown that temporarily preserves some soft-key bits |
|
||||||
|
| `F770` | local panel action/change code |
|
||||||
|
|
||||||
|
Relevant ROM behavior:
|
||||||
|
|
||||||
|
- Init clears `F711-F717` and sets `F718=H'FF`.
|
||||||
|
- `5A7A` clears `F711.4-F711.7` if `F726 == 0`.
|
||||||
|
- The FRT timer path decrements `F726`; when it expires, it clears `F713.6` and `F711.4-F711.7`.
|
||||||
|
- The OTHERS/COPY branch sets `F711.7` and `F726=H'64` to keep the local key/display state alive briefly.
|
||||||
|
|
||||||
|
## Bench Implications
|
||||||
|
|
||||||
|
To make the local COPY path available from the panel, the fake CCU probably needs to:
|
||||||
|
|
||||||
|
1. Recover to a live `CONNECT: OK` style session.
|
||||||
|
2. Seed root OTHERS soft-key bits:
|
||||||
|
|
||||||
|
```text
|
||||||
|
00 01 0F 18 00 4C ; E000[0x008F] bits 11+12
|
||||||
|
```
|
||||||
|
|
||||||
|
3. During a live continuation/report window, seed the COPY page visibility bit:
|
||||||
|
|
||||||
|
```text
|
||||||
|
06 00 15 00 01 48 ; E400[0x0015] nonzero
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Still satisfy the `F791.7` local copy-start gate.
|
||||||
|
|
||||||
|
The current hardest unknown is step 4: the ROM uses `F791.7` in several places, but the source that sets it has not yet been identified.
|
||||||
|
|
||||||
|
## Bench Observation: OTHERS Gate Probe
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```text
|
||||||
|
00 00 00 80 00 DA ; recover/seed CONNECT OK
|
||||||
|
00 01 0F 18 00 4C ; E000[0x008F] = 0x1800
|
||||||
|
06 00 15 00 01 48 ; E400[0x0015] = 0x0001, sent in active window
|
||||||
|
```
|
||||||
|
|
||||||
|
Observed on the real panel without touching the controls:
|
||||||
|
|
||||||
|
- LCD stayed at `CONNECT: OK`.
|
||||||
|
- SHUTTER seven-segment display changed to something like `EUS`; manuals make this likely `EVS` rendered on a seven-segment display.
|
||||||
|
- Iris AUTO lamp illuminated.
|
||||||
|
- OTHERS menu did not appear by itself.
|
||||||
|
|
||||||
|
Interpretation:
|
||||||
|
|
||||||
|
- The sequence reached real UI state, not only serial parser state.
|
||||||
|
- `E000[0x008F]=0x1800` is now a candidate shutter/mode-status value as well as an OTHERS soft-key source. Treat the earlier "soft-key bits" interpretation as incomplete.
|
||||||
|
- `E400[0x0015]=0x0001` may be the OTHERS/COPY visibility bit, but it may also affect an iris/auto feature path. Isolate before assigning a final meaning.
|
||||||
|
|
||||||
|
Recommended isolation probes:
|
||||||
|
|
||||||
|
```text
|
||||||
|
00 01 0F 08 00 5C ; E000[0x008F] bit 11 only
|
||||||
|
00 01 0F 10 00 44 ; E000[0x008F] bit 12 only
|
||||||
|
00 01 0F 18 00 4C ; E000[0x008F] bits 11+12
|
||||||
|
06 00 15 00 00 49 ; E400[0x0015] clear/zero
|
||||||
|
06 00 15 00 01 48 ; E400[0x0015] low nonzero
|
||||||
|
06 00 15 80 00 C9 ; E400[0x0015] high nonzero
|
||||||
|
```
|
||||||
|
|
||||||
|
Scenario files:
|
||||||
|
|
||||||
|
- `scenarios/others-isolate-008f-bit11.json`
|
||||||
|
- `scenarios/others-isolate-008f-bit12.json`
|
||||||
|
- `scenarios/others-isolate-008f-bits11-12.json`
|
||||||
|
- `scenarios/others-isolate-e400-0015-low.json`
|
||||||
|
- `scenarios/others-isolate-e400-0015-high.json`
|
||||||
|
- `scenarios/others-isolate-008f-then-e400-clear.json`
|
||||||
|
|
||||||
|
Isolation results:
|
||||||
|
|
||||||
|
| Scenario | Visible panel result | Serial result |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `others-isolate-008f-bit11` | Iris AUTO lamp on, SHUTTER seven-segment shows observed `EUS`, likely manual `EVS` | `04 01 0F 08 00 58`, then repeated `02 00 02 00 00 5A` |
|
||||||
|
| `others-isolate-008f-bit12` | Iris AUTO lamp on, SHUTTER seven-segment shows literal letters `OFF` | `04 01 0F 10 00 40`, then repeated `02 00 02 00 00 5A` |
|
||||||
|
| `others-isolate-008f-bits11-12` | Iris AUTO lamp on, SHUTTER seven-segment shows observed `EUS`, likely manual `EVS` | `04 01 0F 18 00 48`, then repeated `02 00 02 00 00 5A` |
|
||||||
|
| `others-isolate-e400-0015-low` | LCD stays `CONNECT: OK` only | repeated `01 00 02 00 00 59` after command 6 |
|
||||||
|
| `others-isolate-e400-0015-high` | LCD stays `CONNECT: OK` only | repeated `01 00 02 00 00 59` after command 6 |
|
||||||
|
| `others-isolate-008f-then-e400-clear` | Iris AUTO lamp on, SHUTTER seven-segment shows observed `EUS`, likely manual `EVS` | repeated `01 00 02 00 00 59` after command 6 |
|
||||||
|
|
||||||
|
Updated interpretation:
|
||||||
|
|
||||||
|
- `E000[0x008F]` directly affects visible shutter/iris UI state.
|
||||||
|
- Bit 11 selects the observed `EUS` shutter display, probably manual `EVS`; bit 12 selects literal shutter-display text `OFF`; when both are present, the likely `EVS` display appears to win.
|
||||||
|
- The iris AUTO lamp turns on for either bit 11 or bit 12, so it may be tied to the same status selector or to the resulting display mode.
|
||||||
|
- `E400[0x0015]` does not visibly change the panel by itself, even though command 6 does alter the report stream from `02 00 02 00 00 5A` to `01 00 02 00 00 59`.
|
||||||
|
- Keep `E400[0x0015]` as a probable OTHERS/COPY visibility/report-gate candidate, but do not assign the shutter/iris effect to it.
|
||||||
|
|
||||||
|
Manual correlation:
|
||||||
|
|
||||||
|
- The RCP-TX7 operating instructions list `OTHERS (1/6: SHUTTER)` with an `EVS` button, and say to use the shutter block `C.SCAN` or `SHUTTER ON/OFF` buttons when not using EVS.
|
||||||
|
- The same RCP-TX7 manual lists `EVS/ECS` under OTHERS for DXC-D30/D30P normal settings.
|
||||||
|
- A later CCU/RCP manual states that when EVS is on, `EVS` is displayed; when the shutter switch is off, `OFF` is displayed.
|
||||||
|
- Therefore `E000[0x008F].11` is best labeled `shutter_evs_display_or_mode`, and `E000[0x008F].12` is best labeled `shutter_off_display_or_mode` until ROM traces split display-only status from actual camera setting.
|
||||||
@@ -4,6 +4,12 @@ This document is the current working model for the serial protocol spoken by the
|
|||||||
|
|
||||||
A later RCP manual mentions a "PT2 compatibility mode" for controlling the same CCU family this panel was made for. We are using "PT2" here as a practical label for this six-byte SCI1 protocol model. It is not yet a claim that every field name matches Sony's official PT2 terminology.
|
A later RCP manual mentions a "PT2 compatibility mode" for controlling the same CCU family this panel was made for. We are using "PT2" here as a practical label for this six-byte SCI1 protocol model. It is not yet a claim that every field name matches Sony's official PT2 terminology.
|
||||||
|
|
||||||
|
Focused companion notes:
|
||||||
|
|
||||||
|
- [PT2 Copy State Machine](pt2-copy-state-machine.md)
|
||||||
|
- [PT2 Menu State Machine](pt2-menu-state-machine.md)
|
||||||
|
- [PT2 Shutter Display Trace](pt2-shutter-display-trace.md)
|
||||||
|
|
||||||
## Current High-Confidence Facts
|
## Current High-Confidence Facts
|
||||||
|
|
||||||
- The real bench link is `38400 8E1`, not `38400 8N1`.
|
- The real bench link is `38400 8E1`, not `38400 8N1`.
|
||||||
@@ -562,10 +568,27 @@ The `0x006D` copy path is now confirmed outside the earlier all-suite ordering c
|
|||||||
- Selector `0x006D` dispatches to `H'3015`. Forced decoding shows it sets `F731.7`, loads `F798=H'C8`, sets `F795.6/F795.7`, sets display selector `F732=H'1903`, sets `FB02=H'64`, calls `48FA`, then sets `F76E.6`.
|
- Selector `0x006D` dispatches to `H'3015`. Forced decoding shows it sets `F731.7`, loads `F798=H'C8`, sets `F795.6/F795.7`, sets display selector `F732=H'1903`, sets `FB02=H'64`, calls `48FA`, then sets `F76E.6`.
|
||||||
- The LCD dispatch for these states is now traced: `loc_48FA` reads the high byte at `F732`, so `F732=H'1903/H'1904` selects display page `0x19`, not direct page `0x03/0x04`. `493E[0x19] -> H'930A`; that page's local table at `H'931C` includes `H'9F6A` for `COPY` / `IN PROGRESS` and `H'9FDA` for `COPY` / `COMPLETED`. The low byte at `F733` is the substate selector: `0x03` is in-progress and `0x04` is completed.
|
- The LCD dispatch for these states is now traced: `loc_48FA` reads the high byte at `F732`, so `F732=H'1903/H'1904` selects display page `0x19`, not direct page `0x03/0x04`. `493E[0x19] -> H'930A`; that page's local table at `H'931C` includes `H'9F6A` for `COPY` / `IN PROGRESS` and `H'9FDA` for `COPY` / `COMPLETED`. The low byte at `F733` is the substate selector: `0x03` is in-progress and `0x04` is completed.
|
||||||
- This makes the likely copy handshake: `0x006D` starts copy and sets the `F795.6/F795.7` in-progress flags; `0x006C` is the completion/exit sibling only when those flags are live. Sending `0x006C` alone can therefore blank or clear state instead of displaying `COPY COMPLETED`.
|
- This makes the likely copy handshake: `0x006D` starts copy and sets the `F795.6/F795.7` in-progress flags; `0x006C` is the completion/exit sibling only when those flags are live. Sending `0x006C` alone can therefore blank or clear state instead of displaying `COPY COMPLETED`.
|
||||||
|
- Bench step-through confirmed the sequence model: `006C` alone produced `CONNECT OK -> blank`; `006D` alone produced `CONNECT OK -> COPY IN PROGRESS`; `006D` followed by `006C` after 250 ms produced a brief `COPY IN PROGRESS` then `COPY COMPLETED`; the same after 1.0 s and 1.5 s produced a longer `COPY IN PROGRESS` then `COPY COMPLETED`; after 2.0 s or 2.5 s it fell to `CONNECT:NOT ACT` instead of completing. Repeating `006D` before `006C` also completed successfully in the 2x and 3x repeat tests. A longer `006D` hold test kept `COPY IN PROGRESS` active for several seconds and then completed when `006C` arrived, while the same hold without `006C` timed out from `COPY IN PROGRESS` to `CONNECT:NOT ACT`. This points to `006D` as an in-progress/progress-window refresh selector and `006C` as the explicit completion/exit selector, not a stateless command pair.
|
||||||
- The FRT1 timer path decrements `F797` and `F798`; when either reaches zero, it clears `F731.7`. This matches the observed transient display modes falling back to `CONNECT:NOT ACT`.
|
- The FRT1 timer path decrements `F797` and `F798`; when either reaches zero, it clears `F731.7`. This matches the observed transient display modes falling back to `CONNECT:NOT ACT`.
|
||||||
- The string `COPY IN PROGRESS` is present in the ROM LCD resources, so the `006D` result is not a generic serial artifact.
|
- The string `COPY IN PROGRESS` is present in the ROM LCD resources, so the `006D` result is not a generic serial artifact.
|
||||||
- Manual interpretation: the RCP-TX7 operating manual describes `COPY IN PROGRESS` as the LCD state shown during the multi-camera `COPY TO SLAVES` data-transfer operation over the RS232C command-link system. During that state, all linked RCP units display the message and their buttons/knobs are locked until `COPY COMPLETED`. Therefore selector `0x006D` is best treated as entering a command-link copy/data-transfer state, not as a normal CCU connection ACK.
|
- Manual interpretation: the RCP-TX7 operating manual describes `COPY IN PROGRESS` as the LCD state shown during the multi-camera `COPY TO SLAVES` data-transfer operation over the RS232C command-link system. During that state, all linked RCP units display the message and their buttons/knobs are locked until `COPY COMPLETED`. Therefore selector `0x006D` is best treated as entering a command-link copy/data-transfer state, not as a normal CCU connection ACK.
|
||||||
|
|
||||||
|
RCP-side OTHERS/COPY menu trace:
|
||||||
|
|
||||||
|
- The OTHERS menu is page `0x01`: `493E[0x01] -> H'631C`, local table `H'632E`.
|
||||||
|
- Local table entry 1 points to `H'6FF0`, the page that renders `OTHERS` / `COPY TO SLAVES`.
|
||||||
|
- The entry descriptor immediately before `H'6FF0` requires selector `0x0015` in the secondary table: `E400[0x0015] != 0`. Because command 6 writes `E400`, this is probably a CCU-provided feature/visibility bit, and command 6 must be sent in a live continuation/report window to have an effect.
|
||||||
|
- When the page sees `F770.2` set, it only follows the local copy-start branch if `F791.7` is already set. That branch sets `F76E.6`, `F795.7`, `F731.7`, `F798=H'C8`, `F711.7`, `F726=H'64`, calls `loc_5500`, then displays `COPY TO SLAVES`. This is the RCP-side equivalent of the serial `0x006D` copy-start effect.
|
||||||
|
- If `F770.2` is set while `F791.7` is clear, the ROM diverts through `H'704C` to a `SET RCP` / `MASTER` display path instead of starting copy. That makes `F791.7` a second, likely master/link/session gate for the physical COPY operation.
|
||||||
|
- The OTHERS root handler at `H'6EE4` also tests primary selector `E000[0x008F]` (`H'E11E`) bits 11 and 12, and uses them to set `F711.6` and `F711.4`. Bench isolation shows this selector is broader than an OTHERS gate: bit 11 makes the SHUTTER seven-segment display show observed `EUS`, probably the manual's `EVS` display, and bit 12 makes it show the literal letters `OFF`; either bit also illuminates the iris AUTO lamp.
|
||||||
|
- Candidate gate probes, not final protocol truth:
|
||||||
|
|
||||||
|
```text
|
||||||
|
00 01 0F 18 00 4C ; command 0, set E000[0x008F] bits 11+12
|
||||||
|
06 00 15 00 01 48 ; command 6, set E400[0x0015] nonzero; requires live continuation
|
||||||
|
06 00 15 80 00 C9 ; command 6, alternate nonzero visibility value; requires live continuation
|
||||||
|
```
|
||||||
|
|
||||||
Read table state:
|
Read table state:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -588,6 +611,87 @@ This fits the real panel behavior:
|
|||||||
- Correct fake-CCU traffic can wake it to `CONNECT: OK`.
|
- Correct fake-CCU traffic can wake it to `CONNECT: OK`.
|
||||||
- Without richer CCU state, readouts illuminate but show placeholders like `----`.
|
- Without richer CCU state, readouts illuminate but show placeholders like `----`.
|
||||||
|
|
||||||
|
## Active-State Local-Control Watch
|
||||||
|
|
||||||
|
Bench evidence now suggests `CONNECT: OK` is maintained by an ongoing CCU refresh stream, not by one magic wake frame. This creates a useful local-control test: keep the RCP in the active state and press/turn physical controls while logging device TX.
|
||||||
|
|
||||||
|
Two JSON scenarios are set up for that:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\active-control-report-watch-quiet.json --parity E --log captures\active-control-report-watch-quiet.txt --result-json captures\active-control-report-watch-quiet-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\active-control-report-watch-broad.json --parity E --log captures\active-control-report-watch-broad.txt --result-json captures\active-control-report-watch-broad-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\active-control-report-watch-gated.json --parity E --log captures\active-control-report-watch-gated.txt --result-json captures\active-control-report-watch-gated-result.json
|
||||||
|
```
|
||||||
|
|
||||||
|
The quiet scenario sends the selector-zero OK seed, then refreshes `E000[0x0093]=0x9020` every 0.60 s. This is the lowest-noise active hold that has already kept `CONNECT: OK` alive.
|
||||||
|
|
||||||
|
The broad scenario streams `E000[0x008F]=0x1800` and `E000[0x0093]=0xFFFF` every cycle. This is noisier, but may open more local-control/status gates.
|
||||||
|
|
||||||
|
The gated scenario first seeds candidate secondary-table feature bits with command 6:
|
||||||
|
|
||||||
|
```text
|
||||||
|
06 00 15 80 00 C9 ; E400[0x0015] OTHERS/COPY visibility candidate
|
||||||
|
06 01 0F 18 00 4A ; E400[0x008F] shutter/OTHERS bits 11+12
|
||||||
|
06 01 13 FF FF 4E ; E400[0x0093] broad local-report/status gate candidate
|
||||||
|
```
|
||||||
|
|
||||||
|
Then it streams `E000[0x008F]=0x1800` and `E000[0x0093]=0x90FF`. This is the better next watch if quiet/broad E000-only refreshes do not produce local-control TX.
|
||||||
|
|
||||||
|
After a run, summarize unexpected device frames with:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario_unexpected.py captures\active-control-report-watch-quiet.txt --show-all
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario_unexpected.py captures\active-control-report-watch-broad.txt --show-all
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario_unexpected.py captures\active-control-report-watch-gated.txt --show-all
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected refresh responses are ignored by default: heartbeat, table readbacks, and `02 00 02 00 00 5A`. Any remaining checksum-valid frame is a candidate local-control report. This is where physical button/dial reports should appear if the RCP only talks while the CCU keeps the selector tables active.
|
||||||
|
|
||||||
|
The unexpected-frame summarizer also labels known autonomous button frames so they are not mistaken for newly unlocked controls:
|
||||||
|
|
||||||
|
```text
|
||||||
|
00 00 15 80 00 CF ; known CALL active report
|
||||||
|
00 00 15 00 00 4F ; known CALL inactive report
|
||||||
|
00 00 07 80 00 DD ; known CAM POWER report
|
||||||
|
```
|
||||||
|
|
||||||
|
First quiet/broad watch captures on 2026-05-26 showed no unexpected checksum-valid frames in the observed window:
|
||||||
|
|
||||||
|
```text
|
||||||
|
active-control-report-watch-quiet: 114 detected frames, all expected refresh/heartbeat/readback
|
||||||
|
active-control-report-watch-broad: 133 detected frames, all expected refresh/heartbeat/readback
|
||||||
|
```
|
||||||
|
|
||||||
|
Those runs stopped mid-scenario, so this is not a full negative proof. The practical interpretation is narrower: E000 active-state refresh alone did not make the pressed controls emit visible TX in the watched window. The gated command-6 version is the next ROM-supported test.
|
||||||
|
|
||||||
|
The first gated watch capture produced a new periodic active-state response:
|
||||||
|
|
||||||
|
```text
|
||||||
|
02 00 04 00 00 5C ; gated 0x0004 transition candidate, seen twice
|
||||||
|
01 00 04 00 00 5F ; gated 0x0004 active response candidate, seen 328 times
|
||||||
|
```
|
||||||
|
|
||||||
|
After treating those as expected gated refresh traffic, the capture had zero novel frames. A direct search found no known CALL/CAM POWER frames in that log. So the gated setup changed the session/status response shape, but it did not yet prove that physical controls beyond the already-known autonomous buttons are reporting.
|
||||||
|
|
||||||
|
## Lamp Selector Mapping
|
||||||
|
|
||||||
|
Bench lamp sweeps now prove that several panel outputs are directly driven by command-0 selector writes while `CONNECT: OK` is alive. The current detailed map lives in `docs/pt2-lamp-selector-map.md`.
|
||||||
|
|
||||||
|
Newest confirmed behavior:
|
||||||
|
|
||||||
|
- `lamp-known-button-selector-probe` made CAM, CALL, BARS, MASTER, and camera tally outputs flash individually.
|
||||||
|
- `0x0007 = 0x8000/0x0000` blinked CAM POWER in isolation.
|
||||||
|
- `0x0015 = 0x8000/0x0000` blinked CALL and red tally in isolation.
|
||||||
|
- Fresh-boot isolation maps `0x0013` to SLAVE, `0x0016` to green tally, and `0x0017` to BARS for the `0x8000/0x0000` value pair.
|
||||||
|
- Fresh-boot isolation maps `0x0092` to iris AUTO/OFF behavior, and maps both `0x00B9` and `0x0110` to KNEE-related behavior.
|
||||||
|
- A ROM trace now explains why the KNEE tests looked non-level-held. `loc_1795` is reached from the panel input lane (`F104 -> F692 -> F6F0.1`) and reads `E000[0x00B9]` plus `E000[0x0110]`.
|
||||||
|
- The live KNEE value/report gate is `0x00B9.13`, not the earlier bench-only `0x00B9.15` guess.
|
||||||
|
- `0x0110.15` forces a timed KNEE page/display override (`F732=0x1C03`, `FB02=0x14`), which matches the observed "lights, then clears" behavior.
|
||||||
|
- On that KNEE LCD page, `0x0110.15` selects `DL`, `0x00B9.15` selects `PRESET`, and both clear selects `AUTO`.
|
||||||
|
- When `0x00B9.13` is set and `0x0110.15` is clear, the ROM reports/updates selector `0x00BC` from the `F692 - F6B2` panel-input delta. See `docs/pt2-knee-rom-trace.md`.
|
||||||
|
- The first KNEE ROM probe produced a new bench LCD state with `DTL` on the left and `KNEE` on the right, matching the ROM page-0x1C DETAIL/KNEE neighborhood.
|
||||||
|
- A follow-up isolation lit the KNEE AUTO lamp in later KNEE windows but did not change the LCD. Current model: KNEE AUTO lamp/status is mostly selector driven, while the DETAIL/KNEE LCD page needs an additional local menu/display condition.
|
||||||
|
|
||||||
## What Is Still Unknown
|
## What Is Still Unknown
|
||||||
|
|
||||||
- The official PT2 names for commands and selectors.
|
- The official PT2 names for commands and selectors.
|
||||||
@@ -612,7 +716,7 @@ This fits the real panel behavior:
|
|||||||
5. Dump selector table state before and after CONNECT OK.
|
5. Dump selector table state before and after CONNECT OK.
|
||||||
6. Seed selectors `0x003`, `0x040`, and `0x0F6` after selector-zero OK and watch lamps/readouts.
|
6. Seed selectors `0x003`, `0x040`, and `0x0F6` after selector-zero OK and watch lamps/readouts.
|
||||||
7. Mine selector dispatch handlers for known UI text terms: `IRIS`, `GAIN`, `SHUTTER`, `BARS`, `BLACK`, `CALL`, `AUTO`, `DIAG`.
|
7. Mine selector dispatch handlers for known UI text terms: `IRIS`, `GAIN`, `SHUTTER`, `BARS`, `BLACK`, `CALL`, `AUTO`, `DIAG`.
|
||||||
8. Build a fake-CCU streamer that repeatedly writes a small selector set and logs which RCP reports appear.
|
8. Run the active-control watch scenarios and map any unexpected frames back to physical controls.
|
||||||
|
|
||||||
## Source Files And Reports
|
## Source Files And Reports
|
||||||
|
|
||||||
|
|||||||
201
docs/pt2-shutter-display-trace.md
Normal file
201
docs/pt2-shutter-display-trace.md
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# PT2 Shutter Display Trace
|
||||||
|
|
||||||
|
This note collects the current ROM evidence for the shutter seven-segment display and related selector traffic.
|
||||||
|
|
||||||
|
## Confirmed Bench Mapping
|
||||||
|
|
||||||
|
The real panel responds to primary selector `0x008F`:
|
||||||
|
|
||||||
|
| Command 0 write | Meaning candidate | Observed panel result |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `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` | live default/clear | in the short clear-control run, SHUTTER swapped to `OFF`, then back to `EVS` when bit 11 was restored |
|
||||||
|
|
||||||
|
Manual correlation:
|
||||||
|
|
||||||
|
- The RCP-TX7 manual has `OTHERS (1/6: SHUTTER)` with an `EVS` button.
|
||||||
|
- 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`. `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
|
||||||
|
|
||||||
|
Primary table address:
|
||||||
|
|
||||||
|
```text
|
||||||
|
selector 0x008F -> E000 + 2 * 0x008F = H'E11E
|
||||||
|
```
|
||||||
|
|
||||||
|
The OTHERS/SHUTTER menu handler is `H'6EE4`.
|
||||||
|
|
||||||
|
Important instructions:
|
||||||
|
|
||||||
|
```text
|
||||||
|
6F6E: BTST.W #11, @H'E11E
|
||||||
|
6F74: BSET.B #6, R0
|
||||||
|
6F76: BTST.W #12, @H'E11E
|
||||||
|
6F7C: BSET.B #4, R0
|
||||||
|
6F7E: MOV:G.B R0, @H'F711
|
||||||
|
```
|
||||||
|
|
||||||
|
This is the direct consumer seen so far. The current decompile does not show another static read of `H'E11E` outside this handler.
|
||||||
|
|
||||||
|
`H'6EE4` also programs local descriptor RAM before this:
|
||||||
|
|
||||||
|
```text
|
||||||
|
6EFD: F73E = H'088F
|
||||||
|
6F09: F74E = H'0800
|
||||||
|
6F0F: F742 = H'088F
|
||||||
|
6F1B: F752 = H'1000
|
||||||
|
```
|
||||||
|
|
||||||
|
Those descriptors match selector `0x008F` plus the two observed masks `0x0800` and `0x1000`, so the generic panel-output updater also appears to know about the same selector.
|
||||||
|
|
||||||
|
## Local Panel Trigger Path
|
||||||
|
|
||||||
|
`H'6EE4` can also generate a selector `0x008F` report/update from local OTHERS/SHUTTER controls:
|
||||||
|
|
||||||
|
```text
|
||||||
|
6F26: read F770 local action byte
|
||||||
|
6F2E: keep low two action bits
|
||||||
|
6F37: if action bit path and E400[0x008F].11 is enabled, set E800[0x008F] = 0x0800
|
||||||
|
6F45: if alternate action path and E400[0x008F].12 is enabled, set E800[0x008F] = 0x1000
|
||||||
|
6F53: R3 = 0x008F
|
||||||
|
6F64: call 3E54 report/target-frame builder
|
||||||
|
```
|
||||||
|
|
||||||
|
Practical meaning:
|
||||||
|
|
||||||
|
- The CCU can force the display state by writing `E000[0x008F]`.
|
||||||
|
- The RCP can also try to report local EVS/OFF changes through selector `0x008F`, but only when the secondary-table feature bits `E400[0x008F].11/.12` allow it.
|
||||||
|
|
||||||
|
## Adjacent Shutter Value Family
|
||||||
|
|
||||||
|
The periodic/control-change scanner at `H'15E0` processes changed input words collected by IRQ3 from the external panel chips. Around the shutter path it calls `H'19A2`, which compares a local delta against the current primary table value and, if changed, writes the `E800` current table and calls `H'3E54`.
|
||||||
|
|
||||||
|
Candidate selectors:
|
||||||
|
|
||||||
|
| Handler | Source RAM | Gate | Selector sent | Meaning candidate |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `H'17C9` | `F6AE/F6CE` | `E000[0x0093].12` | `0x00A3` | clear-scan/shutter value lane |
|
||||||
|
| `H'17FB` | `F6AC/F6CC` | `E000[0x0093].12` | `0x00A4` | clear-scan/shutter value lane |
|
||||||
|
| `H'182D` | `F6AA/F6CA` | `E000[0x0093].5`, `F717.2` clear | `0x00A5` | shutter value lane |
|
||||||
|
| `H'182D` | `F6AA/F6CA` | `F717.2` set | `0x00D8` | alternate/DXC-637 shutter lane |
|
||||||
|
| `H'1891` | `F6A8/F6C8` | `E000[0x0093].5`, `F717.2` clear | `0x0080` | shutter value lane |
|
||||||
|
| `H'1891` | `F6A8/F6C8` | `F717.2` set | `0x00D9` | alternate/DXC-637 shutter lane |
|
||||||
|
| `H'18E7` | `F6A6/F6C6` | `E000[0x0093].5`, `F717.2` clear | `0x00A6` | shutter value lane |
|
||||||
|
| `H'18E7` | `F6A6/F6C6` | `F717.2` set | `0x00DA` | alternate/DXC-637 shutter lane |
|
||||||
|
| `H'194A` | `F6A4/F6C4` | `F731 <= 3` | `0x0080` | shared value lane |
|
||||||
|
| `H'1979` | `F6A2/F6C2` plus `F68C` scale | `F731 <= 3` | `0x0081` | scaled analog value lane |
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
01 01 0F 00 00 55 ; read 0x008F
|
||||||
|
01 01 13 00 00 49 ; read 0x0093 gate/status
|
||||||
|
01 01 23 00 00 79 ; read 0x00A3
|
||||||
|
01 01 24 00 00 7E ; read 0x00A4
|
||||||
|
01 01 25 00 00 7F ; read 0x00A5
|
||||||
|
01 01 58 00 00 02 ; read 0x00D8
|
||||||
|
01 01 00 00 00 5A ; read 0x0080
|
||||||
|
01 01 59 00 00 03 ; read 0x00D9
|
||||||
|
01 01 26 00 00 7C ; read 0x00A6
|
||||||
|
01 01 5A 00 00 00 ; read 0x00DA
|
||||||
|
01 01 01 00 00 5B ; read 0x0081
|
||||||
|
```
|
||||||
|
|
||||||
|
Potential display probes after `CONNECT: OK`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
00 01 0F 00 00 54 ; clear selector 0x008F
|
||||||
|
00 01 13 80 00 C8 ; set 0x0093 high bit candidate
|
||||||
|
00 01 13 FF FF 48 ; enable all 0x0093 gates candidate
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-auto-candidates.json --parity E --log captures\shutter-0093-blackflare-auto-candidates.txt --result-json captures\shutter-0093-blackflare-auto-candidates-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-slow-marked.json --parity E --log captures\shutter-0093-blackflare-slow-marked.txt --result-json captures\shutter-0093-blackflare-slow-marked-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-field-groups.json --parity E --log captures\shutter-0093-blackflare-field-groups.txt --result-json captures\shutter-0093-blackflare-field-groups-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-field-confirm.json --parity E --log captures\shutter-0093-blackflare-field-confirm.txt --result-json captures\shutter-0093-blackflare-field-confirm-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-field-stream-confirm.json --parity E --log captures\shutter-0093-blackflare-field-stream-confirm.txt --result-json captures\shutter-0093-blackflare-field-stream-confirm-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-confirm-f020.json --parity E --log captures\shutter-0093-blackflare-confirm-f020.txt --result-json captures\shutter-0093-blackflare-confirm-f020-result.json
|
||||||
|
-Manual-auto-manual
|
||||||
|
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-confirm-ff20.json --parity E --log captures\shutter-0093-blackflare-confirm-ff20.txt --result-json captures\shutter-0093-blackflare-confirm-ff20-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-confirm-9f20.json --parity E --log captures\shutter-0093-blackflare-confirm-9f20.txt --result-json captures\shutter-0093-blackflare-confirm-9f20-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-confirm-90ff.json --parity E --log captures\shutter-0093-blackflare-confirm-90ff.txt --result-json captures\shutter-0093-blackflare-confirm-90ff-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-confirm-9fff.json --parity E --log captures\shutter-0093-blackflare-confirm-9fff.txt --result-json captures\shutter-0093-blackflare-confirm-9fff-result.json
|
||||||
|
.\.venv\Scripts\python.exe scripts\serial_scenario.py scenarios\shutter-0093-blackflare-lowbyte-groups.json --parity E --log captures\shutter-0093-blackflare-lowbyte-groups.txt --result-json captures\shutter-0093-blackflare-lowbyte-groups-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.
|
||||||
|
7. `shutter-0093-blackflare-auto-candidates.json`: uses the known `0x9020` black/flare-manual context and adds each remaining bit to hunt for the `0xFFFF` black/flare-AUTO effect.
|
||||||
|
8. `shutter-0093-blackflare-slow-marked.json`: repeats the hunt without clear/OK resets between candidates, so white-balance should flicker less and black/flare AUTO transitions can be matched to candidate holds.
|
||||||
|
9. `shutter-0093-blackflare-field-groups.json`: tests multi-bit field groups after the slow-marked run suggested black/flare AUTO is not one single extra bit over `0x9020`.
|
||||||
|
10. `shutter-0093-blackflare-field-confirm.json`: shorter, longer-hold confirmation of the broad field groups after the first field-groups run produced three MANUAL->AUTO->MANUAL swaps.
|
||||||
|
11. `shutter-0093-blackflare-field-stream-confirm.json`: repeats each candidate every 0.60 s after the longer-hold confirmation fell into `CONNECT:NOT ACT`, testing the CCU-refresh model directly.
|
||||||
|
12. `shutter-0093-blackflare-confirm-*.json`: one-candidate streamed confirmations. Each run includes a known `0xFFFF` AUTO positive control, then brackets one candidate with `0x9020` manual context. After the positive-control section, the expected candidate pattern is MANUAL -> AUTO -> MANUAL -> AUTO -> MANUAL only if that candidate drives black/flare AUTO.
|
||||||
|
13. `shutter-0093-blackflare-lowbyte-groups.json`: keeps the high byte fixed at `0x90` and varies only the low byte, after `0x90FF` and `0x9FFF` both toggled black/flare AUTO.
|
||||||
|
|
||||||
|
## 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-0093-bit-isolation` | stepped through `0x1000`, `0x0020`, `0x1020`, `0x8000`, `0x8020`, `0x9000`, `0x9020` | white-balance lamps swapped between MANUAL and PRESET; black/flare stayed MANUAL | bit 15 remains the prime white-balance PRESET candidate; black/flare AUTO is likely outside bits 15/12/5 |
|
||||||
|
| `shutter-0093-blackflare-auto-candidates` | stepped through `0x9020`, `0xFFFF`, then `0x9020` plus each remaining bit | black/flare swapped AUTO/MANUAL more slowly than white-balance MANUAL/PRESET | the clear/OK reset before each candidate likely caused extra white-balance flicker; use the slow-marked follow-up to map black/flare transitions to exact bits |
|
||||||
|
| `shutter-0093-blackflare-slow-marked` | held `0x9020`, `0xFFFF`, then alternated `0x9020` with each candidate | white-balance stayed stable, black/flare swapped twice with large pauses; panel stayed `CONNECT: OK` throughout | likely only the manual-reference to `0xFFFF` and `0xFFFF` back to `0x9020` changed black/flare, so AUTO is probably a multi-bit field rather than one added bit |
|
||||||
|
| `shutter-0093-blackflare-field-groups` | held broad grouped values such as `0xF020`, `0xFF20`, `0x9F20`, `0x90FF`, `0x9FFF` | black/flare made three MANUAL->AUTO->MANUAL swaps | broad field combinations can produce black/flare AUTO; use the shorter confirmation run to identify which grouped windows caused the swaps |
|
||||||
|
| `shutter-0093-blackflare-field-confirm` | held `0xFFFF` for 2.8 s, then candidate groups | one MANUAL->AUTO transition at the start, then `CONNECT:NOT ACT`; PRESET white-balance lamp briefly flashed a few times while inactive | a silent 2.8 s hold is too long; traffic must be refreshed, and some lamp latch/update paths can still flash during inactive display cleanup |
|
||||||
|
| `shutter-0093-blackflare-field-stream-confirm` | streamed every candidate at 0.60 s and saw 148 `02 00 02 00 00 5A` OK-path responses with no resync errors | manual/auto/manual groups were visible, then `CONNECT:NOT ACT` after the stream ended | the stream itself kept OK alive; the final inactive state is likely just the refresh stopping. Candidate isolation needs streamed, one-candidate tests |
|
||||||
|
| `shutter-0093-blackflare-confirm-f020`, `ff20`, `9f20` | each completed cleanly with 137 OK-path responses and no resync errors | MANUAL->AUTO->MANUAL only | only the built-in `0xFFFF` positive control produced AUTO; these candidates did not drive black/flare AUTO by themselves |
|
||||||
|
| `shutter-0093-blackflare-confirm-90ff`, `9fff` | each completed cleanly with 137 OK-path responses and no resync errors | black/flare went back and forth a couple of times | `0x90FF` is sufficient to drive the AUTO effect, so the black/flare field is likely in the low byte of `0x0093`; `0x9FFF` is a superset rather than a separate high-byte requirement |
|
||||||
|
| `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 manual/preset and black/flare manual/auto side effects, and still gates some ROM-observed shutter/clear-scan report lanes. Current black/flare evidence points to `0x0093` high byte `0x90` as enough context, with the low byte selecting the black/flare MANUAL/AUTO state.
|
||||||
@@ -148,6 +148,11 @@ def label_frame(frame: bytes) -> str:
|
|||||||
bytes.fromhex("0780C040A0FD"): "visible_40A0_family_C0",
|
bytes.fromhex("0780C040A0FD"): "visible_40A0_family_C0",
|
||||||
bytes.fromhex("07804020902D"): "visible_retry_0040_2090_candidate",
|
bytes.fromhex("07804020902D"): "visible_retry_0040_2090_candidate",
|
||||||
bytes.fromhex("0780C060205D"): "visible_C0_6020_family_candidate",
|
bytes.fromhex("0780C060205D"): "visible_C0_6020_family_candidate",
|
||||||
|
bytes.fromhex("0000158000CF"): "known_call_button_active_report",
|
||||||
|
bytes.fromhex("00001500004F"): "known_call_button_inactive_report",
|
||||||
|
bytes.fromhex("0000078000DD"): "known_cam_power_button_report",
|
||||||
|
bytes.fromhex("01000400005F"): "gated_active_0004_response_candidate",
|
||||||
|
bytes.fromhex("02000400005C"): "gated_active_0004_transition_candidate",
|
||||||
}
|
}
|
||||||
label = labels.get(frame, "")
|
label = labels.get(frame, "")
|
||||||
if label:
|
if label:
|
||||||
|
|||||||
336
h8536/emulator/report_queue_probe.py
Normal file
336
h8536/emulator/report_queue_probe.py
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from ..formatting import h16, parse_int
|
||||||
|
from .cli import load_rom
|
||||||
|
from .eeprom_image import write_eeprom_snapshot
|
||||||
|
from .runner import H8536Emulator
|
||||||
|
from .rx_probe import RunContext, _run_until, _rx_ready, format_frame
|
||||||
|
from .uart import UartTiming
|
||||||
|
|
||||||
|
|
||||||
|
CHECKSUM_SEED = 0x5A
|
||||||
|
REPORT_QUEUE_START = 0xF870
|
||||||
|
REPORT_QUEUE_HEAD = 0xF9B0
|
||||||
|
REPORT_QUEUE_TAIL = 0xF9B5
|
||||||
|
TX_STAGING_START = 0xF850
|
||||||
|
TX_FRAME_START = 0xF858
|
||||||
|
TX_FRAME_LENGTH = 6
|
||||||
|
CURRENT_TABLE_START = 0xE800
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ReportQueueProbeResult:
|
||||||
|
rom_path: Path
|
||||||
|
report_word: int
|
||||||
|
payload_selector: int
|
||||||
|
payload: int
|
||||||
|
expected_frame: bytes
|
||||||
|
boot_summary: str
|
||||||
|
steps: int
|
||||||
|
stopped_reason: str
|
||||||
|
tx_frames: tuple[bytes, ...]
|
||||||
|
staging_bytes: bytes
|
||||||
|
finalized_bytes: bytes
|
||||||
|
state: dict[str, int]
|
||||||
|
eeprom_writes: tuple[str, ...]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def emitted_expected_frame(self) -> bool:
|
||||||
|
return self.expected_frame in self.tx_frames
|
||||||
|
|
||||||
|
def as_dict(self) -> dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"kind": "h8536_report_queue_probe",
|
||||||
|
"rom_path": str(self.rom_path),
|
||||||
|
"report_word": f"0x{self.report_word:04X}",
|
||||||
|
"payload_selector": f"0x{self.payload_selector:04X}",
|
||||||
|
"payload": f"0x{self.payload:04X}",
|
||||||
|
"expected_frame": format_frame(self.expected_frame),
|
||||||
|
"emitted_expected_frame": self.emitted_expected_frame,
|
||||||
|
"boot_summary": self.boot_summary,
|
||||||
|
"steps": self.steps,
|
||||||
|
"stopped_reason": self.stopped_reason,
|
||||||
|
"tx_frames": [format_frame(frame) for frame in self.tx_frames],
|
||||||
|
"staging_bytes_f850_f855": format_frame(self.staging_bytes),
|
||||||
|
"finalized_bytes_f858_f85d": format_frame(self.finalized_bytes),
|
||||||
|
"state": {name: _format_state_value(name, value) for name, value in self.state.items()},
|
||||||
|
"eeprom_writes": list(self.eeprom_writes),
|
||||||
|
}
|
||||||
|
|
||||||
|
def lines(self) -> list[str]:
|
||||||
|
lines = [
|
||||||
|
f"rom={self.rom_path}",
|
||||||
|
self.boot_summary,
|
||||||
|
f"report_word={h16(self.report_word)} payload_selector={h16(self.payload_selector)} payload={h16(self.payload)}",
|
||||||
|
f"expected_frame={format_frame(self.expected_frame)}",
|
||||||
|
f"emitted_expected_frame={int(self.emitted_expected_frame)}",
|
||||||
|
f"stopped={self.stopped_reason} steps={self.steps}",
|
||||||
|
"tx_frames=" + (" | ".join(format_frame(frame) for frame in self.tx_frames) or "none"),
|
||||||
|
f"staging_F850_F855={format_frame(self.staging_bytes)}",
|
||||||
|
f"finalized_F858_F85D={format_frame(self.finalized_bytes)}",
|
||||||
|
"state:",
|
||||||
|
]
|
||||||
|
for name, value in self.state.items():
|
||||||
|
width = 4 if name in {"queue_word", "current_table_word"} else 2
|
||||||
|
lines.append(f" {name}=0x{value:0{width}X}")
|
||||||
|
if self.eeprom_writes:
|
||||||
|
lines.append("eeprom_writes:")
|
||||||
|
lines.extend(f" {line}" for line in self.eeprom_writes)
|
||||||
|
else:
|
||||||
|
lines.append("eeprom_writes=none")
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def build_expected_report_frame(report_word: int, payload: int) -> bytes:
|
||||||
|
first, second, third = encode_report_header(report_word)
|
||||||
|
frame = bytes(
|
||||||
|
[
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
third,
|
||||||
|
(payload >> 8) & 0xFF,
|
||||||
|
payload & 0xFF,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return frame + bytes([frame_checksum(frame)])
|
||||||
|
|
||||||
|
|
||||||
|
def encode_report_header(report_word: int) -> tuple[int, int, int]:
|
||||||
|
raw = report_word & 0xFFFF
|
||||||
|
encoded_selector = _loc_6206_selector_encode(raw)
|
||||||
|
|
||||||
|
r1 = _swap_bytes(raw)
|
||||||
|
r1 = (r1 & 0xFF00) | ((r1 & 0xFF) >> 1)
|
||||||
|
r2 = r1 & 0xFF
|
||||||
|
|
||||||
|
first = r1 & 0x07
|
||||||
|
third = encoded_selector & 0xFF
|
||||||
|
swapped_encoded = _swap_bytes(encoded_selector)
|
||||||
|
second = (swapped_encoded & 0xFF) | (r2 & 0x78)
|
||||||
|
return first & 0xFF, second & 0xFF, third & 0xFF
|
||||||
|
|
||||||
|
|
||||||
|
def report_payload_selector(report_word: int) -> int:
|
||||||
|
return report_word & 0x01FF
|
||||||
|
|
||||||
|
|
||||||
|
def frame_checksum(frame_without_checksum: bytes) -> int:
|
||||||
|
checksum = CHECKSUM_SEED
|
||||||
|
for value in frame_without_checksum[: TX_FRAME_LENGTH - 1]:
|
||||||
|
checksum ^= value
|
||||||
|
return checksum & 0xFF
|
||||||
|
|
||||||
|
|
||||||
|
def run_report_queue_probe(
|
||||||
|
*,
|
||||||
|
report_word: int = 0x0204,
|
||||||
|
payload: int = 0x0000,
|
||||||
|
queue_index: int = 0,
|
||||||
|
rom_path: Path | None = None,
|
||||||
|
boot_steps: int = 250_000,
|
||||||
|
max_steps: int = 200_000,
|
||||||
|
eeprom_seed: str = "blank",
|
||||||
|
eeprom_image: bytes | None = None,
|
||||||
|
tx_wire_timing: bool = False,
|
||||||
|
uart_baud: int = 38_400,
|
||||||
|
uart_format: str = "8E1",
|
||||||
|
p9_fast_path: bool = True,
|
||||||
|
p9_fast_input: int = 0xFF,
|
||||||
|
p7_input: int = 0xFF,
|
||||||
|
) -> tuple[H8536Emulator, ReportQueueProbeResult]:
|
||||||
|
rom_bytes, discovered_rom_path = load_rom(rom_path)
|
||||||
|
emulator = H8536Emulator(
|
||||||
|
rom_bytes,
|
||||||
|
p9_fast_path_enabled=p9_fast_path,
|
||||||
|
p9_fast_default_input_byte=p9_fast_input,
|
||||||
|
p7_input=p7_input,
|
||||||
|
eeprom_seed=eeprom_seed,
|
||||||
|
sci1_tx_timing=UartTiming.from_format(uart_format, baud=uart_baud) if tx_wire_timing else None,
|
||||||
|
)
|
||||||
|
if eeprom_image is not None:
|
||||||
|
emulator.memory.load_eeprom_image(eeprom_image)
|
||||||
|
|
||||||
|
boot_context = RunContext()
|
||||||
|
boot_used, boot_reason = _run_until(emulator, boot_steps, _rx_ready, boot_context)
|
||||||
|
boot_summary = (
|
||||||
|
f"boot={boot_reason} steps={boot_used} pc={h16(emulator.cpu.pc)} "
|
||||||
|
f"rx_serviceable={int(_rx_ready(emulator))} lcd_display={emulator.memory.lcd.display_text(lines=4)!r}"
|
||||||
|
)
|
||||||
|
|
||||||
|
payload_selector = report_payload_selector(report_word)
|
||||||
|
expected_frame = build_expected_report_frame(report_word, payload)
|
||||||
|
_seed_report_queue(emulator, report_word=report_word, payload=payload, queue_index=queue_index)
|
||||||
|
emulator.memory.clear_eeprom_write_log()
|
||||||
|
|
||||||
|
start_frame_count = len(emulator.sci1.tx_frames)
|
||||||
|
|
||||||
|
def emitted_expected(inner: H8536Emulator) -> bool:
|
||||||
|
return expected_frame in inner.sci1.tx_frames[start_frame_count:]
|
||||||
|
|
||||||
|
run_context = RunContext()
|
||||||
|
steps, reason = _run_until(emulator, max_steps, emitted_expected, run_context)
|
||||||
|
stopped_reason = "expected_frame" if reason == "predicate" else reason
|
||||||
|
|
||||||
|
state = _state_snapshot(emulator, queue_index=queue_index, payload_selector=payload_selector)
|
||||||
|
staging = bytes(emulator.memory.read8(address) for address in range(TX_STAGING_START, TX_STAGING_START + TX_FRAME_LENGTH))
|
||||||
|
finalized = bytes(emulator.memory.read8(address) for address in range(TX_FRAME_START, TX_FRAME_START + TX_FRAME_LENGTH))
|
||||||
|
result = ReportQueueProbeResult(
|
||||||
|
rom_path=discovered_rom_path,
|
||||||
|
report_word=report_word & 0xFFFF,
|
||||||
|
payload_selector=payload_selector,
|
||||||
|
payload=payload & 0xFFFF,
|
||||||
|
expected_frame=expected_frame,
|
||||||
|
boot_summary=boot_summary,
|
||||||
|
steps=steps,
|
||||||
|
stopped_reason=stopped_reason,
|
||||||
|
tx_frames=tuple(emulator.sci1.tx_frames[start_frame_count:]),
|
||||||
|
staging_bytes=staging,
|
||||||
|
finalized_bytes=finalized,
|
||||||
|
state=state,
|
||||||
|
eeprom_writes=tuple(emulator.memory.p9_bus.x24164_bus.write_log_lines(limit=80)),
|
||||||
|
)
|
||||||
|
return emulator, result
|
||||||
|
|
||||||
|
|
||||||
|
def build_arg_parser() -> argparse.ArgumentParser:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Seed the ROM report queue and let the H8/536 ROM build the matching SCI1 TX frame."
|
||||||
|
)
|
||||||
|
parser.add_argument("--rom", type=Path, help="ROM image path; defaults to ROM/M27C512@DIP28_1.BIN")
|
||||||
|
parser.add_argument("--report-word", type=parse_int, default=0x0204, help="word to place in F870 report queue")
|
||||||
|
parser.add_argument("--payload", type=parse_int, default=0x0000, help="word to place in E800[current selector]")
|
||||||
|
parser.add_argument("--queue-index", type=parse_int, default=0, help="F870 queue slot to seed")
|
||||||
|
parser.add_argument("--boot-steps", type=int, default=250_000, help="maximum boot steps before queue seeding")
|
||||||
|
parser.add_argument("--max-steps", type=int, default=200_000, help="maximum steps after queue seeding")
|
||||||
|
parser.add_argument("--tx-wire-timing", action="store_true", help="model UART TX character time between TXI bytes")
|
||||||
|
parser.add_argument("--uart-baud", type=parse_int, default=38_400, help="baud rate used with --tx-wire-timing")
|
||||||
|
parser.add_argument("--uart-format", default="8E1", help="UART format used with --tx-wire-timing")
|
||||||
|
parser.add_argument("--no-p9-fast-path", action="store_true", help="disable shortcut handling for known P9 routines")
|
||||||
|
parser.add_argument("--p9-fast-input", type=parse_int, default=0xFF, help="default byte returned by P9 fast-path reads")
|
||||||
|
parser.add_argument("--p7-input", type=parse_int, default=0xFF, help="external P7 pin state; DIP-off default is 0xFF")
|
||||||
|
parser.add_argument("--eeprom-seed", choices=("blank", "factory"), default="blank", help="initial X24164/shadow state")
|
||||||
|
parser.add_argument("--eeprom-load", type=Path, help="load a 0x1000-byte logical EEPROM image before booting")
|
||||||
|
parser.add_argument("--eeprom-save", type=Path, help="save the final EEPROM image")
|
||||||
|
parser.add_argument("--eeprom-report", type=Path, help="write a readable EEPROM snapshot")
|
||||||
|
parser.add_argument("--eeprom-report-json", type=Path, help="write a structured EEPROM snapshot")
|
||||||
|
parser.add_argument("--eeprom-report-include-image", action="store_true", help="include full EEPROM image in JSON")
|
||||||
|
parser.add_argument("--json", action="store_true", help="print JSON instead of text")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv: list[str] | None = None) -> int:
|
||||||
|
args = build_arg_parser().parse_args(argv)
|
||||||
|
emulator, result = run_report_queue_probe(
|
||||||
|
report_word=args.report_word,
|
||||||
|
payload=args.payload,
|
||||||
|
queue_index=args.queue_index,
|
||||||
|
rom_path=args.rom,
|
||||||
|
boot_steps=args.boot_steps,
|
||||||
|
max_steps=args.max_steps,
|
||||||
|
eeprom_seed=args.eeprom_seed,
|
||||||
|
eeprom_image=args.eeprom_load.read_bytes() if args.eeprom_load else None,
|
||||||
|
tx_wire_timing=args.tx_wire_timing,
|
||||||
|
uart_baud=args.uart_baud,
|
||||||
|
uart_format=args.uart_format,
|
||||||
|
p9_fast_path=not args.no_p9_fast_path,
|
||||||
|
p9_fast_input=args.p9_fast_input,
|
||||||
|
p7_input=args.p7_input,
|
||||||
|
)
|
||||||
|
|
||||||
|
if args.json:
|
||||||
|
print(json.dumps(result.as_dict(), indent=2, sort_keys=True))
|
||||||
|
else:
|
||||||
|
for line in result.lines():
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
if args.eeprom_save:
|
||||||
|
args.eeprom_save.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
args.eeprom_save.write_bytes(emulator.memory.dump_eeprom_image())
|
||||||
|
print(f"eeprom_saved={args.eeprom_save}")
|
||||||
|
if args.eeprom_report:
|
||||||
|
write_eeprom_snapshot(emulator.memory, args.eeprom_report, rom_bytes=emulator.memory.rom.data)
|
||||||
|
print(f"eeprom_report={args.eeprom_report}")
|
||||||
|
if args.eeprom_report_json:
|
||||||
|
write_eeprom_snapshot(
|
||||||
|
emulator.memory,
|
||||||
|
args.eeprom_report_json,
|
||||||
|
rom_bytes=emulator.memory.rom.data,
|
||||||
|
as_json=True,
|
||||||
|
include_image_hex=args.eeprom_report_include_image,
|
||||||
|
)
|
||||||
|
print(f"eeprom_report_json={args.eeprom_report_json}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _seed_report_queue(
|
||||||
|
emulator: H8536Emulator,
|
||||||
|
*,
|
||||||
|
report_word: int,
|
||||||
|
payload: int,
|
||||||
|
queue_index: int,
|
||||||
|
) -> None:
|
||||||
|
queue_index &= 0x7F
|
||||||
|
queue_address = REPORT_QUEUE_START + (queue_index * 2)
|
||||||
|
payload_address = CURRENT_TABLE_START + (report_payload_selector(report_word) * 2)
|
||||||
|
memory = emulator.memory
|
||||||
|
memory.write16(queue_address, report_word)
|
||||||
|
memory.write16(payload_address, payload)
|
||||||
|
memory.write8(REPORT_QUEUE_TAIL, queue_index)
|
||||||
|
memory.write8(REPORT_QUEUE_HEAD, (queue_index + 1) & 0x7F)
|
||||||
|
memory.write8(0xF9C0, 0x00)
|
||||||
|
memory.write8(0xF9C3, 0x00)
|
||||||
|
memory.write8(0xFAA2, 0x00)
|
||||||
|
memory.write8(0xFAA3, 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
def _state_snapshot(emulator: H8536Emulator, *, queue_index: int, payload_selector: int) -> dict[str, int]:
|
||||||
|
memory = emulator.memory
|
||||||
|
queue_address = REPORT_QUEUE_START + ((queue_index & 0x7F) * 2)
|
||||||
|
payload_address = CURRENT_TABLE_START + ((payload_selector & 0x01FF) * 2)
|
||||||
|
return {
|
||||||
|
"queue_head_F9B0": memory.read8(REPORT_QUEUE_HEAD),
|
||||||
|
"queue_tail_F9B5": memory.read8(REPORT_QUEUE_TAIL),
|
||||||
|
"queue_word": memory.read16(queue_address),
|
||||||
|
"current_table_word": memory.read16(payload_address),
|
||||||
|
"tx_gate_F9C0": memory.read8(0xF9C0),
|
||||||
|
"rx_index_F9C3": memory.read8(0xF9C3),
|
||||||
|
"heartbeat_gate_F9C4": memory.read8(0xF9C4),
|
||||||
|
"session_flags_FAA2": memory.read8(0xFAA2),
|
||||||
|
"pending_mask_FAA3": memory.read8(0xFAA3),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _loc_6206_selector_encode(value: int) -> int:
|
||||||
|
value &= 0x01FF
|
||||||
|
if value <= 0x007F:
|
||||||
|
return value
|
||||||
|
if value <= 0x017F:
|
||||||
|
return ((value - 0x0080) + 0x0100) & 0xFFFF
|
||||||
|
return ((value - 0x0180) + 0x0200) & 0xFFFF
|
||||||
|
|
||||||
|
|
||||||
|
def _swap_bytes(value: int) -> int:
|
||||||
|
value &= 0xFFFF
|
||||||
|
return ((value & 0x00FF) << 8) | ((value >> 8) & 0x00FF)
|
||||||
|
|
||||||
|
|
||||||
|
def _format_state_value(name: str, value: int) -> str:
|
||||||
|
width = 4 if name in {"queue_word", "current_table_word"} else 2
|
||||||
|
return f"0x{value:0{width}X}"
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ReportQueueProbeResult",
|
||||||
|
"build_expected_report_frame",
|
||||||
|
"encode_report_header",
|
||||||
|
"frame_checksum",
|
||||||
|
"main",
|
||||||
|
"report_payload_selector",
|
||||||
|
"run_report_queue_probe",
|
||||||
|
]
|
||||||
@@ -230,9 +230,13 @@ def _step_table_sweep(ctx: ScenarioContext, spec: dict[str, Any]) -> None:
|
|||||||
selectors = _selector_list(spec)
|
selectors = _selector_list(spec)
|
||||||
gap = float(spec.get("gap", 0.080))
|
gap = float(spec.get("gap", 0.080))
|
||||||
ack = _ack_config(spec.get("ack_on", {}))
|
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(
|
ctx.logger.event(
|
||||||
f"TABLE_SWEEP selectors={len(selectors)} gap={gap:.3f}s "
|
f"TABLE_SWEEP selectors={len(selectors)} gap={gap:.3f}s {ack_note}"
|
||||||
f"ack_targets={len(ack['targets'])} ack_frame={format_frame(ack['frame'])}"
|
|
||||||
)
|
)
|
||||||
for selector in selectors:
|
for selector in selectors:
|
||||||
if ctx.abort_requested:
|
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]:
|
def _ack_config(raw: Any) -> dict[str, Any]:
|
||||||
spec = raw if isinstance(raw, dict) else {}
|
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)))
|
targets = _parse_frame_list(spec.get("frames", spec.get("frame", DEFAULT_ACK_TARGET)))
|
||||||
|
if not enabled:
|
||||||
|
targets = set()
|
||||||
return {
|
return {
|
||||||
"targets": set(targets),
|
"targets": set(targets),
|
||||||
"frame": _parse_optional_frame(spec.get("ack_frame"), DEFAULT_ACK_FRAME),
|
"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)),
|
"poll_interval": float(spec.get("poll_interval", 0.005)),
|
||||||
"post_read": float(spec.get("post_ack_read", 0.250)),
|
"post_read": float(spec.get("post_ack_read", 0.250)),
|
||||||
"once_per_selector": bool(spec.get("once_per_selector", True)),
|
"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_acks": _optional_int(spec.get("max_acks")),
|
||||||
"max_target_hits": _optional_int(spec.get("max_target_hits")),
|
"max_target_hits": _optional_int(spec.get("max_target_hits")),
|
||||||
"abort_on_limit": bool(spec.get("abort_on_limit", True)),
|
"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):
|
for index, step in enumerate(_scenario_steps(scenario), start=1):
|
||||||
action, spec = _normalize_step(step)
|
action, spec = _normalize_step(step)
|
||||||
print(f"step[{index}]={action}", file=stdout)
|
print(f"step[{index}]={action}", file=stdout)
|
||||||
if action == "send":
|
_print_step_dry_run(action, spec, stdout)
|
||||||
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":
|
def _print_step_dry_run(action: str, spec: dict[str, Any], stdout: TextIO, *, indent: str = " ") -> None:
|
||||||
selectors = _selector_list(spec)
|
if action == "send":
|
||||||
ack = _ack_config(spec.get("ack_on", {}))
|
frame = _parse_required_frame(spec.get("frame"))
|
||||||
if selectors:
|
print(f"{indent}frame={format_frame(frame)} checksum_ok={int(frame_checksum_ok(frame))}", file=stdout)
|
||||||
first = selectors[0]
|
if float(spec.get("listen", 0.0)) > 0:
|
||||||
last = selectors[-1]
|
print(f"{indent}listen={float(spec.get('listen', 0.0)):.3f}s", file=stdout)
|
||||||
print(f" selectors={len(selectors)} first=0x{first:03X} last=0x{last:03X}", file=stdout)
|
elif action in {"drain", "listen", "wait"}:
|
||||||
else:
|
print(f"{indent}seconds={float(spec.get('seconds', spec.get('value', 0.0))):.3f}", file=stdout)
|
||||||
print(" selectors=0", file=stdout)
|
elif action == "wait_ready":
|
||||||
print(f" gap={float(spec.get('gap', 0.080)):.3f}", file=stdout)
|
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"]):
|
for target in sorted(ack["targets"]):
|
||||||
print(f" ack_target={format_frame(target)}", file=stdout)
|
print(f"{indent}ack_target={format_frame(target)}", file=stdout)
|
||||||
print(f" ack_frame={format_frame(ack['frame'])}", file=stdout)
|
print(f"{indent}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}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:
|
def _emit_summary(ctx: ScenarioContext, logger: BenchLogger) -> None:
|
||||||
|
|||||||
136
h8536/serial_scenario_unexpected.py
Normal file
136
h8536/serial_scenario_unexpected.py
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from collections import Counter
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Iterable, TextIO
|
||||||
|
|
||||||
|
|
||||||
|
DETECT_RE = re.compile(
|
||||||
|
r"^(?P<time>\d\d:\d\d:\d\d\.\d{3})\s+DETECT\s+"
|
||||||
|
r"(?:(?P<label>\S+)\s+)?(?P<frame>(?:[0-9A-Fa-f]{2}\s*){6})\s*$"
|
||||||
|
)
|
||||||
|
|
||||||
|
DEFAULT_IGNORED_LABELS = {
|
||||||
|
"heartbeat",
|
||||||
|
"connect_ok_path_response_candidate",
|
||||||
|
"connect_c0_path_response_candidate",
|
||||||
|
"table_readback_candidate",
|
||||||
|
"gated_active_0004_response_candidate",
|
||||||
|
"gated_active_0004_transition_candidate",
|
||||||
|
}
|
||||||
|
|
||||||
|
KNOWN_FRAME_LABELS = {
|
||||||
|
"00 00 15 80 00 CF": "known_call_button_active_report",
|
||||||
|
"00 00 15 00 00 4F": "known_call_button_inactive_report",
|
||||||
|
"00 00 07 80 00 DD": "known_cam_power_button_report",
|
||||||
|
"01 00 04 00 00 5F": "gated_active_0004_response_candidate",
|
||||||
|
"02 00 04 00 00 5C": "gated_active_0004_transition_candidate",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class DetectedFrame:
|
||||||
|
timestamp: str
|
||||||
|
label: str
|
||||||
|
frame: str
|
||||||
|
line_number: int
|
||||||
|
|
||||||
|
|
||||||
|
def build_arg_parser() -> argparse.ArgumentParser:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Show unexpected DETECT frames from a serial_scenario capture log."
|
||||||
|
)
|
||||||
|
parser.add_argument("log", type=Path, help="serial_scenario capture log")
|
||||||
|
parser.add_argument(
|
||||||
|
"--include-refresh",
|
||||||
|
action="store_true",
|
||||||
|
help="include heartbeat, table-readback, and CONNECT OK refresh frames",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--show-all",
|
||||||
|
action="store_true",
|
||||||
|
help="print every matching DETECT frame after the summary",
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv: list[str] | None = None, *, stdout: TextIO = sys.stdout) -> int:
|
||||||
|
args = build_arg_parser().parse_args(argv)
|
||||||
|
text = args.log.read_text(encoding="utf-8")
|
||||||
|
frames = parse_detected_frames(text.splitlines())
|
||||||
|
interesting = frames if args.include_refresh else filter_expected_refresh(frames)
|
||||||
|
print(format_report(frames, interesting, include_refresh=args.include_refresh, show_all=args.show_all), file=stdout)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def parse_detected_frames(lines: Iterable[str]) -> list[DetectedFrame]:
|
||||||
|
frames: list[DetectedFrame] = []
|
||||||
|
for line_number, line in enumerate(lines, start=1):
|
||||||
|
match = DETECT_RE.match(line.strip())
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
frame = " ".join(match.group("frame").upper().split())
|
||||||
|
label = KNOWN_FRAME_LABELS.get(frame, match.group("label") or "checksum_ok_unlabeled")
|
||||||
|
frames.append(
|
||||||
|
DetectedFrame(
|
||||||
|
timestamp=match.group("time"),
|
||||||
|
label=label,
|
||||||
|
frame=frame,
|
||||||
|
line_number=line_number,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return frames
|
||||||
|
|
||||||
|
|
||||||
|
def filter_expected_refresh(frames: Iterable[DetectedFrame]) -> list[DetectedFrame]:
|
||||||
|
return [frame for frame in frames if frame.label not in DEFAULT_IGNORED_LABELS]
|
||||||
|
|
||||||
|
|
||||||
|
def format_report(
|
||||||
|
frames: list[DetectedFrame],
|
||||||
|
interesting: list[DetectedFrame],
|
||||||
|
*,
|
||||||
|
include_refresh: bool,
|
||||||
|
show_all: bool,
|
||||||
|
) -> str:
|
||||||
|
lines = [
|
||||||
|
"Serial scenario unexpected-frame summary",
|
||||||
|
f"detected_frames={len(frames)} mode={'all' if include_refresh else 'unexpected-only'}",
|
||||||
|
]
|
||||||
|
label_counts = Counter(frame.label for frame in frames)
|
||||||
|
if label_counts:
|
||||||
|
lines.append("labels:")
|
||||||
|
for label, count in sorted(label_counts.items()):
|
||||||
|
lines.append(f" {label}: {count}")
|
||||||
|
ignored = len(frames) - len(interesting)
|
||||||
|
if not include_refresh:
|
||||||
|
lines.append(f"ignored_expected_refresh={ignored}")
|
||||||
|
lines.append(f"interesting_frames={len(interesting)}")
|
||||||
|
|
||||||
|
frame_counts = Counter((frame.frame, frame.label) for frame in interesting)
|
||||||
|
if frame_counts:
|
||||||
|
lines.append("interesting frame counts:")
|
||||||
|
for (frame_text, label), count in sorted(frame_counts.items(), key=lambda item: (-item[1], item[0][0])):
|
||||||
|
first = next(frame for frame in interesting if frame.frame == frame_text and frame.label == label)
|
||||||
|
lines.append(f" {count:4d}x {frame_text} label={label} first={first.timestamp} line={first.line_number}")
|
||||||
|
else:
|
||||||
|
lines.append("no unexpected checksum-valid frames found")
|
||||||
|
|
||||||
|
if show_all and interesting:
|
||||||
|
lines.append("timeline:")
|
||||||
|
for frame in interesting:
|
||||||
|
lines.append(f" {frame.timestamp} line={frame.line_number} {frame.frame} label={frame.label}")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"DetectedFrame",
|
||||||
|
"filter_expected_refresh",
|
||||||
|
"format_report",
|
||||||
|
"main",
|
||||||
|
"parse_detected_frames",
|
||||||
|
]
|
||||||
8
h8536_emulator_report_queue_probe.py
Normal file
8
h8536_emulator_report_queue_probe.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Compatibility wrapper for the H8/536 report-queue emulator probe."""
|
||||||
|
|
||||||
|
from h8536.emulator.report_queue_probe import main
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
52
scenarios/active-control-report-watch-broad.json
Normal file
52
scenarios/active-control-report-watch-broad.json
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"name": "active-control-report-watch-broad",
|
||||||
|
"notes": [
|
||||||
|
"Hold CONNECT OK while streaming broader camera/status words that may enable more local controls.",
|
||||||
|
"Press or turn one physical control at a time while this runs. Note the rough time and control name.",
|
||||||
|
"This is noisier than the quiet watch: each cycle writes 0x008F and 0x0093, so use the unexpected-frame summarizer after the run."
|
||||||
|
],
|
||||||
|
"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": 80,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "broad_refresh_008f_1800",
|
||||||
|
"frame": "00 01 0F 18 00 4C",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "broad_refresh_0093_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 1.50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
70
scenarios/active-control-report-watch-gated.json
Normal file
70
scenarios/active-control-report-watch-gated.json
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"name": "active-control-report-watch-gated",
|
||||||
|
"notes": [
|
||||||
|
"Hold CONNECT OK and seed candidate secondary-table E400 gates before watching for local-control TX reports.",
|
||||||
|
"This follows the ROM clue that some local report paths require E400 feature bits, not only E000 display/status words.",
|
||||||
|
"Press or turn one physical control at a time while this runs. Note the rough time and control name."
|
||||||
|
],
|
||||||
|
"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": "secondary_gate_0015_other_copy_candidate",
|
||||||
|
"frame": "06 00 15 80 00 C9",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "secondary_gate_008f_shutter_bits_11_12",
|
||||||
|
"frame": "06 01 0F 18 00 4A",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "secondary_gate_0093_all_bits",
|
||||||
|
"frame": "06 01 13 FF FF 4E",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 80,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "gated_refresh_008f_1800",
|
||||||
|
"frame": "00 01 0F 18 00 4C",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "gated_refresh_0093_90ff",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 0.30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 1.50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
46
scenarios/active-control-report-watch-quiet.json
Normal file
46
scenarios/active-control-report-watch-quiet.json
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"name": "active-control-report-watch-quiet",
|
||||||
|
"notes": [
|
||||||
|
"Hold the panel in CONNECT OK with the least noisy proven refresh stream, then watch for local-control TX reports.",
|
||||||
|
"Press or turn one physical control at a time while this runs. Note the rough time and control name.",
|
||||||
|
"Expected refresh traffic is table readback for 0x0093 plus 02 00 02 00 00 5A OK-path responses; anything else is interesting."
|
||||||
|
],
|
||||||
|
"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": 100,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "quiet_active_refresh_0093_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 1.50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
53
scenarios/copy-hold-006d-5x-006c.json
Normal file
53
scenarios/copy-hold-006d-5x-006c.json
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"name": "copy-hold-006d-5x-006c",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, send 006D every 1 second for five starts/progress ticks, then send 006C.",
|
||||||
|
"Tests whether repeated 006D can hold the copy-in-progress state for a longer transfer before completion."
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "power_cycle",
|
||||||
|
"off_seconds": 1.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_ready",
|
||||||
|
"timeout": 10.0,
|
||||||
|
"heartbeats": 2,
|
||||||
|
"require": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "drain",
|
||||||
|
"seconds": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_1",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_2",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_progress_006d",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_complete_candidate_006c",
|
||||||
|
"frame": "05 00 6C 00 00 33",
|
||||||
|
"listen": 10.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
51
scenarios/copy-hold-006d-5x-no-complete.json
Normal file
51
scenarios/copy-hold-006d-5x-no-complete.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "copy-hold-006d-5x-no-complete",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, send 006D every 1 second five times, then do not send 006C.",
|
||||||
|
"Tests whether the timeout/fallback is measured from the last 006D progress tick."
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "power_cycle",
|
||||||
|
"off_seconds": 1.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_ready",
|
||||||
|
"timeout": 10.0,
|
||||||
|
"heartbeats": 2,
|
||||||
|
"require": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "drain",
|
||||||
|
"seconds": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_1",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_2",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_progress_006d",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 10.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
53
scenarios/copy-repeat-006d-2x-006c.json
Normal file
53
scenarios/copy-repeat-006d-2x-006c.json
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"name": "copy-repeat-006d-2x-006c",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, send 006D twice one second apart, then send 006C.",
|
||||||
|
"Tests whether repeating the in-progress selector extends/resets the completion window or interferes with completion."
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "power_cycle",
|
||||||
|
"off_seconds": 1.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_ready",
|
||||||
|
"timeout": 10.0,
|
||||||
|
"heartbeats": 2,
|
||||||
|
"require": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "drain",
|
||||||
|
"seconds": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_1",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_2",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_start_006d_1",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_start_006d_2",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_complete_candidate_006c",
|
||||||
|
"frame": "05 00 6C 00 00 33",
|
||||||
|
"listen": 10.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
59
scenarios/copy-repeat-006d-3x-006c.json
Normal file
59
scenarios/copy-repeat-006d-3x-006c.json
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"name": "copy-repeat-006d-3x-006c",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, send 006D three times one second apart, then send 006C.",
|
||||||
|
"Tests whether repeated in-progress selectors can keep the copy state alive longer than the single-start window."
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "power_cycle",
|
||||||
|
"off_seconds": 1.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_ready",
|
||||||
|
"timeout": 10.0,
|
||||||
|
"heartbeats": 2,
|
||||||
|
"require": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "drain",
|
||||||
|
"seconds": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_1",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_2",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_start_006d_1",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_start_006d_2",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_start_006d_3",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_complete_candidate_006c",
|
||||||
|
"frame": "05 00 6C 00 00 33",
|
||||||
|
"listen": 10.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
47
scenarios/copy-step-006d-006c-1500ms.json
Normal file
47
scenarios/copy-step-006d-006c-1500ms.json
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "copy-step-006d-006c-1500ms",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, send 006D, then send 006C 1.5 seconds later.",
|
||||||
|
"Narrows the working copy-complete window between the known 1.0s success and 2.5s failure."
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "power_cycle",
|
||||||
|
"off_seconds": 1.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_ready",
|
||||||
|
"timeout": 10.0,
|
||||||
|
"heartbeats": 2,
|
||||||
|
"require": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "drain",
|
||||||
|
"seconds": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_1",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_2",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_start_006d",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 1.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_complete_candidate_006c",
|
||||||
|
"frame": "05 00 6C 00 00 33",
|
||||||
|
"listen": 10.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
47
scenarios/copy-step-006d-006c-2000ms.json
Normal file
47
scenarios/copy-step-006d-006c-2000ms.json
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "copy-step-006d-006c-2000ms",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, send 006D, then send 006C 2.0 seconds later.",
|
||||||
|
"Narrows the copy-complete acceptance window before the known 2.5s failure."
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "power_cycle",
|
||||||
|
"off_seconds": 1.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_ready",
|
||||||
|
"timeout": 10.0,
|
||||||
|
"heartbeats": 2,
|
||||||
|
"require": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "drain",
|
||||||
|
"seconds": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_1",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_baseline_2",
|
||||||
|
"frame": "04 00 00 80 00 DE",
|
||||||
|
"listen": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_start_006d",
|
||||||
|
"frame": "05 00 6D 00 00 32",
|
||||||
|
"listen": 2.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "copy_complete_candidate_006c",
|
||||||
|
"frame": "05 00 6C 00 00 33",
|
||||||
|
"listen": 10.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
100
scenarios/knee-detail-physical-button-watch.json
Normal file
100
scenarios/knee-detail-physical-button-watch.json
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
{
|
||||||
|
"name": "knee-detail-physical-button-watch",
|
||||||
|
"notes": [
|
||||||
|
"Create clean watch windows for the physical DETAIL and KNEE buttons near the LCD.",
|
||||||
|
"The ROM trace suggests these buttons may be the missing F104 panel-input transition into loc_1795.",
|
||||||
|
"Watch the console labels and LCD. During the labeled windows, press DETAIL, KNEE, then DETAIL/KNEE alternately."
|
||||||
|
],
|
||||||
|
"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": "ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "prepare_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "prepare_00b9_bit13_gate",
|
||||||
|
"frame": "00 01 39 20 00 42",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 5.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "read_00bc_after_detail_press_window",
|
||||||
|
"frame": "01 01 3C 00 00 66",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "refresh_00b9_bit13_gate_for_knee_press",
|
||||||
|
"frame": "00 01 39 20 00 42",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 5.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "read_00bc_after_knee_press_window",
|
||||||
|
"frame": "01 01 3C 00 00 66",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "prepare_00b9_a0_for_page_label_watch",
|
||||||
|
"frame": "00 01 39 A0 00 C2",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 6.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "prepare_0110_dl_override_then_press_buttons",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 6.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "final_read_00bc",
|
||||||
|
"frame": "01 01 3C 00 00 66",
|
||||||
|
"listen": 0.80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
206
scenarios/knee-rom-dtl-knee-isolation.json
Normal file
206
scenarios/knee-rom-dtl-knee-isolation.json
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
{
|
||||||
|
"name": "knee-rom-dtl-knee-isolation",
|
||||||
|
"notes": [
|
||||||
|
"Isolate which ROM-derived KNEE selector sequence creates the bench DTL/KNEE LCD state.",
|
||||||
|
"Record the exact case label visible in the console when DTL/KNEE appears or disappears.",
|
||||||
|
"Cases separate 0x00B9.13 gate, 0x00B9.15 label bit, and 0x0110.15 timed override."
|
||||||
|
],
|
||||||
|
"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": "case_a_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_a_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_a_clear_00b9",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_a_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_a_set_00b9_bit13_only_watch_dtl_knee",
|
||||||
|
"frame": "00 01 39 20 00 42",
|
||||||
|
"listen": 3.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "case_b_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_b_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_b_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_b_set_00b9_bits15_and_13_watch_dtl_knee",
|
||||||
|
"frame": "00 01 39 A0 00 C2",
|
||||||
|
"listen": 3.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "case_c_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_c_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_c_clear_00b9",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_c_set_0110_bit15_only_watch_dtl_knee",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 3.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "case_d_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_d_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_d_set_00b9_bit13_then_0110_override_part1",
|
||||||
|
"frame": "00 01 39 20 00 42",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_d_set_0110_bit15_after_00b9_bit13_watch_dtl_knee",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 3.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "case_e_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_e_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_e_set_00b9_a0_then_0110_override_part1",
|
||||||
|
"frame": "00 01 39 A0 00 C2",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_e_set_0110_bit15_after_00b9_a0_watch_dtl_knee",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 3.00
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
132
scenarios/knee-rom-gate-and-value-probe.json
Normal file
132
scenarios/knee-rom-gate-and-value-probe.json
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"name": "knee-rom-gate-and-value-probe",
|
||||||
|
"notes": [
|
||||||
|
"Probe the ROM-derived KNEE model from docs/pt2-knee-rom-trace.md.",
|
||||||
|
"The key correction is that 0x00B9.13 gates the live KNEE value/report branch, while 0x0110.15 forces the timed KNEE page.",
|
||||||
|
"Serial writes may only prepare the state. If the panel has a KNEE-related control, move it during the long gate windows and watch for selector 0x00BC reports or visible KNEE changes."
|
||||||
|
],
|
||||||
|
"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": "ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "clear_00b9",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "read_00bc_baseline",
|
||||||
|
"frame": "01 01 3C 00 00 66",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "set_00b9_bit13_gate_move_knee_control_if_possible",
|
||||||
|
"frame": "00 01 39 20 00 42",
|
||||||
|
"listen": 4.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "read_00bc_after_gate_window",
|
||||||
|
"frame": "01 01 3C 00 00 66",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "set_00b9_bits15_and_13_preset_label_plus_gate",
|
||||||
|
"frame": "00 01 39 A0 00 C2",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "set_0110_bit15_dl_timed_page_override",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 2.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "clear_0110_return_to_value_path",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "read_00bc_after_override_clear",
|
||||||
|
"frame": "01 01 3C 00 00 66",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 2,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "00bc_direct_low_probe",
|
||||||
|
"frame": "00 01 3C 00 00 67",
|
||||||
|
"listen": 0.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "00bc_direct_mid_probe",
|
||||||
|
"frame": "00 01 3C 40 00 27",
|
||||||
|
"listen": 0.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "00bc_direct_high_probe",
|
||||||
|
"frame": "00 01 3C 80 00 E7",
|
||||||
|
"listen": 0.35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "read_00bc_direct_probe",
|
||||||
|
"frame": "01 01 3C 00 00 66",
|
||||||
|
"listen": 0.50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "final_clear_00b9",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "final_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
160
scenarios/lamp-0093-lowbyte-sweep.json
Normal file
160
scenarios/lamp-0093-lowbyte-sweep.json
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-0093-lowbyte-sweep",
|
||||||
|
"notes": [
|
||||||
|
"Hold CONNECT OK and vary only the low byte of E000[0x0093] while keeping high byte 0x90.",
|
||||||
|
"Record white-balance AUTO/PRESET/MANUAL, black/flare AUTO/MANUAL/FLARE, iris AUTO, shutter display, and LCD.",
|
||||||
|
"Known references: 0x9020 has behaved like a black/flare manual context; 0x90FF has produced black/flare auto toggles."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 2,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9000",
|
||||||
|
"frame": "00 01 13 90 00 D8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9000",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9001",
|
||||||
|
"frame": "00 01 13 90 01 D9",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9001",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9002",
|
||||||
|
"frame": "00 01 13 90 02 DA",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9002",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9004",
|
||||||
|
"frame": "00 01 13 90 04 DC",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9004",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9008",
|
||||||
|
"frame": "00 01 13 90 08 D0",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9008",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9010",
|
||||||
|
"frame": "00 01 13 90 10 C8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9010",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9040",
|
||||||
|
"frame": "00 01 13 90 40 98",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9040",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0093_9080",
|
||||||
|
"frame": "00 01 13 90 80 58",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_9080",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "positive_0093_90ff",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 0.55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "baseline_0093_9020_after_90ff",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.55
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
184
scenarios/lamp-broad-status-selector-sweep.json
Normal file
184
scenarios/lamp-broad-status-selector-sweep.json
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-broad-status-selector-sweep",
|
||||||
|
"notes": [
|
||||||
|
"Cautious broader primary-table sweep for ROM-mined status selectors that may drive lamps/readouts.",
|
||||||
|
"Each selector is tested with 0x8000 then 0xFFFF, followed by 0x0000 clear. Record visible lamp/readout changes inside each short window.",
|
||||||
|
"If the panel enters CONNECT NOT ACT, stop the run and note the selector label immediately before the transition."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0003_default_high",
|
||||||
|
"frame": "00 00 03 80 00 D9",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0003_all_bits",
|
||||||
|
"frame": "00 00 03 FF FF 59",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0003_clear",
|
||||||
|
"frame": "00 00 03 00 00 59",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0040_high",
|
||||||
|
"frame": "00 00 40 80 00 9A",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0040_all_bits",
|
||||||
|
"frame": "00 00 40 FF FF 1A",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0040_clear",
|
||||||
|
"frame": "00 00 40 00 00 1A",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0081_high",
|
||||||
|
"frame": "00 01 01 80 00 DA",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0081_all_bits",
|
||||||
|
"frame": "00 01 01 FF FF 5A",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0081_clear",
|
||||||
|
"frame": "00 01 01 00 00 5A",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0092_high",
|
||||||
|
"frame": "00 01 12 80 00 C9",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0092_all_bits",
|
||||||
|
"frame": "00 01 12 FF FF 49",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0092_clear",
|
||||||
|
"frame": "00 01 12 00 00 49",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00a7_high",
|
||||||
|
"frame": "00 01 27 80 00 FC",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00a7_all_bits",
|
||||||
|
"frame": "00 01 27 FF FF 7C",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00a7_clear",
|
||||||
|
"frame": "00 01 27 00 00 7C",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b7_high",
|
||||||
|
"frame": "00 01 37 80 00 EC",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b7_all_bits",
|
||||||
|
"frame": "00 01 37 FF FF 6C",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b7_clear",
|
||||||
|
"frame": "00 01 37 00 00 6C",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b9_high",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b9_all_bits",
|
||||||
|
"frame": "00 01 39 FF FF 62",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b9_clear",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0110_high",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0110_all_bits",
|
||||||
|
"frame": "00 01 90 FF FF CB",
|
||||||
|
"listen": 0.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0110_clear",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
82
scenarios/lamp-isolate-cam-call.json
Normal file
82
scenarios/lamp-isolate-cam-call.json
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-isolate-cam-call",
|
||||||
|
"notes": [
|
||||||
|
"Isolate the two strongest known button/lamp selectors from the previous probe.",
|
||||||
|
"Record whether 0x0007 high/low maps to CAM POWER and whether 0x0015 high/low maps to CALL.",
|
||||||
|
"Each state is held long enough to see a visible lamp transition while staying below the usual inactive timeout."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 3,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "cam_candidate_0007_high",
|
||||||
|
"frame": "00 00 07 80 00 DD",
|
||||||
|
"listen": 1.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "cam_candidate_0007_low",
|
||||||
|
"frame": "00 00 07 00 00 5D",
|
||||||
|
"listen": 0.85
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_refresh_before_call",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 3,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "call_candidate_0015_high",
|
||||||
|
"frame": "00 00 15 80 00 CF",
|
||||||
|
"listen": 1.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "call_candidate_0015_low",
|
||||||
|
"frame": "00 00 15 00 00 4F",
|
||||||
|
"listen": 0.85
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
206
scenarios/lamp-isolate-knee-bit-scan.json
Normal file
206
scenarios/lamp-isolate-knee-bit-scan.json
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-isolate-knee-bit-scan",
|
||||||
|
"notes": [
|
||||||
|
"Bit-scan the two fresh-boot KNEE AUTO candidates, 0x00B9 and 0x0110.",
|
||||||
|
"Each selector gets its own fresh CONNECT OK seed, then high-byte bits are tested one at a time with clears between writes.",
|
||||||
|
"Record whether KNEE AUTO, KNEE manual, or any neighboring paint/detail lamp changes during each label."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1_for_00b9",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_00b9",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_bit15_watch",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_bit15",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_bit14_watch",
|
||||||
|
"frame": "00 01 39 40 00 22",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_bit14",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_bit13_watch",
|
||||||
|
"frame": "00 01 39 20 00 42",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_bit13",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_bit12_watch",
|
||||||
|
"frame": "00 01 39 10 00 72",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_bit12",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_bit11_watch",
|
||||||
|
"frame": "00 01 39 08 00 6A",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_bit11",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_lowff_watch",
|
||||||
|
"frame": "00 01 39 00 FF 9D",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_lowff",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_0110",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0110",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_bit15_watch",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_bit15",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_bit14_watch",
|
||||||
|
"frame": "00 01 90 40 00 8B",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_bit14",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_bit13_watch",
|
||||||
|
"frame": "00 01 90 20 00 EB",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_bit13",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_bit12_watch",
|
||||||
|
"frame": "00 01 90 10 00 DB",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_bit12",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_bit11_watch",
|
||||||
|
"frame": "00 01 90 08 00 C3",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_bit11",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_lowff_watch",
|
||||||
|
"frame": "00 01 90 00 FF 34",
|
||||||
|
"listen": 1.30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_lowff",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
232
scenarios/lamp-isolate-knee-status-selectors.json
Normal file
232
scenarios/lamp-isolate-knee-status-selectors.json
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-isolate-knee-status-selectors",
|
||||||
|
"notes": [
|
||||||
|
"Isolate broad status selectors after the prior sweep made the KNEE AUTO lamp flash.",
|
||||||
|
"Each candidate is tested high, clear, all-bits, clear. Record the exact console label when KNEE AUTO changes.",
|
||||||
|
"Stop early if the panel latches or falls out of CONNECT OK."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0003_high",
|
||||||
|
"frame": "00 00 03 80 00 D9",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0003_clear_after_high",
|
||||||
|
"frame": "00 00 03 00 00 59",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0003_all_bits",
|
||||||
|
"frame": "00 00 03 FF FF 59",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0003_clear_after_all",
|
||||||
|
"frame": "00 00 03 00 00 59",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0040_high",
|
||||||
|
"frame": "00 00 40 80 00 9A",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0040_clear_after_high",
|
||||||
|
"frame": "00 00 40 00 00 1A",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0040_all_bits",
|
||||||
|
"frame": "00 00 40 FF FF 1A",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0040_clear_after_all",
|
||||||
|
"frame": "00 00 40 00 00 1A",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0081_high",
|
||||||
|
"frame": "00 01 01 80 00 DA",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0081_clear_after_high",
|
||||||
|
"frame": "00 01 01 00 00 5A",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0081_all_bits",
|
||||||
|
"frame": "00 01 01 FF FF 5A",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0081_clear_after_all",
|
||||||
|
"frame": "00 01 01 00 00 5A",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0092_high",
|
||||||
|
"frame": "00 01 12 80 00 C9",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0092_clear_after_high",
|
||||||
|
"frame": "00 01 12 00 00 49",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0092_all_bits",
|
||||||
|
"frame": "00 01 12 FF FF 49",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0092_clear_after_all",
|
||||||
|
"frame": "00 01 12 00 00 49",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00a7_high",
|
||||||
|
"frame": "00 01 27 80 00 FC",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00a7_clear_after_high",
|
||||||
|
"frame": "00 01 27 00 00 7C",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00a7_all_bits",
|
||||||
|
"frame": "00 01 27 FF FF 7C",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00a7_clear_after_all",
|
||||||
|
"frame": "00 01 27 00 00 7C",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b7_high",
|
||||||
|
"frame": "00 01 37 80 00 EC",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b7_clear_after_high",
|
||||||
|
"frame": "00 01 37 00 00 6C",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b7_all_bits",
|
||||||
|
"frame": "00 01 37 FF FF 6C",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b7_clear_after_all",
|
||||||
|
"frame": "00 01 37 00 00 6C",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b9_high",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b9_clear_after_high",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b9_all_bits",
|
||||||
|
"frame": "00 01 39 FF FF 62",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_00b9_clear_after_all",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0110_high",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0110_clear_after_high",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0110_all_bits",
|
||||||
|
"frame": "00 01 90 FF FF CB",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0110_clear_after_all",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
260
scenarios/lamp-isolate-knee-tail-single-boot.json
Normal file
260
scenarios/lamp-isolate-knee-tail-single-boot.json
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-isolate-knee-tail-single-boot",
|
||||||
|
"notes": [
|
||||||
|
"Fresh-boot isolation for the late broad-status candidates after KNEE AUTO appeared toward the end of the previous run.",
|
||||||
|
"Selector 0x0092 is included as a guard before the stronger tail candidates 0x00A7, 0x00B7, 0x00B9, and 0x0110.",
|
||||||
|
"Each candidate tests high, clear, all bits, clear."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1_for_0092",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0092",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0092_high_watch",
|
||||||
|
"frame": "00 01 12 80 00 C9",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0092_clear_after_high",
|
||||||
|
"frame": "00 01 12 00 00 49",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0092_all_bits_watch",
|
||||||
|
"frame": "00 01 12 FF FF 49",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0092_clear_after_all",
|
||||||
|
"frame": "00 01 12 00 00 49",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_00a7",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_00a7",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00a7_high_watch",
|
||||||
|
"frame": "00 01 27 80 00 FC",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00a7_clear_after_high",
|
||||||
|
"frame": "00 01 27 00 00 7C",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00a7_all_bits_watch",
|
||||||
|
"frame": "00 01 27 FF FF 7C",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00a7_clear_after_all",
|
||||||
|
"frame": "00 01 27 00 00 7C",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_00b7",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_00b7",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b7_high_watch",
|
||||||
|
"frame": "00 01 37 80 00 EC",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b7_clear_after_high",
|
||||||
|
"frame": "00 01 37 00 00 6C",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b7_all_bits_watch",
|
||||||
|
"frame": "00 01 37 FF FF 6C",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b7_clear_after_all",
|
||||||
|
"frame": "00 01 37 00 00 6C",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_00b9",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_00b9",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_high_watch",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_high",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_all_bits_watch",
|
||||||
|
"frame": "00 01 39 FF FF 62",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_00b9_clear_after_all",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_0110",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0110",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_high_watch",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_high",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_all_bits_watch",
|
||||||
|
"frame": "00 01 90 FF FF CB",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0110_clear_after_all",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.90
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
118
scenarios/lamp-isolate-known-neighbors.json
Normal file
118
scenarios/lamp-isolate-known-neighbors.json
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-isolate-known-neighbors",
|
||||||
|
"notes": [
|
||||||
|
"Isolate ROM dispatch neighbors that caused BARS, MASTER, and camera tally changes in the prior run.",
|
||||||
|
"Watch the console label and record exact mappings such as selector_0018_high -> tally red.",
|
||||||
|
"Each selector is tested high then low twice."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 2,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0012_high",
|
||||||
|
"frame": "00 00 12 80 00 C8",
|
||||||
|
"listen": 1.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0012_low",
|
||||||
|
"frame": "00 00 12 00 00 48",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0013_high",
|
||||||
|
"frame": "00 00 13 80 00 C9",
|
||||||
|
"listen": 1.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0013_low",
|
||||||
|
"frame": "00 00 13 00 00 49",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0016_high",
|
||||||
|
"frame": "00 00 16 80 00 CC",
|
||||||
|
"listen": 1.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0016_low",
|
||||||
|
"frame": "00 00 16 00 00 4C",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0017_high",
|
||||||
|
"frame": "00 00 17 80 00 CD",
|
||||||
|
"listen": 1.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0017_low",
|
||||||
|
"frame": "00 00 17 00 00 4D",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0018_high",
|
||||||
|
"frame": "00 00 18 80 00 C2",
|
||||||
|
"listen": 1.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_0018_low",
|
||||||
|
"frame": "00 00 18 00 00 42",
|
||||||
|
"listen": 0.70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_001a_high",
|
||||||
|
"frame": "00 00 1A 80 00 C0",
|
||||||
|
"listen": 1.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_001a_low",
|
||||||
|
"frame": "00 00 1A 00 00 40",
|
||||||
|
"listen": 0.70
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
238
scenarios/lamp-isolate-neighbor-single-boot.json
Normal file
238
scenarios/lamp-isolate-neighbor-single-boot.json
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-isolate-neighbor-single-boot",
|
||||||
|
"notes": [
|
||||||
|
"Fresh-boot isolation for the selector cluster that produced SLAVE, green tally, BARS, MASTER, and related lamps.",
|
||||||
|
"Each candidate starts from a fresh power cycle and CONNECT OK seed so latched lamps from the previous selector cannot contaminate the result.",
|
||||||
|
"Record the visible lamp during the high hold and whether the low write clears it."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1_for_0012",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0012",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0012_high_watch",
|
||||||
|
"frame": "00 00 12 80 00 C8",
|
||||||
|
"listen": 2.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0012_low_clear_watch",
|
||||||
|
"frame": "00 00 12 00 00 48",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_0013",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0013",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0013_high_watch",
|
||||||
|
"frame": "00 00 13 80 00 C9",
|
||||||
|
"listen": 2.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0013_low_clear_watch",
|
||||||
|
"frame": "00 00 13 00 00 49",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_0016",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0016",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0016_high_watch",
|
||||||
|
"frame": "00 00 16 80 00 CC",
|
||||||
|
"listen": 2.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0016_low_clear_watch",
|
||||||
|
"frame": "00 00 16 00 00 4C",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_0017",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0017",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0017_high_watch",
|
||||||
|
"frame": "00 00 17 80 00 CD",
|
||||||
|
"listen": 2.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0017_low_clear_watch",
|
||||||
|
"frame": "00 00 17 00 00 4D",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_0018",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_0018",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0018_high_watch",
|
||||||
|
"frame": "00 00 18 80 00 C2",
|
||||||
|
"listen": 2.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_0018_low_clear_watch",
|
||||||
|
"frame": "00 00 18 00 00 42",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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_ok_seed_1_for_001a",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2_for_001a",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_001a_high_watch",
|
||||||
|
"frame": "00 00 1A 80 00 C0",
|
||||||
|
"listen": 2.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_001a_low_clear_watch",
|
||||||
|
"frame": "00 00 1A 00 00 40",
|
||||||
|
"listen": 1.20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
110
scenarios/lamp-knee-context-hold.json
Normal file
110
scenarios/lamp-knee-context-hold.json
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-knee-context-hold",
|
||||||
|
"notes": [
|
||||||
|
"Test whether the known quiet active refresh context lets KNEE AUTO stay on.",
|
||||||
|
"The prior sustain test showed repeated 0x00B9.15 never lit KNEE AUTO, while repeated 0x0110.15 lit it then cleared around mid-window.",
|
||||||
|
"This pairs each KNEE candidate with the proven 0x0093=0x9020 active refresh stream."
|
||||||
|
],
|
||||||
|
"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": "case_00b9_context_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_00b9_context_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 10,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "context_0093_9020_refresh_for_00b9",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "context_00b9_bit15_knee_test",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 0.35
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "clear_00b9_with_context_watch",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 1.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "case_0110_context_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_0110_context_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 10,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "context_0093_9020_refresh_for_0110",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "context_0110_bit15_knee_test",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 0.35
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "clear_0110_with_context_watch",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.00
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
116
scenarios/lamp-knee-edge-refresh.json
Normal file
116
scenarios/lamp-knee-edge-refresh.json
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-knee-edge-refresh",
|
||||||
|
"notes": [
|
||||||
|
"Test whether KNEE AUTO needs a low-to-high edge on 0x0110.15 rather than repeated high writes.",
|
||||||
|
"The context-hold test kept active serial responses alive, but KNEE AUTO still turned off mid-run.",
|
||||||
|
"This alternates clear/set for 0x0110.15, first by itself and then with 0x0093=0x9020 context refresh."
|
||||||
|
],
|
||||||
|
"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": "edge_only_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_only_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 10,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_only_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_only_set_0110_bit15_watch",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 0.42
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_only_final_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "edge_context_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_context_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 10,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_context_0093_9020_refresh",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_context_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 0.16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_context_set_0110_bit15_watch",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 0.34
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "edge_context_final_clear_0110",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.00
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
110
scenarios/lamp-knee-or-precedence.json
Normal file
110
scenarios/lamp-knee-or-precedence.json
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-knee-or-precedence",
|
||||||
|
"notes": [
|
||||||
|
"Test whether KNEE AUTO is an OR of 0x00B9.15 and 0x0110.15, or whether latest-write/hidden precedence matters.",
|
||||||
|
"Case 1 sets 0x00B9.15, then 0x0110.15, then clears 0x00B9 while 0x0110 remains set.",
|
||||||
|
"Case 2 sets 0x0110.15, then 0x00B9.15, then clears 0x0110 while 0x00B9 remains set."
|
||||||
|
],
|
||||||
|
"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": "case1_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case1_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case1_set_00b9_bit15_watch_knee_auto",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case1_set_0110_bit15_while_00b9_still_set",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case1_clear_00b9_watch_if_knee_stays_on",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case1_clear_0110_watch_knee_off",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "case2_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case2_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case2_set_0110_bit15_watch_knee_auto",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case2_set_00b9_bit15_while_0110_still_set",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case2_clear_0110_watch_if_knee_stays_on",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case2_clear_00b9_watch_knee_off",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 1.20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
98
scenarios/lamp-knee-sustain-compare.json
Normal file
98
scenarios/lamp-knee-sustain-compare.json
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-knee-sustain-compare",
|
||||||
|
"notes": [
|
||||||
|
"Compare how long KNEE AUTO stays lit from repeated 0x00B9.15 versus repeated 0x0110.15 refreshes.",
|
||||||
|
"This follows the precedence result where clearing 0x0110 turned KNEE AUTO off even after 0x00B9 had been set.",
|
||||||
|
"Record whether each repeated-refresh phase holds KNEE AUTO continuously or only flashes it."
|
||||||
|
],
|
||||||
|
"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": "case_00b9_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_00b9_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "refresh_00b9_bit15_hold_test",
|
||||||
|
"frame": "00 01 39 80 00 E2",
|
||||||
|
"listen": 0.55
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "clear_00b9_watch_knee_off",
|
||||||
|
"frame": "00 01 39 00 00 62",
|
||||||
|
"listen": 1.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "case_0110_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "case_0110_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "refresh_0110_bit15_hold_test",
|
||||||
|
"frame": "00 01 90 80 00 4B",
|
||||||
|
"listen": 0.55
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "clear_0110_watch_knee_off",
|
||||||
|
"frame": "00 01 90 00 00 CB",
|
||||||
|
"listen": 1.50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
136
scenarios/lamp-known-button-selector-probe.json
Normal file
136
scenarios/lamp-known-button-selector-probe.json
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
{
|
||||||
|
"name": "lamp-known-button-selector-probe",
|
||||||
|
"notes": [
|
||||||
|
"Probe host writes to selector families already tied to autonomous CAM POWER and CALL reports, plus nearby ROM dispatch entries.",
|
||||||
|
"Record CAM POWER, CALL, BARS, AUTO buttons, and any lamp/display movement immediately during each hold.",
|
||||||
|
"This script avoids command 5 copy/latch selectors; it only writes command-0 primary table values."
|
||||||
|
],
|
||||||
|
"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_ok_seed_1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_seed_2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "cam_power_candidate_0007_high",
|
||||||
|
"frame": "00 00 07 80 00 DD",
|
||||||
|
"listen": 1.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "cam_power_candidate_0007_low",
|
||||||
|
"frame": "00 00 07 00 00 5D",
|
||||||
|
"listen": 1.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "call_candidate_0015_high",
|
||||||
|
"frame": "00 00 15 80 00 CF",
|
||||||
|
"listen": 1.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "call_candidate_0015_low",
|
||||||
|
"frame": "00 00 15 00 00 4F",
|
||||||
|
"listen": 1.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0012_high",
|
||||||
|
"frame": "00 00 12 80 00 C8",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0012_low",
|
||||||
|
"frame": "00 00 12 00 00 48",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0013_high",
|
||||||
|
"frame": "00 00 13 80 00 C9",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0013_low",
|
||||||
|
"frame": "00 00 13 00 00 49",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0016_high",
|
||||||
|
"frame": "00 00 16 80 00 CC",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0016_low",
|
||||||
|
"frame": "00 00 16 00 00 4C",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0017_high",
|
||||||
|
"frame": "00 00 17 80 00 CD",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0017_low",
|
||||||
|
"frame": "00 00 17 00 00 4D",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0018_high",
|
||||||
|
"frame": "00 00 18 80 00 C2",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_0018_low",
|
||||||
|
"frame": "00 00 18 00 00 42",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_001a_high",
|
||||||
|
"frame": "00 00 1A 80 00 C0",
|
||||||
|
"listen": 0.90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "neighbor_001a_low",
|
||||||
|
"frame": "00 00 1A 00 00 40",
|
||||||
|
"listen": 0.50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
49
scenarios/others-copy-gate-probe.json
Normal file
49
scenarios/others-copy-gate-probe.json
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "others-copy-gate-probe",
|
||||||
|
"notes": [
|
||||||
|
"Recover toward CONNECT OK, seed the OTHERS root soft-key bits, then try to set the page-1 COPY TO SLAVES visibility gate.",
|
||||||
|
"Press the panel OTHER/COPY controls during the final listen window and record the LCD/lamp result.",
|
||||||
|
"The command-6 E400 write only works if the ROM is in a live continuation/report window.",
|
||||||
|
"ROM trace also shows a second local COPY-start gate at F791.7; if that is clear, the panel can divert to SET RCP / MASTER instead of COPY."
|
||||||
|
],
|
||||||
|
"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.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "others_root_e000_008f_bits11_12",
|
||||||
|
"frame": "00 01 0F 18 00 4C",
|
||||||
|
"listen": 0.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_for",
|
||||||
|
"frame": "02 00 02 00 00 5A",
|
||||||
|
"timeout": 1.5,
|
||||||
|
"require": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "others_copy_e400_0015_gate",
|
||||||
|
"frame": "06 00 15 00 01 48",
|
||||||
|
"listen": 8.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
scenarios/others-isolate-008f-bit11.json
Normal file
35
scenarios/others-isolate-008f-bit11.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "others-isolate-008f-bit11",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, then write only E000[0x008F].11.",
|
||||||
|
"Use this to isolate whether bit 11 alone changes the shutter display, iris AUTO lamp, or OTHERS soft-key state."
|
||||||
|
],
|
||||||
|
"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.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_008f_bit11_only",
|
||||||
|
"frame": "00 01 0F 08 00 5C",
|
||||||
|
"listen": 8.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
scenarios/others-isolate-008f-bit12.json
Normal file
35
scenarios/others-isolate-008f-bit12.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "others-isolate-008f-bit12",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, then write only E000[0x008F].12.",
|
||||||
|
"Use this to isolate whether bit 12 alone changes the shutter display, iris AUTO lamp, or OTHERS soft-key state."
|
||||||
|
],
|
||||||
|
"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.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_008f_bit12_only",
|
||||||
|
"frame": "00 01 0F 10 00 44",
|
||||||
|
"listen": 8.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
scenarios/others-isolate-008f-bits11-12.json
Normal file
35
scenarios/others-isolate-008f-bits11-12.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "others-isolate-008f-bits11-12",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, then write E000[0x008F].11 and .12 together.",
|
||||||
|
"This repeats the first half of others-copy-gate-probe without the E400[0x0015] write."
|
||||||
|
],
|
||||||
|
"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.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_008f_bits11_12",
|
||||||
|
"frame": "00 01 0F 18 00 4C",
|
||||||
|
"listen": 8.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
47
scenarios/others-isolate-008f-then-e400-clear.json
Normal file
47
scenarios/others-isolate-008f-then-e400-clear.json
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "others-isolate-008f-then-e400-clear",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, write E000[0x008F]=0x1800, then write E400[0x0015]=0x0000 in the live window.",
|
||||||
|
"This is the control case for others-copy-gate-probe: same root bits, but COPY visibility cleared instead of set."
|
||||||
|
],
|
||||||
|
"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.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_008f_bits11_12",
|
||||||
|
"frame": "00 01 0F 18 00 4C",
|
||||||
|
"listen": 0.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_for",
|
||||||
|
"frame": "02 00 02 00 00 5A",
|
||||||
|
"timeout": 1.5,
|
||||||
|
"require": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e400_0015_clear",
|
||||||
|
"frame": "06 00 15 00 00 49",
|
||||||
|
"listen": 8.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
41
scenarios/others-isolate-e400-0015-high.json
Normal file
41
scenarios/others-isolate-e400-0015-high.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "others-isolate-e400-0015-high",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, wait for the live 02 report window, then write E400[0x0015]=0x8000.",
|
||||||
|
"This tests whether the high bit of the same secondary selector behaves differently from 0x0001."
|
||||||
|
],
|
||||||
|
"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.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_for",
|
||||||
|
"frame": "02 00 02 00 00 5A",
|
||||||
|
"timeout": 1.5,
|
||||||
|
"require": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e400_0015_high_nonzero",
|
||||||
|
"frame": "06 00 15 80 00 C9",
|
||||||
|
"listen": 8.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
41
scenarios/others-isolate-e400-0015-low.json
Normal file
41
scenarios/others-isolate-e400-0015-low.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "others-isolate-e400-0015-low",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, wait for the live 02 report window, then write E400[0x0015]=0x0001.",
|
||||||
|
"This isolates the command-6 secondary-table write from the E000[0x008F] write."
|
||||||
|
],
|
||||||
|
"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.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "wait_for",
|
||||||
|
"frame": "02 00 02 00 00 5A",
|
||||||
|
"timeout": 1.5,
|
||||||
|
"require": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e400_0015_low_nonzero",
|
||||||
|
"frame": "06 00 15 00 01 48",
|
||||||
|
"listen": 8.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
48
scenarios/shutter-008f-evs-clear-control.json
Normal file
48
scenarios/shutter-008f-evs-clear-control.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
36
scenarios/shutter-008f-evs-timeout-control.json
Normal file
36
scenarios/shutter-008f-evs-timeout-control.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
236
scenarios/shutter-0093-bit-isolation.json
Normal file
236
scenarios/shutter-0093-bit-isolation.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
436
scenarios/shutter-0093-blackflare-auto-candidates.json
Normal file
436
scenarios/shutter-0093-blackflare-auto-candidates.json
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-auto-candidates",
|
||||||
|
"notes": [
|
||||||
|
"Recover to CONNECT OK, then use known 0x0093=0x9020 black/flare-manual context and add one remaining bit at a time.",
|
||||||
|
"Earlier 0xFFFF made black/flare AUTO, while 0x9020 kept black/flare MANUAL, so the missing AUTO bit should be outside bits 15, 12, and 5.",
|
||||||
|
"Record white-balance MANUAL/PRESET, black/flare MANUAL/AUTO, shutter display, iris AUTO, and LCD state during each candidate window."
|
||||||
|
],
|
||||||
|
"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_known_manual_context_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_known_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit14",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit14",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit14",
|
||||||
|
"frame": "00 01 13 D0 20 B8",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit13",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit13",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit13",
|
||||||
|
"frame": "00 01 13 B0 20 D8",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit11",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit11",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit11",
|
||||||
|
"frame": "00 01 13 98 20 F0",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit10",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit10",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit10",
|
||||||
|
"frame": "00 01 13 94 20 FC",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit9",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit9",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit9",
|
||||||
|
"frame": "00 01 13 92 20 FA",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit8",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit8",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit8",
|
||||||
|
"frame": "00 01 13 91 20 F9",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit7",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit7",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit7",
|
||||||
|
"frame": "00 01 13 90 A0 78",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit6",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit6",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit6",
|
||||||
|
"frame": "00 01 13 90 60 B8",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit4",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit4",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit4",
|
||||||
|
"frame": "00 01 13 90 30 E8",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit3",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit3",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit3",
|
||||||
|
"frame": "00 01 13 90 28 F0",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit2",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit2",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit2",
|
||||||
|
"frame": "00 01 13 90 24 FC",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit1",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit1",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit1",
|
||||||
|
"frame": "00 01 13 90 22 FA",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_clear_before_bit0",
|
||||||
|
"frame": "00 01 13 00 00 48",
|
||||||
|
"listen": 0.18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "selector_zero_ok_before_bit0",
|
||||||
|
"frame": "00 00 00 80 00 DA",
|
||||||
|
"listen": 0.10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "e000_0093_9020_plus_bit0",
|
||||||
|
"frame": "00 01 13 90 21 F9",
|
||||||
|
"listen": 0.85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "table_sweep",
|
||||||
|
"selectors": [
|
||||||
|
"0x093"
|
||||||
|
],
|
||||||
|
"gap": 0.16,
|
||||||
|
"ack_on": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.75
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
scenarios/shutter-0093-blackflare-confirm-90ff.json
Normal file
115
scenarios/shutter-0093-blackflare-confirm-90ff.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-confirm-90ff",
|
||||||
|
"notes": [
|
||||||
|
"Single-candidate streaming confirmation for selector 0x0093 value 0x90FF.",
|
||||||
|
"The known 0xFFFF AUTO reference is included first as a positive control.",
|
||||||
|
"Expected observation pattern if this candidate drives black/flare AUTO: MANUAL -> AUTO -> MANUAL -> AUTO -> MANUAL.",
|
||||||
|
"All holds refresh every 0.60s so CONNECT OK should stay alive during the visual test."
|
||||||
|
],
|
||||||
|
"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": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 6,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "positive_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_after_positive_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_90ff",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_return_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_90ff_repeat",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_tail_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
scenarios/shutter-0093-blackflare-confirm-9f20.json
Normal file
115
scenarios/shutter-0093-blackflare-confirm-9f20.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-confirm-9f20",
|
||||||
|
"notes": [
|
||||||
|
"Single-candidate streaming confirmation for selector 0x0093 value 0x9F20.",
|
||||||
|
"The known 0xFFFF AUTO reference is included first as a positive control.",
|
||||||
|
"Expected observation pattern if this candidate drives black/flare AUTO: MANUAL -> AUTO -> MANUAL -> AUTO -> MANUAL.",
|
||||||
|
"All holds refresh every 0.60s so CONNECT OK should stay alive during the visual test."
|
||||||
|
],
|
||||||
|
"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": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 6,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "positive_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_after_positive_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_9f20",
|
||||||
|
"frame": "00 01 13 9F 20 F7",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_return_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_9f20_repeat",
|
||||||
|
"frame": "00 01 13 9F 20 F7",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_tail_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
scenarios/shutter-0093-blackflare-confirm-9fff.json
Normal file
115
scenarios/shutter-0093-blackflare-confirm-9fff.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-confirm-9fff",
|
||||||
|
"notes": [
|
||||||
|
"Single-candidate streaming confirmation for selector 0x0093 value 0x9FFF.",
|
||||||
|
"The known 0xFFFF AUTO reference is included first as a positive control.",
|
||||||
|
"Expected observation pattern if this candidate drives black/flare AUTO: MANUAL -> AUTO -> MANUAL -> AUTO -> MANUAL.",
|
||||||
|
"All holds refresh every 0.60s so CONNECT OK should stay alive during the visual test."
|
||||||
|
],
|
||||||
|
"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": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 6,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "positive_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_after_positive_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_9fff",
|
||||||
|
"frame": "00 01 13 9F FF 28",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_return_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_9fff_repeat",
|
||||||
|
"frame": "00 01 13 9F FF 28",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_tail_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
scenarios/shutter-0093-blackflare-confirm-f020.json
Normal file
115
scenarios/shutter-0093-blackflare-confirm-f020.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-confirm-f020",
|
||||||
|
"notes": [
|
||||||
|
"Single-candidate streaming confirmation for selector 0x0093 value 0xF020.",
|
||||||
|
"The known 0xFFFF AUTO reference is included first as a positive control.",
|
||||||
|
"Expected observation pattern if this candidate drives black/flare AUTO: MANUAL -> AUTO -> MANUAL -> AUTO -> MANUAL.",
|
||||||
|
"All holds refresh every 0.60s so CONNECT OK should stay alive during the visual test."
|
||||||
|
],
|
||||||
|
"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": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 6,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "positive_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_after_positive_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_f020",
|
||||||
|
"frame": "00 01 13 F0 20 98",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_return_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_f020_repeat",
|
||||||
|
"frame": "00 01 13 F0 20 98",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_tail_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
scenarios/shutter-0093-blackflare-confirm-ff20.json
Normal file
115
scenarios/shutter-0093-blackflare-confirm-ff20.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-confirm-ff20",
|
||||||
|
"notes": [
|
||||||
|
"Single-candidate streaming confirmation for selector 0x0093 value 0xFF20.",
|
||||||
|
"The known 0xFFFF AUTO reference is included first as a positive control.",
|
||||||
|
"Expected observation pattern if this candidate drives black/flare AUTO: MANUAL -> AUTO -> MANUAL -> AUTO -> MANUAL.",
|
||||||
|
"All holds refresh every 0.60s so CONNECT OK should stay alive during the visual test."
|
||||||
|
],
|
||||||
|
"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": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 6,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "positive_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_after_positive_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_ff20",
|
||||||
|
"frame": "00 01 13 FF 20 97",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_return_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_ff20_repeat",
|
||||||
|
"frame": "00 01 13 FF 20 97",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_tail_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
106
scenarios/shutter-0093-blackflare-field-confirm.json
Normal file
106
scenarios/shutter-0093-blackflare-field-confirm.json
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-field-confirm",
|
||||||
|
"notes": [
|
||||||
|
"Shorter black/flare field confirmation after the field-groups run produced three MANUAL->AUTO->MANUAL swaps.",
|
||||||
|
"This keeps only the broad candidates most likely to explain those swaps, with longer holds for easier visual correlation.",
|
||||||
|
"Each candidate is preceded by 0x9020 manual context. Count which candidate windows produce black/flare AUTO."
|
||||||
|
],
|
||||||
|
"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": "manual_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 2.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_candidate_f020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_f020_high_upper_nibble",
|
||||||
|
"frame": "00 01 13 F0 20 98",
|
||||||
|
"listen": 2.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_candidate_ff20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_ff20_all_high_byte",
|
||||||
|
"frame": "00 01 13 FF 20 97",
|
||||||
|
"listen": 2.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_candidate_9f20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_9f20_high_low_nibble",
|
||||||
|
"frame": "00 01 13 9F 20 F7",
|
||||||
|
"listen": 2.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_candidate_90ff",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_90ff_low_byte",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 2.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_candidate_9fff",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_9fff_high_low_nibble_plus_low_byte",
|
||||||
|
"frame": "00 01 13 9F FF 28",
|
||||||
|
"listen": 2.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.75
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
154
scenarios/shutter-0093-blackflare-field-groups.json
Normal file
154
scenarios/shutter-0093-blackflare-field-groups.json
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-field-groups",
|
||||||
|
"notes": [
|
||||||
|
"Follow-up after the slow-marked run: black/flare swapped only twice, likely on 0x9020 -> 0xFFFF and back to 0x9020.",
|
||||||
|
"That suggests black/flare AUTO is not one single extra bit over 0x9020, but a multi-bit mode field.",
|
||||||
|
"Each candidate is preceded by 0x9020 manual context. Record whether black/flare changes during the candidate hold."
|
||||||
|
],
|
||||||
|
"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": "known_manual_context_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_high_upper_nibble_f020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_high_upper_nibble_f020",
|
||||||
|
"frame": "00 01 13 F0 20 98",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_all_high_byte_ff20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_all_high_byte_ff20",
|
||||||
|
"frame": "00 01 13 FF 20 97",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_high_low_nibble_9f20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_high_low_nibble_9f20",
|
||||||
|
"frame": "00 01 13 9F 20 F7",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_low_byte_90ff",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_low_byte_90ff",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_high_low_nibble_plus_low_byte_9fff",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_high_low_nibble_plus_low_byte_9fff",
|
||||||
|
"frame": "00 01 13 9F FF 28",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_low_bits0_5_903f",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_low_bits0_5_903f",
|
||||||
|
"frame": "00 01 13 90 3F E7",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_high_low_nibble_combo_9b20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_high_low_nibble_combo_9b20",
|
||||||
|
"frame": "00 01 13 9B 20 F3",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_high_low_nibble_combo_9d20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_high_low_nibble_combo_9d20",
|
||||||
|
"frame": "00 01 13 9D 20 F5",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_high_low_nibble_combo_9e20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_high_low_nibble_combo_9e20",
|
||||||
|
"frame": "00 01 13 9E 20 F6",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.75
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
178
scenarios/shutter-0093-blackflare-field-stream-confirm.json
Normal file
178
scenarios/shutter-0093-blackflare-field-stream-confirm.json
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-field-stream-confirm",
|
||||||
|
"notes": [
|
||||||
|
"Streaming confirmation for selector 0x0093 black/flare fields.",
|
||||||
|
"The prior field-confirm run held candidates too long and fell into CONNECT NOT ACT during the 0xFFFF hold.",
|
||||||
|
"This repeats each candidate every 0.60s so the candidate value itself acts like a CCU refresh stream."
|
||||||
|
],
|
||||||
|
"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": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_manual_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_manual_9020_before_f020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_candidate_f020",
|
||||||
|
"frame": "00 01 13 F0 20 98",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_manual_9020_before_ff20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_candidate_ff20",
|
||||||
|
"frame": "00 01 13 FF 20 97",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_manual_9020_before_9f20",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_candidate_9f20",
|
||||||
|
"frame": "00 01 13 9F 20 F7",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_manual_9020_before_90ff",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_candidate_90ff",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_manual_9020_before_9fff",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 4,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "stream_candidate_9fff",
|
||||||
|
"frame": "00 01 13 9F FF 28",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.75
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
210
scenarios/shutter-0093-blackflare-lowbyte-groups.json
Normal file
210
scenarios/shutter-0093-blackflare-lowbyte-groups.json
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-lowbyte-groups",
|
||||||
|
"notes": [
|
||||||
|
"Narrow black/flare AUTO now that 0x90FF and 0x9FFF both toggled AUTO but 0xF020/0xFF20/0x9F20 did not.",
|
||||||
|
"This keeps the high byte fixed at 0x90 and varies only the low byte.",
|
||||||
|
"Use 0x9020 as the manual reference and 0x90FF as the low-byte AUTO positive control."
|
||||||
|
],
|
||||||
|
"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": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_reference_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 6,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "positive_lowbyte_auto_90ff",
|
||||||
|
"frame": "00 01 13 90 FF 27",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_9000",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_9000_lowbyte_none",
|
||||||
|
"frame": "00 01 13 90 00 D8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_901f",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_901f_low_bits_0_to_4",
|
||||||
|
"frame": "00 01 13 90 1F C7",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_903f",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_903f_low_bits_0_to_5",
|
||||||
|
"frame": "00 01 13 90 3F E7",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_90c0",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_90c0_low_bits_6_to_7",
|
||||||
|
"frame": "00 01 13 90 C0 18",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_90e0",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_90e0_low_bits_5_to_7",
|
||||||
|
"frame": "00 01 13 90 E0 38",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_before_90df",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 5,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_90df_all_except_bit5",
|
||||||
|
"frame": "00 01 13 90 DF 07",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "repeat",
|
||||||
|
"count": 8,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "manual_tail_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 0.60
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
202
scenarios/shutter-0093-blackflare-slow-marked.json
Normal file
202
scenarios/shutter-0093-blackflare-slow-marked.json
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
{
|
||||||
|
"name": "shutter-0093-blackflare-slow-marked",
|
||||||
|
"notes": [
|
||||||
|
"Slow marked follow-up for selector 0x0093 black/flare AUTO hunting.",
|
||||||
|
"Each candidate is preceded by known 0x9020 context, which previously kept black/flare MANUAL. This avoids the clear/OK reset flicker that made white-balance swap quickly.",
|
||||||
|
"Record whether black/flare changes during the candidate hold. White-balance should be steadier because all candidates keep the 0x9020 base bits."
|
||||||
|
],
|
||||||
|
"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": "known_manual_context_9020",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_auto_reference_ffff",
|
||||||
|
"frame": "00 01 13 FF FF 48",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit14",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit14_d020",
|
||||||
|
"frame": "00 01 13 D0 20 B8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit13",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit13_b020",
|
||||||
|
"frame": "00 01 13 B0 20 D8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit11",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit11_9820",
|
||||||
|
"frame": "00 01 13 98 20 F0",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit10",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit10_9420",
|
||||||
|
"frame": "00 01 13 94 20 FC",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit9",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit9_9220",
|
||||||
|
"frame": "00 01 13 92 20 FA",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit8",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit8_9120",
|
||||||
|
"frame": "00 01 13 91 20 F9",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit7",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit7_90a0",
|
||||||
|
"frame": "00 01 13 90 A0 78",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit6",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit6_9060",
|
||||||
|
"frame": "00 01 13 90 60 B8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit4",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit4_9030",
|
||||||
|
"frame": "00 01 13 90 30 E8",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit3",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit3_9028",
|
||||||
|
"frame": "00 01 13 90 28 F0",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit2",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit2_9024",
|
||||||
|
"frame": "00 01 13 90 24 FC",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit1",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit1_9022",
|
||||||
|
"frame": "00 01 13 90 22 FA",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "known_manual_context_9020_before_bit0",
|
||||||
|
"frame": "00 01 13 90 20 F8",
|
||||||
|
"listen": 1.20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"label": "candidate_bit0_9021",
|
||||||
|
"frame": "00 01 13 90 21 F9",
|
||||||
|
"listen": 1.80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "listen",
|
||||||
|
"seconds": 0.75
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
87
scenarios/shutter-0093-gate-8000.json
Normal file
87
scenarios/shutter-0093-gate-8000.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
87
scenarios/shutter-0093-gate-ffff.json
Normal file
87
scenarios/shutter-0093-gate-ffff.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
55
scenarios/shutter-adjacent-readback.json
Normal file
55
scenarios/shutter-adjacent-readback.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
16
scripts/serial_scenario_unexpected.py
Normal file
16
scripts/serial_scenario_unexpected.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Summarize unexpected device frames from a serial_scenario log."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
if str(ROOT) not in sys.path:
|
||||||
|
sys.path.insert(0, str(ROOT))
|
||||||
|
|
||||||
|
from h8536.serial_scenario_unexpected import main
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
26
tests/test_emulator_report_queue_probe.py
Normal file
26
tests/test_emulator_report_queue_probe.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from h8536.emulator.report_queue_probe import (
|
||||||
|
build_expected_report_frame,
|
||||||
|
encode_report_header,
|
||||||
|
report_payload_selector,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EmulatorReportQueueProbeTest(unittest.TestCase):
|
||||||
|
def test_report_word_0204_builds_observed_gated_active_frame(self):
|
||||||
|
self.assertEqual(encode_report_header(0x0204), (0x01, 0x00, 0x04))
|
||||||
|
self.assertEqual(report_payload_selector(0x0204), 0x0004)
|
||||||
|
self.assertEqual(build_expected_report_frame(0x0204, 0x0000), bytes.fromhex("01 00 04 00 00 5F"))
|
||||||
|
|
||||||
|
def test_report_word_0404_builds_observed_transition_frame(self):
|
||||||
|
self.assertEqual(encode_report_header(0x0404), (0x02, 0x00, 0x04))
|
||||||
|
self.assertEqual(report_payload_selector(0x0404), 0x0004)
|
||||||
|
self.assertEqual(build_expected_report_frame(0x0404, 0x0000), bytes.fromhex("02 00 04 00 00 5C"))
|
||||||
|
|
||||||
|
def test_payload_bytes_feed_frame_value_and_checksum(self):
|
||||||
|
self.assertEqual(build_expected_report_frame(0x0204, 0x1234), bytes.fromhex("01 00 04 12 34 79"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user