]> cloudbase.mooo.com Git - irmp.git/blobdiff - irsnd.c
Version 3.0.7 - added SAMSUNGAH protocol, improved some code for ESP8266
[irmp.git] / irsnd.c
diff --git a/irsnd.c b/irsnd.c
index a45fc426893528ff8d3374585a8f3fd08783d632..1656bde8c305a07bff1f8b325c5a773b4d7b4c6e 100644 (file)
--- a/irsnd.c
+++ b/irsnd.c
@@ -1,19 +1,20 @@
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
  * @file irsnd.c\r
  *\r
- * Copyright (c) 2010-2015 Frank Meyer - frank(at)fli4l.de\r
+ * Copyright (c) 2010-2016 Frank Meyer - frank(at)fli4l.de\r
  *\r
  * Supported AVR mikrocontrollers:\r
  *\r
  * ATtiny87,  ATtiny167\r
  * ATtiny45,  ATtiny85\r
  * ATtiny44   ATtiny84\r
+ * ATtiny2313 ATtiny4313\r
  * ATmega8,   ATmega16,  ATmega32\r
  * ATmega162\r
  * ATmega164, ATmega324, ATmega644,  ATmega644P, ATmega1284, ATmega1284P\r
  * ATmega88,  ATmega88P, ATmega168,  ATmega168P, ATmega328P\r
  *\r
- * $Id: irsnd.c,v 1.86 2015/05/07 06:51:10 fm Exp $\r
+ * $Id: irsnd.c,v 1.103 2017/02/17 09:13:06 fm Exp $\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
  * it under the terms of the GNU General Public License as published by\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h\r
 #  endif // IRSND_OCx\r
 \r
+#elif defined (__AVR_ATtiny2313__) || defined (__AVR_ATtiny4313__)  // ATtiny2313/4313 uses OC0A = PB2 or OC0B = PD5\r
+#  if IRSND_OCx == IRSND_OC0A                                       // OC0A\r
+#    define IRSND_PORT_LETTER                       B\r
+#    define IRSND_BIT_NUMBER                        2\r
+#  elif IRSND_OCx == IRSND_OC0B                                     // OC0B\r
+#    define IRSND_PORT_LETTER                       D\r
+#    define IRSND_BIT_NUMBER                        5\r
+#  else\r
+#    error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h\r
+#  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATtiny87__) || defined (__AVR_ATtiny167__)     // ATtiny87/167 uses OC0A = PA2\r
 #  if IRSND_OCx == IRSND_OC0A                                       // OC0A\r
 #    define IRSND_PORT_LETTER                       A\r
 #  endif // IRSND_OCx\r
 \r
 #elif defined (__AVR_ATmega8__)                                     // ATmega8 uses only OC2 = PB3\r
-#  if IRSND_OCx == IRSND_OC2                                        // OC0A\r
+#  if IRSND_OCx == IRSND_OC2                                        // OC2\r
 #    define IRSND_PORT_LETTER                       B\r
 #    define IRSND_BIT_NUMBER                        3\r
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC2 in irsndconfig.h\r
 #  endif // IRSND_OCx\r
-#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__)      // ATmega16|32 uses OC2 = PD7\r
+#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__)      // ATmega16|32 uses OC0 = PB3 or OC2 = PD7\r
 #  if IRSND_OCx == IRSND_OC2                                        // OC2\r
 #    define IRSND_PORT_LETTER                       D\r
 #    define IRSND_BIT_NUMBER                        7\r
+#  elif IRSND_OCx == IRSND_OC0                                      // OC0\r
+#    define IRSND_PORT_LETTER                       B\r
+#    define IRSND_BIT_NUMBER                        3\r
 #  else\r
-#    error Wrong value for IRSND_OCx, choose IRSND_OC2 in irsndconfig.h\r
+#    error Wrong value for IRSND_OCx, choose IRSND_OC2 or IRSND_OC0 in irsndconfig.h\r
 #  endif // IRSND_OCx\r
 \r
 #elif defined (__AVR_ATmega162__)                                   // ATmega162 uses OC2 = PB1 or OC0 = PB0\r
 #  endif // IRSND_OCx\r
 \r
 #elif defined (__AVR_ATmega8515__)                                  // ATmega8515 uses OC0 = PB0 or OC1A = PD5 or OC1B = PE2\r
-#  if IRSND_OCx == IRSND_OC0   \r
+#  if IRSND_OCx == IRSND_OC0\r
 #    define IRSND_PORT_LETTER                       B\r
 #    define IRSND_BIT_NUMBER                        0\r
-#  elif IRSND_OCx == IRSND_OC1A \r
+#  elif IRSND_OCx == IRSND_OC1A\r
 #    define IRSND_PORT_LETTER                       D\r
 #    define IRSND_BIT_NUMBER                        5\r
-#  elif IRSND_OCx == IRSND_OC1B \r
+#  elif IRSND_OCx == IRSND_OC1B\r
 #    define IRSND_PORT_LETTER                       E\r
 #    define IRSND_BIT_NUMBER                        2\r
 #  endif // IRSND_OCx\r
 \r
-#elif defined (__AVR_ATxmega128A1U__)                               // ATxmega128A1U \r
-#  if IRSND_OCx == IRSND_XMEGA_OC0A   \r
+#elif defined (__AVR_XMEGA__)                                       // ATxmega\r
+#  if IRSND_OCx == IRSND_XMEGA_OC0A\r
 #    define IRSND_BIT_NUMBER                        0\r
 #  elif IRSND_OCx == IRSND_XMEGA_OC0B\r
 #    define IRSND_BIT_NUMBER                        1\r
 #  elif IRSND_OCx == IRSND_XMEGA_OC1B\r
 #    define IRSND_BIT_NUMBER                        5\r
 #  else\r
-#    error Wrong value for IRSND_OCx, choose IRSND_OC0, IRSND_OC1A, or IRSND_OC1B in irsndconfig.h\r
+#    error Wrong value for IRSND_OCx, choose IRSND_XMEGA_OC0A, IRSND_XMEGA_OC0B, IRSND_XMEGA_OC0C, IRSND_XMEGA_OC0D, IRSND_XMEGA_OC1A, or IRSND_XMEGA_OC1B in irsndconfig.h\r
 #  endif // IRSND_OCx\r
 \r
-#elif defined (PIC_C18)    //Microchip C18 compiler\r
+#elif defined (PIC_C18)                                                 // Microchip C18 compiler\r
+    //Nothing here to do here -> See irsndconfig.h\r
+#elif defined (ARM_STM32)                                               // STM32\r
     //Nothing here to do here -> See irsndconfig.h\r
-#elif defined (ARM_STM32)  //STM32\r
+#elif defined (__xtensa__)                                              // ESP8266\r
     //Nothing here to do here -> See irsndconfig.h\r
+\r
+/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
+ * Macro digitalPinHasPWM bothers PIC_C18 compiler, but why?\r
+ *\r
+ * #elif defined (TEENSY_ARM_CORTEX_M4)                                // Teensy3\r
+ * #  if !digitalPinHasPWM(IRSND_PIN)\r
+ * #    error need pin with PWM output.\r
+ * #  endif\r
+ *---------------------------------------------------------------------------------------------------------------------------------------------------\r
+ */\r
 #else\r
 #  if !defined (unix) && !defined (WIN32)\r
 #    error mikrocontroller not defined, please fill in definitions here.\r
 #define KASEIKYO_AUTO_REPETITION_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * KASEIKYO_AUTO_REPETITION_PAUSE_TIME + 0.5)            // use uint16_t!\r
 #define KASEIKYO_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * KASEIKYO_FRAME_REPEAT_PAUSE_TIME + 0.5)               // use uint16_t!\r
 \r
+#define PANASONIC_START_BIT_PULSE_LEN           (uint8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME + 0.5)\r
+#define PANASONIC_START_BIT_PAUSE_LEN           (uint8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PAUSE_TIME + 0.5)\r
+#define PANASONIC_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * PANASONIC_PULSE_TIME + 0.5)\r
+#define PANASONIC_1_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * PANASONIC_1_PAUSE_TIME + 0.5)\r
+#define PANASONIC_0_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * PANASONIC_0_PAUSE_TIME + 0.5)\r
+#define PANASONIC_AUTO_REPETITION_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * PANASONIC_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!\r
+#define PANASONIC_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * PANASONIC_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\r
+\r
+#define MITSU_HEAVY_START_BIT_PULSE_LEN         (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME + 0.5)\r
+#define MITSU_HEAVY_START_BIT_PAUSE_LEN         (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME + 0.5)\r
+#define MITSU_HEAVY_PULSE_LEN                   (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME + 0.5)\r
+#define MITSU_HEAVY_1_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME + 0.5)\r
+#define MITSU_HEAVY_0_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME + 0.5)\r
+#define MITSU_HEAVY_FRAME_REPEAT_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * MITSU_HEAVY_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!\r
+\r
 #define RECS80_START_BIT_PULSE_LEN              (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)\r
 #define RECS80_START_BIT_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)\r
 #define RECS80_PULSE_LEN                        (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)\r
 \r
 #define RC6_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)\r
 #define RC6_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)\r
-#define RC6_TOGGLE_BIT_LEN                      (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME + 0.5)\r
 #define RC6_BIT_LEN                             (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)\r
+#define RC6_BIT_2_LEN                           (uint8_t)(F_INTERRUPTS * RC6_BIT_2_TIME + 0.5)\r
+#define RC6_BIT_3_LEN                           (uint8_t)(F_INTERRUPTS * RC6_BIT_3_TIME + 0.5)\r
 #define RC6_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * RC6_FRAME_REPEAT_PAUSE_TIME + 0.5)                    // use uint16_t!\r
 \r
 #define DENON_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)\r
 #define TELEFUNKEN_AUTO_REPETITION_PAUSE_LEN    (uint16_t)(F_INTERRUPTS * TELEFUNKEN_AUTO_REPETITION_PAUSE_TIME + 0.5)          // use uint16_t!\r
 #define TELEFUNKEN_FRAME_REPEAT_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * TELEFUNKEN_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!\r
 \r
+#define BOSE_START_BIT_PULSE_LEN                (uint8_t)(F_INTERRUPTS * BOSE_START_BIT_PULSE_TIME + 0.5)\r
+#define BOSE_START_BIT_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * BOSE_START_BIT_PAUSE_TIME + 0.5)\r
+#define BOSE_PULSE_LEN                          (uint8_t)(F_INTERRUPTS * BOSE_PULSE_TIME + 0.5)\r
+#define BOSE_1_PAUSE_LEN                        (uint8_t)(F_INTERRUPTS * BOSE_1_PAUSE_TIME + 0.5)\r
+#define BOSE_0_PAUSE_LEN                        (uint8_t)(F_INTERRUPTS * BOSE_0_PAUSE_TIME + 0.5)\r
+#define BOSE_AUTO_REPETITION_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * BOSE_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\r
+#define BOSE_FRAME_REPEAT_PAUSE_LEN             (uint16_t)(F_INTERRUPTS * BOSE_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\r
+\r
 #define NUBERT_START_BIT_PULSE_LEN              (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)\r
 #define NUBERT_START_BIT_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)\r
 #define NUBERT_1_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)\r
 #define NUBERT_AUTO_REPETITION_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * NUBERT_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\r
 #define NUBERT_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\r
 \r
+#define FAN_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * FAN_START_BIT_PULSE_TIME + 0.5)\r
+#define FAN_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * FAN_START_BIT_PAUSE_TIME + 0.5)\r
+#define FAN_1_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_1_PULSE_TIME + 0.5)\r
+#define FAN_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_1_PAUSE_TIME + 0.5)\r
+#define FAN_0_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_0_PULSE_TIME + 0.5)\r
+#define FAN_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_0_PAUSE_TIME + 0.5)\r
+#define FAN_AUTO_REPETITION_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * FAN_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\r
+#define FAN_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * FAN_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\r
+\r
 #define SPEAKER_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PULSE_TIME + 0.5)\r
 #define SPEAKER_START_BIT_PAUSE_LEN             (uint8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PAUSE_TIME + 0.5)\r
 #define SPEAKER_1_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * SPEAKER_1_PULSE_TIME + 0.5)\r
 #  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\r
 #  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\r
 #  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\r
+#elif defined (TEENSY_ARM_CORTEX_M4)            // TEENSY\r
+#  define IRSND_FREQ_TYPE                       float\r
+#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\r
+#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\r
+#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\r
+#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\r
+#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\r
+#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\r
+#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\r
+#elif defined (__xtensa__)                      // ESP8266\r
+#  define IRSND_FREQ_TYPE                       float\r
+#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\r
+#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\r
+#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\r
+#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\r
+#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\r
+#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\r
+#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\r
 #else                                           // AVR\r
 #  if F_CPU >= 16000000L\r
 #    define AVR_PRESCALER                       8\r
 #define PENTAX_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME + 0.5)\r
 #define PENTAX_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * PENTAX_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\r
 \r
+#define ACP24_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * ACP24_START_BIT_PULSE_TIME + 0.5)\r
+#define ACP24_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * ACP24_START_BIT_PAUSE_TIME + 0.5)\r
+#define ACP24_REPEAT_START_BIT_PAUSE_LEN        (uint8_t)(F_INTERRUPTS * ACP24_REPEAT_START_BIT_PAUSE_TIME + 0.5)\r
+#define ACP24_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * ACP24_PULSE_TIME + 0.5)\r
+#define ACP24_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * ACP24_1_PAUSE_TIME + 0.5)\r
+#define ACP24_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * ACP24_0_PAUSE_TIME + 0.5)\r
+#define ACP24_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * ACP24_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\r
+\r
 static volatile uint8_t                         irsnd_busy = 0;\r
 static volatile uint8_t                         irsnd_protocol = 0;\r
-static volatile uint8_t                         irsnd_buffer[6] = {0};\r
+static volatile uint8_t                         irsnd_buffer[11] = {0};\r
 static volatile uint8_t                         irsnd_repeat = 0;\r
 static volatile uint8_t                         irsnd_is_on = FALSE;\r
 \r
@@ -458,19 +544,25 @@ irsnd_on (void)
         TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable);      // enable OC-output (is being disabled in TIM_SelectOCxM())\r
         TIM_Cmd(IRSND_TIMER, ENABLE);                   // enable counter\r
 \r
-#  elif defined (__AVR_XMEGA__) \r
-#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                                                                                 // use OC0A\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCAEN_bp);                                         // Compare A \r
-#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                                                                                               // use OC0B\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCBEN_bp);                                         // Compare B \r
-#    elif IRSND_OCx == IRSND_XMEGA_OC0C                                                 // use OC0C\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCCEN_bp);                                         // Compare C\r
-#    elif IRSND_OCx == IRSND_XMEGA_OC0D                                                 // use OC0D\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCDEN_bp);                                         // Compare D\r
-#    elif IRSND_OCx == IRSND_XMEGA_OC0C                                                 // use OC1C\r
-                XMEGA_Timer.CTRLB |= (1<<TC1_CCAEN_bp);                                                                                 // Compare A\r
-#    elif IRSND_OCx == IRSND_XMEGA_OC0D                                                 // use OC1D\r
-                XMEGA_Timer.CTRLB |= (1<<TC1_CCBEN_bp);                                                                                 // Compare B\r
+#  elif defined (TEENSY_ARM_CORTEX_M4)                  // TEENSY\r
+        analogWrite(IRSND_PIN, 33 * 255 / 100);         // pwm 33%\r
+\r
+#  elif defined (__xtensa__)                            // ESP8266 (Arduino)\r
+        analogWrite(IRSND_PIN, 33 * 1023 / 100);        // pwm 33%\r
+\r
+#  elif defined (__AVR_XMEGA__)\r
+#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                 // use OC0A\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCAEN_bp);                 // Compare A\r
+#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                               // use OC0B\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCBEN_bp);                 // Compare B\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC0C                                 // use OC0C\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCCEN_bp);                 // Compare C\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC0D                                 // use OC0D\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCDEN_bp);                 // Compare D\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC1A                                 // use OC1A\r
+                XMEGA_Timer.CTRLB |= (1<<TC1_CCAEN_bp);                 // Compare A\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC1B                                 // use OC1B\r
+                XMEGA_Timer.CTRLB |= (1<<TC1_CCBEN_bp);                 // Compare B\r
 #    else\r
 #       error wrong value of IRSND_OCx\r
 #    endif // IRSND_OCx\r
@@ -516,30 +608,36 @@ irsnd_off (void)
     if (irsnd_is_on)\r
     {\r
 #ifndef ANALYZE\r
-    \r
-#  if defined(PIC_C18)                                  // PIC C18\r
+\r
+#  if defined(PIC_C18)                                                                  // PIC C18\r
         PWMoff();\r
         // IRSND_PIN = 1; //input mode -> disbale PWM output pin (0=PWM on, 1=PWM off)\r
 \r
-#  elif defined (ARM_STM32)                             // STM32\r
-        TIM_Cmd(IRSND_TIMER, DISABLE);                  // disable counter\r
-        TIM_SelectOCxM(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_ForcedAction_InActive);   // force output inactive\r
-        TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable);      // enable OC-output (is being disabled in TIM_SelectOCxM())\r
-        TIM_SetCounter(IRSND_TIMER, 0);                 // reset counter value\r
+#  elif defined (ARM_STM32)                                                             // STM32\r
+        TIM_Cmd(IRSND_TIMER, DISABLE);                                                  // disable counter\r
+        TIM_SelectOCxM(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_ForcedAction_InActive);    // force output inactive\r
+        TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable);                   // enable OC-output (is being disabled in TIM_SelectOCxM())\r
+        TIM_SetCounter(IRSND_TIMER, 0);                                                 // reset counter value\r
+\r
+#  elif defined (TEENSY_ARM_CORTEX_M4)                                                  // TEENSY\r
+        analogWrite(IRSND_PIN, 0);                                                      // pwm off, LOW level\r
+\r
+#  elif defined (__xtensa__)                                                            // ESP8266\r
+        analogWrite(IRSND_PIN, 0);                                                      // pwm off, LOW level\r
 \r
 #  elif defined (__AVR_XMEGA__)\r
-#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                                                                                 // use OC0A \r
+#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                                 // use OC0A\r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCAEN_bp);                                        // Compare A disconnected\r
-#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                                                                                               // use OC0B \r
+#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                                               // use OC0B\r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCBEN_bp);                                        // Compare B disconnected\r
 #    elif IRSND_OCx == IRSND_XMEGA_OC0C                                                 // use OC0C\r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCCEN_bp);                                        // Compare C disconnected\r
 #    elif IRSND_OCx == IRSND_XMEGA_OC0D                                                 // use OC0D\r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCDEN_bp);                                        // Compare D disconnected\r
 #    elif IRSND_OCx == IRSND_XMEGA_OC1A                                                 // use OC1A\r
-                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCAEN_bp);                                        // Compare A disconnected\r
+                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCAEN_bp);                                // Compare A disconnected\r
 #    elif IRSND_OCx == IRSND_XMEGA_OC1B                                                 // use OC1B\r
-                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCBEN_bp);                                        // Compare B disconnected\r
+                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCBEN_bp);                                // Compare B disconnected\r
 #    else\r
 #       error wrong value of IRSND_OCx\r
 #    endif // IRSND_OCx\r
@@ -592,7 +690,7 @@ irsnd_set_freq (IRSND_FREQ_TYPE freq)
 #ifndef ANALYZE\r
 #  if defined(PIC_C18)                                                                      // PIC C18 or XC8\r
 #    if defined(__12F1840)                                                                  // XC8\r
-        TRISA2=0; \r
+        TRISA2=0;\r
         PR2=freq;\r
         CCP1M0=1;\r
         CCP1M1=1;\r
@@ -605,15 +703,15 @@ irsnd_set_freq (IRSND_FREQ_TYPE freq)
         TMR2ON=1;\r
         CCP1CON &=(~0b0011); // p 197 "active high"\r
 #    else                                                                                   // PIC C18\r
-        OpenPWM(freq); \r
+        OpenPWM(freq);\r
         SetDCPWM( (uint16_t) (freq * 2) + 1); // freq*2 = Duty cycles 50%\r
 #    endif\r
         PWMoff();\r
 #  elif defined (ARM_STM32)                                                                 // STM32\r
-         static uint32_t      TimeBaseFreq = 0;\r
+        static uint32_t      TimeBaseFreq = 0;\r
 \r
-         if (TimeBaseFreq == 0)\r
-         {\r
+        if (TimeBaseFreq == 0)\r
+        {\r
             RCC_ClocksTypeDef        RCC_ClocksStructure;\r
             /* Get system clocks and store timer clock in variable */\r
             RCC_GetClocksFreq(&RCC_ClocksStructure);\r
@@ -636,14 +734,24 @@ irsnd_set_freq (IRSND_FREQ_TYPE freq)
                TimeBaseFreq = RCC_ClocksStructure.PCLK2_Frequency * 2;\r
             }\r
 #    endif\r
-         }\r
+        }\r
+\r
+        freq = TimeBaseFreq/freq;\r
 \r
-         freq = TimeBaseFreq/freq;\r
+        /* Set frequency */\r
+        TIM_SetAutoreload(IRSND_TIMER, freq - 1);\r
+        /* Set duty cycle */\r
+        TIM_SetCompare1(IRSND_TIMER, (freq + 1) / 2);\r
 \r
-         /* Set frequency */\r
-         TIM_SetAutoreload(IRSND_TIMER, freq - 1);\r
-         /* Set duty cycle */\r
-         TIM_SetCompare1(IRSND_TIMER, (freq + 1) / 2);\r
+#  elif defined (TEENSY_ARM_CORTEX_M4)\r
+        analogWriteResolution(8);                                                           // 8 bit\r
+        analogWriteFrequency(IRSND_PIN, freq);\r
+        analogWrite(IRSND_PIN, 0);                                                          // pwm off, LOW level\r
+\r
+#elif defined (__xtensa__)\r
+        // analogWriteRange(255);\r
+        analogWriteFreq(freq);\r
+        analogWrite(IRSND_PIN, 0);                                                          // pwm off, LOW level\r
 \r
 #  elif defined (__AVR_XMEGA__)\r
         XMEGA_Timer.CCA = freq;\r
@@ -743,7 +851,17 @@ irsnd_init (void)
 \r
         irsnd_set_freq (IRSND_FREQ_36_KHZ);                                         // set default frequency\r
 \r
-# elif defined (__AVR_XMEGA__)\r
+#  elif defined (TEENSY_ARM_CORTEX_M4)\r
+        if (!digitalPinHasPWM(IRSND_PIN))\r
+        {\r
+            return;\r
+        }\r
+\r
+#  elif defined (__xtensa__)\r
+        pinMode(IRSND_PIN, OUTPUT);\r
+        irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
+\r
+#  elif defined (__AVR_XMEGA__)\r
         IRSND_PORT &= ~(1<<IRSND_BIT);                                              // set IRSND_BIT to low\r
         IRSND_DDR |= (1<<IRSND_BIT);                                                // set IRSND_BIT to output\r
 \r
@@ -755,7 +873,7 @@ irsnd_init (void)
 #    else\r
         XMEGA_Timer.CTRLA |= TC_CLKSEL_DIV1_gc;                                     // start Timer  prescaler = 1\r
 #    endif\r
-                \r
+\r
 # else                                                                              // AVR\r
         IRSND_PORT &= ~(1<<IRSND_BIT);                                              // set IRSND_BIT to low\r
         IRSND_DDR |= (1<<IRSND_BIT);                                                // set IRSND_BIT to output\r
@@ -1037,6 +1155,18 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
             break;\r
         }\r
 #endif\r
+#if IRSND_SUPPORT_TECHNICS_PROTOCOL == 1\r
+        case IRMP_TECHNICS_PROTOCOL:\r
+        {\r
+            command = bitsrevervse (irmp_data_p->command, TECHNICS_COMMAND_LEN);\r
+\r
+            irsnd_buffer[0] = (command & 0x07FC) >> 3;                                                          // CCCCCCCC\r
+            irsnd_buffer[1] = ((command & 0x0007) << 5) | ((~command & 0x07C0) >> 6);                           // CCCccccc\r
+            irsnd_buffer[2] = (~command & 0x003F) << 2;                                                         // cccccc\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
 #if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\r
         case IRMP_KASEIKYO_PROTOCOL:\r
         {\r
@@ -1062,14 +1192,54 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
             break;\r
         }\r
 #endif\r
+#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\r
+        case IRMP_PANASONIC_PROTOCOL:\r
+        {\r
+            address = bitsrevervse (irmp_data_p->address, PANASONIC_ADDRESS_LEN);\r
+            command = bitsrevervse (irmp_data_p->command, PANASONIC_COMMAND_LEN);\r
+\r
+            irsnd_buffer[0] = 0x40;                                                                             // 01000000\r
+            irsnd_buffer[1] = 0x04;                                                                             // 00000100\r
+            irsnd_buffer[2] = 0x01;                                                                             // 00000001\r
+            irsnd_buffer[3] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\r
+            irsnd_buffer[4] = (address & 0x00FF);                                                               // AAAAAAAA\r
+            irsnd_buffer[5] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\r
+            irsnd_buffer[6] = (command & 0x00FF);                                                               // CCCCCCCC\r
+\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
+#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+        case IRMP_MITSU_HEAVY_PROTOCOL:\r
+        {\r
+            address = irmp_data_p->address;\r
+            command = irmp_data_p->command;\r
+\r
+            irsnd_buffer[0] = 0x4A;\r
+            irsnd_buffer[1] = 0x75;\r
+            irsnd_buffer[2] = 0xC3;\r
+            irsnd_buffer[3] = 0x64;\r
+            irsnd_buffer[4] = 0x9B;\r
+            irsnd_buffer[5] = ~(address & 0xFF00) >> 8;\r
+            irsnd_buffer[6] = (address & 0xFF00) >> 8;\r
+            irsnd_buffer[7] = ~(address & 0x00FF);\r
+            irsnd_buffer[8] = (address & 0x00FF);\r
+            irsnd_buffer[9] = ~(command & 0x00FF);\r
+            irsnd_buffer[10] = (command & 0x00FF);\r
+\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
         case IRMP_RECS80_PROTOCOL:\r
         {\r
-            toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40;\r
+            toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x80;\r
 \r
-            irsnd_buffer[0] = 0x80 | toggle_bit_recs80 | ((irmp_data_p->address & 0x0007) << 3) |\r
-                              ((irmp_data_p->command & 0x0038) >> 3);                                           // STAAACCC\r
-            irsnd_buffer[1] = (irmp_data_p->command & 0x07) << 5;                                               // CCC00000\r
+            irsnd_buffer[0] = toggle_bit_recs80 | ((irmp_data_p->address & 0x000F) << 4) |\r
+                              ((irmp_data_p->command & 0x003C) >> 2);                                           // TAAACCCC\r
+            irsnd_buffer[1] = (irmp_data_p->command & 0x03) << 6;                                               // CC000000\r
             irsnd_busy      = TRUE;\r
             break;\r
         }\r
@@ -1146,6 +1316,17 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
             break;\r
         }\r
 #endif\r
+#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\r
+        case IRMP_BOSE_PROTOCOL:\r
+        {\r
+            command = bitsrevervse (irmp_data_p->command, BOSE_COMMAND_LEN);\r
+\r
+            irsnd_buffer[0] = (command & 0xFF00) >> 8;                                                                      // CCCCCCCC\r
+            irsnd_buffer[1] = ~((command & 0xFF00) >> 8);                                                                   // cccccccc\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
         case IRMP_NUBERT_PROTOCOL:\r
         {\r
@@ -1155,6 +1336,15 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
             break;\r
         }\r
 #endif\r
+#if IRSND_SUPPORT_FAN_PROTOCOL == 1\r
+        case IRMP_FAN_PROTOCOL:\r
+        {\r
+            irsnd_buffer[0] = irmp_data_p->command >> 3;                                                        // CCCCCCCC\r
+            irsnd_buffer[1] = (irmp_data_p->command & 0x0007) << 5;                                             // CCC00000\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
 #if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\r
         case IRMP_SPEAKER_PROTOCOL:\r
         {\r
@@ -1275,7 +1465,7 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
 \r
             irsnd_buffer[0] = ((command & 0x06) << 5) | ((address & 0x0003) << 4) | ((command & 0x0780) >> 7);  //          C0 C1 A0 A1 D0 D1 D2 D3\r
             irsnd_buffer[1] = ((command & 0x78) << 1) | ((command & 0x0001) << 3);                              //          D4 D5 D6 D7 V  0  0  0\r
-                                                                                                                \r
+\r
             irsnd_busy      = TRUE;\r
             break;\r
         }\r
@@ -1339,6 +1529,59 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
             break;\r
         }\r
 #endif\r
+#if IRSND_SUPPORT_ACP24_PROTOCOL == 1\r
+#       define ACP_SET_BIT(acp24_bitno, c, irmp_bitno)                                          \\r
+        do                                                                                      \\r
+        {                                                                                       \\r
+            if ((c) & (1<<(irmp_bitno)))                                                        \\r
+            {                                                                                   \\r
+                irsnd_buffer[((acp24_bitno)>>3)] |= 1 << (((7 - (acp24_bitno)) & 0x07));        \\r
+            }                                                                                   \\r
+        } while (0)\r
+\r
+        case IRMP_ACP24_PROTOCOL:\r
+        {\r
+            uint16_t    cmd = irmp_data_p->command;\r
+            uint8_t     i;\r
+\r
+            address = bitsrevervse (irmp_data_p->address, ACP24_ADDRESS_LEN);\r
+\r
+            for (i = 0; i < 8; i++)\r
+            {\r
+                irsnd_buffer[i] = 0x00;                                                                         // CCCCCCCC\r
+            }\r
+\r
+            // ACP24-Frame:\r
+            //           1         2         3         4         5         6\r
+            // 0123456789012345678901234567890123456789012345678901234567890123456789\r
+            // N VVMMM    ? ???    t vmA x                 y                     TTTT\r
+            //\r
+            // irmp_data_p->command:\r
+            //\r
+            //         5432109876543210\r
+            //         NAVVvMMMmtxyTTTT\r
+\r
+            ACP_SET_BIT( 0, cmd, 15);\r
+            ACP_SET_BIT(24, cmd, 14);\r
+            ACP_SET_BIT( 2, cmd, 13);\r
+            ACP_SET_BIT( 3, cmd, 12);\r
+            ACP_SET_BIT(22, cmd, 11);\r
+            ACP_SET_BIT( 4, cmd, 10);\r
+            ACP_SET_BIT( 5, cmd,  9);\r
+            ACP_SET_BIT( 6, cmd,  8);\r
+            ACP_SET_BIT(23, cmd,  7);\r
+            ACP_SET_BIT(20, cmd,  6);\r
+            ACP_SET_BIT(26, cmd,  5);\r
+            ACP_SET_BIT(44, cmd,  4);\r
+            ACP_SET_BIT(66, cmd,  3);\r
+            ACP_SET_BIT(67, cmd,  2);\r
+            ACP_SET_BIT(68, cmd,  1);\r
+            ACP_SET_BIT(69, cmd,  0);\r
+\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
 \r
         default:\r
         {\r
@@ -1398,13 +1641,6 @@ irsnd_ISR (void)
             {\r
                 auto_repetition_pause_counter++;\r
 \r
-#if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
-                if (repeat_frame_pause_len > 0)                                     // frame repeat distance counts from beginning of 1st frame!\r
-                {\r
-                    repeat_frame_pause_len--;\r
-                }\r
-#endif\r
-\r
                 if (auto_repetition_pause_counter >= auto_repetition_pause_len)\r
                 {\r
                     auto_repetition_pause_counter = 0;\r
@@ -1491,7 +1727,7 @@ irsnd_ISR (void)
                     send_trailer = FALSE;\r
                     return irsnd_busy;\r
                 }\r
-                \r
+\r
                 n_repeat_frames             = irsnd_repeat;\r
 \r
                 if (n_repeat_frames == IRSND_ENDLESS_REPETITION)\r
@@ -1676,6 +1912,24 @@ irsnd_ISR (void)
                         break;\r
                     }\r
 #endif\r
+#if IRSND_SUPPORT_TECHNICS_PROTOCOL == 1\r
+                    case IRMP_TECHNICS_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = MATSUSHITA_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = MATSUSHITA_START_BIT_PAUSE_LEN - 1;\r
+                        pulse_1_len                 = MATSUSHITA_PULSE_LEN;\r
+                        pause_1_len                 = MATSUSHITA_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = MATSUSHITA_PULSE_LEN;\r
+                        pause_0_len                 = MATSUSHITA_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = MATSUSHITA_STOP_BIT;\r
+                        complete_data_len           = TECHNICS_COMPLETE_DATA_LEN;                   // here TECHNICS\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = MATSUSHITA_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
 #if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\r
                     case IRMP_KASEIKYO_PROTOCOL:\r
                     {\r
@@ -1694,6 +1948,42 @@ irsnd_ISR (void)
                         break;\r
                     }\r
 #endif\r
+#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\r
+                    case IRMP_PANASONIC_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = PANASONIC_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = PANASONIC_START_BIT_PAUSE_LEN - 1;\r
+                        pulse_1_len                 = PANASONIC_PULSE_LEN;\r
+                        pause_1_len                 = PANASONIC_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = PANASONIC_PULSE_LEN;\r
+                        pause_0_len                 = PANASONIC_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = PANASONIC_STOP_BIT;\r
+                        complete_data_len           = PANASONIC_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = PANASONIC_FRAMES;                             // 1 frame\r
+                        auto_repetition_pause_len   = PANASONIC_AUTO_REPETITION_PAUSE_LEN;          // 40 ms pause\r
+                        repeat_frame_pause_len      = PANASONIC_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
+#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+                    case IRMP_MITSU_HEAVY_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = MITSU_HEAVY_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = MITSU_HEAVY_START_BIT_PAUSE_LEN - 1;\r
+                        pulse_1_len                 = MITSU_HEAVY_PULSE_LEN;\r
+                        pause_1_len                 = MITSU_HEAVY_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = MITSU_HEAVY_PULSE_LEN;\r
+                        pause_0_len                 = MITSU_HEAVY_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = MITSU_HEAVY_STOP_BIT;\r
+                        complete_data_len           = MITSU_HEAVY_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = MITSU_HEAVY_FRAMES;                             // 1 frame\r
+                        auto_repetition_pause_len   = 0;;\r
+                        repeat_frame_pause_len      = MITSU_HEAVY_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_40_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
                     case IRMP_RECS80_PROTOCOL:\r
                     {\r
@@ -1827,11 +2117,29 @@ irsnd_ISR (void)
                         complete_data_len           = THOMSON_COMPLETE_DATA_LEN;\r
                         n_auto_repetitions          = THOMSON_FRAMES;                               // only 1 frame\r
                         auto_repetition_pause_len   = THOMSON_AUTO_REPETITION_PAUSE_LEN;\r
-                        repeat_frame_pause_len      = DENON_FRAME_REPEAT_PAUSE_LEN;\r
+                        repeat_frame_pause_len      = THOMSON_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
 #endif\r
+#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\r
+                    case IRMP_BOSE_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = BOSE_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = BOSE_START_BIT_PAUSE_LEN - 1;\r
+                        pulse_1_len                 = BOSE_PULSE_LEN;\r
+                        pause_1_len                 = BOSE_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = BOSE_PULSE_LEN;\r
+                        pause_0_len                 = BOSE_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = BOSE_STOP_BIT;\r
+                        complete_data_len           = BOSE_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = BOSE_FRAMES;                                // 1 frame\r
+                        auto_repetition_pause_len   = BOSE_AUTO_REPETITION_PAUSE_LEN;             // 40 ms pause\r
+                        repeat_frame_pause_len      = BOSE_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
                     case IRMP_NUBERT_PROTOCOL:\r
                     {\r
@@ -1850,6 +2158,24 @@ irsnd_ISR (void)
                         break;\r
                     }\r
 #endif\r
+#if IRSND_SUPPORT_FAN_PROTOCOL == 1\r
+                    case IRMP_FAN_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = FAN_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = FAN_START_BIT_PAUSE_LEN - 1;\r
+                        pulse_1_len                 = FAN_1_PULSE_LEN;\r
+                        pause_1_len                 = FAN_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = FAN_0_PULSE_LEN;\r
+                        pause_0_len                 = FAN_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = FAN_STOP_BIT;\r
+                        complete_data_len           = FAN_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = FAN_FRAMES;                                   // only 1 frame\r
+                        auto_repetition_pause_len   = FAN_AUTO_REPETITION_PAUSE_LEN;                // 35 ms pause\r
+                        repeat_frame_pause_len      = FAN_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
 #if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\r
                     case IRMP_SPEAKER_PROTOCOL:\r
                     {\r
@@ -2113,6 +2439,24 @@ irsnd_ISR (void)
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
+#endif\r
+#if IRSND_SUPPORT_ACP24_PROTOCOL == 1\r
+                    case IRMP_ACP24_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = ACP24_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = ACP24_START_BIT_PAUSE_LEN - 1;\r
+                        complete_data_len           = ACP24_COMPLETE_DATA_LEN;\r
+                        pulse_1_len                 = ACP24_PULSE_LEN;\r
+                        pause_1_len                 = ACP24_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = ACP24_PULSE_LEN;\r
+                        pause_0_len                 = ACP24_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = ACP24_STOP_BIT;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = ACP24_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
+                        break;\r
+                    }\r
 #endif\r
                     default:\r
                     {\r
@@ -2154,9 +2498,18 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\r
                 case IRMP_MATSUSHITA_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\r
+                case IRMP_TECHNICS_PROTOCOL:\r
+#endif\r
 #if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\r
                 case IRMP_KASEIKYO_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\r
+                case IRMP_PANASONIC_PROTOCOL:\r
+#endif\r
+#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
+                case IRMP_MITSU_HEAVY_PROTOCOL:\r
+#endif\r
 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
                 case IRMP_RECS80_PROTOCOL:\r
 #endif\r
@@ -2169,9 +2522,15 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
                 case IRMP_DENON_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\r
+                case IRMP_BOSE_PROTOCOL:\r
+#endif\r
 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
                 case IRMP_NUBERT_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_FAN_PROTOCOL == 1\r
+                case IRMP_FAN_PROTOCOL:\r
+#endif\r
 #if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\r
                 case IRMP_SPEAKER_PROTOCOL:\r
 #endif\r
@@ -2202,29 +2561,19 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
                 case IRMP_PENTAX_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_ACP24_PROTOCOL == 1\r
+                case IRMP_ACP24_PROTOCOL:\r
+#endif\r
 \r
 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1  || IRSND_SUPPORT_NEC_PROTOCOL == 1 || IRSND_SUPPORT_NEC16_PROTOCOL == 1 || IRSND_SUPPORT_NEC42_PROTOCOL == 1 || \\r
-    IRSND_SUPPORT_LGAIR_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 ||   \\r
+    IRSND_SUPPORT_LGAIR_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 || IRSND_SUPPORT_TECHNICS_PROTOCOL == 1 || \\r
     IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1 || IRSND_SUPPORT_RECS80_PROTOCOL == 1 || IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 || IRSND_SUPPORT_DENON_PROTOCOL == 1 || \\r
-    IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_SPEAKER_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 ||   \\r
-    IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1 || IRSND_SUPPORT_LEGO_PROTOCOL == 1 || IRSND_SUPPORT_THOMSON_PROTOCOL == 1 || \\r
-    IRSND_SUPPORT_ROOMBA_PROTOCOL == 1 || IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1 || IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
+    IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_FAN_PROTOCOL == 1 || IRSND_SUPPORT_SPEAKER_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 || IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_LEGO_PROTOCOL == 1 || IRSND_SUPPORT_THOMSON_PROTOCOL == 1 || IRSND_SUPPORT_ROOMBA_PROTOCOL == 1 || IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_PENTAX_PROTOCOL == 1 || IRSND_SUPPORT_ACP24_PROTOCOL == 1 || IRSND_SUPPORT_PANASONIC_PROTOCOL == 1 || IRSND_SUPPORT_BOSE_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\r
                 {\r
-#if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
-                    if (irsnd_protocol == IRMP_DENON_PROTOCOL)\r
-                    {\r
-                        if (auto_repetition_pause_len > 0)                                          // 2nd frame distance counts from beginning of 1st frame!\r
-                        {\r
-                            auto_repetition_pause_len--;\r
-                        }\r
-\r
-                        if (repeat_frame_pause_len > 0)                                             // frame repeat distance counts from beginning of 1st frame!\r
-                        {\r
-                            repeat_frame_pause_len--;\r
-                        }\r
-                    }\r
-#endif\r
-\r
                     if (pulse_counter == 0)\r
                     {\r
                         if (current_bit == 0xFF)                                                    // send start bit\r
@@ -2536,20 +2885,20 @@ irsnd_ISR (void)
                                     {\r
                                         if (current_bit == 4)                                           // toggle bit (double len)\r
                                         {\r
-                                            pulse_len = 2 * RC6_BIT_LEN;\r
-                                            pause_len = 2 * RC6_BIT_LEN;\r
+                                            pulse_len = RC6_BIT_2_LEN;                                  // = 2 * RC_BIT_LEN\r
+                                            pause_len = RC6_BIT_2_LEN;                                  // = 2 * RC_BIT_LEN\r
                                         }\r
                                     }\r
                                     else // if (irsnd_protocol == IRMP_RC6A_PROTOCOL)\r
                                     {\r
                                         if (current_bit == 4)                                           // toggle bit (double len)\r
                                         {\r
-                                            pulse_len = 2 * RC6_BIT_LEN + RC6_BIT_LEN;                  // hack!\r
-                                            pause_len = 2 * RC6_BIT_LEN;\r
+                                            pulse_len = RC6_BIT_3_LEN;                                  // = 3 * RC6_BIT_LEN\r
+                                            pause_len = RC6_BIT_2_LEN;                                  // = 2 * RC6_BIT_LEN\r
                                         }\r
                                         else if (current_bit == 5)                                      // toggle bit (double len)\r
                                         {\r
-                                            pause_len = 2 * RC6_BIT_LEN;\r
+                                            pause_len = RC6_BIT_2_LEN;                                  // = 2 * RC6_BIT_LEN\r
                                         }\r
                                     }\r
                                 }\r