]> cloudbase.mooo.com Git - irmp.git/blobdiff - irmp.c
Version 3.0.7 - added SAMSUNGAH protocol, improved some code for ESP8266
[irmp.git] / irmp.c
diff --git a/irmp.c b/irmp.c
index 8cbeb49187903c8045cff2b683539c265c0a8121..150d69fef863829b18a7eb780aa87a9035c38417 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-2015 Frank Meyer - frank(at)fli4l.de\r
+ * Copyright (c) 2009-2016 Frank Meyer - frank(at)fli4l.de\r
  *\r
- * $Id: irmp.c,v 1.183 2015/12/03 18:13:45 fm Exp $\r
+ * $Id: irmp.c,v 1.192 2017/02/17 09:13:06 fm Exp $\r
  *\r
  * Supported AVR mikrocontrollers:\r
  *\r
 #define SAMSUNG_0_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\r
 #define SAMSUNG_0_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\r
 \r
+#define SAMSUNGAH_START_BIT_PULSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
+#define SAMSUNGAH_START_BIT_PULSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
+#define SAMSUNGAH_START_BIT_PAUSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
+#define SAMSUNGAH_START_BIT_PAUSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
+#define SAMSUNGAH_PULSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\r
+#define SAMSUNGAH_PULSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\r
+#define SAMSUNGAH_1_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\r
+#define SAMSUNGAH_1_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\r
+#define SAMSUNGAH_0_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\r
+#define SAMSUNGAH_0_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\r
+\r
 #define MATSUSHITA_START_BIT_PULSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
 #define MATSUSHITA_START_BIT_PULSE_LEN_MAX      ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
 #define MATSUSHITA_START_BIT_PAUSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
 #define KASEIKYO_0_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
 #define KASEIKYO_0_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
 \r
+#define MITSU_HEAVY_START_BIT_PULSE_LEN_MIN     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
+#define MITSU_HEAVY_START_BIT_PULSE_LEN_MAX     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
+#define MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
+#define MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
+#define MITSU_HEAVY_PULSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define MITSU_HEAVY_PULSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define MITSU_HEAVY_1_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
+#define MITSU_HEAVY_1_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
+#define MITSU_HEAVY_0_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
+#define MITSU_HEAVY_0_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
+\r
+#define VINCENT_START_BIT_PULSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
+#define VINCENT_START_BIT_PULSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
+#define VINCENT_START_BIT_PAUSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
+#define VINCENT_START_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
+#define VINCENT_PULSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * VINCENT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define VINCENT_PULSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * VINCENT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define VINCENT_1_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
+#define VINCENT_1_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
+#define VINCENT_0_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
+#define VINCENT_0_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
+\r
 #define PANASONIC_START_BIT_PULSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
 #define PANASONIC_START_BIT_PULSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
 #define PANASONIC_START_BIT_PAUSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
@@ -623,6 +656,9 @@ static const char proto_s100[]          PROGMEM = "S100";
 static const char proto_acp24[]         PROGMEM = "ACP24";\r
 static const char proto_technics[]      PROGMEM = "TECHNICS";\r
 static const char proto_panasonic[]     PROGMEM = "PANASONIC";\r
+static const char proto_mitsu_heavy[]   PROGMEM = "MITSU_HEAVY";\r
+static const char proto_vincent[]       PROGMEM = "VINCENT";\r
+static const char proto_samsungah[]     PROGMEM = "SAMSUNGAH";\r
 \r
 static const char proto_radio1[]        PROGMEM = "RADIO1";\r
 \r
@@ -678,6 +714,9 @@ irmp_protocol_names[IRMP_N_PROTOCOLS + 1] PROGMEM =
     proto_acp24,\r
     proto_technics,\r
     proto_panasonic,\r
+    proto_mitsu_heavy,\r
+    proto_vincent,\r
+    proto_samsungah,\r
     proto_radio1\r
 };\r
 \r
@@ -793,7 +832,7 @@ irmp_uart_init (void)
     // Oversampling\r
     USART_OverSampling8Cmd(STM32_UART_COM, ENABLE);\r
 \r
-    // init mit Baudrate, 8Databits, 1Stopbit, keine Parität, kein RTS+CTS\r
+    // init baud rate, 8 data bits, 1 stop bit, no parity, no RTS+CTS\r
     USART_InitStructure.USART_BaudRate = STM32_UART_BAUD;\r
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;\r
     USART_InitStructure.USART_StopBits = USART_StopBits_1;\r
@@ -826,7 +865,7 @@ irmp_uart_init (void)
     // Oversampling\r
     USART_OverSampling8Cmd(STM32_UART_COM, ENABLE);\r
 \r
-    // init mit Baudrate, 8Databits, 1Stopbit, keine Parität, kein RTS+CTS\r
+    // init baud rate, 8 data bits, 1 stop bit, no parity, no RTS+CTS\r
     USART_InitStructure.USART_BaudRate = 115200;\r
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;\r
     USART_InitStructure.USART_StopBits = USART_StopBits_1;\r
@@ -837,7 +876,7 @@ irmp_uart_init (void)
 \r
     // UART enable\r
     USART_Cmd(STM32_UART_COM, ENABLE);\r
-        \r
+\r
 #elif defined(ARDUINO)\r
     // we use the Arduino Serial Imlementation\r
     // you have to call Serial.begin(SER_BAUD); in Arduino setup() function\r
@@ -848,10 +887,10 @@ irmp_uart_init (void)
 \r
     USARTC1.BAUDCTRLB = 0;\r
     USARTC1.BAUDCTRLA = F_CPU / 153600 - 1;\r
-    USARTC1.CTRLA = USART_RXCINTLVL_HI_gc; // High Level (Empfangen)\r
-    USARTC1.CTRLB = USART_TXEN_bm | USART_RXEN_bm; //Aktiviert Senden und Empfangen\r
-    USARTC1.CTRLC = USART_CHSIZE_8BIT_gc; //Größe der Zeichen: 8 Bit\r
-    PORTC.DIR |= (1<<7);  //TXD als Ausgang setzen\r
+    USARTC1.CTRLA = USART_RXCINTLVL_HI_gc;                                                          // high INT level (receive)\r
+    USARTC1.CTRLB = USART_TXEN_bm | USART_RXEN_bm;                                                  // activated RX and TX\r
+    USARTC1.CTRLC = USART_CHSIZE_8BIT_gc;                                                           // 8 Bit\r
+    PORTC.DIR |= (1<<7);                                                                            // TXD is output\r
     PORTC.DIR &= ~(1<<6);\r
 \r
 #else\r
@@ -906,25 +945,31 @@ irmp_uart_putc (unsigned char ch)
 \r
 #else\r
 #if (IRMP_EXT_LOGGING == 0)\r
-        \r
-        #       if defined (__AVR_XMEGA__)\r
-        while (!(USARTC1.STATUS & USART_DREIF_bm));\r
-        USARTC1.DATA = ch;\r
-        \r
-        #       else //AVR_MEGA\r
+\r
+#  if defined (__AVR_XMEGA__)\r
+    while (!(USARTC1.STATUS & USART_DREIF_bm))\r
+    {\r
+        ;\r
+    }\r
+\r
+    USARTC1.DATA = ch;\r
+\r
+#  else // AVR_MEGA\r
     while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE))\r
     {\r
         ;\r
     }\r
 \r
     UART0_UDR = ch;\r
-        #endif //__AVR_XMEGA__\r
+\r
+#  endif // __AVR_XMEGA__\r
+\r
 #else\r
 \r
     sendextlog(ch);                                                         // use external log\r
 \r
-#endif //IRMP_EXT_LOGGING\r
-#endif //ARM_STM32F4XX\r
+#endif // IRMP_EXT_LOGGING\r
+#endif // ARM_STM32F4XX\r
 #else\r
     fputc (ch, stderr);\r
 #endif // UNIX_OR_WINDOWS\r
@@ -1198,6 +1243,31 @@ static const PROGMEM IRMP_PARAMETER samsung_param =
 \r
 #endif\r
 \r
+#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\r
+\r
+static const PROGMEM IRMP_PARAMETER samsungah_param =\r
+{\r
+    IRMP_SAMSUNGAH_PROTOCOL,                                            // protocol:        ir protocol\r
+    SAMSUNGAH_PULSE_LEN_MIN,                                            // pulse_1_len_min: minimum length of pulse with bit value 1\r
+    SAMSUNGAH_PULSE_LEN_MAX,                                            // pulse_1_len_max: maximum length of pulse with bit value 1\r
+    SAMSUNGAH_1_PAUSE_LEN_MIN,                                          // pause_1_len_min: minimum length of pause with bit value 1\r
+    SAMSUNGAH_1_PAUSE_LEN_MAX,                                          // pause_1_len_max: maximum length of pause with bit value 1\r
+    SAMSUNGAH_PULSE_LEN_MIN,                                            // pulse_0_len_min: minimum length of pulse with bit value 0\r
+    SAMSUNGAH_PULSE_LEN_MAX,                                            // pulse_0_len_max: maximum length of pulse with bit value 0\r
+    SAMSUNGAH_0_PAUSE_LEN_MIN,                                          // pause_0_len_min: minimum length of pause with bit value 0\r
+    SAMSUNGAH_0_PAUSE_LEN_MAX,                                          // pause_0_len_max: maximum length of pause with bit value 0\r
+    SAMSUNGAH_ADDRESS_OFFSET,                                           // address_offset:  address offset\r
+    SAMSUNGAH_ADDRESS_OFFSET + SAMSUNGAH_ADDRESS_LEN,                   // address_end:     end of address\r
+    SAMSUNGAH_COMMAND_OFFSET,                                           // command_offset:  command offset\r
+    SAMSUNGAH_COMMAND_OFFSET + SAMSUNGAH_COMMAND_LEN,                   // command_end:     end of command\r
+    SAMSUNGAH_COMPLETE_DATA_LEN,                                        // complete_len:    complete length of frame\r
+    SAMSUNGAH_STOP_BIT,                                                 // stop_bit:        flag: frame has stop bit\r
+    SAMSUNGAH_LSB,                                                      // lsb_first:       flag: LSB first\r
+    SAMSUNGAH_FLAGS                                                     // flags:           some flags\r
+};\r
+\r
+#endif\r
+\r
 #if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1\r
 \r
 static const PROGMEM IRMP_PARAMETER telefunken_param =\r
@@ -1298,6 +1368,56 @@ static const PROGMEM IRMP_PARAMETER panasonic_param =
 \r
 #endif\r
 \r
+#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+\r
+static const PROGMEM IRMP_PARAMETER mitsu_heavy_param =\r
+{\r
+    IRMP_MITSU_HEAVY_PROTOCOL,                                          // protocol:        ir protocol\r
+    MITSU_HEAVY_PULSE_LEN_MIN,                                          // pulse_1_len_min: minimum length of pulse with bit value 1\r
+    MITSU_HEAVY_PULSE_LEN_MAX,                                          // pulse_1_len_max: maximum length of pulse with bit value 1\r
+    MITSU_HEAVY_1_PAUSE_LEN_MIN,                                        // pause_1_len_min: minimum length of pause with bit value 1\r
+    MITSU_HEAVY_1_PAUSE_LEN_MAX,                                        // pause_1_len_max: maximum length of pause with bit value 1\r
+    MITSU_HEAVY_PULSE_LEN_MIN,                                          // pulse_0_len_min: minimum length of pulse with bit value 0\r
+    MITSU_HEAVY_PULSE_LEN_MAX,                                          // pulse_0_len_max: maximum length of pulse with bit value 0\r
+    MITSU_HEAVY_0_PAUSE_LEN_MIN,                                        // pause_0_len_min: minimum length of pause with bit value 0\r
+    MITSU_HEAVY_0_PAUSE_LEN_MAX,                                        // pause_0_len_max: maximum length of pause with bit value 0\r
+    MITSU_HEAVY_ADDRESS_OFFSET,                                         // address_offset:  address offset\r
+    MITSU_HEAVY_ADDRESS_OFFSET + MITSU_HEAVY_ADDRESS_LEN,               // address_end:     end of address\r
+    MITSU_HEAVY_COMMAND_OFFSET,                                         // command_offset:  command offset\r
+    MITSU_HEAVY_COMMAND_OFFSET + MITSU_HEAVY_COMMAND_LEN,               // command_end:     end of command\r
+    MITSU_HEAVY_COMPLETE_DATA_LEN,                                      // complete_len:    complete length of frame\r
+    MITSU_HEAVY_STOP_BIT,                                               // stop_bit:        flag: frame has stop bit\r
+    MITSU_HEAVY_LSB,                                                    // lsb_first:       flag: LSB first\r
+    MITSU_HEAVY_FLAGS                                                   // flags:           some flags\r
+};\r
+\r
+#endif\r
+\r
+#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1\r
+\r
+static const PROGMEM IRMP_PARAMETER vincent_param =\r
+{\r
+    IRMP_VINCENT_PROTOCOL,                                              // protocol:        ir protocol\r
+    VINCENT_PULSE_LEN_MIN,                                              // pulse_1_len_min: minimum length of pulse with bit value 1\r
+    VINCENT_PULSE_LEN_MAX,                                              // pulse_1_len_max: maximum length of pulse with bit value 1\r
+    VINCENT_1_PAUSE_LEN_MIN,                                            // pause_1_len_min: minimum length of pause with bit value 1\r
+    VINCENT_1_PAUSE_LEN_MAX,                                            // pause_1_len_max: maximum length of pause with bit value 1\r
+    VINCENT_PULSE_LEN_MIN,                                              // pulse_0_len_min: minimum length of pulse with bit value 0\r
+    VINCENT_PULSE_LEN_MAX,                                              // pulse_0_len_max: maximum length of pulse with bit value 0\r
+    VINCENT_0_PAUSE_LEN_MIN,                                            // pause_0_len_min: minimum length of pause with bit value 0\r
+    VINCENT_0_PAUSE_LEN_MAX,                                            // pause_0_len_max: maximum length of pause with bit value 0\r
+    VINCENT_ADDRESS_OFFSET,                                             // address_offset:  address offset\r
+    VINCENT_ADDRESS_OFFSET + VINCENT_ADDRESS_LEN,                       // address_end:     end of address\r
+    VINCENT_COMMAND_OFFSET,                                             // command_offset:  command offset\r
+    VINCENT_COMMAND_OFFSET + VINCENT_COMMAND_LEN,                       // command_end:     end of command\r
+    VINCENT_COMPLETE_DATA_LEN,                                          // complete_len:    complete length of frame\r
+    VINCENT_STOP_BIT,                                                   // stop_bit:        flag: frame has stop bit\r
+    VINCENT_LSB,                                                        // lsb_first:       flag: LSB first\r
+    VINCENT_FLAGS                                                       // flags:           some flags\r
+};\r
+\r
+#endif\r
+\r
 #if IRMP_SUPPORT_RECS80_PROTOCOL == 1\r
 \r
 static const PROGMEM IRMP_PARAMETER recs80_param =\r
@@ -2014,18 +2134,24 @@ static IRMP_PARAMETER                           irmp_param;
 static IRMP_PARAMETER                           irmp_param2;\r
 #endif\r
 \r
-static volatile uint_fast8_t                     irmp_ir_detected = FALSE;\r
-static volatile uint_fast8_t                     irmp_protocol;\r
-static volatile uint_fast16_t                    irmp_address;\r
-static volatile uint_fast16_t                    irmp_command;\r
-static volatile uint_fast16_t                    irmp_id;                    // only used for SAMSUNG protocol\r
-static volatile uint_fast8_t                     irmp_flags;\r
-// static volatile uint_fast8_t                  irmp_busy_flag;\r
+static volatile uint_fast8_t                    irmp_ir_detected = FALSE;\r
+static volatile uint_fast8_t                    irmp_protocol;\r
+static volatile uint_fast16_t                   irmp_address;\r
+static volatile uint_fast16_t                   irmp_command;\r
+static volatile uint_fast16_t                   irmp_id;                // only used for SAMSUNG protocol\r
+static volatile uint_fast8_t                    irmp_flags;\r
+// static volatile uint_fast8_t                 irmp_busy_flag;\r
+\r
+#if defined(__MBED__)\r
+// DigitalIn inputPin(IRMP_PIN, PullUp);                                // this requires mbed.h and source to be compiled as cpp\r
+gpio_t                                          gpioIRin;               // use low level c function instead\r
+#endif\r
+\r
 \r
 #ifdef ANALYZE\r
-#define input(x)                            (x)\r
-static uint_fast8_t                              IRMP_PIN;\r
-static uint_fast8_t                              radio;\r
+#define input(x)                                (x)\r
+static uint_fast8_t                             IRMP_PIN;\r
+static uint_fast8_t                             radio;\r
 #endif\r
 \r
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
@@ -2078,6 +2204,22 @@ irmp_init (void)
 #elif defined (TEENSY_ARM_CORTEX_M4)                                    // TEENSY\r
     pinMode(IRMP_PIN, INPUT);\r
 \r
+#elif defined(__xtensa__)                                               // ESP8266\r
+    pinMode(IRMP_BIT_NUMBER, INPUT);\r
+                                                                        // select pin function\r
+#  if (IRMP_BIT_NUMBER == 12)\r
+    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);\r
+//  doesn't work for me:\r
+//  # elif (IRMP_BIT_NUMBER == 13)\r
+//  PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U , FUNC_GPIO13);\r
+#  else\r
+#   warning Please add PIN_FUNC_SELECT when necessary.\r
+#  endif\r
+    GPIO_DIS_OUTPUT(IRMP_BIT_NUMBER);\r
+\r
+#elif defined(__MBED__)\r
+    gpio_init_in_ex(&gpioIRin, IRMP_PIN, IRMP_PINMODE);                 // initialize input for IR diode\r
+\r
 #else                                                                   // AVR\r
     IRMP_PORT &= ~(1<<IRMP_BIT);                                        // deactivate pullup\r
     IRMP_DDR &= ~(1<<IRMP_BIT);                                         // set pin to input\r
@@ -2141,6 +2283,18 @@ irmp_get_data (IRMP_DATA * irmp_data_p)
                 }\r
                 break;\r
 #endif\r
+\r
+\r
+#if IRMP_SUPPORT_NEC_PROTOCOL == 1\r
+            case IRMP_VINCENT_PROTOCOL:\r
+                if ((irmp_command >> 8) == (irmp_command & 0x00FF))\r
+                {\r
+                    irmp_command &= 0xff;\r
+                    rtc = TRUE;\r
+                }\r
+                break;\r
+#endif\r
+\r
 #if IRMP_SUPPORT_BOSE_PROTOCOL == 1\r
             case IRMP_BOSE_PROTOCOL:\r
                 if ((irmp_command >> 8) == (~irmp_command & 0x00FF))\r
@@ -2317,6 +2471,11 @@ static uint_fast8_t genre2;                                                 // s
 static uint_fast8_t  parity;                                                // number of '1' of the first 14 bits, check if even.\r
 #endif\r
 \r
+#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+static uint_fast8_t  check;                                                 // number of '1' of the first 14 bits, check if even.\r
+static uint_fast8_t  mitsu_parity;                                          // number of '1' of the first 14 bits, check if even.\r
+#endif\r
+\r
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
  *  store bit\r
  *  @details  store bit in temp address or temp command\r
@@ -2490,11 +2649,11 @@ irmp_store_bit (uint_fast8_t value)
     {\r
         if (irmp_bit >= 20 && irmp_bit < 24)\r
         {\r
-            irmp_tmp_command |= (((uint_fast16_t) (value)) << (irmp_bit - 8));       // store 4 system bits (genre 1) in upper nibble with LSB first\r
+            irmp_tmp_command |= (((uint_fast16_t) (value)) << (irmp_bit - 8));      // store 4 system bits (genre 1) in upper nibble with LSB first\r
         }\r
         else if (irmp_bit >= 24 && irmp_bit < 28)\r
         {\r
-            genre2 |= (((uint_fast8_t) (value)) << (irmp_bit - 20));                 // store 4 system bits (genre 2) in upper nibble with LSB first\r
+            genre2 |= (((uint_fast8_t) (value)) << (irmp_bit - 20));                // store 4 system bits (genre 2) in upper nibble with LSB first\r
         }\r
 \r
         if (irmp_bit < KASEIKYO_COMPLETE_DATA_LEN)\r
@@ -2511,6 +2670,47 @@ irmp_store_bit (uint_fast8_t value)
     }\r
     else\r
 #endif\r
+\r
+#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+    if (irmp_param.protocol == IRMP_MITSU_HEAVY_PROTOCOL)                           // squeeze 64 bits into 16 bits:\r
+    {\r
+        if (irmp_bit == 72 )\r
+        {                                                                           // irmp_tmp_address, irmp_tmp_command received: check parity & compress\r
+            mitsu_parity = PARITY_CHECK_OK;\r
+\r
+            check = irmp_tmp_address >> 8;                                          // inverted upper byte == lower byte?\r
+            check = ~ check;\r
+\r
+            if (check == (irmp_tmp_address & 0xFF))\r
+            {                                                                       // ok:\r
+                irmp_tmp_address <<= 8;                                             // throw away upper byte\r
+            }\r
+            else\r
+            {\r
+                mitsu_parity = PARITY_CHECK_FAILED;\r
+            }\r
+\r
+            check = irmp_tmp_command >> 8;                                          // inverted upper byte == lower byte?\r
+            check = ~ check;\r
+            if (check == (irmp_tmp_command & 0xFF))\r
+            {                                                                       // ok:  pack together\r
+                irmp_tmp_address |= irmp_tmp_command & 0xFF;                        // byte 1, byte2 in irmp_tmp_address, irmp_tmp_command can be used for byte 3\r
+            }\r
+            else\r
+            {\r
+                mitsu_parity = PARITY_CHECK_FAILED;\r
+            }\r
+            irmp_tmp_command = 0;\r
+        }\r
+\r
+        if (irmp_bit >= 72 )\r
+        {                                                                           // receive 3. word in irmp_tmp_command\r
+            irmp_tmp_command <<= 1;\r
+            irmp_tmp_command |= value;\r
+        }\r
+    }\r
+    else\r
+#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL\r
     {\r
         ;\r
     }\r
@@ -2588,6 +2788,9 @@ irmp_ISR (void)
 \r
 #if defined(__SDCC_stm8)\r
     irmp_input = input(IRMP_GPIO_STRUCT->IDR)\r
+#elif defined(__MBED__)\r
+    //irmp_input = inputPin;\r
+    irmp_input = gpio_read (&gpioIRin);\r
 #else\r
     irmp_input = input(IRMP_PIN);\r
 #endif\r
@@ -2902,6 +3105,20 @@ irmp_ISR (void)
                     else\r
 #endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\r
 \r
+#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\r
+                    if (irmp_pulse_time >= SAMSUNGAH_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNGAH_START_BIT_PULSE_LEN_MAX &&\r
+                        irmp_pause_time >= SAMSUNGAH_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNGAH_START_BIT_PAUSE_LEN_MAX)\r
+                    {                                                           // it's SAMSUNGAH\r
+#ifdef ANALYZE\r
+                        ANALYZE_PRINTF ("protocol = SAMSUNGAH, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",\r
+                                        SAMSUNGAH_START_BIT_PULSE_LEN_MIN, SAMSUNGAH_START_BIT_PULSE_LEN_MAX,\r
+                                        SAMSUNGAH_START_BIT_PAUSE_LEN_MIN, SAMSUNGAH_START_BIT_PAUSE_LEN_MAX);\r
+#endif // ANALYZE\r
+                        irmp_param_p = (IRMP_PARAMETER *) &samsungah_param;\r
+                    }\r
+                    else\r
+#endif // IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\r
+\r
 #if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1\r
                     if (irmp_pulse_time >= MATSUSHITA_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MATSUSHITA_START_BIT_PULSE_LEN_MAX &&\r
                         irmp_pause_time >= MATSUSHITA_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MATSUSHITA_START_BIT_PAUSE_LEN_MAX)\r
@@ -2944,6 +3161,34 @@ irmp_ISR (void)
                     else\r
 #endif // IRMP_SUPPORT_PANASONIC_PROTOCOL == 1\r
 \r
+#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+                    if (irmp_pulse_time >= MITSU_HEAVY_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MITSU_HEAVY_START_BIT_PULSE_LEN_MAX &&\r
+                        irmp_pause_time >= MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX)\r
+                    {                                                           // it's MITSU_HEAVY\r
+#ifdef ANALYZE\r
+                        ANALYZE_PRINTF ("protocol = MITSU_HEAVY, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",\r
+                                        MITSU_HEAVY_START_BIT_PULSE_LEN_MIN, MITSU_HEAVY_START_BIT_PULSE_LEN_MAX,\r
+                                        MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN, MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX);\r
+#endif // ANALYZE\r
+                        irmp_param_p = (IRMP_PARAMETER *) &mitsu_heavy_param;\r
+                    }\r
+                    else\r
+#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+\r
+#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1\r
+                    if (irmp_pulse_time >= VINCENT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= VINCENT_START_BIT_PULSE_LEN_MAX &&\r
+                        irmp_pause_time >= VINCENT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= VINCENT_START_BIT_PAUSE_LEN_MAX)\r
+                    {                                                           // it's VINCENT\r
+#ifdef ANALYZE\r
+                        ANALYZE_PRINTF ("protocol = VINCENT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",\r
+                                        VINCENT_START_BIT_PULSE_LEN_MIN, VINCENT_START_BIT_PULSE_LEN_MAX,\r
+                                        VINCENT_START_BIT_PAUSE_LEN_MIN, VINCENT_START_BIT_PAUSE_LEN_MAX);\r
+#endif // ANALYZE\r
+                        irmp_param_p = (IRMP_PARAMETER *) &vincent_param;\r
+                    }\r
+                    else\r
+#endif // IRMP_SUPPORT_VINCENT_PROTOCOL == 1\r
+\r
 #if IRMP_SUPPORT_RADIO1_PROTOCOL == 1\r
                     if (irmp_pulse_time >= RADIO1_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RADIO1_START_BIT_PULSE_LEN_MAX &&\r
                         irmp_pause_time >= RADIO1_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RADIO1_START_BIT_PAUSE_LEN_MAX)\r
@@ -3758,6 +4003,32 @@ irmp_ISR (void)
                             {\r
                                 irmp_bit++;\r
                             }\r
+#if IRMP_SUPPORT_NEC_PROTOCOL == 1\r
+                            else if ((irmp_param.protocol == IRMP_NEC_PROTOCOL || irmp_param.protocol == IRMP_NEC42_PROTOCOL) && irmp_bit == 0)\r
+                            {                                                               // it was a non-standard repetition frame\r
+#ifdef ANALYZE                                                                              // with 4500µs pause instead of 2250µs\r
+                                ANALYZE_PRINTF ("Detected non-standard repetition frame, switching to NEC repetition\n");\r
+#endif // ANALYZE\r
+                                if (key_repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX)\r
+                                {\r
+                                    irmp_param.stop_bit     = TRUE;                         // set flag\r
+                                    irmp_param.protocol     = IRMP_NEC_PROTOCOL;            // switch protocol\r
+                                    irmp_param.complete_len = irmp_bit;                     // patch length: 16 or 17\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
+                                    key_repetition_len = 0;\r
+                                }\r
+                                else\r
+                                {\r
+#ifdef ANALYZE\r
+                                    ANALYZE_PRINTF ("ignoring NEC repetition frame: timeout occured, key_repetition_len = %d > %d\n",\r
+                                                    key_repetition_len, NEC_FRAME_REPEAT_PAUSE_LEN_MAX);\r
+#endif // ANALYZE\r
+                                    irmp_ir_detected = FALSE;\r
+                                }\r
+                            }\r
+#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1\r
 #if IRMP_SUPPORT_JVC_PROTOCOL == 1\r
                             else if (irmp_param.protocol == IRMP_NEC_PROTOCOL && (irmp_bit == 16 || irmp_bit == 17))      // it was a JVC stop bit\r
                             {\r
@@ -4750,6 +5021,25 @@ irmp_ISR (void)
                         }\r
 #endif // IRMP_SUPPORT_ORTEK_PROTOCOL == 1\r
 \r
+#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+                        if (irmp_param.protocol == IRMP_MITSU_HEAVY_PROTOCOL)\r
+                        {\r
+                            check = irmp_tmp_command >> 8;                    // inverted upper byte == lower byte?\r
+                            check = ~ check;\r
+                            if (check == (irmp_tmp_command & 0xFF)) {         //ok:\r
+                              irmp_tmp_command &= 0xFF;\r
+                            }\r
+                            else  mitsu_parity = PARITY_CHECK_FAILED;\r
+                            if (mitsu_parity == PARITY_CHECK_FAILED)\r
+                            {\r
+#ifdef ANALYZE\r
+                                ANALYZE_PRINTF ("error 7: parity check failed\n");\r
+#endif // ANALYZE\r
+                                irmp_ir_detected = FALSE;\r
+                            }\r
+                        }\r
+#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL\r
+\r
 #if IRMP_SUPPORT_RC6_PROTOCOL == 1\r
                         if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG)     // RC6 mode = 6?\r
                         {\r
@@ -4989,16 +5279,16 @@ get_fdc_key (uint_fast16_t cmd)
 {\r
     static uint8_t key_table[128] =\r
     {\r
-     // 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F\r
-        0,  '^', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'ß', '´',  0,  '\b',\r
-       '\t','q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', '+',  0,   0,  'a',\r
-       's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', '#',  '\r', 0,  '<', 'y', 'x',\r
-       'c', 'v', 'b', 'n', 'm', ',', '.', '-',  0,   0,   0,   0,   0,  ' ',  0,   0,\r
-\r
-        0,  '°', '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', '?', '`',  0,  '\b',\r
-       '\t','Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 'Ü', '*',  0,   0,  'A',\r
-       'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Ö', 'Ä', '\'','\r', 0,  '>', 'Y', 'X',\r
-       'C', 'V', 'B', 'N', 'M', ';', ':', '_',  0,   0,   0,   0,   0,  ' ',  0,   0\r
+     // 0     1    2    3    4    5    6    7    8     9     A     B     C     D    E    F\r
+         0,   '^', '1', '2', '3', '4', '5', '6', '7',  '8',  '9',  '0',  0xDF, '´', 0,   '\b',\r
+        '\t', 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i',  'o',  'p',  0xFC, '+',   0,   0,   'a',\r
+        's',  'd', 'f', 'g', 'h', 'j', 'k', 'l', 0xF6, 0xE4, '#',  '\r', 0,    '<', 'y', 'x',\r
+        'c',  'v', 'b', 'n', 'm', ',', '.', '-', 0,    0,    0,    0,    0,    ' ', 0,   0,\r
+\r
+         0,   '°', '!', '"', '§', '$', '%', '&', '/',  '(',  ')',  '=',  '?',  '`', 0,   '\b',\r
+        '\t', 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I',  'O',  'P',  0xDC, '*',  0,   0,   'A',\r
+        'S',  'D', 'F', 'G', 'H', 'J', 'K', 'L', 0xD6, 0xC4, '\'', '\r', 0,    '>', 'Y', 'X',\r
+        'C',  'V', 'B', 'N', 'M', ';', ':', '_', 0,    0,    0,    0,    0,    ' ', 0,   0\r
     };\r
     static uint_fast8_t state;\r
 \r
@@ -5045,7 +5335,7 @@ get_fdc_key (uint_fast16_t cmd)
                     {\r
                         switch (cmd)\r
                         {\r
-                            case 0x0003: key = '²';     break;\r
+                            case 0x0003: key = 0xB2;    break; // upper 2\r
                             case 0x0008: key = '{';     break;\r
                             case 0x0009: key = '[';     break;\r
                             case 0x000A: key = ']';     break;\r