]> cloudbase.mooo.com Git - irmp.git/blobdiff - irsnd.c
Version 1.6.3: merged manchester decoding, changed output formats of debug modes...
[irmp.git] / irsnd.c
diff --git a/irsnd.c b/irsnd.c
index c18db62ed1e6be89c9cd3047860f21da3aac1c84..c2a4da771c327e9cd2514ba113faa1aed796b272 100644 (file)
--- a/irsnd.c
+++ b/irsnd.c
@@ -3,7 +3,7 @@
  *\r
  * Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de\r
  *\r
- * $Id: irsnd.c,v 1.7 2010/04/14 13:21:39 fm Exp $\r
+ * $Id: irsnd.c,v 1.18 2010/06/10 21:24:50 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
@@ -47,95 +47,72 @@ typedef unsigned short    uint16_t;
 #endif // WIN32\r
 #endif // unix\r
 \r
-#include "irmpconfig.h"\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
-#define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL     1       // flag: support Bang&Olufsen           uses ~250 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
 #define SIRCS_0_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME + 0.5)\r
 #define SIRCS_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME + 0.5)\r
-#define SIRCS_REPETITION_LEN                    (uint16_t)(F_INTERRUPTS * SIRCS_REPETITION_TIME + 0.5)       // use uint16_t!\r
+#define SIRCS_AUTO_REPETITION_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * SIRCS_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!\r
+#define SIRCS_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * SIRCS_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\r
 \r
 #define NEC_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)\r
 #define NEC_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)\r
+#define NEC_REPEAT_START_BIT_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME + 0.5)\r
 #define NEC_PULSE_LEN                           (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)\r
 #define NEC_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)\r
 #define NEC_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)\r
+#define NEC_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\r
 \r
 #define SAMSUNG_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)\r
 #define SAMSUNG_START_BIT_PAUSE_LEN             (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)\r
 #define SAMSUNG_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)\r
 #define SAMSUNG_1_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)\r
 #define SAMSUNG_0_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)\r
+#define SAMSUNG_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * SAMSUNG_FRAME_REPEAT_PAUSE_TIME + 0.5)            // use uint16_t!\r
+\r
+#define SAMSUNG32_AUTO_REPETITION_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * SAMSUNG32_AUTO_REPETITION_PAUSE_TIME + 0.5)       // use uint16_t!\r
+#define SAMSUNG32_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * SAMSUNG32_FRAME_REPEAT_PAUSE_TIME + 0.5)          // use uint16_t!\r
 \r
 #define MATSUSHITA_START_BIT_PULSE_LEN          (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)\r
 #define MATSUSHITA_START_BIT_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)\r
 #define MATSUSHITA_PULSE_LEN                    (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)\r
 #define MATSUSHITA_1_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)\r
 #define MATSUSHITA_0_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)\r
+#define MATSUSHITA_FRAME_REPEAT_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * MATSUSHITA_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
 #define RECS80_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)\r
 #define RECS80_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)\r
+#define RECS80_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * RECS80_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!\r
 \r
 #define RC5_START_BIT_LEN                       (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)\r
 #define RC5_BIT_LEN                             (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)\r
+#define RC5_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * RC5_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\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_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 DENON_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)\r
 #define DENON_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)\r
-#define DENON_REPETITION_LEN                    (uint16_t)(F_INTERRUPTS * DENON_REPETITION_TIME + 0.5)       // use uint16_t!\r
+#define DENON_AUTO_REPETITION_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * DENON_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!\r
+#define DENON_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * DENON_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\r
 \r
 #define RECS80EXT_START_BIT_PULSE_LEN           (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)\r
 #define RECS80EXT_START_BIT_PAUSE_LEN           (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)\r
 #define RECS80EXT_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)\r
 #define RECS80EXT_1_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)\r
 #define RECS80EXT_0_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)\r
+#define RECS80EXT_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * RECS80EXT_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
@@ -143,7 +120,8 @@ typedef unsigned short    uint16_t;
 #define NUBERT_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)\r
 #define NUBERT_0_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)\r
 #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
+#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 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
@@ -156,6 +134,17 @@ typedef unsigned short    uint16_t;
 #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
+#define BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * BANG_OLUFSEN_FRAME_REPEAT_PAUSE_TIME + 0.5)       // use uint16_t!\r
+\r
+#define GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME + 0.5)\r
+#define GRUNDIG_OR_NOKIA_BIT_LEN                (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME + 0.5)\r
+#define GRUNDIG_AUTO_REPETITION_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * GRUNDIG_AUTO_REPETITION_PAUSE_TIME + 0.5)         // use uint16_t!\r
+#define NOKIA_AUTO_REPETITION_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * NOKIA_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!\r
+#define GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_TIME + 0.5)   // use uint16_t!\r
+\r
+#define SIEMENS_START_BIT_LEN                   (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)\r
+#define SIEMENS_BIT_LEN                         (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)\r
+#define SIEMENS_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * SIEMENS_FRAME_REPEAT_PAUSE_TIME + 0.5)            // use uint16_t!\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
@@ -164,9 +153,17 @@ typedef unsigned short    uint16_t;
 #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
+#define FDC1_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * FDC1_START_BIT_PULSE_TIME + 0.5)\r
+#define FDC1_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * FDC1_START_BIT_PAUSE_TIME + 0.5)\r
+#define FDC1_PULSE_LEN                           (uint8_t)(F_INTERRUPTS * FDC1_PULSE_TIME + 0.5)\r
+#define FDC1_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FDC1_1_PAUSE_TIME + 0.5)\r
+#define FDC1_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FDC1_0_PAUSE_TIME + 0.5)\r
+#define FDC1_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * FDC1_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\r
+\r
 static volatile uint8_t                         irsnd_busy;\r
 static volatile uint8_t                         irsnd_protocol;\r
-static volatile uint8_t                         irsnd_buffer[5];\r
+static volatile uint8_t                         irsnd_buffer[6];\r
+static volatile uint8_t                         irsnd_repeat;\r
 static volatile uint8_t                         irsnd_is_on = FALSE;\r
 \r
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
@@ -184,7 +181,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
@@ -205,7 +202,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
@@ -225,7 +222,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
@@ -247,7 +244,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
@@ -279,7 +276,7 @@ bitsrevervse (uint16_t x, uint8_t len)
 \r
 \r
 uint8_t\r
-irsnd_send_data (IRMP_DATA * irmp_data_p)\r
+irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)\r
 {\r
 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
     static uint8_t  toggle_bit_recs80;\r
@@ -293,12 +290,20 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
     uint16_t        address;\r
     uint16_t        command;\r
 \r
-    while (irsnd_busy)\r
+    if (do_wait)\r
     {\r
-        ;\r
+        while (irsnd_busy)\r
+        {\r
+            // do nothing;\r
+        }\r
+    }\r
+    else if (irsnd_busy)\r
+    {\r
+        return (FALSE);\r
     }\r
 \r
     irsnd_protocol  = irmp_data_p->protocol;\r
+    irsnd_repeat    = irmp_data_p->flags;\r
 \r
     switch (irsnd_protocol)\r
     {\r
@@ -307,7 +312,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
@@ -316,15 +320,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
@@ -335,7 +349,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
@@ -349,7 +362,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
@@ -364,7 +376,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
@@ -377,7 +388,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
@@ -390,7 +400,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
@@ -403,7 +412,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
@@ -414,11 +422,10 @@ 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
-            irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1;                                            // CCCCCCC0\r
+            irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7);    // AAAAACCC (1st frame)\r
+            irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1;                                               // CCCCCCC\r
+            irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC (2nd frame)\r
+            irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1;                                            // CCCCCCC\r
             irsnd_busy      = TRUE;\r
             break;\r
         }\r
@@ -426,7 +433,6 @@ 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
@@ -436,13 +442,68 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
         case IRMP_BANG_OLUFSEN_PROTOCOL:\r
         {\r
-            irsnd_protocol  = irmp_data_p->protocol;\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
+#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\r
+        case IRMP_GRUNDIG_PROTOCOL:\r
+        {\r
+            command = bitsrevervse (irmp_data_p->command, GRUNDIG_COMMAND_LEN);\r
+\r
+            irsnd_buffer[0] = 0xFF;                                                                             // S1111111 (1st frame)\r
+            irsnd_buffer[1] = 0xC0;                                                                             // 11\r
+            irsnd_buffer[2] = 0x80 | (command >> 2);                                                            // SCCCCCCC (2nd frame)\r
+            irsnd_buffer[3] = (command << 6) & 0xC0;                                                            // CC\r
+\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
+#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
+        case IRMP_NOKIA_PROTOCOL:\r
+        {\r
+            address = bitsrevervse (irmp_data_p->address, NOKIA_ADDRESS_LEN);\r
+            command = bitsrevervse (irmp_data_p->command, NOKIA_COMMAND_LEN);\r
+\r
+            irsnd_buffer[0] = 0xBF;                                                                             // S0111111 (1st + 3rd frame)\r
+            irsnd_buffer[1] = 0xFF;                                                                             // 11111111\r
+            irsnd_buffer[2] = 0x80;                                                                             // 1\r
+            irsnd_buffer[3] = 0x80 | command >> 1;                                                              // SCCCCCCC (2nd frame)\r
+            irsnd_buffer[4] = (command << 7) | (address >> 1);                                                  // CAAAAAAA\r
+            irsnd_buffer[5] = (address << 7);                                                                   // A\r
+\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
+#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1\r
+        case IRMP_SIEMENS_PROTOCOL:\r
+        {\r
+            irsnd_buffer[0] = ((irmp_data_p->address & 0x0FFF) >> 5);                                           // SAAAAAAA\r
+            irsnd_buffer[1] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x7F) >> 5);      // AAAAA0CC\r
+            irsnd_buffer[2] = (irmp_data_p->command << 3);                                                      // CCCCC0\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
+#if IRSND_SUPPORT_FDC1_PROTOCOL == 1\r
+        case IRMP_FDC1_PROTOCOL:\r
+        {\r
+            address = bitsrevervse (irmp_data_p->address, FDC1_ADDRESS_LEN);\r
+            command = bitsrevervse (irmp_data_p->command, FDC1_COMMAND_LEN);\r
+\r
+            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\r
+            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\r
+            irsnd_buffer[2] = 0;                                                                                // 00000000\r
+            irsnd_buffer[3] = (command &  0x0FE0) >> 5;                                                         // 0CCCCCCC\r
+            irsnd_buffer[4] = ((command & 0x001F) << 3) | 0x07;                                                 // CCCCC111\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
 #endif\r
         default:\r
         {\r
@@ -473,10 +534,14 @@ 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_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
+    static uint8_t  n_auto_repetitions;                                             // number of auto_repetitions\r
+    static uint8_t  auto_repetition_counter;                                        // auto_repetition counter\r
+    static uint16_t auto_repetition_pause_len;                                      // pause before auto_repetition, uint16_t!\r
+    static uint16_t auto_repetition_pause_counter;                                  // pause before auto_repetition, uint16_t!\r
+    static uint8_t  n_repeat_frames;                                                // number of repeat frames\r
+    static uint8_t  repeat_counter;                                                 // repeat counter\r
+    static uint16_t repeat_frame_pause_len;                                         // pause before repeat, uint16_t!\r
+    static uint16_t packet_repeat_pause_counter;                                    // pause before repeat, uint16_t!\r
 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
     static uint8_t  last_bit_value;\r
 #endif\r
@@ -487,19 +552,37 @@ irsnd_ISR (void)
     {\r
         if (current_bit == 0xFF && new_frame)                                       // start of transmission...\r
         {\r
-            if (frame_counter > 0)\r
+            if (auto_repetition_counter > 0)\r
             {\r
-                repetition_pause_counter++;\r
+                auto_repetition_pause_counter++;\r
 \r
-                if (repetition_pause_counter >= repetition_pause)\r
+                if (auto_repetition_pause_counter >= auto_repetition_pause_len)\r
                 {\r
-                    repetition_pause_counter = 0;\r
+                    auto_repetition_pause_counter = 0;\r
 \r
                     if (irsnd_protocol == IRMP_DENON_PROTOCOL)\r
                     {\r
                         current_bit = 16;\r
                         complete_data_len   = 2 * DENON_COMPLETE_DATA_LEN + 1;\r
                     }\r
+                    else if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL)                       // n'th grundig info frame\r
+                    {\r
+                        current_bit = 15;\r
+                        complete_data_len   = 16 + GRUNDIG_COMPLETE_DATA_LEN;\r
+                    }\r
+                    else if (irsnd_protocol == IRMP_NOKIA_PROTOCOL)                         // n'th nokia info frame\r
+                    {\r
+                        if (auto_repetition_counter + 1 < n_auto_repetitions)\r
+                        {\r
+                            current_bit = 23;\r
+                            complete_data_len   = 24 + NOKIA_COMPLETE_DATA_LEN;\r
+                        }\r
+                        else                                                                // nokia stop frame\r
+                        {\r
+                            current_bit = 0xFF;\r
+                            complete_data_len   = NOKIA_COMPLETE_DATA_LEN;\r
+                        }\r
+                    }\r
                 }\r
                 else\r
                 {\r
@@ -516,26 +599,45 @@ irsnd_ISR (void)
                     return irsnd_busy;\r
                 }\r
             }\r
+            else if (repeat_counter > 0 && packet_repeat_pause_counter < repeat_frame_pause_len)\r
+            {\r
+                packet_repeat_pause_counter++;\r
+\r
+#ifdef DEBUG\r
+                if (irsnd_is_on)\r
+                {\r
+                    putchar ('0');\r
+                }\r
+                else\r
+                {\r
+                    putchar ('1');\r
+                }\r
+#endif\r
+                return irsnd_busy;\r
+            }\r
             else\r
             {\r
-                pulse_counter = 0;\r
-                pause_counter = 0;\r
+                n_repeat_frames             = irsnd_repeat;\r
+                packet_repeat_pause_counter = 0;\r
+                pulse_counter               = 0;\r
+                pause_counter               = 0;\r
 \r
                 switch (irsnd_protocol)\r
                 {\r
 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\r
                     case IRMP_SIRCS_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = SIRCS_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = SIRCS_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = SIRCS_1_PULSE_LEN;\r
-                        pause_1_len         = SIRCS_PAUSE_LEN;\r
-                        pulse_0_len         = SIRCS_0_PULSE_LEN;\r
-                        pause_0_len         = SIRCS_PAUSE_LEN;\r
-                        has_stop_bit        = SIRCS_STOP_BIT;\r
-                        complete_data_len   = SIRCS_MINIMUM_DATA_LEN;\r
-                        n_frames            = SIRCS_REPETITION_CNT;\r
-                        repetition_pause    = SIRCS_REPETITION_LEN;                     // 45 ms pause\r
+                        startbit_pulse_len          = SIRCS_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = SIRCS_START_BIT_PAUSE_LEN;\r
+                        pulse_1_len                 = SIRCS_1_PULSE_LEN;\r
+                        pause_1_len                 = SIRCS_PAUSE_LEN;\r
+                        pulse_0_len                 = SIRCS_0_PULSE_LEN;\r
+                        pause_0_len                 = SIRCS_PAUSE_LEN;\r
+                        has_stop_bit                = SIRCS_STOP_BIT;\r
+                        complete_data_len           = SIRCS_MINIMUM_DATA_LEN;\r
+                        n_auto_repetitions          = (repeat_counter == 0) ? SIRCS_FRAMES : 1;     // 3 frames auto repetition if first frame\r
+                        auto_repetition_pause_len   = SIRCS_AUTO_REPETITION_PAUSE_LEN;              // 25ms pause\r
+                        repeat_frame_pause_len      = SIRCS_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_40_KHZ);\r
                         break;\r
                     }\r
@@ -543,15 +645,27 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_NEC_PROTOCOL == 1\r
                     case IRMP_NEC_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = NEC_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = NEC_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = NEC_PULSE_LEN;\r
-                        pause_1_len         = NEC_1_PAUSE_LEN;\r
-                        pulse_0_len         = NEC_PULSE_LEN;\r
-                        pause_0_len         = NEC_0_PAUSE_LEN;\r
-                        has_stop_bit        = NEC_STOP_BIT;\r
-                        complete_data_len   = NEC_COMPLETE_DATA_LEN;\r
-                        n_frames            = 1;\r
+                        startbit_pulse_len          = NEC_START_BIT_PULSE_LEN;\r
+\r
+                        if (repeat_counter > 0)\r
+                        {\r
+                            startbit_pause_len      = NEC_REPEAT_START_BIT_PAUSE_LEN;\r
+                            complete_data_len       = 0;\r
+                        }\r
+                        else\r
+                        {\r
+                            startbit_pause_len      = NEC_START_BIT_PAUSE_LEN;\r
+                            complete_data_len       = NEC_COMPLETE_DATA_LEN;\r
+                        }\r
+\r
+                        pulse_1_len                 = NEC_PULSE_LEN;\r
+                        pause_1_len                 = NEC_1_PAUSE_LEN;\r
+                        pulse_0_len                 = NEC_PULSE_LEN;\r
+                        pause_0_len                 = NEC_0_PAUSE_LEN;\r
+                        has_stop_bit                = NEC_STOP_BIT;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = NEC_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -559,30 +673,34 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\r
                     case IRMP_SAMSUNG_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = SAMSUNG_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = SAMSUNG_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = SAMSUNG_PULSE_LEN;\r
-                        pause_1_len         = SAMSUNG_1_PAUSE_LEN;\r
-                        pulse_0_len         = SAMSUNG_PULSE_LEN;\r
-                        pause_0_len         = SAMSUNG_0_PAUSE_LEN;\r
-                        has_stop_bit        = SAMSUNG_STOP_BIT;\r
-                        complete_data_len   = SAMSUNG_COMPLETE_DATA_LEN;\r
-                        n_frames            = 1;\r
+                        startbit_pulse_len          = SAMSUNG_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = SAMSUNG_START_BIT_PAUSE_LEN;\r
+                        pulse_1_len                 = SAMSUNG_PULSE_LEN;\r
+                        pause_1_len                 = SAMSUNG_1_PAUSE_LEN;\r
+                        pulse_0_len                 = SAMSUNG_PULSE_LEN;\r
+                        pause_0_len                 = SAMSUNG_0_PAUSE_LEN;\r
+                        has_stop_bit                = SAMSUNG_STOP_BIT;\r
+                        complete_data_len           = SAMSUNG_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = SAMSUNG_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
 \r
                     case IRMP_SAMSUNG32_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = SAMSUNG_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = SAMSUNG_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = SAMSUNG_PULSE_LEN;\r
-                        pause_1_len         = SAMSUNG_1_PAUSE_LEN;\r
-                        pulse_0_len         = SAMSUNG_PULSE_LEN;\r
-                        pause_0_len         = SAMSUNG_0_PAUSE_LEN;\r
-                        has_stop_bit        = SAMSUNG_STOP_BIT;\r
-                        complete_data_len   = SAMSUNG32_COMPLETE_DATA_LEN;\r
-                        n_frames            = 1;\r
+                        startbit_pulse_len          = SAMSUNG_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = SAMSUNG_START_BIT_PAUSE_LEN;\r
+                        pulse_1_len                 = SAMSUNG_PULSE_LEN;\r
+                        pause_1_len                 = SAMSUNG_1_PAUSE_LEN;\r
+                        pulse_0_len                 = SAMSUNG_PULSE_LEN;\r
+                        pause_0_len                 = SAMSUNG_0_PAUSE_LEN;\r
+                        has_stop_bit                = SAMSUNG_STOP_BIT;\r
+                        complete_data_len           = SAMSUNG32_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = SAMSUNG32_FRAMES;                             // 2 frames\r
+                        auto_repetition_pause_len   = SAMSUNG32_AUTO_REPETITION_PAUSE_LEN;          // 47 ms pause\r
+                        repeat_frame_pause_len      = SAMSUNG32_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -590,15 +708,17 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\r
                     case IRMP_MATSUSHITA_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = MATSUSHITA_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = MATSUSHITA_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = MATSUSHITA_PULSE_LEN;\r
-                        pause_1_len         = MATSUSHITA_1_PAUSE_LEN;\r
-                        pulse_0_len         = MATSUSHITA_PULSE_LEN;\r
-                        pause_0_len         = MATSUSHITA_0_PAUSE_LEN;\r
-                        has_stop_bit        = MATSUSHITA_STOP_BIT;\r
-                        complete_data_len   = MATSUSHITA_COMPLETE_DATA_LEN;\r
-                        n_frames            = 1;\r
+                        startbit_pulse_len          = MATSUSHITA_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = MATSUSHITA_START_BIT_PAUSE_LEN;\r
+                        pulse_1_len                 = MATSUSHITA_PULSE_LEN;\r
+                        pause_1_len                 = MATSUSHITA_1_PAUSE_LEN;\r
+                        pulse_0_len                 = MATSUSHITA_PULSE_LEN;\r
+                        pause_0_len                 = MATSUSHITA_0_PAUSE_LEN;\r
+                        has_stop_bit                = MATSUSHITA_STOP_BIT;\r
+                        complete_data_len           = MATSUSHITA_COMPLETE_DATA_LEN;\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
@@ -606,15 +726,17 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
                     case IRMP_RECS80_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = RECS80_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = RECS80_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = RECS80_PULSE_LEN;\r
-                        pause_1_len         = RECS80_1_PAUSE_LEN;\r
-                        pulse_0_len         = RECS80_PULSE_LEN;\r
-                        pause_0_len         = RECS80_0_PAUSE_LEN;\r
-                        has_stop_bit        = RECS80_STOP_BIT;\r
-                        complete_data_len   = RECS80_COMPLETE_DATA_LEN;\r
-                        n_frames            = 1;\r
+                        startbit_pulse_len          = RECS80_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = RECS80_START_BIT_PAUSE_LEN;\r
+                        pulse_1_len                 = RECS80_PULSE_LEN;\r
+                        pause_1_len                 = RECS80_1_PAUSE_LEN;\r
+                        pulse_0_len                 = RECS80_PULSE_LEN;\r
+                        pause_0_len                 = RECS80_0_PAUSE_LEN;\r
+                        has_stop_bit                = RECS80_STOP_BIT;\r
+                        complete_data_len           = RECS80_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = RECS80_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -622,15 +744,17 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\r
                     case IRMP_RECS80EXT_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = RECS80EXT_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = RECS80EXT_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = RECS80EXT_PULSE_LEN;\r
-                        pause_1_len         = RECS80EXT_1_PAUSE_LEN;\r
-                        pulse_0_len         = RECS80EXT_PULSE_LEN;\r
-                        pause_0_len         = RECS80EXT_0_PAUSE_LEN;\r
-                        has_stop_bit        = RECS80EXT_STOP_BIT;\r
-                        complete_data_len   = RECS80EXT_COMPLETE_DATA_LEN;\r
-                        n_frames            = 1;\r
+                        startbit_pulse_len          = RECS80EXT_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = RECS80EXT_START_BIT_PAUSE_LEN;\r
+                        pulse_1_len                 = RECS80EXT_PULSE_LEN;\r
+                        pause_1_len                 = RECS80EXT_1_PAUSE_LEN;\r
+                        pulse_0_len                 = RECS80EXT_PULSE_LEN;\r
+                        pause_0_len                 = RECS80EXT_0_PAUSE_LEN;\r
+                        has_stop_bit                = RECS80EXT_STOP_BIT;\r
+                        complete_data_len           = RECS80EXT_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = RECS80EXT_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -638,15 +762,15 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_RC5_PROTOCOL == 1\r
                     case IRMP_RC5_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = RC5_BIT_LEN;\r
-                        startbit_pause_len  = RC5_BIT_LEN;\r
-                        pulse_1_len         = RC5_BIT_LEN;\r
-                        pause_1_len         = RC5_BIT_LEN;\r
-                        pulse_0_len         = RC5_BIT_LEN;\r
-                        pause_0_len         = RC5_BIT_LEN;\r
-                        has_stop_bit        = RC5_STOP_BIT;\r
-                        complete_data_len   = RC5_COMPLETE_DATA_LEN;\r
-                        n_frames            = 1;\r
+                        startbit_pulse_len          = RC5_BIT_LEN;\r
+                        startbit_pause_len          = RC5_BIT_LEN;\r
+                        pulse_len                   = RC5_BIT_LEN;\r
+                        pause_len                   = RC5_BIT_LEN;\r
+                        has_stop_bit                = RC5_STOP_BIT;\r
+                        complete_data_len           = RC5_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = RC5_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
                         break;\r
                     }\r
@@ -654,16 +778,17 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
                     case IRMP_DENON_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = 0x00;\r
-                        startbit_pause_len  = 0x00;\r
-                        pulse_1_len         = DENON_PULSE_LEN;\r
-                        pause_1_len         = DENON_1_PAUSE_LEN;\r
-                        pulse_0_len         = DENON_PULSE_LEN;\r
-                        pause_0_len         = DENON_0_PAUSE_LEN;\r
-                        has_stop_bit        = DENON_STOP_BIT;\r
-                        complete_data_len   = DENON_COMPLETE_DATA_LEN;\r
-                        n_frames            = 2;\r
-                        repetition_pause    = DENON_REPETITION_LEN;                     // 65 ms pause after 1st frame (15 bits)\r
+                        startbit_pulse_len          = 0x00;\r
+                        startbit_pause_len          = 0x00;\r
+                        pulse_1_len                 = DENON_PULSE_LEN;\r
+                        pause_1_len                 = DENON_1_PAUSE_LEN;\r
+                        pulse_0_len                 = DENON_PULSE_LEN;\r
+                        pause_0_len                 = DENON_0_PAUSE_LEN;\r
+                        has_stop_bit                = DENON_STOP_BIT;\r
+                        complete_data_len           = DENON_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = DENON_FRAMES;                                 // 2 frames, 2nd with inverted command\r
+                        auto_repetition_pause_len   = DENON_AUTO_REPETITION_PAUSE_LEN;              // 65 ms pause after 1st frame\r
+                        repeat_frame_pause_len      = DENON_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_32_KHZ);\r
                         break;\r
                     }\r
@@ -671,16 +796,17 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
                     case IRMP_NUBERT_PROTOCOL:\r
                     {\r
-                        startbit_pulse_len  = NUBERT_START_BIT_PULSE_LEN;\r
-                        startbit_pause_len  = NUBERT_START_BIT_PAUSE_LEN;\r
-                        pulse_1_len         = NUBERT_1_PULSE_LEN;\r
-                        pause_1_len         = NUBERT_1_PAUSE_LEN;\r
-                        pulse_0_len         = NUBERT_0_PULSE_LEN;\r
-                        pause_0_len         = NUBERT_0_PAUSE_LEN;\r
-                        has_stop_bit        = NUBERT_STOP_BIT;\r
-                        complete_data_len   = NUBERT_COMPLETE_DATA_LEN;\r
-                        n_frames            = 2;\r
-                        repetition_pause    = NUBERT_REPETITION_LEN;                     // 35 ms pause\r
+                        startbit_pulse_len          = NUBERT_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = NUBERT_START_BIT_PAUSE_LEN;\r
+                        pulse_1_len                 = NUBERT_1_PULSE_LEN;\r
+                        pause_1_len                 = NUBERT_1_PAUSE_LEN;\r
+                        pulse_0_len                 = NUBERT_0_PULSE_LEN;\r
+                        pause_0_len                 = NUBERT_0_PAUSE_LEN;\r
+                        has_stop_bit                = NUBERT_STOP_BIT;\r
+                        complete_data_len           = NUBERT_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = NUBERT_FRAMES;                                // 2 frames\r
+                        auto_repetition_pause_len   = NUBERT_AUTO_REPETITION_PAUSE_LEN;             // 35 ms pause\r
+                        repeat_frame_pause_len      = NUBERT_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
                         break;\r
                     }\r
@@ -688,19 +814,88 @@ irsnd_ISR (void)
 #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
+                        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_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN;\r
+                        last_bit_value              = 0;\r
                         irsnd_set_freq (IRSND_FREQ_455_KHZ);\r
                         break;\r
                     }\r
+#endif\r
+#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\r
+                    case IRMP_GRUNDIG_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                        startbit_pause_len          = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;\r
+                        pulse_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                        pause_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                        has_stop_bit                = GRUNDIG_OR_NOKIA_STOP_BIT;\r
+                        complete_data_len           = GRUNDIG_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = GRUNDIG_FRAMES;                               // 2 frames\r
+                        auto_repetition_pause_len   = GRUNDIG_AUTO_REPETITION_PAUSE_LEN;            // 20m sec pause\r
+                        repeat_frame_pause_len      = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;      // 117 msec pause\r
+                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
+\r
+                        break;\r
+                    }\r
+#endif\r
+#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
+                    case IRMP_NOKIA_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                        startbit_pause_len          = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;\r
+                        pulse_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                        pause_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                        has_stop_bit                = GRUNDIG_OR_NOKIA_STOP_BIT;\r
+                        complete_data_len           = NOKIA_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = NOKIA_FRAMES;                                 // 2 frames\r
+                        auto_repetition_pause_len   = NOKIA_AUTO_REPETITION_PAUSE_LEN;              // 20 msec pause\r
+                        repeat_frame_pause_len      = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;      // 117 msec pause\r
+                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
+#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1\r
+                    case IRMP_SIEMENS_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = SIEMENS_BIT_LEN;\r
+                        startbit_pause_len          = SIEMENS_BIT_LEN;\r
+                        pulse_len                   = SIEMENS_BIT_LEN;\r
+                        pause_len                   = SIEMENS_BIT_LEN;\r
+                        has_stop_bit                = SIEMENS_STOP_BIT;\r
+                        complete_data_len           = SIEMENS_COMPLETE_DATA_LEN - 1;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = SIEMENS_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
+#if IRSND_SUPPORT_FDC1_PROTOCOL == 1\r
+                    case IRMP_FDC1_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = FDC1_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = FDC1_START_BIT_PAUSE_LEN;\r
+                        complete_data_len           = FDC1_COMPLETE_DATA_LEN;\r
+                        pulse_1_len                 = FDC1_PULSE_LEN;\r
+                        pause_1_len                 = FDC1_1_PAUSE_LEN;\r
+                        pulse_0_len                 = FDC1_PULSE_LEN;\r
+                        pause_0_len                 = FDC1_0_PAUSE_LEN;\r
+                        has_stop_bit                = FDC1_STOP_BIT;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = FDC1_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
+                        break;\r
+                    }\r
 #endif\r
                     default:\r
                     {\r
@@ -714,6 +909,7 @@ irsnd_ISR (void)
         if (irsnd_busy)\r
         {\r
             new_frame = FALSE;\r
+\r
             switch (irsnd_protocol)\r
             {\r
 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\r
@@ -744,6 +940,14 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
                 case IRMP_BANG_OLUFSEN_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_NEC_PROTOCOL == 1\r
+                case IRMP_FDC1_PROTOCOL:\r
+#endif\r
+\r
+\r
+#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1  || IRSND_SUPPORT_NEC_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_RECS80_PROTOCOL == 1 || IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 || IRSND_SUPPORT_DENON_PROTOCOL == 1 || IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || IRSND_SUPPORT_FDC1_PROTOCOL == 1\r
                 {\r
                     if (pulse_counter == 0)\r
                     {\r
@@ -836,7 +1040,7 @@ irsnd_ISR (void)
                         {\r
                             pulse_len = pulse_0_len;\r
 \r
-                            if (frame_counter < n_frames)\r
+                            if (auto_repetition_counter < n_auto_repetitions)\r
                             {\r
                                 pause_len = pause_0_len;\r
                             }\r
@@ -870,12 +1074,12 @@ irsnd_ISR (void)
                         if (current_bit >= complete_data_len + has_stop_bit)\r
                         {\r
                             current_bit = 0xFF;\r
-                            frame_counter++;\r
+                            auto_repetition_counter++;\r
 \r
-                            if (frame_counter == n_frames)\r
+                            if (auto_repetition_counter == n_auto_repetitions)\r
                             {\r
                                 irsnd_busy = FALSE;\r
-                                frame_counter = 0;\r
+                                auto_repetition_counter = 0;\r
                             }\r
                             new_frame = TRUE;\r
                         }\r
@@ -885,86 +1089,149 @@ irsnd_ISR (void)
                     }\r
                     break;\r
                 }\r
+#endif\r
+\r
 #if IRSND_SUPPORT_RC5_PROTOCOL == 1\r
                 case IRMP_RC5_PROTOCOL:\r
-                {\r
-                    uint8_t first_pulse;\r
-                    uint8_t next_bit = FALSE;\r
+#endif\r
+#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1\r
+                case IRMP_SIEMENS_PROTOCOL:\r
+#endif\r
+#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\r
+                case IRMP_GRUNDIG_PROTOCOL:\r
+#endif\r
+#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
+                case IRMP_NOKIA_PROTOCOL:\r
+#endif\r
 \r
-                    if (current_bit == 0xFF)                                                    // 1 start bit\r
-                    {\r
-                        first_pulse = FALSE;\r
-                    }\r
-                    else                                                                        // send n'th bit\r
+#if IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 || IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
+                {\r
+                    if (pulse_counter == pulse_len && pause_counter == pause_len)\r
                     {\r
-                        first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? FALSE : TRUE;\r
-                    }\r
+                        current_bit++;\r
 \r
-                    if (first_pulse)\r
-                    {\r
-                        if (pulse_counter < RC5_BIT_LEN)\r
+                        if (current_bit >= complete_data_len)\r
                         {\r
-                            if (pulse_counter == 0)\r
+                            current_bit = 0xFF;\r
+\r
+#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
+                            if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)\r
                             {\r
-                                irsnd_on ();\r
+                                auto_repetition_counter++;\r
+\r
+                                if (repeat_counter > 0)\r
+                                {                                       // set 117 msec pause time\r
+                                    auto_repetition_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;\r
+                                }\r
+\r
+                                if (repeat_counter < n_repeat_frames)       // tricky: repeat n info frames per auto repetition before sending last stop frame\r
+                                {\r
+                                    n_auto_repetitions++;                   // increment number of auto repetitions\r
+                                    repeat_counter++;\r
+                                }\r
+                                else if (auto_repetition_counter == n_auto_repetitions)\r
+                                {\r
+                                    irsnd_busy = FALSE;\r
+                                    auto_repetition_counter = 0;\r
+                                }\r
                             }\r
-                            pulse_counter++;\r
-                        }\r
-                        else if (pause_counter < RC5_BIT_LEN)\r
-                        {\r
-                            if (pause_counter == 0)\r
+                            else\r
+#endif\r
                             {\r
-                                irsnd_off ();\r
+                                irsnd_busy  = FALSE;\r
                             }\r
-                            pause_counter++;\r
-                        }\r
-                        else\r
-                        {\r
-                            next_bit = TRUE;\r
+\r
+                            new_frame = TRUE;\r
+                            irsnd_off ();\r
                         }\r
+\r
+                        pulse_counter = 0;\r
+                        pause_counter = 0;\r
                     }\r
-                    else\r
+\r
+                    if (! new_frame)\r
                     {\r
-                        if (pause_counter < RC5_BIT_LEN)\r
+                        uint8_t first_pulse;\r
+\r
+#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
+                        if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)\r
                         {\r
-                            if (pause_counter == 0)\r
+                            if (current_bit == 0xFF ||                                                                  // start bit of start-frame\r
+                                (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL && current_bit == 15) ||                       // start bit of info-frame (Grundig)\r
+                                (irsnd_protocol == IRMP_NOKIA_PROTOCOL && (current_bit == 23 || current_bit == 47)))    // start bit of info- or stop-frame (Nokia)\r
+                            {\r
+                                pulse_len = startbit_pulse_len;\r
+                                pause_len = startbit_pause_len;\r
+                                first_pulse = TRUE;\r
+                            }\r
+                            else                                                                        // send n'th bit\r
                             {\r
-                                irsnd_off ();\r
+                                pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                                pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
+                                first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;\r
                             }\r
-                            pause_counter++;\r
                         }\r
-                        else if (pulse_counter < RC5_BIT_LEN)\r
+                        else // if (irsnd_protocol == IRMP_RC5_PROTOCOL || irsnd_protocol == IRMP_SIEMENS_PROTOCOL)\r
+#endif\r
                         {\r
-                            if (pulse_counter == 0)\r
+                            if (current_bit == 0xFF)                                                    // 1 start bit\r
+                            {\r
+                                first_pulse = TRUE;\r
+                            }\r
+                            else                                                                        // send n'th bit\r
+                            {\r
+                                first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;\r
+                            }\r
+\r
+                            if (irsnd_protocol == IRMP_RC5_PROTOCOL)\r
                             {\r
-                                irsnd_on ();\r
+                                first_pulse = first_pulse ? FALSE : TRUE;\r
                             }\r
-                            pulse_counter++;\r
                         }\r
-                        else\r
+\r
+                        if (first_pulse)\r
                         {\r
-                            next_bit = TRUE;\r
+                            if (pulse_counter < pulse_len)\r
+                            {\r
+                                if (pulse_counter == 0)\r
+                                {\r
+                                    irsnd_on ();\r
+                                }\r
+                                pulse_counter++;\r
+                            }\r
+                            else // if (pause_counter < pause_len)\r
+                            {\r
+                                if (pause_counter == 0)\r
+                                {\r
+                                    irsnd_off ();\r
+                                }\r
+                                pause_counter++;\r
+                            }\r
                         }\r
-                    }\r
-\r
-                    if (next_bit)\r
-                    {\r
-                        current_bit++;\r
-\r
-                        if (current_bit >= RC5_COMPLETE_DATA_LEN)\r
+                        else\r
                         {\r
-                            current_bit = 0xFF;\r
-                            irsnd_busy  = FALSE;\r
-                            new_frame = TRUE;\r
-                            irsnd_off ();\r
+                            if (pause_counter < pause_len)\r
+                            {\r
+                                if (pause_counter == 0)\r
+                                {\r
+                                    irsnd_off ();\r
+                                }\r
+                                pause_counter++;\r
+                            }\r
+                            else // if (pulse_counter < pulse_len)\r
+                            {\r
+                                if (pulse_counter == 0)\r
+                                {\r
+                                    irsnd_on ();\r
+                                }\r
+                                pulse_counter++;\r
+                            }\r
                         }\r
-\r
-                        pulse_counter = 0;\r
-                        pause_counter = 0;\r
                     }\r
                     break;\r
                 }\r
-#endif // IRSND_SUPPORT_RC5_PROTOCOL\r
+#endif // IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 || IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
+\r
                 default:\r
                 {\r
                     irsnd_busy = FALSE;\r
@@ -972,6 +1239,20 @@ irsnd_ISR (void)
                 }\r
             }\r
         }\r
+\r
+        if (! irsnd_busy)\r
+        {\r
+            if (repeat_counter < n_repeat_frames)\r
+            {\r
+                repeat_counter++;\r
+                irsnd_busy = TRUE;\r
+            }\r
+            else\r
+            {\r
+                n_repeat_frames = 0;\r
+                repeat_counter = 0;\r
+            }\r
+        }\r
     }\r
 \r
 #ifdef DEBUG\r
@@ -1001,16 +1282,14 @@ int
 main (int argc, char ** argv)\r
 {\r
     int         idx;\r
-    int         cnt;\r
     int         protocol;\r
     int         address;\r
     int         command;\r
-    int         repeat = 1;\r
     IRMP_DATA   irmp_data;\r
 \r
-    if (argc != 4)\r
+    if (argc != 4 && argc != 5)\r
     {\r
-        fprintf (stderr, "usage: %s protocol hex-address hex-command > filename\n", argv[0]);\r
+        fprintf (stderr, "usage: %s protocol hex-address hex-command [repeat] > filename\n", argv[0]);\r
         return 1;\r
     }\r
 \r
@@ -1022,16 +1301,26 @@ main (int argc, char ** argv)
         irmp_data.address = address;\r
         irmp_data.command = command;\r
 \r
+        if (argc == 5)\r
+        {\r
+            irmp_data.flags = atoi (argv[4]);\r
+        }\r
+        else\r
+        {\r
+            irmp_data.flags = 0;\r
+        }\r
+\r
         irsnd_init ();\r
 \r
-        for (cnt = 0; cnt < repeat; cnt++)\r
-        {\r
-            (void) irsnd_send_data (&irmp_data);\r
+        (void) irsnd_send_data (&irmp_data, TRUE);\r
 \r
-            for (idx = 0; idx < 3000; idx++)\r
-            {\r
-                irsnd_ISR ();\r
-            }\r
+        while (irsnd_busy)\r
+        {\r
+            irsnd_ISR ();\r
+        }\r
+        for (idx = 0; idx < 20; idx++)\r
+        {\r
+            irsnd_ISR ();\r
         }\r
 \r
         putchar ('\n');\r