]> cloudbase.mooo.com Git - irmp.git/blobdiff - irmp.c
libopencm3: Add IRMP_LOGGING
[irmp.git] / irmp.c
diff --git a/irmp.c b/irmp.c
index 3895bba092838d46a94c3b9235991d1af51b879a..2b9d96580dc9a03ebdef3ce6fca1fb8c971bff00 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.184 2016/01/12 11:53:34 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
@@ -701,6 +740,14 @@ irmp_protocol_names[IRMP_N_PROTOCOLS + 1] PROGMEM =
 #  include "stm32f4xx_usart.h"\r
 #elif defined(ARM_STM32F10X)\r
 #  define  STM32_UART_COM     USART3                                    // UART3 on PB10\r
+#elif defined(LIBOPENCM3)                                               //\r
+#  include <libopencm3/stm32/usart.h>\r
+#  define STM32_UART_COM        USART2                                  // UART2 on PA2\r
+#  define STM32_UART_GPIO_PORT  GPIOA\r
+#  define STM32_UART_GPIO_PIN   GPIO2\r
+#  define STM32_UART_COM_RCC    RCC_USART2\r
+#  define STM32_UART_GPIO_RCC   RCC_GPIOA\r
+#  define STM32_UART_BAUD       115200                                  // 115200 Baud\r
 #elif defined(ARDUINO)                                                  // Arduino Serial implementation\r
 #  if defined(USB_SERIAL)\r
 #    include "usb_serial.h"\r
@@ -837,7 +884,24 @@ irmp_uart_init (void)
 \r
     // UART enable\r
     USART_Cmd(STM32_UART_COM, ENABLE);\r
-        \r
+\r
+#elif defined(LIBOPENCM3)\r
+    rcc_periph_clock_enable(STM32_UART_COM_RCC);\r
+    /* Setup GPIO pin for USART TX */\r
+    rcc_periph_clock_enable(STM32_UART_GPIO_RCC);\r
+    gpio_set_mode(STM32_UART_GPIO_PORT, GPIO_MODE_OUTPUT_2_MHZ,\r
+                GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, STM32_UART_GPIO_PIN);\r
+\r
+    /* Setup UART parameters. */\r
+    usart_set_baudrate(STM32_UART_COM, STM32_UART_BAUD);\r
+    usart_set_databits(STM32_UART_COM, 8);\r
+    usart_set_stopbits(STM32_UART_COM, USART_STOPBITS_1);\r
+    usart_set_parity(STM32_UART_COM, USART_PARITY_NONE);\r
+    usart_set_flow_control(STM32_UART_COM, USART_FLOWCONTROL_NONE);\r
+    usart_set_mode(STM32_UART_COM, USART_MODE_TX_RX);\r
+    /* Finally enable the USART. */\r
+    usart_enable(STM32_UART_COM);\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
@@ -900,31 +964,43 @@ irmp_uart_putc (unsigned char ch)
         USART_SendData(STM32_UART_COM, '\r');\r
     }\r
 \r
+#elif defined(LIBOPENCM3)\r
+    if (ch == '\n') {\r
+        usart_send_blocking(STM32_UART_COM, '\r');\r
+    }\r
+    usart_send_blocking(STM32_UART_COM, ch);\r
+\r
 #elif defined(ARDUINO)\r
     // we use the Arduino Serial Imlementation\r
     usb_serial_putchar(ch);\r
 \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 +1274,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 +1399,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
@@ -2069,6 +2220,13 @@ irmp_init (void)
 #  endif\r
     GPIO_Init(IRMP_PORT, &GPIO_InitStructure);\r
 \r
+#elif defined (LIBOPENCM3)                                             // STM32 with libopencm3\r
+\r
+    /* GPIOx clock enable */\r
+    rcc_periph_clock_enable(IRMP_PORT_RCC);\r
+    /* GPIO Configuration */\r
+    gpio_set_mode(IRMP_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, IRMP_BIT);\r
+\r
 #elif defined(STELLARIS_ARM_CORTEX_M4)\r
     // Enable the GPIO port\r
     ROM_SysCtlPeripheralEnable(IRMP_PORT_PERIPH);\r
@@ -2085,6 +2243,7 @@ irmp_init (void)
     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
@@ -2162,6 +2321,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
@@ -2338,6 +2509,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
@@ -2511,11 +2687,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
@@ -2532,6 +2708,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
@@ -2926,6 +3143,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
@@ -2968,6 +3199,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
@@ -3782,6 +4041,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
@@ -4774,6 +5059,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
@@ -5013,16 +5317,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',    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
+     // 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
@@ -5069,7 +5373,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