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: improve cec pin analyzer code Author: Hans Verkuil <hans.verk...@cisco.com> Date: Sun Dec 3 16:44:48 2017 +0100 Greatly improve the cec pin analyzer code, making the output more readable and fixing various bugs. Signed-off-by: Hans Verkuil <hans.verk...@cisco.com> utils/cec-ctl/cec-ctl.cpp | 42 ++++++++------ utils/cec-ctl/cec-pin.cpp | 138 ++++++++++++++++++++++++++-------------------- 2 files changed, 102 insertions(+), 78 deletions(-) --- http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=288451ca1d032f14f09dcd1d2a7c6a15e04204bc diff --git a/utils/cec-ctl/cec-ctl.cpp b/utils/cec-ctl/cec-ctl.cpp index e442431b3e3e..5b1873a12194 100644 --- a/utils/cec-ctl/cec-ctl.cpp +++ b/utils/cec-ctl/cec-ctl.cpp @@ -1329,6 +1329,26 @@ static inline unsigned response_time_ms(const struct cec_msg &msg) return 0; } +static void generate_eob_event(__u64 ts, FILE *fstore) +{ + if (!eob_ts || eob_ts_max >= ts) + return; + + struct cec_event ev_eob = { + eob_ts, + CEC_EVENT_PIN_CEC_HIGH + }; + + if (fstore) { + fprintf(fstore, "%llu.%09llu %d\n", + ev_eob.ts / 1000000000, ev_eob.ts % 1000000000, + ev_eob.event - CEC_EVENT_PIN_CEC_LOW); + fflush(fstore); + } + if (fstore != stdout) + log_event(ev_eob); +} + static void monitor(struct node &node, __u32 monitor_time, const char *store_pin) { __u32 monitor = CEC_MODE_MONITOR; @@ -1437,37 +1457,23 @@ static void monitor(struct node &node, __u32 monitor_time, const char *store_pin ev.event == CEC_EVENT_PIN_HPD_LOW || ev.event == CEC_EVENT_PIN_HPD_HIGH) pin_event = true; + generate_eob_event(ev.ts, fstore); if (pin_event && fstore) { fprintf(fstore, "%llu.%09llu %d\n", ev.ts / 1000000000, ev.ts % 1000000000, ev.event - CEC_EVENT_PIN_CEC_LOW); fflush(fstore); } - if ((!pin_event || options[OptMonitorPin]) && - fstore != stdout) + if ((!pin_event || options[OptMonitorPin]) && fstore != stdout) log_event(ev); } - if (!pin_event && eob_ts && fstore != stdout) { + if (eob_ts) { struct timespec ts; __u64 ts64; clock_gettime(CLOCK_MONOTONIC, &ts); ts64 = ts.tv_sec * 1000000000ULL + ts.tv_nsec; - if (ts64 >= eob_ts_max) { - struct cec_event ev = { - eob_ts, - CEC_EVENT_PIN_CEC_HIGH - }; - - if (fstore) { - fprintf(fstore, "%llu.%09llu %d\n", - ev.ts / 1000000000, ev.ts % 1000000000, - ev.event - CEC_EVENT_PIN_CEC_LOW); - fflush(fstore); - } - if (options[OptMonitorPin]) - log_event(ev); - } + generate_eob_event(ts64, fstore); } } if (fstore && fstore != stdout) diff --git a/utils/cec-ctl/cec-pin.cpp b/utils/cec-ctl/cec-pin.cpp index 3b7f1d95c514..97f70a5e1f00 100644 --- a/utils/cec-ctl/cec-pin.cpp +++ b/utils/cec-ctl/cec-pin.cpp @@ -47,19 +47,19 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -static const char *find_opcode_name(__u8 opcode) +static std::string find_opcode_name(__u8 opcode) { for (unsigned i = 0; i < ARRAY_SIZE(msgtable); i++) if (msgtable[i].opcode == opcode) - return msgtable[i].name; + return std::string(": ") + msgtable[i].name; return ""; } -static const char *find_cdc_opcode_name(__u8 opcode) +static std::string find_cdc_opcode_name(__u8 opcode) { for (unsigned i = 0; i < ARRAY_SIZE(cdcmsgtable); i++) if (cdcmsgtable[i].opcode == opcode) - return cdcmsgtable[i].name; + return std::string(": ") + cdcmsgtable[i].name; return ""; } @@ -120,18 +120,24 @@ static bool cdc; static void cec_pin_rx_start_bit_was_high(__u64 usecs, __u64 usecs_min) { if (low_usecs + usecs_min > CEC_TIM_START_BIT_TOTAL_MAX) { - state = CEC_ST_IDLE; - printf("%10.06f: total start bit time too long (%.2f > %.2f ms)\n", + printf("%10.06f: start bit: total period too long (%.2f > %.2f ms)\n", ts, (low_usecs + usecs_min) / 1000.0, CEC_TIM_START_BIT_TOTAL_MAX / 1000.0); - return; + if (low_usecs + usecs_min > CEC_TIM_START_BIT_TOTAL_MAX + CEC_TIM_MARGIN * 5) { + printf("\n"); + state = CEC_ST_IDLE; + return; + } } if (low_usecs + usecs < CEC_TIM_START_BIT_TOTAL_MIN - CEC_TIM_MARGIN) { - state = CEC_ST_IDLE; - printf("%10.06f: total start bit time too short (%.2f < %.2f ms)\n", + printf("%10.06f: start bit: total period too short (%.2f < %.2f ms)\n", ts, (low_usecs + usecs) / 1000.0, CEC_TIM_START_BIT_TOTAL_MIN / 1000.0); - return; + if (low_usecs + usecs < CEC_TIM_START_BIT_TOTAL_MIN - CEC_TIM_MARGIN * 6) { + printf("\n"); + state = CEC_ST_IDLE; + return; + } } state = CEC_ST_RECEIVING_DATA; rx_bit = 0; @@ -145,18 +151,24 @@ static void cec_pin_rx_start_bit_was_high(__u64 usecs, __u64 usecs_min) static void cec_pin_rx_start_bit_was_low(__u64 ev_ts, __u64 usecs, __u64 usecs_min) { if (usecs_min > CEC_TIM_START_BIT_LOW_MAX) { - state = CEC_ST_IDLE; - printf("%10.06f: start bit low too long (%.2f > %.2f ms)\n", + printf("%10.06f: start bit: low time too long (%.2f > %.2f ms)\n", ts, usecs_min / 1000.0, CEC_TIM_START_BIT_LOW_MAX / 1000.0); - return; + if (usecs_min > CEC_TIM_START_BIT_LOW_MAX + CEC_TIM_MARGIN * 5) { + printf("\n"); + state = CEC_ST_IDLE; + return; + } } if (usecs < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_MARGIN) { - state = CEC_ST_IDLE; - printf("%10.06f: start bit low too short (%.2f < %.2f ms)\n", + printf("%10.06f: start bit: low time too short (%.2f < %.2f ms)\n", ts, usecs / 1000.0, CEC_TIM_START_BIT_LOW_MIN / 1000.0); - return; + if (usecs_min < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_MARGIN * 6) { + printf("\n"); + state = CEC_ST_IDLE; + return; + } } low_usecs = usecs; eob_ts = ev_ts + 1000 * (CEC_TIM_START_BIT_TOTAL - low_usecs); @@ -169,11 +181,11 @@ static void cec_pin_rx_data_bit_was_high(bool is_high, __u64 ev_ts, __u64 usecs, bool bit; if (rx_bit < 9 && low_usecs + usecs_min > CEC_TIM_DATA_BIT_TOTAL_MAX) { - printf("%10.06f: data bit %d total time too long (%.2f ms)\n", + printf("%10.06f: data bit %d: total period too long (%.2f ms)\n", ts, rx_bit, (low_usecs + usecs_min) / 1000.0); } if (low_usecs + usecs < CEC_TIM_DATA_BIT_TOTAL_MIN - CEC_TIM_MARGIN) { - printf("%10.06f: data bit %d total time too short (%.2f ms)\n\n", + printf("%10.06f: data bit %d: total period too short (%.2f ms)\n", ts, rx_bit, (low_usecs + usecs) / 1000.0); } bit = low_usecs < CEC_TIM_DATA_BIT_1_LOW_MAX + CEC_TIM_MARGIN; @@ -186,18 +198,16 @@ static void cec_pin_rx_data_bit_was_high(bool is_high, __u64 ev_ts, __u64 usecs, if (byte_cnt == 0) { bcast = (byte & 0xf) == 0xf; - s = std::string(la2s(byte >> 4)) + + s = ": " + std::string(la2s(byte >> 4)) + " to " + (bcast ? "All" : la2s(byte & 0xf)); } else if (byte_cnt == 1) { s = find_opcode_name(byte); } else if (cdc && byte_cnt == 4) { s = find_cdc_opcode_name(byte); } - printf("%10.06f: rx 0x%02x%s%s%s (%s) %s\n", - (ev_ts / 1000 - usecs - low_usecs + CEC_TIM_DATA_BIT_TOTAL) / 1000000.0, byte, + printf("%10.06f: rx 0x%02x%s%s%s%s\n", ts, byte, eom ? " EOM" : "", (bcast ^ bit) ? " NACK" : " ACK", bcast ? " (broadcast)" : "", - ts2s(ev_ts - usecs * 1000).c_str(), s.c_str()); if (show_info) printf("\n"); @@ -209,7 +219,7 @@ static void cec_pin_rx_data_bit_was_high(bool is_high, __u64 ev_ts, __u64 usecs, rx_bit++; if (rx_bit == 10) { if ((!eom && ack) && low_usecs + usecs_min > CEC_TIM_DATA_BIT_TOTAL_MAX) - printf("%10.06f: data bit %d total time too long (%.2f ms)\n", + printf("%10.06f: data bit %d: total period too long (%.2f ms)\n", ts, rx_bit - 1, (low_usecs + usecs_min) / 1000.0); if (eom || is_high || low_usecs + usecs_min > CEC_TIM_DATA_BIT_TOTAL_MAX) state = is_high ? CEC_ST_IDLE : CEC_ST_RECEIVE_START_BIT; @@ -226,53 +236,44 @@ static void cec_pin_rx_data_bit_was_low(__u64 ev_ts, __u64 usecs, __u64 usecs_mi low_usecs = usecs; if (usecs >= CEC_TIM_LOW_DRIVE_ERROR_MIN - CEC_TIM_MARGIN && usecs <= CEC_TIM_LOW_DRIVE_ERROR_MAX + CEC_TIM_MARGIN) { - state = CEC_ST_IDLE; printf("%10.06f: low drive (%.2f ms) detected\n\n", ts, usecs / 1000.0); + state = CEC_ST_IDLE; return; } if (usecs_min >= CEC_TIM_LOW_DRIVE_ERROR_MAX) { - state = CEC_ST_IDLE; printf("%10.06f: low drive too long (%.2f > %.2f ms)\n\n", ts, usecs_min / 1000.0, CEC_TIM_LOW_DRIVE_ERROR_MAX / 1000.0); + state = CEC_ST_IDLE; return; } - if (rx_bit == 0 && byte_cnt) { - if (!rx_bit && usecs_min > CEC_TIM_START_BIT_LOW_MAX) { - state = CEC_ST_IDLE; - printf("%10.06f: start bit low too long (%.2f > %.2f ms)\n\n", - ts, usecs_min / 1000.0, - CEC_TIM_START_BIT_LOW_MAX / 1000.0); - return; - } - if (usecs >= CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_MARGIN) { - state = CEC_ST_RECEIVE_START_BIT; - return; - } + if (rx_bit == 0 && byte_cnt && + usecs >= CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_MARGIN) { + printf("%10.06f: unexpected start bit\n", ts); + cec_pin_rx_start_bit_was_low(ev_ts, usecs, usecs_min); + state = CEC_ST_RECEIVE_START_BIT; + return; } + if (usecs_min > CEC_TIM_DATA_BIT_0_LOW_MAX) { - printf("%10.06f: data bit %d low too long (%.2f ms)\n", + printf("%10.06f: data bit %d: low time too long (%.2f ms)\n", ts, rx_bit, usecs_min / 1000.0); if (usecs_min > CEC_TIM_DATA_BIT_TOTAL_MAX) { - state = CEC_ST_IDLE; printf("\n"); + state = CEC_ST_IDLE; } return; } if (usecs_min > CEC_TIM_DATA_BIT_1_LOW_MAX && usecs < CEC_TIM_DATA_BIT_0_LOW_MIN - CEC_TIM_MARGIN) { - state = CEC_ST_IDLE; - printf("%10.06f: data bit %d invalid 0->1 transition (%.2f ms)\n\n", + printf("%10.06f: data bit %d: invalid 0->1 transition (%.2f ms)\n", ts, rx_bit, usecs / 1000.0); - return; } if (usecs < CEC_TIM_DATA_BIT_1_LOW_MIN - CEC_TIM_MARGIN) { - state = CEC_ST_IDLE; - printf("%10.06f: data bit %d low too short (%.2f ms)\n\n", + printf("%10.06f: data bit %d: low time too short (%.2f ms)\n", ts, rx_bit, usecs / 1000.0); - return; } eob_ts = ev_ts + 1000 * (CEC_TIM_DATA_BIT_TOTAL - low_usecs); @@ -314,6 +315,7 @@ void log_event_pin(bool is_high, __u64 ev_ts) static __u64 last_change_ts; static __u64 last_1_to_0_ts; static bool was_high = true; + double bit_periods = ((ev_ts - last_ts) / 1000.0) / CEC_TIM_DATA_BIT_TOTAL; eob_ts = eob_ts_max = 0; @@ -323,34 +325,50 @@ void log_event_pin(bool is_high, __u64 ev_ts) if (is_high) return; } - cec_pin_debug(ev_ts, (ev_ts - last_ts) / 1000, was_high, is_high); if (show_info) { printf("%10.06f: ", ts); - if (last_change_ts && is_high && was_high) + if (last_change_ts && is_high && was_high && + (ev_ts - last_1_to_0_ts) / 1000000 <= 10) + printf("1 -> 1 (was 1 for %.2f ms, period of previous %spulse %.2f ms)\n", + (ev_ts - last_change_ts) / 1000000.0, + state == CEC_ST_RECEIVE_START_BIT ? "start " : "", + (ev_ts - last_1_to_0_ts) / 1000000.0); + else if (last_change_ts && is_high && was_high) printf("1 -> 1 (%.2f ms)\n", (ev_ts - last_change_ts) / 1000000.0); - else if (was_high) - printf("1 -> 0 (was 1 for %.2f ms, bit period %.2f ms)\n", + else if (was_high && state == CEC_ST_IDLE) { + if (bit_periods > 1 && bit_periods < 10) + printf("1 -> 0 (was 1 for %.2f ms, free signal time = %.1f bit periods)\n", + (ev_ts - last_change_ts) / 1000000.0, bit_periods); + else + printf("1 -> 0 (was 1 for %.2f ms)\n", + (ev_ts - last_change_ts) / 1000000.0); + } else if (was_high && (ev_ts - last_1_to_0_ts) / 1000000 <= 10) + printf("1 -> 0 (was 1 for %.2f ms, period of previous %spulse %.2f ms)\n", (ev_ts - last_change_ts) / 1000000.0, + state == CEC_ST_RECEIVE_START_BIT ? "start " : "", (ev_ts - last_1_to_0_ts) / 1000000.0); + else if (was_high) + printf("1 -> 0 (was 1 for %.2f ms)\n", + (ev_ts - last_change_ts) / 1000000.0); + else if (last_change_ts && state == CEC_ST_RECEIVE_START_BIT) + printf("0 -> 1 (was 0 for %.2f ms)\n", + (ev_ts - last_change_ts) / 1000000.0); else if (last_change_ts) - printf("0 -> 1 (was 0 for %.2f ms, %d)\n", + printf("0 -> 1 (was 0 for %.2f ms, indicates %d bit)\n", (ev_ts - last_change_ts) / 1000000.0, (ev_ts - last_change_ts) / 1000 < CEC_TIM_DATA_BIT_1_LOW_MAX + CEC_TIM_MARGIN); else printf("0 -> 1\n"); - last_change_ts = ev_ts; - if (!is_high) - last_1_to_0_ts = ev_ts; - } - if (!is_high) { - float usecs = (ev_ts - last_ts) / 1000; - unsigned periods = usecs / CEC_TIM_DATA_BIT_TOTAL; - - if (periods > 1 && periods < 10) - printf("free signal time = %.1f bit periods\n", usecs / CEC_TIM_DATA_BIT_TOTAL); + } else if (!is_high && bit_periods > 1 && bit_periods < 10) { + printf("%10.06f: free signal time = %.1f bit periods\n", + ts, bit_periods); } + cec_pin_debug(ev_ts, (ev_ts - last_ts) / 1000, was_high, is_high); + last_change_ts = ev_ts; + if (!is_high) + last_1_to_0_ts = ev_ts; last_ts = ev_ts; was_high = is_high; } _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits