Response from RCP

This commit is contained in:
Aiden
2026-05-13 13:10:25 +10:00
parent f99a60710e
commit f406bc12a2
21 changed files with 2073 additions and 4 deletions

View File

@@ -437,3 +437,683 @@ Emerging pattern:
- `CONNECT: NOT ACT` appears to be a parser-recognized but not session-active
state. It may indicate the RCP recognizes the command class as CCU-like, but
the remaining status/identity/activation fields are wrong or incomplete.
### Targeted Field Matrix Probe
After the `0x15-0x30` sweep, the best next experiment is not a broader command
sweep. The command byte is clearly relevant, but active-session behavior may
depend on the state/value fields or the prefix bytes. Use
`scripts/serial_probe_matrix.py` to hold one promising command constant and vary
only a small set of fields.
Start with command `0x15` because it is already associated with the RCP's own
`CALL` output frames:
```powershell
python scripts/serial_probe_matrix.py --port COM5 --commands 0x15 --states "0x00 0x80" --values "0x00 0x80" --after-each 1.2 --prompt-screen --log captures/rcp-matrix-cmd15-state-value.txt
```
Dry-run frames:
```text
00 00 15 00 00 4F
00 00 15 00 80 CF
00 00 15 80 00 CF
00 00 15 80 80 4F
```
Why this is useful:
- `00 00 15 00 00 4F` and `00 00 15 80 00 CF` match the RCP's observed
`CALL` frames.
- `00 00 15 00 80 CF` matches the command-sweep shape that triggered
`CONNECT: NOT ACT`.
- `00 00 15 80 80 4F` checks whether both high/state bits together change the
parser state.
If all four still produce only `CONNECT: NOT ACT` or no change, the next matrix
should keep `cmd=0x15`, `state=0x00`, `value=0x80`, and vary only prefix bytes:
```powershell
python scripts/serial_probe_matrix.py --port COM5 --prefix2s "0x00-0x0F" --commands 0x15 --states 0x00 --values 0x80 --after-each 1.2 --prompt-screen --log captures/rcp-matrix-cmd15-prefix2-00-0f.txt
```
Treat any result other than heartbeat-only pin 4 output as high-priority. In
particular, look for a new RCP frame, a different LCD message, or any transition
from `CONNECT: NOT ACT` to an active/connected state.
### 2026-05-13 Command `0x15` State/Value Matrix Result
Capture:
- `captures/rcp-matrix-cmd15-state-value.txt`
Frames tested:
| Command | State | Value | TX frame | Screen result |
| ---: | ---: | ---: | --- | --- |
| `0x15` | `0x00` | `0x00` | `00 00 15 00 00 4F` | `CONNECT NOT ACT` |
| `0x15` | `0x00` | `0x80` | `00 00 15 00 80 CF` | `CONNECT NOT ACT` |
| `0x15` | `0x80` | `0x00` | `00 00 15 80 00 CF` | `CONNECT NOT ACT` |
| `0x15` | `0x80` | `0x80` | `00 00 15 80 80 4F` | `CONNECT NOT ACT` |
Analyzer result:
- Pin 4 RX stayed at heartbeat only: `00 00 00 00 80 DA`.
- No non-heartbeat RCP-to-host frames were observed.
- The RCP was sensitive to all four command `0x15` variants, including both
frames that match the panel's own `CALL` output, but none advanced the panel
beyond `CONNECT NOT ACT`.
Interpretation:
- For command `0x15`, the tested state/value high bits are not enough to produce
an active session.
- The missing host response is likely in another field, a required repeated
cadence, a multi-frame exchange, or a CCU/camera identity/status frame.
- Since command `0x15` is parser-visible across all tested state/value variants,
it is a good anchor for prefix-byte testing.
Recommended next matrix:
```powershell
python scripts/serial_probe_matrix.py --port COM5 --prefix2s "0x00-0x0F" --commands 0x15 --states 0x00 --values 0x80 --after-each 1.2 --prompt-screen --log captures/rcp-matrix-cmd15-prefix2-00-0f.txt
```
If all `prefix2` values behave the same, repeat with `prefix1s "0x00-0x0F"` and
`prefix2s 0x00`. Prefix bytes may encode device address, CCU identity, panel
number, or bus direction.
### 2026-05-13 Command `0x15` Prefix2 Matrix Result
Capture:
- `captures/rcp-matrix-cmd15-prefix2-00-0f.txt`
Test shape:
- `p1=0x00`
- `p2=0x00-0x0F`
- `cmd=0x15`
- `state=0x00`
- `value=0x80`
Analyzer result:
- Pin 4 RX stayed at heartbeat only: `00 00 00 00 80 DA`.
- No non-heartbeat RCP-to-host frames were observed.
- The log contains 263 heartbeat RX frames and 16 transmitted prefix2 variants.
Screen observations:
- `CONNECT NOT ACT` was recorded after prefix2 values `0x00`, `0x01`, `0x02`,
`0x03`, `0x04`, `0x05`, `0x06`, `0x08`, `0x09`, `0x0A`, `0x0B`, `0x0C`,
`0x0D`, and `0x0E`.
- No screen marker was recorded after prefix2 `0x07` or `0x0F`.
- One marker was typed as `CONNECT NTO ACT`; treat this as the same
observation unless later testing proves otherwise.
Interpretation:
- Prefix2 did not produce an active session in the tested low-nibble range.
- The missing response is still not visible on pin 4.
- The missing markers at `0x07` and `0x0F` may be real parser behavior, because
both have low three bits set, but this needs a focused confirmation run before
treating it as a rule.
Recommended confirmation:
```powershell
python scripts/serial_probe_matrix.py --port COM5 --prefix2s "0x06 0x07 0x08 0x0E 0x0F" --commands 0x15 --states 0x00 --values 0x80 --after-each 1.2 --prompt-screen --log captures/rcp-matrix-cmd15-prefix2-confirm.txt
```
Reset the RCP after any screen-triggering result. This keeps the comparison
between trigger and non-trigger prefix2 values clean.
### 2026-05-13 Prefix2 Confirmation Result
Capture:
- `captures/rcp-matrix-cmd15-prefix2-confirm.txt`
Test shape:
- `p1=0x00`
- `p2=0x06`, `0x07`, `0x08`, `0x0E`, `0x0F`
- `cmd=0x15`
- `state=0x00`
- `value=0x80`
Screen observations:
| Prefix2 | TX frame | Screen marker |
| ---: | --- | --- |
| `0x06` | `00 06 15 00 80 C9` | `CONNECT NOT ACT` |
| `0x07` | `00 07 15 00 80 C8` | none recorded |
| `0x08` | `00 08 15 00 80 C7` | `CONNECT NOT ACT` |
| `0x0E` | `00 0E 15 00 80 C1` | `CONNECT NOT ACT` |
| `0x0F` | `00 0F 15 00 80 C0` | none recorded |
Analyzer result:
- 65 heartbeat RX frames: `00 00 00 00 80 DA`.
- 14 apparent non-heartbeat RX frames after `p2=0x0F`:
`00 00 00 80 DA 00`.
- No other RCP-to-host frame shape was observed.
Interpretation:
- `p2=0x07` and `p2=0x0F` again failed to produce a recorded screen marker,
while neighboring values did.
- The apparent `00 00 00 80 DA 00` response after `p2=0x0F` is probably a
one-byte framing slip of the normal heartbeat stream, because it is exactly
the heartbeat sequence viewed from byte offset 1:
`00 00 00 00 80 DA 00 00 ...`.
- Because the shifted heartbeat also satisfies the current XOR checksum
hypothesis, checksum validity alone is not enough to prove frame alignment.
Recommended raw confirmation for `p2=0x0F`:
```powershell
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 0F 15 00 80 C0" --repeat 1 --delay 1.5 --after 5 --frame-size 0 --log captures/rcp-prefix2-0f-raw.txt
```
Then repeat for `p2=0x07`:
```powershell
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 07 15 00 80 C8" --repeat 1 --delay 1.5 --after 5 --frame-size 0 --log captures/rcp-prefix2-07-raw.txt
```
Raw capture avoids imposing 6-byte alignment on the received stream, so it
should show whether the apparent non-heartbeat is a real frame or just a shifted
view of the heartbeat.
### Series Resistor Note
Current host-to-RCP tests use a series resistor between adapter `TXD` and RCP
pin 7 as a protection measure. A 4.7 kOhm series resistor should normally still
work with a high-impedance RS-232 receiver input, so it is unlikely to explain a
selective pattern where nearby checksum-valid frames behave differently.
Possible resistor-related failure modes:
- If the RCP input is much lower impedance than expected, 4.7 kOhm could reduce
the voltage swing at pin 7.
- If the input is clamped internally, the resistor may limit current enough to
make the received waveform marginal.
- Marginal signaling would more likely produce random missed/garbled frames
than a repeatable distinction between specific prefix values.
Low-risk check:
- Measure pin 7 relative to pin 9 on the RCP side of the resistor while the
adapter is idle; it should show a strong RS-232 idle level, not near 0 V.
- If testing without the resistor, first try a smaller protection resistor such
as 1 kOhm rather than going straight to a direct connection.
- Compare one known-trigger frame, such as `00 06 15 00 80 C9`, and one
suspected non-trigger frame, such as `00 07 15 00 80 C8`, using the same reset
procedure.
### Direct Response Sweep Without Screen Logging
For response hunting, use `scripts/serial_direct_response_sweep.py` rather than
the older fixed-frame sweep. It sends checksum-valid 6-byte host frames, but
reads pin 4 as raw bytes and checks whether the received data can be explained
as the repeated heartbeat:
```text
00 00 00 00 80 DA
```
This avoids treating shifted heartbeat bytes such as `00 00 00 80 DA 00` as a
new response frame.
Recommended first direct sweep:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0x00-0xFF" --states 0x00 --values 0x80 --after-each 0.6 --stop-on-anomaly --log captures/rcp-direct-cmd-00-ff.txt
```
What to watch for:
- If the script reports `Anomalies: 0`, the panel never sent raw bytes that
differed from the heartbeat stream during this sweep.
- If it stops on an anomaly, preserve the log and rerun only the reported frame
with raw capture before assuming it is a real response.
- Keep the same resistor/wiring setup for this run so the result remains
comparable to the earlier observations.
If the command-only direct sweep finds nothing, the next direct grid should be
split into two chunks to stay within the default safety limit:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --prefix2s "0x00-0x0F" --commands "0x00-0x1F" --states 0x00 --values 0x80 --after-each 0.4 --stop-on-anomaly --log captures/rcp-direct-p2-00-0f-cmd-00-1f.txt
python scripts/serial_direct_response_sweep.py --port COM5 --prefix2s "0x00-0x0F" --commands "0x20-0x3F" --states 0x00 --values 0x80 --after-each 0.4 --stop-on-anomaly --log captures/rcp-direct-p2-00-0f-cmd-20-3f.txt
```
### 2026-05-13 Direct Command Sweep Response Hit
Capture:
- `captures/rcp-direct-cmd-00-ff.txt`
Sweep shape:
- `p1=0x00`
- `p2=0x00`
- `cmd=0x00-0xFF`
- `state=0x00`
- `value=0x80`
- Stop on first raw RX anomaly.
Important result:
- The sweep stopped immediately after transmitting command `0xB5`:
`00 00 B5 00 80 6F`.
- The previous transmitted command was `0xB4`: `00 00 B4 00 80 6E`, about
0.6 seconds earlier.
- The RCP produced repeated non-heartbeat frames:
`07 80 6D 20 D8 48`.
- Final raw capture showed the same frame repeated, then the panel returned to
the normal heartbeat `00 00 00 00 80 DA`.
Observed response:
```text
07 80 6D 20 D8 48
07 80 6D 20 D8 48
07 80 6D 20 D8 48
...
00 00 00 00 80 DA
```
Checksum check:
- `5A xor 07 xor 80 xor 6D xor 20 xor D8 = 48`.
- This means `07 80 6D 20 D8 48` is a real checksum-valid 6-byte frame under the
current checksum hypothesis, not a shifted heartbeat artifact.
Interpretation:
- This is the first confirmed non-heartbeat RCP-to-host serial response on pin
4 during host-frame probing.
- `cmd=0xB5` is the most likely trigger, but `cmd=0xB4` should be retested
because it was sent one read window earlier and delayed responses are possible.
- The response frame shape suggests the RCP may be reporting a status or
identity-like frame with `p1=0x07`, `p2=0x80`, `cmd=0x6D`, `state=0x20`,
`value=0xD8`.
Recommended confirmation tests:
```powershell
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 00 B4 00 80 6E" --repeat 1 --delay 1.5 --after 5 --frame-size 0 --log captures/rcp-confirm-cmd-b4-raw.txt
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 00 B5 00 80 6F" --repeat 1 --delay 1.5 --after 5 --frame-size 0 --log captures/rcp-confirm-cmd-b5-raw.txt
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 00 B6 00 80 6C" --repeat 1 --delay 1.5 --after 5 --frame-size 0 --log captures/rcp-confirm-cmd-b6-raw.txt
```
If `cmd=0xB5` reliably triggers the `07 80 6D 20 D8 48` response, test whether
the response depends on the state/value fields:
```powershell
python scripts/serial_probe_matrix.py --port COM5 --commands 0xB5 --states "0x00 0x80" --values "0x00 0x80" --after-each 1.2 --prompt-screen --log captures/rcp-matrix-cmd-b5-state-value.txt
```
### 2026-05-13 B4/B5/B6 Single-Frame Confirmation
Captures:
- `captures/rcp-confirm-cmd-b4-raw.txt`
- `captures/rcp-confirm-cmd-b5-raw.txt`
- `captures/rcp-confirm-cmd-b6-raw.txt`
Single frames tested:
| Command | TX frame | Pin 4 result |
| ---: | --- | --- |
| `0xB4` | `00 00 B4 00 80 6E` | heartbeat only |
| `0xB5` | `00 00 B5 00 80 6F` | heartbeat only |
| `0xB6` | `00 00 B6 00 80 6C` | heartbeat only |
Interpretation:
- The earlier `07 80 6D 20 D8 48` response did not reproduce from isolated
single-frame `B4`, `B5`, or `B6` tests.
- The response may require prior sweep history, a command sequence, repeated
cadence, or a temporary parser/session state produced by many earlier frames.
- The `B5` frame is still the best suspect because the direct sweep reported the
anomaly in the read window immediately after transmitting `B5`, but it is not
sufficient by itself in a fresh single-frame test.
Recommended focused replay:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --after-each 0.6 --stop-on-anomaly --log captures/rcp-direct-cmd-b0-b8-replay.txt
```
If that does not reproduce the response, try the same range with a shorter
cadence to better mimic the long sweep:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --after-each 0.25 --stop-on-anomaly --log captures/rcp-direct-cmd-b0-b8-fast.txt
```
If the focused range still does not reproduce it, rerun the longer sweep from
`0xA0-0xB8` rather than the full `0x00-0xFF` range:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xA0-0xB8" --states 0x00 --values 0x80 --after-each 0.6 --stop-on-anomaly --log captures/rcp-direct-cmd-a0-b8-replay.txt
```
### 2026-05-13 B0-B8 Focused Replay Hit
Capture:
- `captures/rcp-direct-cmd-b0-b8-replay.txt`
Replay shape:
- `p1=0x00`
- `p2=0x00`
- `cmd=0xB0-0xB8`
- `state=0x00`
- `value=0x80`
- `after-each=0.6`
- Stop on first raw RX anomaly.
Important result:
- The sweep sent `cmd=0xB0`, then `cmd=0xB1`.
- The anomaly was captured in the read window immediately after transmitting
`cmd=0xB1`: `00 00 B1 00 80 6B`.
- The RCP emitted one checksum-valid non-heartbeat frame:
`07 80 6C 20 D8 49`.
- The final read window returned to heartbeat-only traffic.
Checksum check:
- `5A xor 07 xor 80 xor 6C xor 20 xor D8 = 49`.
Comparison with the earlier full sweep hit:
| Trigger window | RCP response |
| --- | --- |
| After `cmd=0xB1` in focused `B0-B8` replay | `07 80 6C 20 D8 49` |
| After `cmd=0xB5` in full `00-FF` sweep | `07 80 6D 20 D8 48` |
Interpretation:
- The non-heartbeat response is reproducible with a short local sequence, so it
does not require the entire `0x00-0xFF` sweep history.
- The response may be sequence-dependent: `B1` alone is not yet proven as the
trigger because `B0` was sent one window earlier.
- The response command byte changed from `0x6D` to `0x6C`, which suggests the
RCP may be returning a status/identity code related to the host command or to
internal state.
Recommended tight confirmations:
```powershell
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 00 B0 00 80 6A" --repeat 1 --delay 1.5 --after 5 --frame-size 0 --log captures/rcp-confirm-cmd-b0-raw.txt
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 00 B1 00 80 6B" --repeat 1 --delay 1.5 --after 5 --frame-size 0 --log captures/rcp-confirm-cmd-b1-raw.txt
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB1" --states 0x00 --values 0x80 --after-each 0.6 --stop-on-anomaly --log captures/rcp-direct-cmd-b0-b1-replay.txt
```
If `B1` alone is heartbeat-only but `B0-B1` reproduces the response, treat
`B0 -> B1` as a required two-frame sequence.
### 2026-05-13 B0/B1 Tight Confirmation Result
Captures:
- `captures/rcp-confirm-cmd-b0-raw.txt`
- `captures/rcp-confirm-cmd-b1-raw.txt`
- `captures/rcp-direct-cmd-b0-b1-replay.txt`
Results:
| Test | Pin 4 result |
| --- | --- |
| Single `B0`: `00 00 B0 00 80 6A` | heartbeat only |
| Single `B1`: `00 00 B1 00 80 6B` | heartbeat only |
| Sequence `B0 -> B1` | heartbeat only, `Anomalies: 0` |
Interpretation:
- The `07 80 6C 20 D8 49` response from the `B0-B8` replay did not reproduce
with the minimal `B0 -> B1` sequence.
- The response may be intermittent, cadence-sensitive, dependent on a longer
sequence such as `B0-B8`, or affected by panel state that was not identical
between runs.
- The next priority is measuring reproducibility of the same short range rather
than expanding the search space.
Recommended reproducibility test:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --after-each 0.6 --cycles 5 --cycle-pause 2 --log captures/rcp-direct-cmd-b0-b8-cycles.txt
```
Run this without `--stop-on-anomaly` so all five cycles complete and the log can
show whether the response happens consistently, intermittently, or only once.
### Power-Cycle Isolation Test Plan
Use this plan when intentionally power-cycling the RCP between tests. The goal
is to distinguish a cold-boot reproducible protocol response from a response
that only appears after accumulated parser/session state.
Before each test:
1. Stop any serial script.
2. Power off the RCP.
3. Wait at least 5 seconds.
4. Power on the RCP.
5. Wait until the panel is stable and heartbeat traffic has resumed.
6. Run exactly one test command.
Keep the wiring and series resistor the same between tests unless the test name
explicitly says otherwise.
#### Set A: Cold-Boot Reproducibility
Run these first. They test whether the `B0-B8` response is repeatable from a
fresh power cycle.
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-a1-b0-b8.txt
```
Power-cycle, then:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-a2-b0-b8.txt
```
Power-cycle, then:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-a3-b0-b8.txt
```
Expected useful outcomes:
- If all three produce the same response, the sequence is cold-boot
reproducible.
- If only some produce a response, the behavior may be timing-sensitive or
intermittent.
- If none produce a response, the earlier hit likely depended on prior panel
state.
#### Set B: Minimum Sequence Length
Run this set only if Set A produces at least one response. Power-cycle between
each command. These tests find the shortest command prefix that can trigger a
non-heartbeat response.
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB1" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-b1-b0-b1.txt
```
Power-cycle, then:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB2" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-b2-b0-b2.txt
```
Power-cycle, then:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB3" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-b3-b0-b3.txt
```
Power-cycle, then:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB4" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-b4-b0-b4.txt
```
#### Set C: Cadence Sensitivity
Run this set if Set A is inconsistent or if Set B does not identify a clean
minimum sequence. Power-cycle between each command.
Slow cadence:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --settle 3 --after-each 1.2 --stop-on-anomaly --log captures/rcp-powercycle-c1-b0-b8-slow.txt
```
Fast cadence:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --settle 3 --after-each 0.25 --stop-on-anomaly --log captures/rcp-powercycle-c2-b0-b8-fast.txt
```
Very fast cadence:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB8" --states 0x00 --values 0x80 --settle 3 --after-each 0.1 --stop-on-anomaly --log captures/rcp-powercycle-c3-b0-b8-very-fast.txt
```
#### Set D: Control Tests
Run these if the `B0-B8` range is producing responses. Power-cycle between
each command. These confirm the response is specific to the `B0` range.
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xA8-0xAF" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-d1-a8-af-control.txt
```
Power-cycle, then:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB8-0xBF" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-d2-b8-bf-control.txt
```
If a response appears in control ranges too, the trigger may be a broader
command class rather than a specific `B0-B8` sequence.
### 2026-05-13 Power-Cycle Set A Result
Captures:
- `captures/rcp-powercycle-a1-b0-b8.txt`
- `captures/rcp-powercycle-a2-b0-b8.txt`
- `captures/rcp-powercycle-a3-b0-b8.txt`
Each run was performed after a panel power cycle. All three runs produced the
same non-heartbeat response.
| Run | Trigger window | RCP response | Result |
| --- | --- | --- | --- |
| A1 | after `B1`: `00 00 B1 00 80 6B` | `07 80 6C 20 D8 49` repeated | anomaly |
| A2 | after `B1`: `00 00 B1 00 80 6B` | `07 80 6C 20 D8 49` repeated | anomaly |
| A3 | after `B1`: `00 00 B1 00 80 6B` | `07 80 6C 20 D8 49` repeated | anomaly |
Observed raw pattern in each run:
```text
07 80 6C 20 D8 49
07 80 6C 20 D8 49
07 80 6C 20 D8 49
...
00 00 00 00 80 DA
```
Interpretation:
- The `B0-B8` response is cold-boot reproducible.
- The response appears immediately after the `B1` transmit window when the test
starts from a fresh power cycle.
- The earlier `B0 -> B1` heartbeat-only result was likely affected by panel
state from previous experiments, timing, or not starting from an equivalent
cold condition.
- The next test should determine whether `B0 -> B1` is sufficient from a fresh
power cycle, or whether the script/test context of the `B0-B8` run matters.
Recommended next power-cycle tests:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB1" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-b1-b0-b1.txt
```
Power-cycle, then:
```powershell
python scripts/serial_probe_response.py --port COM5 --tx-frame "00 00 B1 00 80 6B" --repeat 1 --delay 3 --after 5 --frame-size 0 --log captures/rcp-powercycle-b1-alone-raw.txt
```
If `B0-B1` reproduces but `B1` alone does not, treat `B0 -> B1` as the minimum
cold-boot sequence.
### 2026-05-13 Minimum Cold-Boot Sequence Result
Captures:
- `captures/rcp-powercycle-b0.txt`
- `captures/rcp-powercycle-b1-b0-b1.txt`
- `captures/rcp-powercycle-b1-alone-raw.txt`
Each test was run after a panel power cycle.
| Test | TX frame(s) | Pin 4 result |
| --- | --- | --- |
| `B0` alone | `00 00 B0 00 80 6A` | heartbeat only, `Anomalies: 0` |
| `B1` alone | `00 00 B1 00 80 6B` | heartbeat only |
| `B0 -> B1` | `00 00 B0 00 80 6A`, then `00 00 B1 00 80 6B` | `07 80 6C 20 D8 49` repeated |
Conclusion:
- The minimum confirmed cold-boot trigger is the two-frame sequence:
```text
Host -> RCP: 00 00 B0 00 80 6A
Host -> RCP: 00 00 B1 00 80 6B
RCP -> Host: 07 80 6C 20 D8 49
```
- Neither `B0` nor `B1` is sufficient alone from a cold panel.
- `B0` appears to prime the panel, and `B1` completes the query/trigger.
- The response repeats for a short period, then the panel returns to the normal
heartbeat `00 00 00 00 80 DA`.
Recommended next tests:
1. Timing sensitivity between `B0` and `B1`.
2. State/value sensitivity of the `B0 -> B1` pair.
3. Whether the response changes when sending nearby pairs such as `B1 -> B2`,
`B2 -> B3`, etc.
Suggested timing tests, with power cycle between each:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB1" --states 0x00 --values 0x80 --settle 3 --after-each 0.1 --stop-on-anomaly --log captures/rcp-powercycle-timing-b0-b1-100ms.txt
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB0-0xB1" --states 0x00 --values 0x80 --settle 3 --after-each 1.2 --stop-on-anomaly --log captures/rcp-powercycle-timing-b0-b1-1200ms.txt
```
Suggested nearby-pair tests, with power cycle between each:
```powershell
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB1-0xB2" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-pair-b1-b2.txt
python scripts/serial_direct_response_sweep.py --port COM5 --commands "0xB2-0xB3" --states 0x00 --values 0x80 --settle 3 --after-each 0.6 --stop-on-anomaly --log captures/rcp-powercycle-pair-b2-b3.txt
```