]> cloudbase.mooo.com Git - irmp.git/blobdiff - irmp.c
version 2.0.0-pre3: changed handling of double width pulses/pauses in manchester...
[irmp.git] / irmp.c
diff --git a/irmp.c b/irmp.c
index 5c35ccf04769a2f9e22ff3115c2153e2a1177260..1016dbc8469d08a6287b6bf3b5a00959b9a8ad20 100644 (file)
--- a/irmp.c
+++ b/irmp.c
@@ -1,9 +1,9 @@
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
  * irmp.c - infrared multi-protocol decoder, supports several remote control protocols\r
  *\r
- * Copyright (c) 2009-2010 Frank Meyer - frank(at)fli4l.de\r
+ * Copyright (c) 2009-2011 Frank Meyer - frank(at)fli4l.de\r
  *\r
- * $Id: irmp.c,v 1.99 2011/03/10 12:29:13 fm Exp $\r
+ * $Id: irmp.c,v 1.101 2011/04/20 09:09:48 fm Exp $\r
  *\r
  * ATMEGA88 @ 8 MHz\r
  *\r
@@ -32,6 +32,7 @@
  * NIKON        - Nikon cameras\r
  * RUWIDO       - T-Home\r
  * KATHREIN     - Kathrein\r
+ * LEGO         - Lego Power Functions RC\r
  *\r
  *---------------------------------------------------------------------------------------------------------------------------------------------------\r
  *\r
@@ -486,12 +487,9 @@ typedef unsigned int16  uint16_t;
 \r
 #define RC5_START_BIT_LEN_MIN                   ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define RC5_START_BIT_LEN_MAX                   ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
-#define RC5_START_BIT_LEN_MIN_2                 ((uint8_t)(F_INTERRUPTS * 2 * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define RC5_START_BIT_LEN_MAX_2                 ((uint8_t)(F_INTERRUPTS * 2 * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
+\r
 #define RC5_BIT_LEN_MIN                         ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define RC5_BIT_LEN_MAX                         ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
-#define RC5_BIT_LEN_MIN_2                       ((uint8_t)(F_INTERRUPTS * 2 * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define RC5_BIT_LEN_MAX_2                       ((uint8_t)(F_INTERRUPTS * 2 * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
 \r
 #define DENON_PULSE_LEN_MIN                     ((uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define DENON_PULSE_LEN_MAX                     ((uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
@@ -511,14 +509,9 @@ typedef unsigned int16  uint16_t;
 #define RC6_TOGGLE_BIT_LEN_MIN                  ((uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define RC6_TOGGLE_BIT_LEN_MAX                  ((uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
 #define RC6_BIT_PULSE_LEN_MIN                   ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define RC6_BIT_PULSE_LEN_MAX                   ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_30 + 0.5) + 1)       // pulses: 300 - 700\r
-#define RC6_BIT_PAUSE_LEN_MIN                   ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)       // pauses: 300 - 600\r
-#define RC6_BIT_PAUSE_LEN_MAX                   ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
-\r
-#define RC6_BIT_PULSE_LEN_MIN_2                 ((uint8_t)(F_INTERRUPTS * 2 * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define RC6_BIT_PULSE_LEN_MAX_2                 ((uint8_t)(F_INTERRUPTS * 2 * RC6_BIT_TIME * MAX_TOLERANCE_60 + 0.5) + 1)   // pulses: 600 - 1400\r
-#define RC6_BIT_PAUSE_LEN_MIN_2                 ((uint8_t)(F_INTERRUPTS * 2 * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)   // pauses: 600 - 1200\r
-#define RC6_BIT_PAUSE_LEN_MAX_2                 ((uint8_t)(F_INTERRUPTS * 2 * RC6_BIT_TIME * MAX_TOLERANCE_60 + 0.5) + 1)\r
+#define RC6_BIT_PULSE_LEN_MAX                   ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_60 + 0.5) + 1)       // pulses: 300 - 800\r
+#define RC6_BIT_PAUSE_LEN_MIN                   ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
+#define RC6_BIT_PAUSE_LEN_MAX                   ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_20 + 0.5) + 1)       // pauses: 300 - 600\r
 \r
 #define RECS80EXT_START_BIT_PULSE_LEN_MIN       ((uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MIN_TOLERANCE_00 + 0.5) - 1)\r
 #define RECS80EXT_START_BIT_PULSE_LEN_MAX       ((uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MAX_TOLERANCE_00 + 0.5) + 1)\r
@@ -576,8 +569,6 @@ typedef unsigned int16  uint16_t;
 #define GRUNDIG_NOKIA_IR60_START_BIT_LEN_MAX    ((uint8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
 #define GRUNDIG_NOKIA_IR60_BIT_LEN_MIN          ((uint8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
 #define GRUNDIG_NOKIA_IR60_BIT_LEN_MAX          ((uint8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
-#define GRUNDIG_NOKIA_IR60_BIT_LEN_MIN_2        ((uint8_t)(F_INTERRUPTS * 2 * GRUNDIG_NOKIA_IR60_BIT_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
-#define GRUNDIG_NOKIA_IR60_BIT_LEN_MAX_2        ((uint8_t)(F_INTERRUPTS * 2 * GRUNDIG_NOKIA_IR60_BIT_TIME * MAX_TOLERANCE_50 + 0.5) + 1)\r
 #define GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MIN    ((uint8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) + 1)\r
 #define GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MAX    ((uint8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
 \r
@@ -585,18 +576,10 @@ typedef unsigned int16  uint16_t;
 #define SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX       ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
 #define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN       ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX       ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
-#define SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN_2     ((uint8_t)(F_INTERRUPTS * 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX_2     ((uint8_t)(F_INTERRUPTS * 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
-#define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN_2     ((uint8_t)(F_INTERRUPTS * 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX_2     ((uint8_t)(F_INTERRUPTS * 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
 #define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN             ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX             ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
 #define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN             ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX             ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
-#define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN_2           ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME_2 * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX_2           ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME_2 * MAX_TOLERANCE_60 + 0.5) + 1)\r
-#define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN_2           ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME_2 * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX_2           ((uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME_2 * MAX_TOLERANCE_60 + 0.5) + 1)\r
 \r
 #define FDC_START_BIT_PULSE_LEN_MIN             ((uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)   // 5%: avoid conflict with NETBOX\r
 #define FDC_START_BIT_PULSE_LEN_MAX             ((uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5))\r
@@ -675,6 +658,17 @@ typedef unsigned int16  uint16_t;
 #define NETBOX_PULSE_REST_LEN                   ((uint8_t)(F_INTERRUPTS * NETBOX_PULSE_TIME / 4))\r
 #define NETBOX_PAUSE_REST_LEN                   ((uint8_t)(F_INTERRUPTS * NETBOX_PAUSE_TIME / 4))\r
 \r
+#define LEGO_START_BIT_PULSE_LEN_MIN            ((uint8_t)(F_INTERRUPTS * LEGO_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define LEGO_START_BIT_PULSE_LEN_MAX            ((uint8_t)(F_INTERRUPTS * LEGO_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define LEGO_START_BIT_PAUSE_LEN_MIN            ((uint8_t)(F_INTERRUPTS * LEGO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define LEGO_START_BIT_PAUSE_LEN_MAX            ((uint8_t)(F_INTERRUPTS * LEGO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define LEGO_PULSE_LEN_MIN                      ((uint8_t)(F_INTERRUPTS * LEGO_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define LEGO_PULSE_LEN_MAX                      ((uint8_t)(F_INTERRUPTS * LEGO_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define LEGO_1_PAUSE_LEN_MIN                    ((uint8_t)(F_INTERRUPTS * LEGO_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define LEGO_1_PAUSE_LEN_MAX                    ((uint8_t)(F_INTERRUPTS * LEGO_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define LEGO_0_PAUSE_LEN_MIN                    ((uint8_t)(F_INTERRUPTS * LEGO_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define LEGO_0_PAUSE_LEN_MAX                    ((uint8_t)(F_INTERRUPTS * LEGO_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+\r
 #define IMON_START_BIT_PULSE_LEN_MIN            ((uint8_t)(F_INTERRUPTS * IMON_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define IMON_START_BIT_PULSE_LEN_MAX            ((uint8_t)(F_INTERRUPTS * IMON_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
 #define IMON_START_BIT_PAUSE_LEN_MIN            ((uint8_t)(F_INTERRUPTS * IMON_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
@@ -1091,10 +1085,10 @@ static PROGMEM IRMP_PARAMETER rc5_param =
     RC5_BIT_LEN_MAX,                                                    // pulse_1_len_max: here: maximum length of short pulse\r
     RC5_BIT_LEN_MIN,                                                    // pause_1_len_min: here: minimum length of short pause\r
     RC5_BIT_LEN_MAX,                                                    // pause_1_len_max: here: maximum length of short pause\r
-    RC5_BIT_LEN_MIN_2,                                                  // pulse_0_len_min: here: minimum length of long pulse\r
-    RC5_BIT_LEN_MAX_2,                                                  // pulse_0_len_max: here: maximum length of long pulse\r
-    RC5_BIT_LEN_MIN_2,                                                  // pause_0_len_min: here: minimum length of long pause\r
-    RC5_BIT_LEN_MAX_2,                                                  // pause_0_len_max: here: maximum length of long pause\r
+    0,                                                                  // pulse_0_len_min: here: not used\r
+    0,                                                                  // pulse_0_len_max: here: not used\r
+    0,                                                                  // pause_0_len_min: here: not used\r
+    0,                                                                  // pause_0_len_max: here: not used\r
     RC5_ADDRESS_OFFSET,                                                 // address_offset:  address offset\r
     RC5_ADDRESS_OFFSET + RC5_ADDRESS_LEN,                               // address_end:     end of address\r
     RC5_COMMAND_OFFSET,                                                 // command_offset:  command offset\r
@@ -1142,10 +1136,10 @@ static PROGMEM IRMP_PARAMETER rc6_param =
     RC6_BIT_PULSE_LEN_MAX,                                              // pulse_1_len_max: here: maximum length of short pulse\r
     RC6_BIT_PAUSE_LEN_MIN,                                              // pause_1_len_min: here: minimum length of short pause\r
     RC6_BIT_PAUSE_LEN_MAX,                                              // pause_1_len_max: here: maximum length of short pause\r
-    RC6_BIT_PULSE_LEN_MIN_2,                                            // pulse_0_len_min: here: minimum length of long pulse\r
-    RC6_BIT_PULSE_LEN_MAX_2,                                            // pulse_0_len_max: here: maximum length of long pulse\r
-    RC6_BIT_PAUSE_LEN_MIN_2,                                            // pause_0_len_min: here: minimum length of long pause\r
-    RC6_BIT_PAUSE_LEN_MAX_2,                                            // pause_0_len_max: here: maximum length of long pause\r
+    0,                                                                  // pulse_0_len_min: here: not used\r
+    0,                                                                  // pulse_0_len_max: here: not used\r
+    0,                                                                  // pause_0_len_min: here: not used\r
+    0,                                                                  // pause_0_len_max: here: not used\r
     RC6_ADDRESS_OFFSET,                                                 // address_offset:  address offset\r
     RC6_ADDRESS_OFFSET + RC6_ADDRESS_LEN,                               // address_end:     end of address\r
     RC6_COMMAND_OFFSET,                                                 // command_offset:  command offset\r
@@ -1245,11 +1239,10 @@ static PROGMEM IRMP_PARAMETER grundig_param =
     GRUNDIG_NOKIA_IR60_BIT_LEN_MAX,                                     // pulse_1_len_max: here: maximum length of short pulse\r
     GRUNDIG_NOKIA_IR60_BIT_LEN_MIN,                                     // pause_1_len_min: here: minimum length of short pause\r
     GRUNDIG_NOKIA_IR60_BIT_LEN_MAX,                                     // pause_1_len_max: here: maximum length of short pause\r
-    GRUNDIG_NOKIA_IR60_BIT_LEN_MIN_2,                                   // pulse_0_len_min: here: minimum length of long pulse\r
-    GRUNDIG_NOKIA_IR60_BIT_LEN_MAX_2,                                   // pulse_0_len_max: here: maximum length of long pulse\r
-    GRUNDIG_NOKIA_IR60_BIT_LEN_MIN_2,                                   // pause_0_len_min: here: minimum length of long pause\r
-    GRUNDIG_NOKIA_IR60_BIT_LEN_MAX_2,                                   // pause_0_len_max: here: maximum length of long pause\r
-\r
+    0,                                                                  // pulse_0_len_min: here: not used\r
+    0,                                                                  // pulse_0_len_max: here: not used\r
+    0,                                                                  // pause_0_len_min: here: not used\r
+    0,                                                                  // pause_0_len_max: here: not used\r
     GRUNDIG_ADDRESS_OFFSET,                                             // address_offset:  address offset\r
     GRUNDIG_ADDRESS_OFFSET + GRUNDIG_ADDRESS_LEN,                       // address_end:     end of address\r
     GRUNDIG_COMMAND_OFFSET,                                             // command_offset:  command offset\r
@@ -1271,10 +1264,10 @@ static PROGMEM IRMP_PARAMETER ruwido_param =
     SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX,                                // pulse_1_len_max: here: maximum length of short pulse\r
     SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN,                                // pause_1_len_min: here: minimum length of short pause\r
     SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX,                                // pause_1_len_max: here: maximum length of short pause\r
-    SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN_2,                              // pulse_0_len_min: here: minimum length of long pulse\r
-    SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX_2,                              // pulse_0_len_max: here: maximum length of long pulse\r
-    SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN_2,                              // pause_0_len_min: here: minimum length of long pause\r
-    SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX_2,                              // pause_0_len_max: here: maximum length of long pause\r
+    0,                                                                  // pulse_0_len_min: here: not used\r
+    0,                                                                  // pulse_0_len_max: here: not used\r
+    0,                                                                  // pause_0_len_min: here: not used\r
+    0,                                                                  // pause_0_len_max: here: not used\r
     RUWIDO_ADDRESS_OFFSET,                                              // address_offset:  address offset\r
     RUWIDO_ADDRESS_OFFSET + RUWIDO_ADDRESS_LEN,                         // address_end:     end of address\r
     RUWIDO_COMMAND_OFFSET,                                              // command_offset:  command offset\r
@@ -1412,6 +1405,31 @@ static PROGMEM IRMP_PARAMETER netbox_param =
 \r
 #endif\r
 \r
+#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\r
+\r
+static PROGMEM IRMP_PARAMETER lego_param =\r
+{\r
+    IRMP_LEGO_PROTOCOL,                                                 // protocol:        ir protocol\r
+    LEGO_PULSE_LEN_MIN,                                                 // pulse_1_len_min: minimum length of pulse with bit value 1\r
+    LEGO_PULSE_LEN_MAX,                                                 // pulse_1_len_max: maximum length of pulse with bit value 1\r
+    LEGO_1_PAUSE_LEN_MIN,                                               // pause_1_len_min: minimum length of pause with bit value 1\r
+    LEGO_1_PAUSE_LEN_MAX,                                               // pause_1_len_max: maximum length of pause with bit value 1\r
+    LEGO_PULSE_LEN_MIN,                                                 // pulse_0_len_min: minimum length of pulse with bit value 0\r
+    LEGO_PULSE_LEN_MAX,                                                 // pulse_0_len_max: maximum length of pulse with bit value 0\r
+    LEGO_0_PAUSE_LEN_MIN,                                               // pause_0_len_min: minimum length of pause with bit value 0\r
+    LEGO_0_PAUSE_LEN_MAX,                                               // pause_0_len_max: maximum length of pause with bit value 0\r
+    LEGO_ADDRESS_OFFSET,                                                // address_offset:  address offset\r
+    LEGO_ADDRESS_OFFSET + LEGO_ADDRESS_LEN,                             // address_end:     end of address\r
+    LEGO_COMMAND_OFFSET,                                                // command_offset:  command offset\r
+    LEGO_COMMAND_OFFSET + LEGO_COMMAND_LEN,                             // command_end:     end of command\r
+    LEGO_COMPLETE_DATA_LEN,                                             // complete_len:    complete length of frame\r
+    LEGO_STOP_BIT,                                                      // stop_bit:        flag: frame has stop bit\r
+    LEGO_LSB,                                                           // lsb_first:       flag: LSB first\r
+    LEGO_FLAGS                                                          // flags:           some flags\r
+};\r
+\r
+#endif\r
+\r
 #if IRMP_SUPPORT_IMON_PROTOCOL == 1\r
 \r
 static PROGMEM IRMP_PARAMETER imon_param =\r
@@ -1584,6 +1602,24 @@ irmp_get_data (IRMP_DATA * irmp_data_p)
                 break;\r
 #endif\r
 #endif // 0\r
+#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\r
+            case IRMP_LEGO_PROTOCOL:\r
+            {\r
+                uint8_t crc = 0x0F ^ ((irmp_command & 0xF000) >> 12) ^ ((irmp_command & 0x0F00) >> 8) ^ ((irmp_command & 0x00F0) >> 4);\r
+\r
+                if ((irmp_command & 0x000F) == crc)\r
+                {\r
+                    irmp_command >>= 4;\r
+                    rtc = TRUE;\r
+                }\r
+                else\r
+                {\r
+                    ANALYZE_PRINTF ("CRC error in LEGO protocol\n");\r
+                    rtc = TRUE;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
             default:\r
                 rtc = TRUE;\r
         }\r
@@ -1974,10 +2010,10 @@ irmp_ISR (void)
 #endif // IRMP_SUPPORT_RECS80_PROTOCOL == 1\r
 \r
 #if IRMP_SUPPORT_RC5_PROTOCOL == 1\r
-                    if (((irmp_pulse_time >= RC5_START_BIT_LEN_MIN   && irmp_pulse_time <= RC5_START_BIT_LEN_MAX) ||\r
-                         (irmp_pulse_time >= RC5_START_BIT_LEN_MIN_2 && irmp_pulse_time <= RC5_START_BIT_LEN_MAX_2)) &&\r
-                        ((irmp_pause_time >= RC5_START_BIT_LEN_MIN   && irmp_pause_time <= RC5_START_BIT_LEN_MAX) ||\r
-                         (irmp_pause_time >= RC5_START_BIT_LEN_MIN_2 && irmp_pause_time <= RC5_START_BIT_LEN_MAX_2)))\r
+                    if (((irmp_pulse_time >= RC5_START_BIT_LEN_MIN     && irmp_pulse_time <= RC5_START_BIT_LEN_MAX) ||\r
+                         (irmp_pulse_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX)) &&\r
+                        ((irmp_pause_time >= RC5_START_BIT_LEN_MIN     && irmp_pause_time <= RC5_START_BIT_LEN_MAX) ||\r
+                         (irmp_pause_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX)))\r
                     {                                                           // it's RC5\r
 #if IRMP_SUPPORT_FDC_PROTOCOL == 1\r
                         if (irmp_pulse_time >= FDC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FDC_START_BIT_PULSE_LEN_MAX &&\r
@@ -2013,16 +2049,16 @@ irmp_ISR (void)
                         {\r
                             ANALYZE_PRINTF ("protocol = RC5, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or pulse: %3d - %3d, pause: %3d - %3d\n",\r
                                             RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,\r
-                                            RC5_START_BIT_LEN_MIN_2, RC5_START_BIT_LEN_MAX_2,\r
+                                            2 * RC5_START_BIT_LEN_MIN, 2 * RC5_START_BIT_LEN_MAX,\r
                                             RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,\r
-                                            RC5_START_BIT_LEN_MIN_2, RC5_START_BIT_LEN_MAX_2);\r
+                                            2 * RC5_START_BIT_LEN_MIN, 2 * RC5_START_BIT_LEN_MAX);\r
                         }\r
 \r
                         irmp_param_p = (IRMP_PARAMETER *) &rc5_param;\r
                         last_pause = irmp_pause_time;\r
 \r
-                        if ((irmp_pulse_time > RC5_START_BIT_LEN_MAX && irmp_pulse_time <= RC5_START_BIT_LEN_MAX_2) ||\r
-                            (irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= RC5_START_BIT_LEN_MAX_2))\r
+                        if ((irmp_pulse_time > RC5_START_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX) ||\r
+                            (irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX))\r
                         {\r
                           last_value  = 0;\r
                           rc5_cmd_bit6 = 1<<6;\r
@@ -2126,15 +2162,15 @@ irmp_ISR (void)
 \r
 #if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1\r
                     if (((irmp_pulse_time >= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX) ||\r
-                         (irmp_pulse_time >= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN_2 && irmp_pulse_time <= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX_2)) &&\r
+                         (irmp_pulse_time >= 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX)) &&\r
                         ((irmp_pause_time >= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX) || \r
-                         (irmp_pause_time >= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN_2 && irmp_pause_time <= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX_2)))\r
+                         (irmp_pause_time >= 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX)))\r
                     {                                                           // it's RUWIDO or SIEMENS\r
                         ANALYZE_PRINTF ("protocol = RUWIDO, start bit timings: pulse: %3d - %3d or %3d - %3d, pause: %3d - %3d or %3d - %3d\n",\r
                                         SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN,   SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX,\r
-                                        SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN_2, SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX_2,\r
+                                        2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX,\r
                                         SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN,   SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX,\r
-                                        SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN_2, SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX_2);\r
+                                        2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX);\r
                         irmp_param_p = (IRMP_PARAMETER *) &ruwido_param;\r
                         last_pause = irmp_pause_time;\r
                         last_value  = 1;\r
@@ -2190,6 +2226,18 @@ irmp_ISR (void)
                     else\r
 #endif // IRMP_SUPPORT_NETBOX_PROTOCOL == 1\r
 \r
+#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\r
+                    if (irmp_pulse_time >= LEGO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= LEGO_START_BIT_PULSE_LEN_MAX &&\r
+                        irmp_pause_time >= LEGO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= LEGO_START_BIT_PAUSE_LEN_MAX)\r
+                    {\r
+                        ANALYZE_PRINTF ("protocol = LEGO, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",\r
+                                        LEGO_START_BIT_PULSE_LEN_MIN, LEGO_START_BIT_PULSE_LEN_MAX,\r
+                                        LEGO_START_BIT_PAUSE_LEN_MIN, LEGO_START_BIT_PAUSE_LEN_MAX);\r
+                        irmp_param_p = (IRMP_PARAMETER *) &lego_param;\r
+                    }\r
+                    else\r
+#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1\r
+\r
 #if IRMP_SUPPORT_IMON_PROTOCOL == 1\r
                     if (irmp_pulse_time >= IMON_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= IMON_START_BIT_PULSE_LEN_MAX &&\r
                         irmp_pause_time >= IMON_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= IMON_START_BIT_PAUSE_LEN_MAX)\r
@@ -2220,9 +2268,9 @@ irmp_ISR (void)
                         else\r
                         {\r
                             ANALYZE_PRINTF ("pulse: %3d - %3d or %3d - %3d\n", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max,\r
-                                            irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);\r
+                                            2 * irmp_param.pulse_1_len_min, 2 * irmp_param.pulse_1_len_max);\r
                             ANALYZE_PRINTF ("pause: %3d - %3d or %3d - %3d\n", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max,\r
-                                            irmp_param.pause_0_len_min, irmp_param.pause_0_len_max);\r
+                                            2 * irmp_param.pause_1_len_min, 2 * irmp_param.pause_1_len_max);\r
                         }\r
 \r
 #if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\r
@@ -2245,8 +2293,8 @@ irmp_ISR (void)
 \r
                         if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))\r
                         {\r
-                            ANALYZE_PRINTF ("pulse_0: %3d - %3d\n", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);\r
-                            ANALYZE_PRINTF ("pause_0: %3d - %3d\n", irmp_param.pause_0_len_min, irmp_param.pause_0_len_max);\r
+                            ANALYZE_PRINTF ("pulse_0: %3d - %3d\n", 2 * irmp_param.pulse_1_len_min, 2 * irmp_param.pulse_1_len_max);\r
+                            ANALYZE_PRINTF ("pause_0: %3d - %3d\n", 2 * irmp_param.pause_1_len_min, 2 * irmp_param.pause_1_len_max);\r
                         }\r
 \r
 #if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
@@ -2271,7 +2319,7 @@ irmp_ISR (void)
                          irmp_param.protocol != IRMP_RUWIDO_PROTOCOL && // Manchester, but not RUWIDO\r
                          irmp_param.protocol != IRMP_RC6_PROTOCOL)      // Manchester, but not RC6\r
                     {\r
-                        if (irmp_pause_time > irmp_param.pulse_1_len_max && irmp_pause_time <= irmp_param.pulse_0_len_max)      // XXXXXXXX!!!\r
+                        if (irmp_pause_time > irmp_param.pulse_1_len_max && irmp_pause_time <= 2 * irmp_param.pulse_1_len_max)\r
                         {\r
                             ANALYZE_PRINTF ("%8d [bit %2d: pulse = %3d, pause = %3d] ", time_counter, irmp_bit, irmp_pulse_time, irmp_pause_time);\r
                             ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '0' : '1');\r
@@ -2407,7 +2455,7 @@ irmp_ISR (void)
                                 irmp_tmp_command <<= 1;\r
                                 irmp_tmp_command |= first_bit;\r
                             }\r
-                            else if (irmp_pause_time >= irmp_param.pause_0_len_max && irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN - 2)\r
+                            else if (irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN - 2)\r
                             {                                                           // special manchester decoder\r
                                 irmp_param.complete_len = GRUNDIG_COMPLETE_DATA_LEN;    // correct complete len\r
                                 got_light = TRUE;                                       // this is a lie, but generates a stop bit ;-)\r
@@ -2434,7 +2482,7 @@ irmp_ISR (void)
 #if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1\r
                         if (irmp_param.protocol == IRMP_RUWIDO_PROTOCOL && !irmp_param.stop_bit)\r
                         {\r
-                            if (irmp_pause_time >= irmp_param.pause_0_len_max && irmp_bit >= RUWIDO_COMPLETE_DATA_LEN - 2)\r
+                            if (irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= RUWIDO_COMPLETE_DATA_LEN - 2)\r
                             {                                                           // special manchester decoder\r
                                 irmp_param.complete_len = RUWIDO_COMPLETE_DATA_LEN;     // correct complete len\r
                                 got_light = TRUE;                                       // this is a lie, but generates a stop bit ;-)\r
@@ -2463,7 +2511,7 @@ irmp_ISR (void)
 #endif\r
 #if IRMP_SUPPORT_MANCHESTER == 1\r
                         if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) &&\r
-                            irmp_pause_time >= irmp_param.pause_0_len_max && irmp_bit >= irmp_param.complete_len - 2 && !irmp_param.stop_bit)\r
+                            irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= irmp_param.complete_len - 2 && !irmp_param.stop_bit)\r
                         {                                                       // special manchester decoder\r
                             got_light = TRUE;                                   // this is a lie, but generates a stop bit ;-)\r
                             irmp_param.stop_bit = TRUE;                         // set flag\r
@@ -2545,11 +2593,11 @@ irmp_ISR (void)
 #if IRMP_SUPPORT_MANCHESTER == 1\r
                     if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))                                     // Manchester\r
                     {\r
-#if 0\r
-                        if (irmp_pulse_time > irmp_param.pulse_1_len_max /* && irmp_pulse_time <= irmp_param.pulse_0_len_max */)\r
-#else // better:\r
-                        if (irmp_pulse_time > irmp_param.pulse_1_len_max && irmp_pulse_time <= irmp_param.pulse_0_len_max &&\r
-                            irmp_pause_time <= irmp_param.pause_0_len_max)\r
+#if 1\r
+                        if (irmp_pulse_time > irmp_param.pulse_1_len_max /* && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max */)\r
+#else // better, but some IR-RCs use asymmetric timings :-/\r
+                        if (irmp_pulse_time > irmp_param.pulse_1_len_max && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max &&\r
+                            irmp_pause_time <= 2 * irmp_param.pause_1_len_max)\r
 #endif\r
                         {\r
 #if IRMP_SUPPORT_RC6_PROTOCOL == 1\r
@@ -2580,7 +2628,7 @@ irmp_ISR (void)
                                     ANALYZE_PUTCHAR ('T');\r
                                     irmp_store_bit (1);\r
 \r
-                                    if (irmp_pause_time > irmp_param.pause_0_len_max)\r
+                                    if (irmp_pause_time > 2 * irmp_param.pause_1_len_max)\r
                                     {\r
                                         last_value = 0;\r
                                     }\r
@@ -2605,12 +2653,12 @@ irmp_ISR (void)
                                 }\r
                             }\r
                         }\r
-                        else if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max /* &&\r
-                                 irmp_pause_time <= irmp_param.pause_0_len_max */)\r
+                        else if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max\r
+                                 /* && irmp_pause_time <= 2 * irmp_param.pause_1_len_max */)\r
                         {\r
                             uint8_t manchester_value;\r
 \r
-                            if (last_pause > irmp_param.pause_1_len_max && last_pause <= irmp_param.pause_0_len_max)\r
+                            if (last_pause > irmp_param.pause_1_len_max && last_pause <= 2 * irmp_param.pause_1_len_max)\r
                             {\r
                                 manchester_value = last_value ? 0 : 1;\r
                                 last_value  = manchester_value;\r
@@ -2825,6 +2873,7 @@ irmp_ISR (void)
 #endif // IRMP_SUPPORT_NEC42_PROTOCOL == 1\r
                         irmp_bit == 8 && irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX)\r
                     {\r
+printf ("! %d %d !\n", irmp_pause_time, NEC_START_BIT_PAUSE_LEN_MAX);\r
                         ANALYZE_PRINTF ("Switching to NEC16 protocol\n");\r
                         irmp_param.protocol = IRMP_NEC16_PROTOCOL;\r
                         irmp_param.address_offset   = NEC16_ADDRESS_OFFSET;\r
@@ -3327,8 +3376,8 @@ print_timings (void)
             SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN, SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX,\r
             SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN, SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX,\r
             SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN, SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX,\r
-            SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN_2, SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX_2,\r
-            SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN_2, SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX_2);\r
+            2 * SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX,\r
+            2 * SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX);\r
 \r
     printf ("FDC            1  %3d - %3d  %3d - %3d  %3d - %3d  %3d - %3d  %3d - %3d  %3d - %3d\n",\r
             FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX, FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX,\r
@@ -3344,6 +3393,12 @@ print_timings (void)
             NIKON_START_BIT_PULSE_LEN_MIN, NIKON_START_BIT_PULSE_LEN_MAX, NIKON_START_BIT_PAUSE_LEN_MIN, NIKON_START_BIT_PAUSE_LEN_MAX,\r
             NIKON_PULSE_LEN_MIN, NIKON_PULSE_LEN_MAX, NIKON_0_PAUSE_LEN_MIN, NIKON_0_PAUSE_LEN_MAX,\r
             NIKON_PULSE_LEN_MIN, NIKON_PULSE_LEN_MAX, NIKON_1_PAUSE_LEN_MIN, NIKON_1_PAUSE_LEN_MAX);\r
+\r
+    printf ("LEGO           1  %3d - %3d  %3d - %3d  %3d - %3d  %3d - %3d  %3d - %3d  %3d - %3d\n",\r
+            LEGO_START_BIT_PULSE_LEN_MIN, LEGO_START_BIT_PULSE_LEN_MAX, LEGO_START_BIT_PAUSE_LEN_MIN, LEGO_START_BIT_PAUSE_LEN_MAX,\r
+            LEGO_PULSE_LEN_MIN, LEGO_PULSE_LEN_MAX, LEGO_0_PAUSE_LEN_MIN, LEGO_0_PAUSE_LEN_MAX,\r
+            LEGO_PULSE_LEN_MIN, LEGO_PULSE_LEN_MAX, LEGO_1_PAUSE_LEN_MIN, LEGO_1_PAUSE_LEN_MAX);\r
+\r
 }\r
 \r
 void\r