]> cloudbase.mooo.com Git - irmp.git/blobdiff - irsnd.c
Version 1.2.1: added APPLE_PROTOCOL to irsnd
[irmp.git] / irsnd.c
diff --git a/irsnd.c b/irsnd.c
index ac616f1848a16e950e3007c3332e61a9a872a6cb..fb0ac471c5e3250d718d7c80a441cff239d45cbf 100644 (file)
--- a/irsnd.c
+++ b/irsnd.c
@@ -3,6 +3,8 @@
  *\r
  * Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de\r
  *\r
+ * $Id: irsnd.c,v 1.9 2010/04/28 14:58:59 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
  * the Free Software Foundation; either version 2 of the License, or\r
@@ -46,43 +48,9 @@ typedef unsigned short    uint16_t;
 #endif // unix\r
 \r
 #include "irmp.h"\r
+#include "irsndconfig.h"\r
 #include "irsnd.h"\r
 \r
-/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
- * Change settings from 1 to 0 if you want to disable one or more encoders.\r
- * This saves program space.\r
- * 1 enable  decoder\r
- * 0 disable decoder\r
- *---------------------------------------------------------------------------------------------------------------------------------------------------\r
- */\r
-#define IRSND_SUPPORT_SIRCS_PROTOCOL            1       // flag: support SIRCS                  uses ~150 bytes\r
-#define IRSND_SUPPORT_NEC_PROTOCOL              1       // flag: support NEC                    uses ~100 bytes\r
-#define IRSND_SUPPORT_SAMSUNG_PROTOCOL          1       // flag: support Samsung + Samsung32    uses ~300 bytes\r
-#define IRSND_SUPPORT_MATSUSHITA_PROTOCOL       1       // flag: support Matsushita             uses ~150 bytes\r
-#define IRSND_SUPPORT_KASEIKYO_PROTOCOL         0       // flag: support Kaseikyo               NOT SUPPORTED YET!\r
-#define IRSND_SUPPORT_RECS80_PROTOCOL           1       // flag: support RECS80                 uses ~100 bytes\r
-#define IRSND_SUPPORT_RC5_PROTOCOL              1       // flag: support RC5                    uses ~250 bytes\r
-#define IRSND_SUPPORT_DENON_PROTOCOL            1       // flag: support DENON                  uses ~200 bytes\r
-#define IRSND_SUPPORT_RC6_PROTOCOL              0       // flag: support RC6                    NOT SUPPORTED YET!\r
-#define IRSND_SUPPORT_RECS80EXT_PROTOCOL        1       // flag: support RECS80EXT              uses ~100 bytes\r
-#define IRSND_SUPPORT_NUBERT_PROTOCOL           1       // flag: support NUBERT                 uses ~100 bytes\r
-\r
-\r
-/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
- * Change hardware pin here:\r
- *---------------------------------------------------------------------------------------------------------------------------------------------------\r
- */\r
-#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega644P__)\r
-#define IRSND_PORT          PORTD                       // port D\r
-#define IRSND_DDR           DDRD                        // ddr D\r
-#define IRSND_BIT           7                           // OC2A\r
-#else\r
-#define IRSND_PORT          PORTB                       // port B\r
-#define IRSND_DDR           DDRB                        // ddr B\r
-#define IRSND_BIT           3                           // OC2A\r
-#endif // __AVR...\r
-\r
-\r
 #define SIRCS_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME + 0.5)\r
 #define SIRCS_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME + 0.5)\r
 #define SIRCS_1_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME + 0.5)\r
@@ -141,11 +109,24 @@ typedef unsigned short    uint16_t;
 #define NUBERT_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)\r
 #define NUBERT_REPETITION_LEN                   (uint16_t)(F_INTERRUPTS * NUBERT_REPETITION_TIME + 0.5)       // use uint16_t!\r
 \r
+#define BANG_OLUFSEN_START_BIT1_PULSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_START_BIT2_PULSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_START_BIT3_PULSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_PULSE_LEN                  (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_1_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_0_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_R_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)\r
+#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN      (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)\r
+\r
 #define IRSND_FREQ_32_KHZ                       (uint8_t) ((F_CPU / 32000 / 2) - 1)\r
 #define IRSND_FREQ_36_KHZ                       (uint8_t) ((F_CPU / 36000 / 2) - 1)\r
 #define IRSND_FREQ_38_KHZ                       (uint8_t) ((F_CPU / 38000 / 2) - 1)\r
 #define IRSND_FREQ_40_KHZ                       (uint8_t) ((F_CPU / 40000 / 2) - 1)\r
 #define IRSND_FREQ_56_KHZ                       (uint8_t) ((F_CPU / 56000 / 2) - 1)\r
+#define IRSND_FREQ_455_KHZ                      (uint8_t) ((F_CPU / 455000 / 2) - 1)\r
 \r
 static volatile uint8_t                         irsnd_busy;\r
 static volatile uint8_t                         irsnd_protocol;\r
@@ -167,7 +148,7 @@ irsnd_on (void)
         TCCR2 |= (1<<COM20)|(1<<WGM21);                 // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A\r
 #else\r
         TCCR2A |= (1<<COM2A0)|(1<<WGM21);               // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A\r
-#endif // __AVR...\r
+#endif  // __AVR...\r
 #endif // DEBUG\r
         irsnd_is_on = TRUE;\r
     }\r
@@ -188,7 +169,7 @@ irsnd_off (void)
         TCCR2 &= ~(1<<COM20);                                                           // normal port operation, OC2A disconnected.\r
 #else\r
         TCCR2A &= ~(1<<COM2A0);                                                         // normal port operation, OC2A disconnected.\r
-#endif // __AVR...\r
+#endif  // __AVR...\r
         IRSND_PORT  &= ~(1<<IRSND_BIT);                                                 // set IRSND_BIT to low\r
 #endif // DEBUG\r
         irsnd_is_on = FALSE;\r
@@ -208,7 +189,7 @@ irsnd_set_freq (uint8_t freq)
     OCR2 = freq;\r
 #else\r
     OCR2A = freq;\r
-#endif // __AVR...\r
+#endif  // __AVR...\r
 #endif // DEBUG\r
 }\r
 \r
@@ -230,7 +211,7 @@ irsnd_init (void)
 #else\r
     TCCR2A = (1<<WGM21);                                                            // CTC mode\r
     TCCR2B |= (1<<CS20);                                                            // 0x01, start Timer 2, no prescaling\r
-#endif // __AVR...    \r
+#endif  // __AVR...    \r
 \r
     irsnd_set_freq (IRSND_FREQ_36_KHZ);                                             // default frequency\r
 #endif // DEBUG\r
@@ -290,7 +271,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
         {\r
             command = bitsrevervse (irmp_data_p->command, SIRCS_MINIMUM_DATA_LEN);\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = (command & 0x0FF0) >> 4;                                                         // CCCCCCCC\r
             irsnd_buffer[1] = (command & 0x000F) << 4;                                                         // CCCC0000\r
             irsnd_busy      = TRUE;\r
@@ -299,15 +279,25 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
 #endif\r
 #if IRSND_SUPPORT_NEC_PROTOCOL == 1\r
         case IRMP_NEC_PROTOCOL:\r
+        case IRMP_APPLE_PROTOCOL:\r
         {\r
             address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);\r
             command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\r
             irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\r
             irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\r
-            irsnd_buffer[3] = ~((command & 0xFF00) >> 8);                                                       // cccccccc\r
+\r
+            if (irsnd_protocol == IRMP_APPLE_PROTOCOL)\r
+            {\r
+                irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with fix bitmask instead of inverted command\r
+                irsnd_buffer[3] = 0x8B;                                                                         // 10001011\r
+            }\r
+            else\r
+            {\r
+                irsnd_buffer[3] = ~((command & 0xFF00) >> 8);                                                   // cccccccc\r
+            }\r
+\r
             irsnd_busy      = TRUE;\r
             break;\r
         }\r
@@ -318,7 +308,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
             address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);\r
             command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN);\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] =  (address & 0xFF00) >> 8;                                                         // AAAAAAAA\r
             irsnd_buffer[1] =  (address & 0x00FF);                                                              // AAAAAAAA\r
             irsnd_buffer[2] =  (command & 0x00F0) | ((command & 0xF000) >> 12);                                 // IIIICCCC\r
@@ -332,7 +321,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
             address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);\r
             command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN);\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\r
             irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\r
             irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\r
@@ -347,7 +335,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
             address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN);\r
             command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN);\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = (command & 0x0FF0) >> 4;                                                          // CCCCCCCC\r
             irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8);                            // CCCCAAAA\r
             irsnd_buffer[2] = (address & 0x00FF);                                                               // AAAAAAAA\r
@@ -360,7 +347,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
         {\r
             toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40;\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\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
@@ -373,7 +359,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
         {\r
             toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40;\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = 0x80 | toggle_bit_recs80ext | ((irmp_data_p->address & 0x000F) << 2) |\r
                                 ((irmp_data_p->command & 0x0030) >> 4);                                         // STAAAACC\r
             irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4;                                               // CCCC0000\r
@@ -386,7 +371,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
         {\r
             toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40;\r
 \r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = ((irmp_data_p->command & 0x40) ? 0x00 : 0x80) | toggle_bit_rc5 |\r
                                 ((irmp_data_p->address & 0x001F) << 1) | ((irmp_data_p->command & 0x20) >> 5);  // CTAAAAAC\r
             irsnd_buffer[1] = (irmp_data_p->command & 0x1F) << 3;                                               // CCCCC000\r
@@ -397,7 +381,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
 #if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
         case IRMP_DENON_PROTOCOL:\r
         {\r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7);    // AAAAACCC\r
             irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1;                                               // CCCCCCC0\r
             irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC\r
@@ -409,12 +392,21 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
         case IRMP_NUBERT_PROTOCOL:\r
         {\r
-            irsnd_protocol  = irmp_data_p->protocol;\r
             irsnd_buffer[0] = irmp_data_p->command >> 2;                                                        // CCCCCCCC\r
             irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6;                                             // CC000000\r
             irsnd_busy      = TRUE;\r
             break;\r
         }\r
+#endif\r
+#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
+        case IRMP_BANG_OLUFSEN_PROTOCOL:\r
+        {\r
+            irsnd_buffer[0] = irmp_data_p->command >> 11;                                                       // SXSCCCCC\r
+            irsnd_buffer[1] = irmp_data_p->command >> 3;                                                        // CCCCCCCC\r
+            irsnd_buffer[2] = (irmp_data_p->command & 0x0007) << 5;                                             // CCC00000\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
 #endif\r
         default:\r
         {\r
@@ -445,18 +437,21 @@ irsnd_ISR (void)
     static uint8_t  has_stop_bit;\r
     static uint8_t  new_frame = TRUE;\r
     static uint8_t  complete_data_len;\r
-    static uint8_t  n_repetitions;                                                  // number of repetitions\r
-    static uint8_t  repetition_counter;                                             // repetition counter\r
+    static uint8_t  n_frames;                                                  // number of repetitions\r
+    static uint8_t  frame_counter;                                             // repetition counter\r
     static uint16_t repetition_pause;                                               // pause before repetition, uint16_t!\r
     static uint16_t repetition_pause_counter;                                       // pause before repetition, uint16_t!\r
-    uint8_t         pulse_len = 0xFF;\r
-    uint8_t         pause_len = 0xFF;\r
+#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
+    static uint8_t  last_bit_value;\r
+#endif\r
+    static uint8_t  pulse_len = 0xFF;\r
+    static uint8_t  pause_len = 0xFF;\r
 \r
     if (irsnd_busy)\r
     {\r
         if (current_bit == 0xFF && new_frame)                                       // start of transmission...\r
         {\r
-            if (repetition_counter > 0)\r
+            if (frame_counter > 0)\r
             {\r
                 repetition_pause_counter++;\r
 \r
@@ -487,6 +482,9 @@ irsnd_ISR (void)
             }\r
             else\r
             {\r
+                pulse_counter = 0;\r
+                pause_counter = 0;\r
+\r
                 switch (irsnd_protocol)\r
                 {\r
 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\r
@@ -500,7 +498,7 @@ irsnd_ISR (void)
                         pause_0_len         = SIRCS_PAUSE_LEN;\r
                         has_stop_bit        = SIRCS_STOP_BIT;\r
                         complete_data_len   = SIRCS_MINIMUM_DATA_LEN;\r
-                        n_repetitions       = SIRCS_REPETITION_CNT;\r
+                        n_frames            = SIRCS_REPETITION_CNT;\r
                         repetition_pause    = SIRCS_REPETITION_LEN;                     // 45 ms pause\r
                         irsnd_set_freq (IRSND_FREQ_40_KHZ);\r
                         break;\r
@@ -517,7 +515,7 @@ irsnd_ISR (void)
                         pause_0_len         = NEC_0_PAUSE_LEN;\r
                         has_stop_bit        = NEC_STOP_BIT;\r
                         complete_data_len   = NEC_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 1;\r
+                        n_frames            = 1;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -533,7 +531,7 @@ irsnd_ISR (void)
                         pause_0_len         = SAMSUNG_0_PAUSE_LEN;\r
                         has_stop_bit        = SAMSUNG_STOP_BIT;\r
                         complete_data_len   = SAMSUNG_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 1;\r
+                        n_frames            = 1;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -548,7 +546,7 @@ irsnd_ISR (void)
                         pause_0_len         = SAMSUNG_0_PAUSE_LEN;\r
                         has_stop_bit        = SAMSUNG_STOP_BIT;\r
                         complete_data_len   = SAMSUNG32_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 1;\r
+                        n_frames            = 1;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -564,7 +562,7 @@ irsnd_ISR (void)
                         pause_0_len         = MATSUSHITA_0_PAUSE_LEN;\r
                         has_stop_bit        = MATSUSHITA_STOP_BIT;\r
                         complete_data_len   = MATSUSHITA_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 1;\r
+                        n_frames            = 1;\r
                         irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
                         break;\r
                     }\r
@@ -580,7 +578,7 @@ irsnd_ISR (void)
                         pause_0_len         = RECS80_0_PAUSE_LEN;\r
                         has_stop_bit        = RECS80_STOP_BIT;\r
                         complete_data_len   = RECS80_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 1;\r
+                        n_frames            = 1;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -596,7 +594,7 @@ irsnd_ISR (void)
                         pause_0_len         = RECS80EXT_0_PAUSE_LEN;\r
                         has_stop_bit        = RECS80EXT_STOP_BIT;\r
                         complete_data_len   = RECS80EXT_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 1;\r
+                        n_frames            = 1;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -612,7 +610,7 @@ irsnd_ISR (void)
                         pause_0_len         = RC5_BIT_LEN;\r
                         has_stop_bit        = RC5_STOP_BIT;\r
                         complete_data_len   = RC5_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 1;\r
+                        n_frames            = 1;\r
                         irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
                         break;\r
                     }\r
@@ -628,7 +626,7 @@ irsnd_ISR (void)
                         pause_0_len         = DENON_0_PAUSE_LEN;\r
                         has_stop_bit        = DENON_STOP_BIT;\r
                         complete_data_len   = DENON_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 2;\r
+                        n_frames            = 2;\r
                         repetition_pause    = DENON_REPETITION_LEN;                     // 65 ms pause after 1st frame (15 bits)\r
                         irsnd_set_freq (IRSND_FREQ_32_KHZ);\r
                         break;\r
@@ -645,11 +643,28 @@ irsnd_ISR (void)
                         pause_0_len         = NUBERT_0_PAUSE_LEN;\r
                         has_stop_bit        = NUBERT_STOP_BIT;\r
                         complete_data_len   = NUBERT_COMPLETE_DATA_LEN;\r
-                        n_repetitions       = 2;\r
+                        n_frames            = 2;\r
                         repetition_pause    = NUBERT_REPETITION_LEN;                     // 35 ms pause\r
                         irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
                         break;\r
                     }\r
+#endif\r
+#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
+                    case IRMP_BANG_OLUFSEN_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len  = BANG_OLUFSEN_START_BIT1_PULSE_LEN;\r
+                        startbit_pause_len  = BANG_OLUFSEN_START_BIT1_PAUSE_LEN;\r
+                        pulse_1_len         = BANG_OLUFSEN_PULSE_LEN;\r
+                        pause_1_len         = BANG_OLUFSEN_1_PAUSE_LEN;\r
+                        pulse_0_len         = BANG_OLUFSEN_PULSE_LEN;\r
+                        pause_0_len         = BANG_OLUFSEN_0_PAUSE_LEN;\r
+                        has_stop_bit        = BANG_OLUFSEN_STOP_BIT;\r
+                        complete_data_len   = BANG_OLUFSEN_COMPLETE_DATA_LEN;\r
+                        n_frames            = 1;\r
+                        last_bit_value      = 0;\r
+                        irsnd_set_freq (IRSND_FREQ_455_KHZ);\r
+                        break;\r
+                    }\r
 #endif\r
                     default:\r
                     {\r
@@ -689,59 +704,110 @@ irsnd_ISR (void)
 #endif\r
 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
                 case IRMP_NUBERT_PROTOCOL:\r
+#endif\r
+#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
+                case IRMP_BANG_OLUFSEN_PROTOCOL:\r
 #endif\r
                 {\r
-                    if (current_bit == 0xFF)                                                    // send start bit\r
+                    if (pulse_counter == 0)\r
                     {\r
-                        pulse_len = startbit_pulse_len;\r
-                        pause_len = startbit_pause_len;\r
-                    }\r
-                    else if (current_bit < complete_data_len)                                   // send n'th bit\r
-                    {\r
-                        if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)\r
+                        if (current_bit == 0xFF)                                                    // send start bit\r
+                        {\r
+                            pulse_len = startbit_pulse_len;\r
+                            pause_len = startbit_pause_len;\r
+                        }\r
+                        else if (current_bit < complete_data_len)                                   // send n'th bit\r
                         {\r
-                            if (current_bit < SAMSUNG_ADDRESS_LEN)                              // send address bits\r
+#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\r
+                            if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)\r
                             {\r
-                                pulse_len = SAMSUNG_PULSE_LEN;\r
-                                pause_len = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ?\r
-                                                SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;\r
+                                if (current_bit < SAMSUNG_ADDRESS_LEN)                              // send address bits\r
+                                {\r
+                                    pulse_len = SAMSUNG_PULSE_LEN;\r
+                                    pause_len = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ?\r
+                                                    SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;\r
+                                }\r
+                                else if (current_bit == SAMSUNG_ADDRESS_LEN)                        // send SYNC bit (16th bit)\r
+                                {\r
+                                    pulse_len = SAMSUNG_PULSE_LEN;\r
+                                    pause_len = SAMSUNG_START_BIT_PAUSE_LEN;\r
+                                }\r
+                                else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN)                   // send n'th bit\r
+                                {\r
+                                    uint8_t cur_bit = current_bit - 1;                              // sync skipped, offset = -1 !\r
+\r
+                                    pulse_len = SAMSUNG_PULSE_LEN;\r
+                                    pause_len = (irsnd_buffer[cur_bit / 8] & (1<<(7-(cur_bit % 8)))) ?\r
+                                                    SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;\r
+                                }\r
                             }\r
-                            else if (current_bit == SAMSUNG_ADDRESS_LEN)                        // send SYNC bit (16th bit)\r
+                            else\r
+#endif\r
+\r
+#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
+                            if (irsnd_protocol == IRMP_BANG_OLUFSEN_PROTOCOL)\r
                             {\r
-                                pulse_len = SAMSUNG_PULSE_LEN;\r
-                                pause_len = SAMSUNG_START_BIT_PAUSE_LEN;\r
+                                if (current_bit == 0)                                               // send 2nd start bit\r
+                                {\r
+                                    pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;\r
+                                    pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;\r
+                                }\r
+                                else if (current_bit == 1)                                          // send 3rd start bit\r
+                                {\r
+                                    pulse_len = BANG_OLUFSEN_START_BIT3_PULSE_LEN;\r
+                                    pause_len = BANG_OLUFSEN_START_BIT3_PAUSE_LEN;\r
+                                }\r
+                                else if (current_bit == 2)                                          // send 4th start bit\r
+                                {\r
+                                    pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;\r
+                                    pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;\r
+                                }\r
+                                else if (current_bit == 19)                                          // send trailer bit\r
+                                {\r
+                                    pulse_len = BANG_OLUFSEN_PULSE_LEN;\r
+                                    pause_len = BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN;\r
+                                }\r
+                                else if (current_bit < BANG_OLUFSEN_COMPLETE_DATA_LEN)              // send n'th bit\r
+                                {\r
+                                    uint8_t cur_bit_value = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0;\r
+                                    pulse_len = BANG_OLUFSEN_PULSE_LEN;\r
+\r
+                                    if (cur_bit_value == last_bit_value)\r
+                                    {\r
+                                        pause_len = BANG_OLUFSEN_R_PAUSE_LEN;\r
+                                    }\r
+                                    else\r
+                                    {\r
+                                        pause_len = cur_bit_value ? BANG_OLUFSEN_1_PAUSE_LEN : BANG_OLUFSEN_0_PAUSE_LEN;\r
+                                        last_bit_value = cur_bit_value;\r
+                                    }\r
+                                }\r
                             }\r
-                            else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN)                   // send n'th bit\r
+                            else\r
+#endif\r
+                            if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))\r
                             {\r
-                                uint8_t cur_bit = current_bit - 1;\r
-\r
-                                pulse_len = SAMSUNG_PULSE_LEN;\r
-                                pause_len = (irsnd_buffer[cur_bit / 8] & (1<<(7-(cur_bit % 8)))) ?\r
-                                                SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;\r
+                                pulse_len = pulse_1_len;\r
+                                pause_len = pause_1_len;\r
+                            }\r
+                            else\r
+                            {\r
+                                pulse_len = pulse_0_len;\r
+                                pause_len = pause_0_len;\r
                             }\r
                         }\r
-                        else if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))\r
-                        {\r
-                            pulse_len = pulse_1_len;\r
-                            pause_len = pause_1_len;\r
-                        }\r
-                        else\r
+                        else if (has_stop_bit)                                                                      // send stop bit\r
                         {\r
                             pulse_len = pulse_0_len;\r
-                            pause_len = pause_0_len;\r
-                        }\r
-                    }\r
-                    else if (has_stop_bit)                                                                      // send stop bit\r
-                    {\r
-                        pulse_len = pulse_0_len;\r
 \r
-                        if (repetition_counter < n_repetitions)\r
-                        {\r
-                            pause_len = pause_0_len;\r
-                        }\r
-                        else\r
-                        {\r
-                            pause_len = 255;                                        // last frame: pause of 255\r
+                            if (frame_counter < n_frames)\r
+                            {\r
+                                pause_len = pause_0_len;\r
+                            }\r
+                            else\r
+                            {\r
+                                pause_len = 255;                                        // last frame: pause of 255\r
+                            }\r
                         }\r
                     }\r
 \r
@@ -768,12 +834,12 @@ irsnd_ISR (void)
                         if (current_bit >= complete_data_len + has_stop_bit)\r
                         {\r
                             current_bit = 0xFF;\r
-                            repetition_counter++;\r
+                            frame_counter++;\r
 \r
-                            if (repetition_counter == n_repetitions)\r
+                            if (frame_counter == n_frames)\r
                             {\r
                                 irsnd_busy = FALSE;\r
-                                repetition_counter = 0;\r
+                                frame_counter = 0;\r
                             }\r
                             new_frame = TRUE;\r
                         }\r