# Discovery Notes This file records hands-on observations separately from manual-derived facts. Treat these as bench notes: useful and current, but still worth rechecking with photos, continuity tests, and instrument captures. ## 2026-05-13 - RCP-TX7 10-Pin Power and Cable Observed on the RCP-TX7 10-pin remote connector/cable during restoration work: - Pin 9 confirmed as ground / DC return. - Pin 10 confirmed as power input. - Cable color for pin 9 / ground: brown. - Cable color for pin 10 / +12 V power: brown-white. - Cable colors for pins 1-8 have been continuity-mapped; see the working cable map below. - Yellow and yellow-white conductors are present in the cable but did not map to connector pins during continuity testing. - Multimeter reading from pin 9 ground to pin 4 serial data: about -9 V. - Multimeter reading from pin 9 ground to pin 7 serial data: about +0.037 V. - Pins 4 and 7 were the only serial-related combinations that produced a meaningful multimeter result during this check. - With power present on pins 9 and 10, the panel shows a green `PANEL ACTIVE` light. - The inside of the 10-pin cable contains 12 wires total. - Three of those wire groups are twisted pairs. Immediate implications: - The bench result agrees with the RCP-TX7 and CCU-TX7 manual pinout for pins 9 and 10. - The 12-conductor cable construction suggests not every conductor maps one-to-one to the 10 connector pins; shielding/drain, duplicated grounds, or paired signal returns may be present. - The three twisted pairs are likely important candidates for serial data, composite video, and/or power/ground pairing, but this should be confirmed by continuity testing rather than color or twist assumptions. - Pin 4 measuring around -9 V relative to pin 9 strongly suggests true RS-232 level idle on at least the RCP-to-CCU/camera data line. - Pin 7 near 0 V may be inactive/floating until a CCU or camera drives the return data line. ### Working Cable Map This table combines the manual-derived pin purpose with hands-on color mapping. Rows marked `confirmed` have been checked on the current cable/panel under test. | Pin | Purpose | Cable color | Status | Notes | | ---: | --- | --- | --- | --- | | 1 | Spare / unused | red | confirmed | No function shown in service manual. | | 2 | VBS / composite video X | black | confirmed | 1.0 Vp-p composite video input to RCP. | | 3 | VBS / composite video ground | green | confirmed | Video reference/ground. | | 4 | Serial data, RCP to CCU/camera | orange | confirmed | RS-232C-based data direction. | | 5 | Serial/data ground | blue | confirmed | One of two serial/data grounds. | | 6 | Serial/data ground | grey | confirmed | One of two serial/data grounds. | | 7 | Serial data, CCU/camera to RCP | purple | confirmed | RS-232C-based data direction. | | 8 | Spare / unused | purple-white | confirmed | No function shown in service manual. | | 9 | DC return / ground | brown | confirmed | Confirmed as ground on current cable. | | 10 | +12 V remote power input | brown-white | confirmed | Confirmed as power input on current cable. | ### Unmapped Cable Conductors The cable contains two additional conductors that did not show continuity to the 10 connector pins during the current test: | Conductor color | Current status | Notes | | --- | --- | --- | | yellow | unmapped | May be shield/drain-related, spare, broken, or connected only at one end. | | yellow-white | unmapped | May be shield/drain-related, spare, broken, or connected only at one end. | Recheck these against connector shells, shield braid/drain, cable strain relief hardware, and both ends of the cable if accessible. Suggested next observations to capture: 1. Connector orientation photo showing pin numbering reference. 2. Wire color list, including which colors form each twisted pair. 3. Confirm whether yellow and yellow-white connect to shield, shell, or one end only. 4. Resistance between pins 5, 6, and 9 with the cable disconnected. 5. Scope idle voltage and activity on pins 4 and 7 relative to pins 5/6 and pin 9 while pressing panel controls and, later, while connected to a CCU or camera. ## Serial Capture Setup Initial USB serial adapter wiring for passive listening: | Adapter terminal | RCP-TX7 cable pin | Cable color | Purpose | | --- | ---: | --- | --- | | `GND` | 9 | brown | Shared reference / DC return | | `RXD` | 4 | orange | Listen to RCP-to-CCU/camera serial data | Do not connect adapter `TXD` during the first capture pass. Pin 4 measured about -9 V relative to pin 9, so use the adapter's RS-232 side, not TTL UART mode. Capture helper: ```powershell python -m pip install pyserial python scripts/serial_sniff.py --list python scripts/serial_sniff.py --port COM3 --baud 38400 --ascii python scripts/serial_sniff.py --port COM3 --baud 38400 --frame-size 6 --log captures/rcp-pin4.txt ``` Replace `COM3` with the adapter port shown by `--list` or Windows Device Manager. While the script is running, press simple RCP controls and watch for new hex bytes. ### 2026-05-13 Initial Pin 4 Capture With the adapter in RS-232 mode, adapter `RXD` connected to RCP pin 4, and adapter `GND` connected to pin 9, the stream produced repeating 6-byte patterns: ```text 00 00 00 00 80 DA 00 00 07 80 00 DD ``` Observed behavior: - Frames repeat roughly every 200 ms during the sample. - The stream sometimes appeared split as `00` followed by five bytes, which is likely a read-timeout/chunking artifact rather than a protocol feature. - Button presses did not obviously correlate with a visible byte change in the first capture. Current interpretation: - This looks like a regular RCP-origin heartbeat/status transmission on pin 4, not random noise. - Because only pin 4 is connected, this may be the panel repeatedly trying to announce itself or poll a missing CCU/camera. - Pin 7 measured near 0 V and is probably quiet until a CCU/camera drives the return channel. Next capture passes: 1. Use `--frame-size 6` to avoid misleading `1 + 5` packet splits. 2. Capture a quiet baseline for 30 seconds. 3. Capture separate files while pressing one control repeatedly, naming the action in the filename. 4. Later, capture pin 7 when connected to a real CCU/camera or a controlled test transmitter. ### 2026-05-13 Baseline vs CAM POWER Capture Capture files: - `captures/rcp-pin4-baseline.txt` - `captures/rcp-pin4-cam-power.txt` - `captures/rcp-pin4-call.txt` Frame counts from the available logs: | Capture | Frame | Count | Current label | | --- | --- | ---: | --- | | baseline | `00 00 00 00 80 DA` | 67 | idle heartbeat | | CAM POWER | `00 00 00 00 80 DA` | 23 | idle heartbeat | | CAM POWER | `00 00 07 80 00 DD` | 4 | CAM POWER candidate | | CALL | `00 00 00 00 80 DA` | 17 | idle heartbeat | | CALL | `00 00 15 80 00 CF` | 4 | CALL candidate, state/high bit set | | CALL | `00 00 15 00 00 4F` | 4 | CALL candidate, state/high bit clear | Current interpretation: - The baseline capture contains only `00 00 00 00 80 DA`. - Pressing `CAM POWER` introduces `00 00 07 80 00 DD`. - Pressing `CALL` introduces `00 00 15 80 00 CF` and `00 00 15 00 00 4F`. - Other tested buttons did not obviously produce unique frames while the panel was not connected to a CCU/camera. - `CAM POWER` and `CALL` may be among the few controls the panel transmits even without a completed host/CCU session. - The CALL frames differ by byte 4 (`80` vs `00`) and final byte (`CF` vs `4F`), suggesting a state bit plus checksum or complement-style trailing byte. - Current checksum hypothesis: byte 6 is XOR checksum with seed `0x5A` over the first five bytes. Examples: - `5A xor 00 xor 00 xor 00 xor 00 xor 80 = DA` - `5A xor 00 xor 00 xor 07 xor 80 xor 00 = DD` - `5A xor 00 xor 00 xor 15 xor 80 xor 00 = CF` - `5A xor 00 xor 00 xor 15 xor 00 xor 00 = 4F` Helper for future captures: ```powershell python scripts/analyze_capture.py captures/rcp-pin4-baseline.txt captures/rcp-pin4-cam-power.txt captures/rcp-pin4-call.txt ``` ## Host Response Experiments The RCP currently appears to be in an offline heartbeat state. With no CCU/camera response present, only `CAM POWER` and `CALL` have been observed to send unique frames beyond the heartbeat. The next protocol step is to learn what the RCP expects on pin 7 (`CCU/camera -> RCP`). Important wiring for host-response tests: | Adapter terminal | RCP-TX7 cable pin | Cable color | Purpose | | --- | ---: | --- | --- | | `GND` | 9 | brown | Shared reference / DC return | | `TXD` | 7 | purple | Candidate host-to-RCP transmit line | Suggested safety precautions: - Use the adapter's RS-232 side, not TTL UART. - Keep adapter `RXD` on pin 4 if possible so the RCP output is still logged. - Add a series resistor, for example 1 k to 4.7 k, between adapter `TXD` and pin 7 for early experiments. - Send one candidate frame at a time or repeat at a slow cadence. Avoid brute forcing unknown byte ranges. - Watch for changes in heartbeat, LCD state, panel lock state, or new frames on pin 4. Frame sender: ```powershell python scripts/serial_send_frame.py --port COM3 --dry-run python scripts/serial_send_frame.py --port COM3 --frame "00 00 00 00 80 DA" --repeat 5 --interval 0.2 ``` On Windows, a COM port is usually exclusive, so the sniffer and sender cannot open the same adapter at the same time. Use the combined probe script when RXD is connected to pin 4 and TXD is connected to pin 7: ```powershell python scripts/serial_probe_response.py --port COM3 --tx-frame "00 00 00 00 80 DA" --repeat 5 --interval 0.2 --log captures/rcp-response-test.txt ``` This listens first, sends the candidate response from the same serial session, then keeps listening for changes on pin 4. Candidate first response: - `00 00 00 00 80 DA` - mirror the observed heartbeat as a possible no-op/ack. If mirroring the heartbeat changes nothing, the next low-risk approach is to capture a real CCU/camera response rather than guessing. If no host is available, try only checksum-valid, documented-frame-shape candidates and record every attempt in a separate capture log. ### 2026-05-13 Heartbeat Mirror Response Result Experiment: - Adapter `TXD` connected to RCP pin 7. - Sent `00 00 00 00 80 DA` on the host-to-RCP line as a mirrored heartbeat / possible no-op acknowledgement. - Capture file: `captures/rcp-response-heartbeat-mirror.txt`. Observed result: - The RCP screen changed to `CONNECT: NOT ACT`. - During this capture, pin 4 still transmitted only `00 00 00 00 80 DA`. - Frame count: 59 received heartbeat frames, 10 transmitted mirrored heartbeat frames. - Pin 4 heartbeat timing became more frequent during the response window, then returned to the slower baseline cadence afterward. Current interpretation: - The RCP is detecting return-channel traffic on pin 7. - Mirroring the heartbeat is enough to move the panel out of the simple offline state, but it does not complete active host/CCU negotiation. - `NOT ACT` likely means connected/not active, connected/not activated, or a similar state where the link is electrically/protocol-visible but no valid control session has been established. - The RCP did not emit a new command/status frame on pin 4 in response to the mirrored heartbeat, so the next handshake step is probably not simply an echo of its heartbeat. Additional checksum-valid response tests: | Capture | TX frame | RX result on pin 4 | Screen result | | --- | --- | --- | --- | | `captures/rcp-response-zero-state.txt` | `00 00 00 00 00 5A` | heartbeat only | `CONNECT: NOT ACT` | | `captures/rcp-response-state-byte4.txt` | `00 00 00 80 00 DA` | heartbeat only | `CONNECT: NOT ACT` | | `captures/rcp-response-invalid-checksum.txt` | `00 00 00 00 80 00` | heartbeat only | `CONNECT: NOT ACT` | | TXD connected, no transmitted bytes | RS-232 idle only | heartbeat only | no `CONNECT: NOT ACT` | | Single-byte test | `00` | heartbeat only | no `CONNECT: NOT ACT` | | Single-byte test | `FF` | heartbeat only | no `CONNECT: NOT ACT` | | Short-frame test | `00 00 00` | heartbeat only | no `CONNECT: NOT ACT` | | Frame-length test | `00 00 00 00` | heartbeat only | no `CONNECT: NOT ACT` | | Frame-length test | `00 00 00 00 80` | heartbeat only | no `CONNECT: NOT ACT` | | Frame-length test | `00 00 00 00 80 DA 00` | heartbeat only | `CONNECT: NOT ACT` | Updated interpretation: - `CONNECT: NOT ACT` is probably a link-present state, not proof of a correct CCU handshake. - The RCP reacts to several checksum-valid 6-byte frames on pin 7, but continues sending only the pin 4 heartbeat. - An intentionally invalid checksum frame also produced `CONNECT: NOT ACT`, so that display state does not prove checksum acceptance. - The response needed to enter an active control session likely needs a specific status/identity/activation frame, not just a valid no-op frame shape. - TXD connected at idle without transmitted bytes did not produce `CONNECT: NOT ACT`, so the display state appears to require received byte activity on pin 7, not merely a driven RS-232 idle level. - Single-byte and three-byte transmissions did not produce `CONNECT: NOT ACT`, so the RCP is likely recognizing a minimum frame length or parser shape rather than arbitrary serial bytes. - Four-byte and five-byte transmissions did not produce `CONNECT: NOT ACT`, but a seven-byte transmission beginning with the known six-byte heartbeat did. This suggests the first six bytes are enough to trigger the parser/link state, and the seventh byte may be ignored, buffered for a later frame, or treated as extra data after the recognized packet. - None of the tested host frames have caused the RCP to emit anything on pin 4 except the heartbeat. Command-field response tests, using frame shape `00 00 CMD 00 80 CHECKSUM`: | Capture | TX frame | Checksum | Screen result | Notes | | --- | --- | --- | --- | --- | | `captures/rcp-response-cmd01.txt` | `00 00 01 00 80 DB` | valid | `CONNECT: NOT ACT` | 6-byte command-shaped frame accepted enough to change display. | | `captures/rcp-response-cmd02.txt` | `00 00 02 00 80 DB` | invalid | `CONNECT: NOT ACT` | Bad checksum still changed display. | | `captures/rcp-response-cmd02.txt` | `00 00 02 00 80 D8` | valid | `CONNECT: NOT ACT` | Valid checksum also changed display. | | `captures/rcp-response-cmd03.txt` | `00 00 03 00 80 D9` | valid | `CONNECT: NOT ACT` | 6-byte command-shaped frame accepted enough to change display. | | `captures/rcp-response-cmd04.txt` | `00 00 7F 00 80 A5` | valid | no screen change | First observed checksum-valid 6-byte frame that does not trigger `CONNECT: NOT ACT`. | | `captures/rcp-response-cmd05.txt` | `00 00 80 00 80 5A` | valid | `CONNECT: NOT ACT` | 6-byte command-shaped frame accepted enough to change display. | Implications from command-field tests: - Screen change is not simply based on frame length or checksum validity. - The command/status byte matters: `0x7F` appears ignored or treated as non-link-establishing, despite a valid checksum. - Tested commands `0x00`, `0x01`, `0x02`, `0x03`, and `0x80` can trigger `CONNECT: NOT ACT`; `0x7F` did not. - The RCP operating manual notes that `CAM POWER`, `MASTER`/`SLAVE`, and some monitor functions are available only when connected to a CCU, so active state may depend on CCU identity/status bits. Next low-risk response experiments: 1. Repeat the same test with logging enabled so the pin 4 output before, during, and after `CONNECT: NOT ACT` is captured. 2. Try sending the mirrored heartbeat continuously at a cadence close to the RCP heartbeat, for example every 0.6 seconds, and watch whether the display state changes. 3. Probe semantic fields within the six-byte frame shape, changing one byte at a time and logging both screen state and pin 4 output. Prioritize small command values and avoid broad brute-force sweeps. 4. Prefer capturing a real CCU/camera pin 7 response before broad guessing. ### Command Sweep Helper A cautious command-byte sweep helper is available at `scripts/serial_sweep_commands.py`. It sends only checksum-valid six-byte frames using the current frame/checksum hypothesis and marks any RCP output that is not the known heartbeat. Recommended first sweep: ```powershell python scripts/serial_sweep_commands.py --port COM5 --start 0x00 --end 0x20 --after-each 1.0 --log captures/rcp-sweep-cmd-00-20.txt ``` Optional dry run: ```powershell python scripts/serial_sweep_commands.py --port COM5 --start 0x00 --end 0x20 --dry-run ``` Use small ranges and keep watching the RCP screen while the sweep runs. The log captures TX/RX bytes, but it cannot record screen messages unless they are noted manually afterward. The `0x00-0x20` sweep produced `CONNECT: NOT ACT` roughly halfway through the run, but the exact command was not recorded in the log. Rerun a narrower range with manual screen prompts: ```powershell python scripts/serial_sweep_commands.py --port COM5 --start 0x0C --end 0x14 --after-each 1.2 --prompt-screen --log captures/rcp-sweep-cmd-0c-14-screen.txt ``` At each prompt, press Enter for no screen change, type `CONNECT: NOT ACT` when that appears, or type `q` to stop. Prompted sweep result: - Capture: `captures/rcp-sweep-cmd-0c-14-screen.txt`. - The RCP was reset after each screen trigger to clear its state, so recorded triggers should be treated as independent fresh observations. - First recorded screen marker: after command `0x0C`, frame `00 00 0C 00 80 D6`, screen `CONNECT: NOT ACT`. - Later manual screen markers were recorded after `0x0D`, `0x10`, `0x11`, `0x12`, `0x13`, and `0x14`. - No manual screen markers were recorded after `0x0E` or `0x0F`. - Pin 4 output remained the heartbeat `00 00 00 00 80 DA` throughout. Interpretation: - Commands `0x0C`, `0x0D`, `0x10`, `0x11`, `0x12`, `0x13`, and `0x14` have independent evidence of triggering `CONNECT: NOT ACT` in this sweep. - Commands `0x0E` and `0x0F` did not have a screen marker recorded in this sweep and are current non-trigger candidates. - Because pin 4 stayed heartbeat-only, this state change is visible on the LCD but does not yet produce a new RCP-to-host serial response. Second prompted sweep result: - Capture: `captures/rcp-sweep-cmd-15-30-screen.txt`. - The log includes one partial/restarted pass at the beginning, then a fuller prompted sweep through `0x30`. - Pin 4 output remained the heartbeat `00 00 00 00 80 DA` throughout. Commands with recorded `CONNECT: NOT ACT` screen markers: | Command | TX frame | | ---: | --- | | `0x15` | `00 00 15 00 80 CF` | | `0x16` | `00 00 16 00 80 CC` | | `0x17` | `00 00 17 00 80 CD` | | `0x18` | `00 00 18 00 80 C2` | | `0x19` | `00 00 19 00 80 C3` | | `0x1A` | `00 00 1A 00 80 C0` | | `0x1B` | `00 00 1B 00 80 C1` | | `0x1C` | `00 00 1C 00 80 C6` | | `0x1D` | `00 00 1D 00 80 C7` | | `0x28` | `00 00 28 00 80 F2` | | `0x29` | `00 00 29 00 80 F3` | | `0x2C` | `00 00 2C 00 80 F6` | | `0x2D` | `00 00 2D 00 80 F7` | | `0x30` | `00 00 30 00 80 EA` | Commands with no recorded screen marker in this sweep: ```text 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x2A 0x2B 0x2E 0x2F ``` Emerging pattern: - Some command byte ranges trigger `CONNECT: NOT ACT` while nearby checksum-valid commands do not. - Triggering still does not make the RCP transmit anything except the heartbeat. - `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 ```