This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:

Subject: cec-ctl: add --test-reliability option
Author:  Hans Verkuil <hverkuil-ci...@xs4all.nl>
Date:    Thu Oct 3 15:49:10 2024 +0200

This new option repeatedly transmits <Give Physical Addr> and
verifies that the reply is always the same. This should detect
poor CEC signal quality, since that should introduce bit errors.

Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>

 utils/cec-ctl/cec-ctl.1.in |  7 +++++
 utils/cec-ctl/cec-ctl.cpp  | 66 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 1 deletion(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=2e7492386e6ed494c1e2b3afd950c48324b2c494
diff --git a/utils/cec-ctl/cec-ctl.1.in b/utils/cec-ctl/cec-ctl.1.in
index 357c111c84e1..78ddd500819e 100644
--- a/utils/cec-ctl/cec-ctl.1.in
+++ b/utils/cec-ctl/cec-ctl.1.in
@@ -271,6 +271,13 @@ via the \fB\-\-analyze\-pin\fR option. Use \- to write to 
stdout instead of to a
 Read and analyze the CEC pin events from the given file. Use \- to read from 
stdin
 instead of from a file.
 .TP
+\fB\-\-test\-reliability\fR \fI<count>\fR
+This option tests the CEC reliability by transmitting <Give Physical Addr> up 
to
+\fI<count>\fR times (or forever if \fI<count>\fR is 0) and check if the reply 
is
+always the same. Since the reply is a broadcast message, it is in practice 
never
+Nacked and so any bit errors due to poor CEC signal quality will clearly show 
up.
+The message will be sent to the logical address specified by \fB\-\-to\fR.
+.TP
 \fB\-\-test\-standby\-wakeup\-cycle\fR 
[\fIpolls\fR=\fI<n>\fR][,\fIsleep\fR=\fI<secs>\fR][,\fIhpd\-may\-be\-low\fR=\fI<0/1>\fR]
 This option tests the standby-wakeup cycle behavior of the display. It polls 
up to
 \fI<n>\fR times (default 15), waiting for a state change. If that fails then it
diff --git a/utils/cec-ctl/cec-ctl.cpp b/utils/cec-ctl/cec-ctl.cpp
index eec16377cb38..faf17abffd62 100644
--- a/utils/cec-ctl/cec-ctl.cpp
+++ b/utils/cec-ctl/cec-ctl.cpp
@@ -121,6 +121,7 @@ enum Option {
        OptFeatSetAudioRate,
        OptFeatSinkHasARCTx,
        OptFeatSourceHasARCRx,
+       OptTestReliability,
        OptTestStandbyWakeupCycle,
        OptStressTestStandbyWakeupCycle,
        OptStressTestRandomStandbyWakeupCycle,
@@ -228,6 +229,7 @@ static struct option long_options[] = {
        { "stress-test-power-cycle", required_argument, nullptr, 
OptStressTestStandbyWakeupCycle }, \
        { "test-random-power-states", required_argument, nullptr, 
OptStressTestRandomStandbyWakeupCycle }, \
 
+       { "test-reliability", required_argument, nullptr, OptTestReliability }, 
\
        { "test-standby-wakeup-cycle", optional_argument, nullptr, 
OptTestStandbyWakeupCycle }, \
        { "stress-test-standby-wakeup-cycle", required_argument, nullptr, 
OptStressTestStandbyWakeupCycle }, \
        { "stress-test-random-standby-wakeup-cycle", required_argument, 
nullptr, OptStressTestRandomStandbyWakeupCycle }, \
@@ -326,6 +328,10 @@ static void usage()
               "                           Use - for stdout.\n"
               "  --analyze-pin <from>     Analyze the low-level CEC pin 
changes from the file <from>.\n"
               "                           Use - for stdin.\n"
+              "  --test-reliability <count>\n"
+              "                           Test CEC line reliability. It 
transmits <Give Physical Address>\n"
+              "                           up to <count> times, checking that 
the broadcast reply is always the same.\n"
+              "                           If <count> is 0, then keep trying 
forever.\n"
               "  --test-standby-wakeup-cycle 
[polls=<n>][,sleep=<secs>][,hpd-may-be-low=<0/1>]\n"
               "                           Test standby-wakeup cycle behavior 
of the display. It polls up to\n"
               "                           <n> times (default 15), waiting for 
a state change. If\n"
@@ -1301,6 +1307,56 @@ static int transmit_msg_retry(const struct node &node, 
struct cec_msg &msg)
        return ret;
 }
 
+static void test_reliability(const struct node &node, unsigned int to, 
unsigned int cnt)
+{
+       struct cec_log_addrs laddrs = { };
+       struct cec_msg msg;
+       unsigned from, iter = 0;
+       __u8 prim_dev, cur_prim_dev;
+       __u16 pa, cur_pa;
+
+       doioctl(&node, CEC_ADAP_G_LOG_ADDRS, &laddrs);
+       if (laddrs.log_addr[0] == CEC_LOG_ADDR_INVALID) {
+               printf("FAIL: invalid logical address\n");
+               std::exit(EXIT_FAILURE);
+       }
+       from = laddrs.log_addr[0];
+       cec_msg_init(&msg, from, to);
+       cec_msg_give_physical_addr(&msg, true);
+       doioctl(&node, CEC_TRANSMIT, &msg);
+       if (!cec_msg_status_is_ok(&msg)) {
+               printf("Iteration 0: FAIL: %s\n", cec_status2s(msg).c_str());
+               std::exit(EXIT_FAILURE);
+       }
+       pa = (msg.msg[2] << 8) | msg.msg[3];
+       prim_dev = msg.msg[4];
+
+       printf("Iteration 0: Physical Address: %x.%x.%x.%x Primary Device Type: 
%s\n",
+              cec_phys_addr_exp(pa), cec_prim_type2s(prim_dev));
+
+       while (1) {
+               iter++;
+               cec_msg_init(&msg, from, to);
+               cec_msg_give_physical_addr(&msg, true);
+               doioctl(&node, CEC_TRANSMIT, &msg);
+               if (!cec_msg_status_is_ok(&msg)) {
+                       printf("Iteration %u: FAIL: %s\n", iter, 
cec_status2s(msg).c_str());
+                       std::exit(EXIT_FAILURE);
+               }
+               cur_pa = (msg.msg[2] << 8) | msg.msg[3];
+               cur_prim_dev = msg.msg[4];
+               bool pass = pa == cur_pa && prim_dev == cur_prim_dev;
+
+               printf("Iteration %u: %s: Physical Address: %x.%x.%x.%x Primary 
Device Type: %s\n",
+                      iter, pass ? "PASS" : "FAIL",
+                      cec_phys_addr_exp(cur_pa), 
cec_prim_type2s(cur_prim_dev));
+               if (!pass)
+                       break;
+               if (cnt && cnt-- == 1)
+                       break;
+       }
+}
+
 static int init_standby_wakeup_cycle_test(const struct node &node, unsigned 
repeats, unsigned max_tries)
 {
        struct cec_msg msg;
@@ -2310,6 +2366,7 @@ int main(int argc, char **argv)
        double stress_test_standby_wakeup_cycle_sleep_before_on = 0;
        double stress_test_standby_wakeup_cycle_sleep_before_off = 0;
        bool stress_test_standby_wakeup_cycle_hpd_may_be_low = false;
+       unsigned int test_reliability_cnt = 0;
        unsigned int test_standby_wakeup_cycle_polls = 15;
        unsigned int test_standby_wakeup_cycle_sleep = 10;
        bool test_standby_wakeup_cycle_hpd_may_be_low = false;
@@ -2699,6 +2756,10 @@ int main(int argc, char **argv)
                        list_devices();
                        return 0;
 
+               case OptTestReliability:
+                       test_reliability_cnt = strtoul(optarg, nullptr, 0);
+                       break;
+
                case OptTestStandbyWakeupCycle: {
                        static constexpr const char *arg_names[] = {
                                "polls",
@@ -3095,7 +3156,8 @@ int main(int argc, char **argv)
                        phys_addrs[la] = (phys_addr << 8) | la;
        }
 
-       if (options[OptTestStandbyWakeupCycle] ||
+       if (options[OptTestReliability] ||
+           options[OptTestStandbyWakeupCycle] ||
            options[OptStressTestStandbyWakeupCycle] ||
            options[OptStressTestRandomStandbyWakeupCycle]) {
                print_version();
@@ -3197,6 +3259,8 @@ int main(int argc, char **argv)
        if (options[OptNonBlocking])
                fcntl(node.fd, F_SETFL, fcntl(node.fd, F_GETFL) & ~O_NONBLOCK);
 
+       if (options[OptTestReliability])
+               test_reliability(node, to, test_reliability_cnt);
        if (options[OptTestStandbyWakeupCycle])
                test_standby_wakeup_cycle(node,
                                          test_standby_wakeup_cycle_polls,

Reply via email to