From 693735dc0ad9b5b322c3b7870aad82085bec038d Mon Sep 17 00:00:00 2001 From: Aiden <68633820+awils27@users.noreply.github.com> Date: Wed, 13 May 2026 17:13:30 +1000 Subject: [PATCH] run 13 --- .../rcp-buttons-call-adjacent-44-host.txt | 23 ++ .../rcp-buttons-call-adjacent-45-host.txt | 23 ++ .../rcp-buttons-call-adjacent-45-state10.txt | 23 ++ .../rcp-buttons-call-adjacent-45-state30.txt | 23 ++ .../rcp-buttons-call-adjacent-46-exact.txt | 23 ++ .../rcp-buttons-call-adjacent-46-host.txt | 17 ++ captures/rcp-buttons-cold-call-high-only.txt | 24 ++ captures/rcp-buttons-cold-call-low-only.txt | 32 +++ .../rcp-buttons-cold-call-pair-gap-50ms.txt | 40 +++ .../rcp-buttons-cold-call-pair-gap-80ms.txt | 30 +++ ...rcp-buttons-cold-call-repeat-2x-gap-2s.txt | 32 +++ ...rcp-buttons-cold-call-repeat-2x-gap-5s.txt | 26 ++ ...rcp-buttons-cold-call-repeat-3x-gap-2s.txt | 30 +++ docs/discovery-notes.md | 216 ++++++++++++++++ docs/pt2-protocol-summary.md | 235 ++++++++++++++++++ ...erial_button_response_test.cpython-312.pyc | Bin 19685 -> 22012 bytes scripts/serial_button_response_test.py | 56 ++++- 17 files changed, 848 insertions(+), 5 deletions(-) create mode 100644 captures/rcp-buttons-call-adjacent-44-host.txt create mode 100644 captures/rcp-buttons-call-adjacent-45-host.txt create mode 100644 captures/rcp-buttons-call-adjacent-45-state10.txt create mode 100644 captures/rcp-buttons-call-adjacent-45-state30.txt create mode 100644 captures/rcp-buttons-call-adjacent-46-exact.txt create mode 100644 captures/rcp-buttons-call-adjacent-46-host.txt create mode 100644 captures/rcp-buttons-cold-call-high-only.txt create mode 100644 captures/rcp-buttons-cold-call-low-only.txt create mode 100644 captures/rcp-buttons-cold-call-pair-gap-50ms.txt create mode 100644 captures/rcp-buttons-cold-call-pair-gap-80ms.txt create mode 100644 captures/rcp-buttons-cold-call-repeat-2x-gap-2s.txt create mode 100644 captures/rcp-buttons-cold-call-repeat-2x-gap-5s.txt create mode 100644 captures/rcp-buttons-cold-call-repeat-3x-gap-2s.txt create mode 100644 docs/pt2-protocol-summary.md diff --git a/captures/rcp-buttons-call-adjacent-44-host.txt b/captures/rcp-buttons-call-adjacent-44-host.txt new file mode 100644 index 0000000..f835511 --- /dev/null +++ b/captures/rcp-buttons-call-adjacent-44-host.txt @@ -0,0 +1,23 @@ +Button test on COM5 at 38400 8N1 +Listening for 15.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:07:02.173 TX startup frame 006 00 00 15 80 00 CF +17:07:02.224 TX startup frame 006 00 00 15 00 00 4F +17:07:02.255 RX 018 bytes 00 00 00 00 80 DA 00 00 00 00 80 DA 07 80 45 20 D0 68 +17:07:02.255 DETECT heartbeat x2 +17:07:02.255 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:07:02.305 TX watch follow-up frame 006 00 00 44 20 D0 EE +17:07:02.913 RX 006 bytes 00 00 00 00 80 DA +17:07:02.913 DETECT heartbeat x1 +17:07:03.159 RX 006 bytes 00 00 00 00 80 DA +17:07:03.159 DETECT heartbeat x1 +17:07:03.403 RX 001 bytes 00 +17:07:03.433 RX 005 bytes 00 00 00 80 DA +17:07:03.646 RX 001 bytes 00 +17:07:03.686 RX 005 bytes 00 00 00 80 DA +17:07:03.899 RX 001 bytes 00 +17:07:03.930 RX 005 bytes 00 00 00 80 DA +17:07:04.173 RX 006 bytes 00 00 00 00 80 DA +17:07:04.173 DETECT heartbeat x1 +17:07:04.814 RX 006 bytes 00 00 00 00 80 DA +17:07:04.814 DETECT heartbeat x1 +Stopped. diff --git a/captures/rcp-buttons-call-adjacent-45-host.txt b/captures/rcp-buttons-call-adjacent-45-host.txt new file mode 100644 index 0000000..7a831c6 --- /dev/null +++ b/captures/rcp-buttons-call-adjacent-45-host.txt @@ -0,0 +1,23 @@ +Button test on COM5 at 38400 8N1 +Listening for 15.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:07:18.913 TX startup frame 006 00 00 15 80 00 CF +17:07:18.964 TX startup frame 006 00 00 15 00 00 4F +17:07:18.995 RX 018 bytes 00 00 00 00 80 DA 00 00 00 00 80 DA 07 80 45 20 D0 68 +17:07:18.995 DETECT heartbeat x2 +17:07:18.995 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:07:19.045 TX watch follow-up frame 006 00 00 45 20 D0 EF +17:07:19.655 RX 001 bytes 00 +17:07:19.685 RX 005 bytes 00 00 00 80 DA +17:07:19.898 RX 001 bytes 00 +17:07:19.930 RX 005 bytes 00 00 00 80 DA +17:07:20.174 RX 006 bytes 00 00 00 00 80 DA +17:07:20.174 DETECT heartbeat x1 +17:07:20.418 RX 006 bytes 00 00 00 00 80 DA +17:07:20.418 DETECT heartbeat x1 +17:07:20.661 RX 001 bytes 00 +17:07:20.692 RX 005 bytes 00 00 00 80 DA +17:07:20.904 RX 001 bytes 00 +17:07:20.934 RX 005 bytes 00 00 00 80 DA +17:07:21.547 RX 001 bytes 00 +17:07:21.577 RX 005 bytes 00 00 00 80 DA +Stopped. diff --git a/captures/rcp-buttons-call-adjacent-45-state10.txt b/captures/rcp-buttons-call-adjacent-45-state10.txt new file mode 100644 index 0000000..ffc9a60 --- /dev/null +++ b/captures/rcp-buttons-call-adjacent-45-state10.txt @@ -0,0 +1,23 @@ +Button test on COM5 at 38400 8N1 +Listening for 15.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:08:17.213 TX startup frame 006 00 00 15 80 00 CF +17:08:17.265 TX startup frame 006 00 00 15 00 00 4F +17:08:17.295 RX 018 bytes 00 00 00 00 80 DA 00 00 00 00 80 DA 07 80 45 20 D0 68 +17:08:17.295 DETECT heartbeat x2 +17:08:17.295 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:08:17.347 TX watch follow-up frame 006 07 80 45 10 D0 58 +17:08:17.958 RX 001 bytes 00 +17:08:17.989 RX 005 bytes 00 00 00 80 DA +17:08:18.234 RX 006 bytes 00 00 00 00 80 DA +17:08:18.234 DETECT heartbeat x1 +17:08:18.480 RX 006 bytes 00 00 00 00 80 DA +17:08:18.480 DETECT heartbeat x1 +17:08:18.725 RX 006 bytes 00 00 00 00 80 DA +17:08:18.725 DETECT heartbeat x1 +17:08:18.970 RX 001 bytes 00 +17:08:19.000 RX 005 bytes 00 00 00 80 DA +17:08:19.214 RX 001 bytes 00 +17:08:19.244 RX 005 bytes 00 00 00 80 DA +17:08:19.856 RX 001 bytes 00 +17:08:19.887 RX 005 bytes 00 00 00 80 DA +Stopped. diff --git a/captures/rcp-buttons-call-adjacent-45-state30.txt b/captures/rcp-buttons-call-adjacent-45-state30.txt new file mode 100644 index 0000000..87a5682 --- /dev/null +++ b/captures/rcp-buttons-call-adjacent-45-state30.txt @@ -0,0 +1,23 @@ +Button test on COM5 at 38400 8N1 +Listening for 15.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:08:00.937 TX startup frame 006 00 00 15 80 00 CF +17:08:00.988 TX startup frame 006 00 00 15 00 00 4F +17:08:01.018 RX 018 bytes 00 00 00 00 80 DA 00 00 00 00 80 DA 07 80 45 20 D0 68 +17:08:01.018 DETECT heartbeat x2 +17:08:01.018 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:08:01.069 TX watch follow-up frame 006 07 80 45 30 D0 78 +17:08:01.618 RX 001 bytes 00 +17:08:01.648 RX 005 bytes 00 00 00 80 DA +17:08:01.864 RX 001 bytes 00 +17:08:01.895 RX 005 bytes 00 00 00 80 DA +17:08:02.139 RX 006 bytes 00 00 00 00 80 DA +17:08:02.139 DETECT heartbeat x1 +17:08:02.384 RX 006 bytes 00 00 00 00 80 DA +17:08:02.384 DETECT heartbeat x1 +17:08:02.627 RX 006 bytes 00 00 00 00 80 DA +17:08:02.627 DETECT heartbeat x1 +17:08:02.873 RX 001 bytes 00 +17:08:02.903 RX 005 bytes 00 00 00 80 DA +17:08:03.511 RX 001 bytes 00 +17:08:03.542 RX 005 bytes 00 00 00 80 DA +Stopped. diff --git a/captures/rcp-buttons-call-adjacent-46-exact.txt b/captures/rcp-buttons-call-adjacent-46-exact.txt new file mode 100644 index 0000000..d4750c4 --- /dev/null +++ b/captures/rcp-buttons-call-adjacent-46-exact.txt @@ -0,0 +1,23 @@ +Button test on COM5 at 38400 8N1 +Listening for 15.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:08:32.940 TX startup frame 006 00 00 15 80 00 CF +17:08:32.991 TX startup frame 006 00 00 15 00 00 4F +17:08:33.021 RX 012 bytes 00 00 00 00 80 DA 07 80 45 20 D0 68 +17:08:33.021 DETECT heartbeat x1 +17:08:33.021 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:08:33.072 TX watch follow-up frame 006 07 80 46 20 D0 6B +17:08:33.681 RX 001 bytes 00 +17:08:33.712 RX 005 bytes 00 00 00 80 DA +17:08:33.924 RX 001 bytes 00 +17:08:33.955 RX 005 bytes 00 00 00 80 DA +17:08:34.198 RX 006 bytes 00 00 00 00 80 DA +17:08:34.198 DETECT heartbeat x1 +17:08:34.441 RX 001 bytes 00 +17:08:34.471 RX 005 bytes 00 00 00 80 DA +17:08:34.685 RX 001 bytes 00 +17:08:34.715 RX 005 bytes 00 00 00 80 DA +17:08:34.960 RX 006 bytes 00 00 00 00 80 DA +17:08:34.960 DETECT heartbeat x1 +17:08:35.600 RX 006 bytes 00 00 00 00 80 DA +17:08:35.600 DETECT heartbeat x1 +Stopped. diff --git a/captures/rcp-buttons-call-adjacent-46-host.txt b/captures/rcp-buttons-call-adjacent-46-host.txt new file mode 100644 index 0000000..2e0a3f2 --- /dev/null +++ b/captures/rcp-buttons-call-adjacent-46-host.txt @@ -0,0 +1,17 @@ +Button test on COM5 at 38400 8N1 +Listening for 15.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:07:40.109 TX startup frame 006 00 00 15 80 00 CF +17:07:40.160 TX startup frame 006 00 00 15 00 00 4F +17:07:40.190 RX 012 bytes 00 00 00 00 80 DA 07 80 45 20 D0 68 +17:07:40.190 DETECT heartbeat x1 +17:07:40.190 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:07:40.241 TX watch follow-up frame 006 00 00 46 20 D0 EC +17:07:42.159 RX 001 bytes 00 +17:07:42.190 RX 005 bytes 00 00 00 80 DA +17:07:42.860 RX 006 bytes 00 00 00 00 80 DA +17:07:42.860 DETECT heartbeat x1 +17:07:43.564 RX 006 bytes 00 00 00 00 80 DA +17:07:43.564 DETECT heartbeat x1 +17:07:44.265 RX 006 bytes 00 00 00 00 80 DA +17:07:44.265 DETECT heartbeat x1 +Stopped. diff --git a/captures/rcp-buttons-cold-call-high-only.txt b/captures/rcp-buttons-cold-call-high-only.txt new file mode 100644 index 0000000..601c2b8 --- /dev/null +++ b/captures/rcp-buttons-cold-call-high-only.txt @@ -0,0 +1,24 @@ +Button test on COM5 at 38400 8N1 +Listening for 12.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +16:55:43.337 TX startup frame 006 00 00 15 80 00 CF +16:55:43.367 RX 012 bytes 00 00 00 00 80 DA 00 00 00 00 80 DA +16:55:43.367 DETECT heartbeat x2 +16:55:43.854 RX 001 bytes 00 +16:55:43.885 RX 005 bytes 00 00 00 80 DA +16:55:44.098 RX 001 bytes 00 +16:55:44.128 RX 005 bytes 00 00 00 80 DA +16:55:44.371 RX 006 bytes 00 00 00 00 80 DA +16:55:44.371 DETECT heartbeat x1 +16:55:44.617 RX 006 bytes 00 00 00 00 80 DA +16:55:44.617 DETECT heartbeat x1 +16:55:44.861 RX 001 bytes 00 +16:55:44.892 RX 005 bytes 00 00 00 80 DA +16:55:45.105 RX 001 bytes 00 +16:55:45.135 RX 005 bytes 00 00 00 80 DA +16:55:45.745 RX 001 bytes 00 +16:55:45.776 RX 005 bytes 00 00 00 80 DA +16:55:46.446 RX 001 bytes 00 +16:55:46.476 RX 005 bytes 00 00 00 80 DA +16:55:47.145 RX 001 bytes 00 +16:55:47.176 RX 005 bytes 00 00 00 80 DA +Stopped. diff --git a/captures/rcp-buttons-cold-call-low-only.txt b/captures/rcp-buttons-cold-call-low-only.txt new file mode 100644 index 0000000..003d726 --- /dev/null +++ b/captures/rcp-buttons-cold-call-low-only.txt @@ -0,0 +1,32 @@ +Button test on COM5 at 38400 8N1 +Listening for 12.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +16:56:01.495 TX startup frame 006 00 00 15 00 00 4F +16:56:01.526 RX 011 bytes 00 00 00 80 DA 00 00 00 00 80 DA +16:56:01.526 DETECT heartbeat x1 +16:56:01.892 RX 001 bytes 00 +16:56:01.922 RX 005 bytes 00 00 00 80 DA +16:56:02.164 RX 006 bytes 00 00 00 00 80 DA +16:56:02.164 DETECT heartbeat x1 +16:56:02.410 RX 006 bytes 00 00 00 00 80 DA +16:56:02.410 DETECT heartbeat x1 +16:56:02.657 RX 006 bytes 00 00 00 00 80 DA +16:56:02.657 DETECT heartbeat x1 +16:56:02.901 RX 001 bytes 00 +16:56:02.931 RX 005 bytes 00 00 00 80 DA +16:56:03.145 RX 001 bytes 00 +16:56:03.176 RX 005 bytes 00 00 00 80 DA +16:56:03.421 RX 006 bytes 00 00 00 00 80 DA +16:56:03.421 DETECT heartbeat x1 +16:56:04.090 RX 001 bytes 00 +16:56:04.120 RX 005 bytes 00 00 00 80 DA +16:56:04.793 RX 001 bytes 00 +16:56:04.823 RX 005 bytes 00 00 00 80 DA +16:56:05.494 RX 001 bytes 00 +16:56:05.525 RX 005 bytes 00 00 00 80 DA +16:56:06.196 RX 001 bytes 00 +16:56:06.227 RX 005 bytes 00 00 00 80 DA +16:56:06.899 RX 001 bytes 00 +16:56:06.929 RX 005 bytes 00 00 00 80 DA +16:56:07.600 RX 006 bytes 00 00 00 00 80 DA +16:56:07.600 DETECT heartbeat x1 +Stopped. diff --git a/captures/rcp-buttons-cold-call-pair-gap-50ms.txt b/captures/rcp-buttons-cold-call-pair-gap-50ms.txt new file mode 100644 index 0000000..0106cae --- /dev/null +++ b/captures/rcp-buttons-cold-call-pair-gap-50ms.txt @@ -0,0 +1,40 @@ +Button test on COM5 at 38400 8N1 +Listening for 12.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +16:54:57.270 TX startup frame 006 00 00 15 80 00 CF +16:54:57.320 TX startup frame 006 00 00 15 00 00 4F +16:54:57.351 RX 012 bytes 00 00 00 00 80 DA 07 80 45 20 D0 68 +16:54:57.351 DETECT heartbeat x1 +16:54:57.351 DETECT watch-frame 07 80 45 20 D0 68 x1 +16:54:58.021 RX 006 bytes 00 00 00 00 80 DA +16:54:58.021 DETECT heartbeat x1 +16:54:58.265 RX 006 bytes 00 00 00 00 80 DA +16:54:58.265 DETECT heartbeat x1 +16:54:58.511 RX 006 bytes 00 00 00 00 80 DA +16:54:58.511 DETECT heartbeat x1 +16:54:58.754 RX 001 bytes 00 +16:54:58.785 RX 005 bytes 00 00 00 80 DA +16:54:58.999 RX 001 bytes 00 +16:54:59.029 RX 005 bytes 00 00 00 80 DA +16:54:59.275 RX 006 bytes 00 00 00 00 80 DA +16:54:59.275 DETECT heartbeat x1 +16:54:59.918 RX 006 bytes 00 00 00 00 80 DA +16:54:59.918 DETECT heartbeat x1 +16:55:00.619 RX 006 bytes 00 00 00 00 80 DA +16:55:00.619 DETECT heartbeat x1 +16:55:01.321 RX 006 bytes 00 00 00 00 80 DA +16:55:01.321 DETECT heartbeat x1 +16:55:02.021 RX 006 bytes 00 00 00 00 80 DA +16:55:02.021 DETECT heartbeat x1 +16:55:02.694 RX 001 bytes 00 +16:55:02.725 RX 005 bytes 00 00 00 80 DA +16:55:03.395 RX 001 bytes 00 +16:55:03.425 RX 005 bytes 00 00 00 80 DA +16:55:04.097 RX 001 bytes 00 +16:55:04.127 RX 005 bytes 00 00 00 80 DA +16:55:04.800 RX 001 bytes 00 +16:55:04.831 RX 005 bytes 00 00 00 80 DA +16:55:05.500 RX 001 bytes 00 +16:55:05.531 RX 005 bytes 00 00 00 80 DA +16:55:06.202 RX 001 bytes 00 +16:55:06.233 RX 005 bytes 00 00 00 80 DA +Stopped. diff --git a/captures/rcp-buttons-cold-call-pair-gap-80ms.txt b/captures/rcp-buttons-cold-call-pair-gap-80ms.txt new file mode 100644 index 0000000..6f50fe8 --- /dev/null +++ b/captures/rcp-buttons-cold-call-pair-gap-80ms.txt @@ -0,0 +1,30 @@ +Button test on COM5 at 38400 8N1 +Listening for 12.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +16:55:23.344 TX startup frame 006 00 00 15 80 00 CF +16:55:23.425 TX startup frame 006 00 00 15 00 00 4F +16:55:23.455 RX 018 bytes 00 00 00 00 80 DA 00 00 00 00 80 DA 07 80 45 20 D0 68 +16:55:23.455 DETECT heartbeat x2 +16:55:23.455 DETECT watch-frame 07 80 45 20 D0 68 x1 +16:55:24.124 RX 001 bytes 00 +16:55:24.155 RX 005 bytes 00 00 00 80 DA +16:55:24.368 RX 001 bytes 00 +16:55:24.398 RX 005 bytes 00 00 00 80 DA +16:55:24.644 RX 006 bytes 00 00 00 00 80 DA +16:55:24.644 DETECT heartbeat x1 +16:55:24.888 RX 006 bytes 00 00 00 00 80 DA +16:55:24.888 DETECT heartbeat x1 +16:55:25.132 RX 001 bytes 00 +16:55:25.162 RX 005 bytes 00 00 00 80 DA +16:55:25.375 RX 001 bytes 00 +16:55:25.405 RX 005 bytes 00 00 00 80 DA +16:55:26.044 RX 006 bytes 00 00 00 00 80 DA +16:55:26.044 DETECT heartbeat x1 +16:55:26.743 RX 006 bytes 00 00 00 00 80 DA +16:55:26.743 DETECT heartbeat x1 +16:55:27.443 RX 006 bytes 00 00 00 00 80 DA +16:55:27.443 DETECT heartbeat x1 +16:55:28.143 RX 006 bytes 00 00 00 00 80 DA +16:55:28.143 DETECT heartbeat x1 +16:55:28.845 RX 006 bytes 00 00 00 00 80 DA +16:55:28.845 DETECT heartbeat x1 +Stopped. diff --git a/captures/rcp-buttons-cold-call-repeat-2x-gap-2s.txt b/captures/rcp-buttons-cold-call-repeat-2x-gap-2s.txt new file mode 100644 index 0000000..0ae389c --- /dev/null +++ b/captures/rcp-buttons-cold-call-repeat-2x-gap-2s.txt @@ -0,0 +1,32 @@ +Button test on COM5 at 38400 8N1 +Listening for 16.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:05:38.733 TX startup frame 006 00 00 15 80 00 CF +17:05:38.784 TX startup frame 006 00 00 15 00 00 4F +17:05:40.785 TX startup frame 006 00 00 15 80 00 CF +17:05:40.837 TX startup frame 006 00 00 15 00 00 4F +17:05:40.868 RX 048 bytes 00 00 00 00 80 DA 07 80 45 20 D0 68 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA +17:05:40.868 DETECT heartbeat x7 +17:05:40.868 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:05:41.356 RX 001 bytes 00 +17:05:41.387 RX 005 bytes 00 00 00 80 DA +17:05:41.602 RX 001 bytes 00 +17:05:41.632 RX 005 bytes 00 00 00 80 DA +17:05:41.845 RX 001 bytes 00 +17:05:41.875 RX 005 bytes 00 00 00 80 DA +17:05:42.119 RX 006 bytes 00 00 00 00 80 DA +17:05:42.119 DETECT heartbeat x1 +17:05:42.363 RX 006 bytes 00 00 00 00 80 DA +17:05:42.363 DETECT heartbeat x1 +17:05:42.606 RX 001 bytes 00 +17:05:42.637 RX 005 bytes 00 00 00 80 DA +17:05:43.248 RX 001 bytes 00 +17:05:43.278 RX 005 bytes 00 00 00 80 DA +17:05:43.949 RX 001 bytes 00 +17:05:43.980 RX 005 bytes 00 00 00 80 DA +17:05:44.649 RX 001 bytes 00 +17:05:44.679 RX 005 bytes 00 00 00 80 DA +17:05:45.350 RX 001 bytes 00 +17:05:45.380 RX 005 bytes 00 00 00 80 DA +17:05:46.048 RX 001 bytes 00 +17:05:46.078 RX 005 bytes 00 00 00 80 DA +Stopped. diff --git a/captures/rcp-buttons-cold-call-repeat-2x-gap-5s.txt b/captures/rcp-buttons-cold-call-repeat-2x-gap-5s.txt new file mode 100644 index 0000000..76e2095 --- /dev/null +++ b/captures/rcp-buttons-cold-call-repeat-2x-gap-5s.txt @@ -0,0 +1,26 @@ +Button test on COM5 at 38400 8N1 +Listening for 22.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:06:01.194 TX startup frame 006 00 00 15 80 00 CF +17:06:01.246 TX startup frame 006 00 00 15 00 00 4F +17:06:06.247 TX startup frame 006 00 00 15 80 00 CF +17:06:06.298 TX startup frame 006 00 00 15 00 00 4F +17:06:06.329 RX 072 bytes 00 00 00 00 80 DA 07 80 45 20 D0 68 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA +17:06:06.329 DETECT heartbeat x11 +17:06:06.329 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:06:06.635 RX 006 bytes 00 00 00 00 80 DA +17:06:06.635 DETECT heartbeat x1 +17:06:06.879 RX 001 bytes 00 +17:06:06.910 RX 005 bytes 00 00 00 80 DA +17:06:07.124 RX 001 bytes 00 +17:06:07.154 RX 005 bytes 00 00 00 80 DA +17:06:07.369 RX 001 bytes 00 +17:06:07.399 RX 005 bytes 00 00 00 80 DA +17:06:07.643 RX 006 bytes 00 00 00 00 80 DA +17:06:07.643 DETECT heartbeat x1 +17:06:07.890 RX 006 bytes 00 00 00 00 80 DA +17:06:07.890 DETECT heartbeat x1 +17:06:08.135 RX 001 bytes 00 +17:06:08.166 RX 005 bytes 00 00 00 80 DA +17:06:08.838 RX 006 bytes 00 00 00 00 80 DA +17:06:08.838 DETECT heartbeat x1 +Stopped. diff --git a/captures/rcp-buttons-cold-call-repeat-3x-gap-2s.txt b/captures/rcp-buttons-cold-call-repeat-3x-gap-2s.txt new file mode 100644 index 0000000..b52fd7c --- /dev/null +++ b/captures/rcp-buttons-cold-call-repeat-3x-gap-2s.txt @@ -0,0 +1,30 @@ +Button test on COM5 at 38400 8N1 +Listening for 24.0s; respond_to_cam_power=False, respond_to_call=False, mirror_call=False +17:06:27.096 TX startup frame 006 00 00 15 80 00 CF +17:06:27.148 TX startup frame 006 00 00 15 00 00 4F +17:06:29.149 TX startup frame 006 00 00 15 80 00 CF +17:06:29.200 TX startup frame 006 00 00 15 00 00 4F +17:06:31.201 TX startup frame 006 00 00 15 80 00 CF +17:06:31.253 TX startup frame 006 00 00 15 00 00 4F +17:06:31.283 RX 089 bytes 00 00 00 80 DA 00 00 00 00 80 DA 07 80 45 20 D0 68 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA 00 00 00 00 80 DA +17:06:31.283 DETECT heartbeat x13 +17:06:31.283 DETECT watch-frame 07 80 45 20 D0 68 x1 +17:06:31.590 RX 001 bytes 00 +17:06:31.620 RX 005 bytes 00 00 00 80 DA +17:06:31.833 RX 001 bytes 00 +17:06:31.864 RX 005 bytes 00 00 00 80 DA +17:06:32.108 RX 006 bytes 00 00 00 00 80 DA +17:06:32.108 DETECT heartbeat x1 +17:06:32.351 RX 006 bytes 00 00 00 00 80 DA +17:06:32.351 DETECT heartbeat x1 +17:06:32.594 RX 001 bytes 00 +17:06:32.625 RX 005 bytes 00 00 00 80 DA +17:06:32.837 RX 001 bytes 00 +17:06:32.867 RX 005 bytes 00 00 00 80 DA +17:06:33.112 RX 006 bytes 00 00 00 00 80 DA +17:06:33.112 DETECT heartbeat x1 +17:06:33.812 RX 006 bytes 00 00 00 00 80 DA +17:06:33.812 DETECT heartbeat x1 +17:06:34.482 RX 001 bytes 00 +17:06:34.513 RX 005 bytes 00 00 00 80 DA +Stopped. diff --git a/docs/discovery-notes.md b/docs/discovery-notes.md index b3d2565..37c1904 100644 --- a/docs/discovery-notes.md +++ b/docs/discovery-notes.md @@ -3276,3 +3276,219 @@ For each test, power-cycle first and do not press any panel buttons. If C1/C2 produce `0x45`, the host can synthesize the CALL event path. If they do not, the RCP's own physical CALL transition is required before the echo pair has meaning. + +### 2026-05-13 Cold No-Button CALL Injection Result + +Captures: + +- `captures/rcp-buttons-cold-call-pair-gap-50ms.txt` +- `captures/rcp-buttons-cold-call-pair-gap-80ms.txt` +- `captures/rcp-buttons-cold-call-high-only.txt` +- `captures/rcp-buttons-cold-call-low-only.txt` + +Observed result: + +| Test | Host startup frame(s) | Result | +| --- | --- | --- | +| C1 | `00 00 15 80 00 CF`, 50 ms gap, `00 00 15 00 00 4F` | `07 80 45 20 D0 68` | +| C2 | `00 00 15 80 00 CF`, 80 ms gap, `00 00 15 00 00 4F` | `07 80 45 20 D0 68` | +| C3 | `00 00 15 80 00 CF` only | heartbeat only | +| C4 | `00 00 15 00 00 4F` only | heartbeat only | + +Interpretation: + +- The host can synthesize the CALL `0x45` response path without pressing the + physical `CALL` button. +- The RCP does not require its own front-panel CALL transition before this path + has meaning. +- The required trigger is the ordered CALL-high then CALL-low pair with a small + inter-frame gap. Either frame alone is insufficient. +- This makes `00 00 15 80 00 CF -> 00 00 15 00 00 4F` a confirmed host-side + event stimulus, not merely an echo of physical button traffic. +- The response still returns to heartbeat afterward; this remains useful for + protocol probing but is not yet an activation/session handshake. + +### Next CALL Tests + +Two useful follow-ups now that the host can synthesize the CALL path: + +1. Determine whether the synthetic CALL trigger is repeatable within one power + cycle, or whether the first `0x45` response latches/suppresses later ones. +2. Probe adjacent `0x45` family responses that might drive the illuminated CALL + button or another visible state. + +### CALL Retrigger / Latch Tests + +Tooling note: + +- `scripts/serial_button_response_test.py` now supports repeating the startup + frame group with `--startup-repeat` and `--startup-repeat-interval`. + +Test R1: two synthetic CALL trigger cycles, 2 second gap. + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 16 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --startup-repeat 2 --startup-repeat-interval 2.0 --watch-frame "07 80 45 20 D0 68" --watch-frame "07 80 45 30 D0 78" --log captures/rcp-buttons-cold-call-repeat-2x-gap-2s.txt +``` + +Test R2: two synthetic CALL trigger cycles, 5 second gap. + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 22 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --startup-repeat 2 --startup-repeat-interval 5.0 --watch-frame "07 80 45 20 D0 68" --watch-frame "07 80 45 30 D0 78" --log captures/rcp-buttons-cold-call-repeat-2x-gap-5s.txt +``` + +Test R3: three synthetic CALL trigger cycles, 2 second gap. + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 24 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --startup-repeat 3 --startup-repeat-interval 2.0 --watch-frame "07 80 45 20 D0 68" --watch-frame "07 80 45 30 D0 78" --log captures/rcp-buttons-cold-call-repeat-3x-gap-2s.txt +``` + +Interpretation: + +- If `Watch totals` shows one `0x45` hit per trigger cycle, this path is + repeatable and not a one-shot latch. +- If only the first cycle produces `0x45`, treat the CALL path as latched until + power cycle or some unknown reset. +- If later cycles produce `07 80 45 30 D0 78` instead of `...20...`, the RCP + may be stepping through a small state machine rather than simply suppressing + repeats. + +### Adjacent `0x45` Family Follow-Up Tests + +Goal: once the synthetic CALL pair has produced `07 80 45 20 D0 68`, send nearby +frames that might act like CALL lamp/tally control. Watch the CALL button lamp, +LCD, and serial stream after each follow-up. + +Useful adjacent candidates: + +| Candidate type | Follow-up frame | Why it is interesting | +| --- | --- | --- | +| host-shaped command below | `00 00 44 20 D0 EE` | adjacent command byte | +| host-shaped command known | `00 00 45 20 D0 EF` | same command, host-shaped | +| host-shaped command above | `00 00 46 20 D0 EC` | adjacent command byte | +| exact-family sibling seen once | `07 80 45 30 D0 78` | observed adjacent state | +| exact-family state below | `07 80 45 10 D0 58` | nearby state nibble | +| exact-family command above | `07 80 46 20 D0 6B` | nearby command nibble | + +Run each candidate in a separate power cycle. The startup CALL pair is used only +to make the RCP produce the known `0x45` response first. + +Test A1: + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 15 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --watch-frame "07 80 45 20 D0 68" --followup-on-watch-frame --followup-frame "00 00 44 20 D0 EE" --log captures/rcp-buttons-call-adjacent-44-host.txt +``` + +Test A2: + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 15 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --watch-frame "07 80 45 20 D0 68" --followup-on-watch-frame --followup-frame "00 00 45 20 D0 EF" --log captures/rcp-buttons-call-adjacent-45-host.txt +``` + +Test A3: + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 15 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --watch-frame "07 80 45 20 D0 68" --followup-on-watch-frame --followup-frame "00 00 46 20 D0 EC" --log captures/rcp-buttons-call-adjacent-46-host.txt +``` + +Test A4: + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 15 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --watch-frame "07 80 45 20 D0 68" --followup-on-watch-frame --followup-frame "07 80 45 30 D0 78" --log captures/rcp-buttons-call-adjacent-45-state30.txt +``` + +Test A5: + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 15 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --watch-frame "07 80 45 20 D0 68" --followup-on-watch-frame --followup-frame "07 80 45 10 D0 58" --log captures/rcp-buttons-call-adjacent-45-state10.txt +``` + +Test A6: + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 15 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --watch-frame "07 80 45 20 D0 68" --followup-on-watch-frame --followup-frame "07 80 46 20 D0 6B" --log captures/rcp-buttons-call-adjacent-46-exact.txt +``` + +Record for each run: + +- whether the CALL button lamp changes +- whether the LCD changes +- whether any non-heartbeat serial data appears after the follow-up + +### 2026-05-13 Initial CALL Retrigger Result + +Captures: + +- `captures/rcp-buttons-cold-call-repeat-2x-gap-2s.txt` +- `captures/rcp-buttons-cold-call-repeat-2x-gap-5s.txt` +- `captures/rcp-buttons-cold-call-repeat-3x-gap-2s.txt` + +Observed result: + +- All configured synthetic CALL trigger cycles were transmitted. +- Each run recorded only one visible `07 80 45 20 D0 68`. +- No LCD change was observed beyond the already known `CONNECT NOT ACT`. + +Important tooling limitation: + +- In this first version of the repeat test, the helper sent all startup trigger + groups before entering its main RX loop. +- That means the captured `0x45` frame count is not a clean per-cycle measure. + A single buffered `0x45` at the end does not prove whether only one cycle + triggered or multiple triggers collapsed into one unread serial burst. + +Interpretation: + +- These runs suggest the CALL path may be latched or at least not obviously + retriggering, but they are not strong enough to prove it. +- A corrected repeat test must read after each trigger group before sending the + next one. + +Tooling update: + +- `scripts/serial_button_response_test.py` now supports + `--startup-read-after-group`, which reads and logs RX after each startup-frame + group before the next repeat. + +Corrected repeat tests: + +```powershell +python scripts/serial_button_response_test.py --port COM5 --duration 16 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --startup-repeat 2 --startup-repeat-interval 2.0 --startup-read-after-group 0.8 --watch-frame "07 80 45 20 D0 68" --watch-frame "07 80 45 30 D0 78" --log captures/rcp-buttons-cold-call-repeat-2x-gap-2s-v2.txt +python scripts/serial_button_response_test.py --port COM5 --duration 22 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --startup-repeat 2 --startup-repeat-interval 5.0 --startup-read-after-group 0.8 --watch-frame "07 80 45 20 D0 68" --watch-frame "07 80 45 30 D0 78" --log captures/rcp-buttons-cold-call-repeat-2x-gap-5s-v2.txt +python scripts/serial_button_response_test.py --port COM5 --duration 24 --prompt --startup-delay 1.0 --startup-frame-interval 0.05 --startup-frame "00 00 15 80 00 CF" --startup-frame "00 00 15 00 00 4F" --startup-repeat 3 --startup-repeat-interval 2.0 --startup-read-after-group 0.8 --watch-frame "07 80 45 20 D0 68" --watch-frame "07 80 45 30 D0 78" --log captures/rcp-buttons-cold-call-repeat-3x-gap-2s-v2.txt +``` + +### 2026-05-13 Adjacent `0x45` Follow-Up Result + +Captures: + +- `captures/rcp-buttons-call-adjacent-44-host.txt` +- `captures/rcp-buttons-call-adjacent-45-host.txt` +- `captures/rcp-buttons-call-adjacent-46-host.txt` +- `captures/rcp-buttons-call-adjacent-45-state30.txt` +- `captures/rcp-buttons-call-adjacent-45-state10.txt` +- `captures/rcp-buttons-call-adjacent-46-exact.txt` + +User observation: + +- No LCD changes were observed beyond the already known `CONNECT NOT ACT`. +- No CALL button lamp change was observed in these runs. + +Serial result: + +| Test | Follow-up frame after `07 80 45 20 D0 68` | Result | +| --- | --- | --- | +| A1 | `00 00 44 20 D0 EE` | heartbeat only after follow-up | +| A2 | `00 00 45 20 D0 EF` | heartbeat only after follow-up | +| A3 | `00 00 46 20 D0 EC` | heartbeat only after follow-up | +| A4 | `07 80 45 30 D0 78` | heartbeat only after follow-up | +| A5 | `07 80 45 10 D0 58` | heartbeat only after follow-up | +| A6 | `07 80 46 20 D0 6B` | heartbeat only after follow-up | + +Interpretation: + +- None of the first adjacent `0x45` family probes appear to drive the CALL lamp + or advance the serial state. +- The obvious nearby command/state variants are not enough on their own to act + like a CALL lamp/tally command. +- The CALL `0x45` family remains useful as a probe point, but the lamp control + is probably elsewhere in the protocol or needs more session context. diff --git a/docs/pt2-protocol-summary.md b/docs/pt2-protocol-summary.md new file mode 100644 index 0000000..605d280 --- /dev/null +++ b/docs/pt2-protocol-summary.md @@ -0,0 +1,235 @@ +# Sony PT2 Camera Control Protocol Working Summary + +This is a working model for restoring the Sony RCP-TX7 style PT2 camera control +link. It is based on bench captures and manuals gathered in this repo, not on an +official Sony protocol specification. + +## Scope + +- Target device: Sony RCP-TX7 camera control panel from the 1990s. +- Likely protocol family: Sony PT2-era camera/RCP control. +- Evidence: newer Sony RCP manuals describe a `PT2`/`PT7` mode switch, and `PT2` + is documented for the same camera line that the TX7 controls. +- Current goal: identify enough of the host/CCU side protocol to restore useful + panel operation. + +## Electrical Layer + +Confirmed wiring and levels: + +| RCP 10-pin pin | Cable color | Current identification | +| ---: | --- | --- | +| 1 | red | spare/unknown | +| 2 | black | VBS/composite video | +| 3 | green | VBS/composite video ground | +| 4 | orange | serial data RCP -> CCU/camera | +| 5 | blue | serial/data ground | +| 6 | grey | serial/data ground | +| 7 | purple | serial data CCU/camera -> RCP | +| 8 | white/purple | spare/unknown | +| 9 | brown | ground/DC return | +| 10 | brown-white | +12 V power | + +Observed idle measurements: + +- Pin 4 relative to pin 9: about `-9 V`. +- Pin 7 relative to pin 9: about `+0.037 V` until driven by the adapter. +- This strongly indicates true RS-232 signaling, not TTL UART. + +Bench adapter setup: + +- Adapter RS-232 `RXD` to RCP pin 4. +- Adapter RS-232 `TXD` to RCP pin 7. +- Adapter `GND` to RCP pin 9. +- Serial settings used throughout: `38400 8N1`. + +## Frame Shape + +Most useful traffic is six bytes: + +```text +prefix1 prefix2 command state value checksum +``` + +Current checksum hypothesis: + +```text +checksum = 0x5A XOR prefix1 XOR prefix2 XOR command XOR state XOR value +``` + +Examples: + +| Frame | Meaning in current model | +| --- | --- | +| `00 00 00 00 80 DA` | RCP heartbeat/status while not active | +| `00 00 07 80 00 DD` | RCP CAM POWER event | +| `00 00 15 80 00 CF` | CALL high/on state | +| `00 00 15 00 00 4F` | CALL low/off state | +| `07 80 45 20 D0 68` | RCP response to host-sent CALL high/low pair | +| `07 80 45 30 D0 78` | sibling CALL-response-family frame, seen once | + +The RCP-origin non-heartbeat responses discovered so far usually begin with +`07 80`. Host frames tested so far usually use `00 00`. + +## Baseline RCP Behavior + +With power and no valid host session, the RCP repeatedly sends: + +```text +00 00 00 00 80 DA +``` + +Only a few front-panel actions have produced unique frames while disconnected: + +| Control | RCP-origin frame | +| --- | --- | +| CAM POWER | `00 00 07 80 00 DD` | +| CALL high/on | `00 00 15 80 00 CF` | +| CALL low/off | `00 00 15 00 00 4F` | + +Most other controls have not yet emitted unique frames in the disconnected or +`CONNECT NOT ACT` state. + +## Display State + +Many checksum-valid and even some invalid host-side frames make the RCP display +`CONNECT NOT ACT`. + +Known interpretation: + +- `CONNECT NOT ACT` means the panel sees activity that looks connection-related. +- It does not mean the panel is active. +- It does not prove checksum validity. +- It can remain on screen while serial behavior changes underneath. + +Unknown: + +- The host sequence that changes the panel from `CONNECT NOT ACT` to an active + control state. + +## Discovery / Status Query Surface + +The strongest discovery/status pattern is: + +```text +Host primer: 00 00 00 00 80 DA +Host query: 00 00 XX 00 80 checksum +RCP reply: 07 80 ... ... ... checksum +``` + +Selected confirmed examples: + +| Host sequence | RCP response | +| --- | --- | +| `00 -> B0` | `07 80 6C 40 30 C1` | +| `00 -> B2` | `07 80 36 10 0C F7` | +| `00 -> B3` | `07 80 36 10 2C D7` | +| `00 -> B4` | `07 80 6D 40 30 C0` | +| `00 -> B5` | `07 80 6D 20 D8 48` | + +Other A/B/C region queries also return structured responses. The response set +looks like a readable status/capability surface, not random noise. + +Important latch behavior: + +- Many discovery/status responses are one-shot after power-up. +- Repeating the same query without a power cycle often returns only heartbeat. +- Re-sending the primer does not always clear this state. +- Broad unlatch sweeps after `B5` and `A0` did not find a reset/unlatch command. + +Working interpretation: + +- The host/CCU probably performs a discovery or capability read early in the + session. +- The panel then enters a state where repeated discovery reads are suppressed. +- A missing session-advance or keepalive step probably follows. + +## CALL Event Path + +This is the most reproducible event-response path found so far. + +The host can send the same frames the RCP uses for CALL state: + +```text +CALL high: 00 00 15 80 00 CF +CALL low: 00 00 15 00 00 4F +``` + +If the host sends CALL high then CALL low with a small inter-frame gap, the RCP +responds: + +```text +07 80 45 20 D0 68 +``` + +Confirmed details: + +- The physical CALL button is not required. +- Cold no-button startup injection works with both 50 ms and 80 ms gaps. +- CALL high alone does not trigger the response. +- CALL low alone does not trigger the response. +- Sending high and low back-to-back is less reliable than adding a gap. + +Known sibling response: + +```text +07 80 45 30 D0 78 +``` + +This was observed once during timing tests. It shares the `07 80 45` response +family, but the exact state meaning is unknown. + +What does not work: + +- Answering `07 80 45 20 D0 68` with `00 00 45 00 80 9F`, + `00 00 45 20 D0 EF`, or exact echo did not change the serial state. +- Triggering the CALL `0x45` path and then sending `00 -> B5` did not produce + the known `B5` discovery response. +- The CALL path is real and useful for probing, but is not currently the + activation handshake. + +## What We Know + +- The link is RS-232-like, not TTL. +- The baud rate is `38400 8N1`. +- The six-byte frame shape and XOR checksum hypothesis explain observed frames. +- The RCP sends heartbeat continuously when not active. +- The RCP can parse host traffic and produce structured, checksum-valid + responses. +- The B/A/C command regions expose one-shot readable response blocks. +- The CALL event path can be synthesized by the host without pressing the + physical button. +- The panel can remain visibly at `CONNECT NOT ACT` while still responding in + protocol-specific ways. + +## What We Do Not Know + +- The complete PT2 session startup handshake. +- The frame or cadence that moves the RCP into an active state. +- The meaning of most response fields. +- Whether `07 80` is always the RCP-origin response prefix. +- Whether host frames always use `00 00`, or if other prefixes are needed for + active mode. +- How camera/CCU identity, camera model, or capability negotiation is encoded. +- Whether the one-shot discovery latch is intentional protocol behavior or a + side effect of an incomplete session. +- Whether video/composite pins carry any status needed for full operation. + +## Restoration Strategy + +Near-term practical strategy: + +1. Treat PT2 as the target personality. +2. Keep using RS-232 at `38400 8N1`. +3. Use `00 -> Bx/Ax/Cx` style queries to map readable status blocks. +4. Use the cold CALL high/low pair as a known host stimulus to verify the RCP is + still parsing traffic. +5. Search for the missing session-advance or keepalive command after discovery, + not inside the CALL path. +6. If possible, capture a working PT2 CCU/RCP exchange; that would collapse a + lot of the search space. + +Most promising unknown: + +- A host-side session cadence or identity/status frame after discovery that + makes `CONNECT NOT ACT` become active. diff --git a/scripts/__pycache__/serial_button_response_test.cpython-312.pyc b/scripts/__pycache__/serial_button_response_test.cpython-312.pyc index d3cb795e8ba19c51dcfce8282b0a34a0f35951fe..6c797465f6f1bf014f0cb29f6e22fca12ed5da56 100644 GIT binary patch delta 4280 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 None: emit(f"{label} raw {hex_preview(data)}") +def emit_rx_chunk(emit, args, totals, watch_totals, data: bytes) -> None: + stamp = dt.datetime.now().strftime("%H:%M:%S.%f")[:-3] + emit(f"{stamp} RX {len(data):03d} bytes {hex_preview(data)}") + if args.ascii: + emit(f"{'':14} ASCII {ascii_preview(data)}") + + for name, pattern in KNOWN_PATTERNS.items(): + count = data.count(pattern) + if count: + totals[name] += count + emit(f"{stamp} DETECT {name} x{count}") + for frame in args.watch_frame or []: + count = data.count(frame) + if count: + key = hex_preview(frame) + watch_totals[key] += count + emit(f"{stamp} DETECT watch-frame {key} x{count}") + + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( description="Listen for CAM POWER/CALL frames and optionally respond to CAM POWER." @@ -189,6 +210,24 @@ def parse_args() -> argparse.Namespace: default=0.05, help="delay between multiple startup frames", ) + parser.add_argument( + "--startup-repeat", + type=int, + default=1, + help="how many times to send the full startup-frame group", + ) + parser.add_argument( + "--startup-repeat-interval", + type=float, + default=1.0, + help="delay between repeated startup-frame groups", + ) + parser.add_argument( + "--startup-read-after-group", + type=float, + default=0.0, + help="seconds to read and log RX after each startup-frame group before the next repeat", + ) parser.add_argument("--response-delay", type=float, default=0.05) parser.add_argument( "--response-frame-interval", @@ -268,10 +307,18 @@ def main() -> int: buffer = bytearray() if args.startup_frame: time.sleep(args.startup_delay) - for frame_index, frame in enumerate(args.startup_frame): - if frame_index: - time.sleep(args.startup_frame_interval) - send_frame(ser, emit, "startup", frame) + for repeat_index in range(args.startup_repeat): + for frame_index, frame in enumerate(args.startup_frame): + if frame_index: + time.sleep(args.startup_frame_interval) + send_frame(ser, emit, "startup", frame) + if args.startup_read_after_group: + group_data = read_window(ser, args.startup_read_after_group) + if group_data: + emit_rx_chunk(emit, args, totals, watch_totals, group_data) + buffer.extend(group_data) + if repeat_index + 1 < args.startup_repeat: + time.sleep(args.startup_repeat_interval) while time.monotonic() < stop_at: data = ser.read(args.chunk_size) @@ -282,7 +329,6 @@ def main() -> int: emit(f"{stamp} RX {len(data):03d} bytes {hex_preview(data)}") if args.ascii: emit(f"{'':14} ASCII {ascii_preview(data)}") - buffer.extend(data) for name, pattern in KNOWN_PATTERNS.items(): count = data.count(pattern)