]> cloudbase.mooo.com Git - irmp.git/blobdiff - irmp.c
Version 2.3.4: improved detection of DENON frame repetition per key
[irmp.git] / irmp.c
diff --git a/irmp.c b/irmp.c
index c8bc29f0acce60f7a951c36d44a5056a6e86b970..5597bd5551acc243ae1881d7b8ae8716d8491959 100644 (file)
--- a/irmp.c
+++ b/irmp.c
@@ -3,7 +3,7 @@
  *\r
  * Copyright (c) 2009-2012 Frank Meyer - frank(at)fli4l.de\r
  *\r
- * $Id: irmp.c,v 1.131 2012/11/18 17:51:26 fm Exp $\r
+ * $Id: irmp.c,v 1.135 2012/12/07 13:04:14 fm Exp $\r
  *\r
  * ATMEGA88 @ 8 MHz\r
  *\r
 #  define ANALYZE_PUTCHAR(a)                    { if (! silent)             { putchar (a);          } }\r
 #  define ANALYZE_ONLY_NORMAL_PUTCHAR(a)        { if (! silent && !verbose) { putchar (a);          } }\r
 #  define ANALYZE_PRINTF(...)                   { if (verbose)              { printf (__VA_ARGS__); } }\r
+#  define ANALYZE_ONLY_NORMAL_PRINTF(...)       { if (! silent && !verbose) { printf (__VA_ARGS__); } }\r
 #  define ANALYZE_NEWLINE()                     { if (verbose)              { putchar ('\n');       } }\r
 static int                                      silent;\r
 static int                                      time_counter;\r
@@ -386,6 +387,7 @@ static int                                      verbose;
 #  define ANALYZE_PUTCHAR(a)\r
 #  define ANALYZE_ONLY_NORMAL_PUTCHAR(a)\r
 #  define ANALYZE_PRINTF(...)\r
+#  define ANALYZE_ONLY_NORMAL_PRINTF(...)\r
 #  define ANALYZE_NEWLINE()\r
 #endif\r
 \r
@@ -397,7 +399,7 @@ static void                                     (*irmp_callback_ptr) (uint8_t);
  *  Protocol names\r
  *---------------------------------------------------------------------------------------------------------------------------------------------------\r
  */\r
-#if IRMP_PROTOCOL_NAMES == 1\r
+#if defined(UNIX_OR_WINDOWS) || IRMP_PROTOCOL_NAMES == 1\r
 char *\r
 irmp_protocol_names[IRMP_N_PROTOCOLS + 1] =\r
 {\r
@@ -446,7 +448,9 @@ irmp_protocol_names[IRMP_N_PROTOCOLS + 1] =
 #include "irmpextlog.h"\r
 #else                                                               // normal UART log (IRMP_EXT_LOGGING == 0)\r
 #define BAUD                                    9600L\r
+#ifndef UNIX_OR_WINDOWS\r
 #include <util/setbaud.h>\r
+#endif\r
 \r
 #ifdef UBRR0H\r
 \r
@@ -497,6 +501,7 @@ irmp_protocol_names[IRMP_N_PROTOCOLS + 1] =
 void\r
 irmp_uart_init (void)\r
 {\r
+#ifndef UNIX_OR_WINDOWS\r
 #if (IRMP_EXT_LOGGING == 0)                                                                         // use UART\r
     UART0_UBRRH = UBRRH_VALUE;                                                                      // set baud rate\r
     UART0_UBRRL = UBRRL_VALUE;\r
@@ -512,6 +517,7 @@ irmp_uart_init (void)
 #else                                                                                               // other log method\r
         initextlog();                                                         \r
 #endif //IRMP_EXT_LOGGING\r
+#endif // UNIX_OR_WINDOWS\r
 }\r
 \r
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
@@ -523,6 +529,7 @@ irmp_uart_init (void)
 void\r
 irmp_uart_putc (unsigned char ch)\r
 {\r
+#ifndef UNIX_OR_WINDOWS\r
 #if (IRMP_EXT_LOGGING == 0)\r
     while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE))\r
     {\r
@@ -533,6 +540,9 @@ irmp_uart_putc (unsigned char ch)
 #else\r
     sendextlog(ch); //Use external log\r
 #endif\r
+#else\r
+    fputc (ch, stderr);\r
+#endif // UNIX_OR_WINDOWS\r
 }\r
 \r
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
@@ -544,6 +554,8 @@ irmp_uart_putc (unsigned char ch)
 #define ENDBITS                        1000                                 // number of sequenced highbits to detect end\r
 #define DATALEN                         700                                 // log buffer size\r
 \r
+#if 0                                                                       // old log routine\r
+\r
 static void\r
 irmp_log (uint8_t val)\r
 {\r
@@ -613,6 +625,98 @@ irmp_log (uint8_t val)
     }\r
 }\r
 \r
+#else                                                                       // new log routine\r
+\r
+static void\r
+irmp_log (uint8_t val)\r
+{\r
+    static uint8_t  buf[DATALEN];                                           // logging buffer\r
+    static uint16_t buf_idx;                                                // index\r
+    static uint8_t  startcycles;                                            // current number of start-zeros\r
+    static uint16_t cnt;                                                    // counts sequenced highbits - to detect end\r
+    static uint8_t  last_val = 1;\r
+\r
+    if (! val && (startcycles < STARTCYCLES) && !buf_idx)                   // prevent that single random zeros init logging\r
+    {\r
+        startcycles++;\r
+    }\r
+    else\r
+    {\r
+        startcycles = 0;\r
+\r
+        if (! val || buf_idx != 0)                                          // start or continue logging on "0", "1" cannot init logging\r
+        {\r
+            if (last_val == val)\r
+            {\r
+                cnt++;\r
+\r
+                if (val && cnt > ENDBITS)                                   // if high received then look at log-stop condition\r
+                {                                                           // if stop condition is true, output on uart\r
+                    uint8_t     i8;\r
+                    uint16_t    i;\r
+                    uint16_t    j;\r
+                    uint8_t     v = '1';\r
+                    uint16_t    d;\r
+\r
+                    for (i8 = 0; i8 < STARTCYCLES; i8++)\r
+                    {\r
+                        irmp_uart_putc ('0');                               // the ignored starting zeros\r
+                    }\r
+\r
+                    for (i = 0; i < buf_idx; i++)\r
+                    {\r
+                        d = buf[i];\r
+\r
+                        if (d == 0xff)\r
+                        {\r
+                            i++;\r
+                            d = buf[i];\r
+                            i++;\r
+                            d |= ((uint16_t) buf[i] << 8);\r
+                        }\r
+\r
+                        for (j = 0; j < d; j++)\r
+                        {\r
+                            irmp_uart_putc (v);\r
+                        }\r
+\r
+                        v = (v == '1') ? '0' : '1';\r
+                    }\r
+\r
+                    for (i8 = 0; i8 < 20; i8++)\r
+                    {\r
+                        irmp_uart_putc ('1');\r
+                    }\r
+\r
+                    irmp_uart_putc ('\n');\r
+                    buf_idx = 0;\r
+                    last_val = 1;\r
+                    cnt = 0;\r
+                }\r
+            }\r
+            else if (buf_idx < DATALEN - 3)\r
+            {\r
+                if (cnt >= 0xff)\r
+                {\r
+                    buf[buf_idx++]  = 0xff;\r
+                    buf[buf_idx++]  = (cnt & 0xff);\r
+                    buf[buf_idx]    = (cnt >> 8);\r
+                }\r
+                else\r
+                {\r
+                    buf[buf_idx] = cnt;\r
+                }\r
+\r
+                buf_idx++;\r
+                cnt = 1;\r
+                last_val = val;\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+#endif\r
+\r
 #else\r
 #define irmp_log(val)\r
 #endif //IRMP_LOGGING\r
@@ -1653,10 +1757,11 @@ irmp_ISR (void)
     static PAUSE_LEN    irmp_pause_time;                                        // count bit time for pause\r
     static uint16_t     last_irmp_address = 0xFFFF;                             // save last irmp address to recognize key repetition\r
     static uint16_t     last_irmp_command = 0xFFFF;                             // save last irmp command to recognize key repetition\r
-    static uint16_t     repetition_len;                                         // SIRCS repeats frame 2-5 times with 45 ms pause\r
+    static uint16_t     key_repetition_len;                                     // SIRCS repeats frame 2-5 times with 45 ms pause\r
     static uint8_t      repetition_frame_number;\r
 #if IRMP_SUPPORT_DENON_PROTOCOL == 1\r
     static uint16_t     last_irmp_denon_command;                                // save last irmp command to recognize DENON frame repetition\r
+    static uint16_t     denon_repetition_len = 0xFFFF;                          // denon repetition len of 2nd auto generated frame\r
 #endif\r
 #if IRMP_SUPPORT_RC5_PROTOCOL == 1\r
     static uint8_t      rc5_cmd_bit6;                                           // bit 6 of RC5 command is the inverted 2nd start bit\r
@@ -1731,16 +1836,22 @@ irmp_ISR (void)
                 }\r
                 else\r
                 {\r
-                    if (repetition_len < 0xFFFF)                                // avoid overflow of counter\r
+                    if (key_repetition_len < 0xFFFF)                            // avoid overflow of counter\r
                     {\r
-                        repetition_len++;\r
+                        key_repetition_len++;\r
 \r
 #if IRMP_SUPPORT_DENON_PROTOCOL == 1\r
-                        if (repetition_len >= DENON_AUTO_REPETITION_PAUSE_LEN && last_irmp_denon_command != 0)\r
+                        if (denon_repetition_len < 0xFFFF)                      // avoid overflow of counter\r
                         {\r
-                            ANALYZE_PRINTF ("%8.3fms error 6: did not receive inverted command repetition\n",\r
-                                            (double) (time_counter * 1000) / F_INTERRUPTS);\r
-                            last_irmp_denon_command = 0;\r
+                            denon_repetition_len++;\r
+\r
+                            if (denon_repetition_len >= DENON_AUTO_REPETITION_PAUSE_LEN && last_irmp_denon_command != 0)\r
+                            {\r
+                                ANALYZE_PRINTF ("%8.3fms error 6: did not receive inverted command repetition\n",\r
+                                                (double) (time_counter * 1000) / F_INTERRUPTS);\r
+                                last_irmp_denon_command = 0;\r
+                                denon_repetition_len = 0xFFFF;\r
+                            }\r
                         }\r
 #endif // IRMP_SUPPORT_DENON_PROTOCOL == 1\r
                     }\r
@@ -3008,7 +3119,7 @@ irmp_ISR (void)
 \r
             if (irmp_start_bit_detected && irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 0)    // enough bits received?\r
             {\r
-                if (last_irmp_command == irmp_tmp_command && repetition_len < AUTO_FRAME_REPETITION_LEN)\r
+                if (last_irmp_command == irmp_tmp_command && key_repetition_len < AUTO_FRAME_REPETITION_LEN)\r
                 {\r
                     repetition_frame_number++;\r
                 }\r
@@ -3022,8 +3133,8 @@ irmp_ISR (void)
                 if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL && (repetition_frame_number == 1 || repetition_frame_number == 2))\r
                 {\r
                     ANALYZE_PRINTF ("code skipped: SIRCS auto repetition frame #%d, counter = %d, auto repetition len = %d\n",\r
-                                    repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);\r
-                    repetition_len = 0;\r
+                                    repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\r
+                    key_repetition_len = 0;\r
                 }\r
                 else\r
 #endif\r
@@ -3033,8 +3144,8 @@ irmp_ISR (void)
                 if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && repetition_frame_number == 1)\r
                 {\r
                     ANALYZE_PRINTF ("code skipped: KASEIKYO auto repetition frame #%d, counter = %d, auto repetition len = %d\n",\r
-                                    repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);\r
-                    repetition_len = 0;\r
+                                    repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\r
+                    key_repetition_len = 0;\r
                 }\r
                 else\r
 #endif\r
@@ -3044,8 +3155,8 @@ irmp_ISR (void)
                 if (irmp_param.protocol == IRMP_SAMSUNG32_PROTOCOL && (repetition_frame_number & 0x01))\r
                 {\r
                     ANALYZE_PRINTF ("code skipped: SAMSUNG32 auto repetition frame #%d, counter = %d, auto repetition len = %d\n",\r
-                                    repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);\r
-                    repetition_len = 0;\r
+                                    repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\r
+                    key_repetition_len = 0;\r
                 }\r
                 else\r
 #endif\r
@@ -3055,8 +3166,8 @@ irmp_ISR (void)
                 if (irmp_param.protocol == IRMP_NUBERT_PROTOCOL && (repetition_frame_number & 0x01))\r
                 {\r
                     ANALYZE_PRINTF ("code skipped: NUBERT auto repetition frame #%d, counter = %d, auto repetition len = %d\n",\r
-                                    repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);\r
-                    repetition_len = 0;\r
+                                    repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\r
+                    key_repetition_len = 0;\r
                 }\r
                 else\r
 #endif\r
@@ -3083,6 +3194,7 @@ irmp_ISR (void)
                             {\r
                                 ANALYZE_PRINTF ("%8.3fms waiting for inverted command repetition\n", (double) (time_counter * 1000) / F_INTERRUPTS);\r
                                 last_irmp_denon_command = irmp_tmp_command;\r
+                                denon_repetition_len = 0;\r
                             }\r
                             else\r
                             {\r
@@ -3090,7 +3202,6 @@ irmp_ISR (void)
                                 last_irmp_denon_command = 0;\r
                             }\r
                             irmp_ir_detected = FALSE;\r
-                            repetition_len = 0;\r
                         }\r
                     }\r
                     else\r
@@ -3117,18 +3228,19 @@ irmp_ISR (void)
 #if IRMP_SUPPORT_NEC_PROTOCOL == 1\r
                         if (irmp_param.protocol == IRMP_NEC_PROTOCOL && irmp_bit == 0)  // repetition frame\r
                         {\r
-                            if (repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX)\r
+                            if (key_repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX)\r
                             {\r
-                                ANALYZE_PRINTF ("Detected NEC repetition frame, repetition_len = %d\n", repetition_len);\r
+                                ANALYZE_PRINTF ("Detected NEC repetition frame, key_repetition_len = %d\n", key_repetition_len);\r
+                                ANALYZE_ONLY_NORMAL_PRINTF("REPETETION FRAME                ");\r
                                 irmp_tmp_address = last_irmp_address;                   // address is last address\r
                                 irmp_tmp_command = last_irmp_command;                   // command is last command\r
                                 irmp_flags |= IRMP_FLAG_REPETITION;\r
-                                repetition_len = 0;\r
+                                key_repetition_len = 0;\r
                             }\r
                             else\r
                             {\r
-                                ANALYZE_PRINTF ("Detected NEC repetition frame, ignoring it: timeout occured, repetition_len = %d > %d\n",\r
-                                                repetition_len, NEC_FRAME_REPEAT_PAUSE_LEN_MAX);\r
+                                ANALYZE_PRINTF ("Detected NEC repetition frame, ignoring it: timeout occured, key_repetition_len = %d > %d\n",\r
+                                                key_repetition_len, NEC_FRAME_REPEAT_PAUSE_LEN_MAX);\r
                                 irmp_ir_detected = FALSE;\r
                             }\r
                         }\r
@@ -3214,7 +3326,7 @@ irmp_ISR (void)
                 {\r
                     if (last_irmp_command == irmp_tmp_command &&\r
                         last_irmp_address == irmp_tmp_address &&\r
-                        repetition_len < IRMP_KEY_REPETITION_LEN)\r
+                        key_repetition_len < IRMP_KEY_REPETITION_LEN)\r
                     {\r
                         irmp_flags |= IRMP_FLAG_REPETITION;\r
                     }\r
@@ -3222,7 +3334,7 @@ irmp_ISR (void)
                     last_irmp_address = irmp_tmp_address;                           // store as last address, too\r
                     last_irmp_command = irmp_tmp_command;                           // store as last command, too\r
 \r
-                    repetition_len = 0;\r
+                    key_repetition_len = 0;\r
                 }\r
                 else\r
                 {\r
@@ -3619,6 +3731,10 @@ get_fdc_key (uint16_t cmd)
 static int         analyze = FALSE;\r
 static int         list = FALSE;\r
 static IRMP_DATA   irmp_data;\r
+static int         expected_protocol;\r
+static int         expected_address;\r
+static int         expected_command;\r
+static int         do_check_expected_values;\r
 \r
 static void\r
 next_tick (void)\r
@@ -3642,8 +3758,8 @@ next_tick (void)
             {\r
                 if ((key >= 0x20 && key < 0x7F) || key >= 0xA0)\r
                 {\r
-                    printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x, key = '%c'\n",\r
-                            irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key, key);\r
+                    printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x, key='%c'",\r
+                            irmp_data.protocol,  irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key, key);\r
                 }\r
                 else if (key == '\r' || key == '\t' || key == KEY_ESCAPE || (key >= 0x80 && key <= 0x9F))                 // function keys\r
                 {\r
@@ -3684,19 +3800,39 @@ next_tick (void)
                         default                  : p = "<UNKNWON>";     break;\r
                     }\r
 \r
-                    printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x, key = %s\n",\r
-                            irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key, p);\r
+                    printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x, key=%s",\r
+                            irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key, p);\r
+                }\r
+                else\r
+                {\r
+                    printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x",\r
+                            irmp_data.protocol,  irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key);\r
+                }\r
+            }\r
+            else\r
+            {\r
+                printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x",\r
+                        irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags);\r
+            }\r
+\r
+            if (do_check_expected_values)\r
+            {\r
+                if (irmp_data.protocol != expected_protocol ||\r
+                    irmp_data.address  != expected_address  ||\r
+                    irmp_data.command  != expected_command)\r
+                {\r
+                    printf ("\nerror 7: expected values differ: p=%2d (%s), a=0x%04x, c=0x%04x\n",\r
+                            expected_protocol, irmp_protocol_names[expected_protocol], expected_address, expected_command);\r
                 }\r
                 else\r
                 {\r
-                    printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x\n",\r
-                            irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key);\r
+                    printf (" checked!\n");\r
                 }\r
+                do_check_expected_values = FALSE;                           // only check 1st frame in a line!\r
             }\r
             else\r
             {\r
-                printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x\n",\r
-                        irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags);\r
+                putchar ('\n');\r
             }\r
         }\r
     }\r
@@ -3858,13 +3994,81 @@ main (int argc, char ** argv)
             }\r
             else\r
             {\r
+                char            buf[1024];\r
+                char *          p;\r
+                int             idx = -1;\r
+\r
                 puts ("-------------------------------------------------------------------");\r
                 putchar (ch);\r
 \r
+\r
                 while ((ch = getchar()) != '\n' && ch != EOF)\r
                 {\r
                     if (ch != '\r')                                                         // ignore CR in DOS/Windows files\r
                     {\r
+                        if (ch == '[' && idx == -1)\r
+                        {\r
+                            idx = 0;\r
+                        }\r
+                        else if (idx >= 0)\r
+                        {\r
+                            if (ch == ']')\r
+                            {\r
+                                do_check_expected_values = FALSE;\r
+                                buf[idx] = '\0';\r
+                                idx = -1;\r
+\r
+                                expected_protocol = atoi (buf);\r
+\r
+                                if (expected_protocol > 0)\r
+                                {\r
+                                    p = buf;\r
+                                    while (*p)\r
+                                    {\r
+                                        if (*p == 'x')\r
+                                        {\r
+                                            p++;\r
+\r
+                                            if (sscanf (p, "%x", &expected_address) == 1)\r
+                                            {\r
+                                                do_check_expected_values = TRUE;\r
+                                            }\r
+                                            break;\r
+                                        }\r
+                                        p++;\r
+                                    }\r
+\r
+                                    if (do_check_expected_values)\r
+                                    {\r
+                                        do_check_expected_values = FALSE;\r
+\r
+                                        while (*p)\r
+                                        {\r
+                                            if (*p == 'x')\r
+                                            {\r
+                                                p++;\r
+\r
+                                                if (sscanf (p, "%x", &expected_command) == 1)\r
+                                                {\r
+                                                    do_check_expected_values = TRUE;\r
+                                                }\r
+                                                break;\r
+                                            }\r
+                                            p++;\r
+                                        }\r
+\r
+                                        if (do_check_expected_values)\r
+                                        {\r
+                                            // printf ("!%2d %04x %04x!\n", expected_protocol, expected_address, expected_command);\r
+                                        }\r
+                                    }\r
+                                }\r
+                            }\r
+                            else if (idx < 1024 - 2)\r
+                            {\r
+                                buf[idx++] = ch;\r
+                            }\r
+                        }\r
                         putchar (ch);\r
                     }\r
                 }\r