]> cloudbase.mooo.com Git - irmp.git/blobdiff - irsnd.c
Version 1.6.5: handle uint8_t overflow above 15395 Hz
[irmp.git] / irsnd.c
diff --git a/irsnd.c b/irsnd.c
index 86cc94f9fe25e69db5ed258e68766ef67b016508..570b916aec696bf9abbba97de14048be06ffe78f 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.12 2010/05/26 08:34:30 fm Exp $\r
+ * $Id: irsnd.c,v 1.19 2010/06/14 15:55:11 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
@@ -56,52 +56,63 @@ typedef unsigned short    uint16_t;
 #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_FRAME_REPETITION_LEN              (uint16_t)(F_INTERRUPTS * SIRCS_FRAME_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_FRAME_REPETITION_LEN          (uint16_t)(F_INTERRUPTS * SAMSUNG32_FRAME_REPETITION_TIME + 0.5)          // use uint16_t!\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_FRAME_REPETITION_LEN              (uint16_t)(F_INTERRUPTS * DENON_FRAME_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
@@ -109,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_FRAME_REPETITION_LEN             (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_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
@@ -122,11 +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_FRAME_REPETITION_LEN            (uint16_t)(F_INTERRUPTS * GRUNDIG_FRAME_REPETITION_TIME + 0.5)      // use uint16_t!\r
-#define NOKIA_FRAME_REPETITION_LEN              (uint16_t)(F_INTERRUPTS * NOKIA_FRAME_REPETITION_TIME + 0.5)        // use uint16_t!\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
@@ -135,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 FDC_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME + 0.5)\r
+#define FDC_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME + 0.5)\r
+#define FDC_PULSE_LEN                           (uint8_t)(F_INTERRUPTS * FDC_PULSE_TIME + 0.5)\r
+#define FDC_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME + 0.5)\r
+#define FDC_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME + 0.5)\r
+#define FDC_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * FDC_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[6];\r
+static volatile uint8_t                         irsnd_repeat;\r
 static volatile uint8_t                         irsnd_is_on = FALSE;\r
 \r
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
@@ -250,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
@@ -264,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
+        while (irsnd_busy)\r
+        {\r
+            // do nothing;\r
+        }\r
+    }\r
+    else if (irsnd_busy)\r
     {\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
@@ -446,6 +480,31 @@ irsnd_send_data (IRMP_DATA * irmp_data_p)
             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_FDC_PROTOCOL == 1\r
+        case IRMP_FDC_PROTOCOL:\r
+        {\r
+            address = bitsrevervse (irmp_data_p->address, FDC_ADDRESS_LEN);\r
+            command = bitsrevervse (irmp_data_p->command, FDC_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
             break;\r
@@ -475,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_len;                                           // 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
@@ -489,32 +552,32 @@ 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_len)\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)\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)\r
+                    else if (irsnd_protocol == IRMP_NOKIA_PROTOCOL)                         // n'th nokia info frame\r
                     {\r
-                        if (frame_counter == 1)\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 // if (frame_counter == 2)\r
+                        else                                                                // nokia stop frame\r
                         {\r
                             current_bit = 0xFF;\r
                             complete_data_len   = NOKIA_COMPLETE_DATA_LEN;\r
@@ -536,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_FRAMES;                             // 3 frames\r
-                        repetition_pause_len    = SIRCS_FRAME_REPETITION_LEN;               // 25ms 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
@@ -563,16 +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;                                        // 1 frame\r
-                        repetition_pause_len    = 0;\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
@@ -580,32 +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;                                        // 1 frame\r
-                        repetition_pause_len    = 0;\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                = SAMSUNG32_FRAMES;                         // 2 frames\r
-                        repetition_pause_len    = SAMSUNG32_FRAME_REPETITION_LEN;           // 47 ms pause\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
@@ -613,16 +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;                                        // 1 frame\r
-                        repetition_pause_len    = 0;\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
@@ -630,16 +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;                                        // 1 frame\r
-                        repetition_pause_len    = 0;\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
@@ -647,16 +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;                                        // 1 frame\r
-                        repetition_pause_len    = 0;\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
@@ -664,16 +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;                                        // 1 frame\r
-                        repetition_pause_len    = 0;\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
@@ -681,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                = DENON_FRAMES;                             // 2 frames, 2nd with inverted command\r
-                        repetition_pause_len    = DENON_FRAME_REPETITION_LEN;               // 65 ms pause after 1st frame\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
@@ -698,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                = NUBERT_FRAMES;                            // 2 frames\r
-                        repetition_pause_len    = NUBERT_FRAME_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
@@ -715,17 +814,18 @@ 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;                                        // 1 frame\r
-                        repetition_pause_len    = 0;\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
@@ -733,33 +833,66 @@ irsnd_ISR (void)
 #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_1_len             = GRUNDIG_OR_NOKIA_BIT_LEN;\r
-                        pause_1_len             = GRUNDIG_OR_NOKIA_BIT_LEN;\r
-                        pulse_0_len             = GRUNDIG_OR_NOKIA_BIT_LEN;\r
-                        pause_0_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_frames                = GRUNDIG_FRAMES;                   // 2 frames\r
-                        repetition_pause_len    = GRUNDIG_FRAME_REPETITION_LEN;     // 20msec pause\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_1_len             = GRUNDIG_OR_NOKIA_BIT_LEN;\r
-                        pause_1_len             = GRUNDIG_OR_NOKIA_BIT_LEN;\r
-                        pulse_0_len             = GRUNDIG_OR_NOKIA_BIT_LEN;\r
-                        pause_0_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_frames                = NOKIA_FRAMES;                   // 2 frames\r
-                        repetition_pause_len    = NOKIA_FRAME_REPETITION_LEN;     // 20msec pause\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_FDC_PROTOCOL == 1\r
+                    case IRMP_FDC_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = FDC_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = FDC_START_BIT_PAUSE_LEN;\r
+                        complete_data_len           = FDC_COMPLETE_DATA_LEN;\r
+                        pulse_1_len                 = FDC_PULSE_LEN;\r
+                        pause_1_len                 = FDC_1_PAUSE_LEN;\r
+                        pulse_0_len                 = FDC_PULSE_LEN;\r
+                        pause_0_len                 = FDC_0_PAUSE_LEN;\r
+                        has_stop_bit                = FDC_STOP_BIT;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = FDC_FRAME_REPEAT_PAUSE_LEN;\r
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
@@ -776,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
@@ -806,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_FDC_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_FDC_PROTOCOL == 1\r
                 {\r
                     if (pulse_counter == 0)\r
                     {\r
@@ -898,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
@@ -932,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
@@ -947,76 +1089,58 @@ 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
-                            {\r
-                                irsnd_on ();\r
-                            }\r
-                            pulse_counter++;\r
-                        }\r
-                        else if (pause_counter < RC5_BIT_LEN)\r
-                        {\r
-                            if (pause_counter == 0)\r
-                            {\r
-                                irsnd_off ();\r
-                            }\r
-                            pause_counter++;\r
-                        }\r
-                        else\r
-                        {\r
-                            next_bit = TRUE;\r
-                        }\r
-                    }\r
-                    else\r
-                    {\r
-                        if (pause_counter < RC5_BIT_LEN)\r
-                        {\r
-                            if (pause_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_off ();\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
-                            pause_counter++;\r
-                        }\r
-                        else if (pulse_counter < RC5_BIT_LEN)\r
-                        {\r
-                            if (pulse_counter == 0)\r
+                            else\r
+#endif\r
                             {\r
-                                irsnd_on ();\r
+                                irsnd_busy  = FALSE;\r
                             }\r
-                            pulse_counter++;\r
-                        }\r
-                        else\r
-                        {\r
-                            next_bit = TRUE;\r
-                        }\r
-                    }\r
 \r
-                    if (next_bit)\r
-                    {\r
-                        current_bit++;\r
-\r
-                        if (current_bit >= RC5_COMPLETE_DATA_LEN)\r
-                        {\r
-                            current_bit = 0xFF;\r
-                            irsnd_busy  = FALSE;\r
                             new_frame = TRUE;\r
                             irsnd_off ();\r
                         }\r
@@ -1024,58 +1148,50 @@ irsnd_ISR (void)
                         pulse_counter = 0;\r
                         pause_counter = 0;\r
                     }\r
-                    break;\r
-                }\r
-#endif // IRSND_SUPPORT_RC5_PROTOCOL\r
-\r
-#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
-                case IRMP_GRUNDIG_PROTOCOL:\r
-                case IRMP_NOKIA_PROTOCOL:\r
-                {\r
-                    uint8_t next_bit = FALSE;\r
 \r
-                    if (current_bit == 0xFF ||                                                                  // start bit of 1st frame\r
-                        (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL && current_bit == 15) ||                       // start bit of 2nd frame (Grundig)\r
-                        (irsnd_protocol == IRMP_NOKIA_PROTOCOL && (current_bit == 23 || current_bit == 47)))    // start bit of 2nd/3rd frame (Nokia)\r
+                    if (! new_frame)\r
                     {\r
-                        if (pulse_counter == 0)\r
-                        {\r
-                            pulse_len = startbit_pulse_len;\r
-                            pause_len = startbit_pause_len;\r
-                        }\r
+                        uint8_t first_pulse;\r
 \r
-                        if (pulse_counter < pulse_len)\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 (pulse_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
-                                irsnd_on ();\r
+                                pulse_len = startbit_pulse_len;\r
+                                pause_len = startbit_pause_len;\r
+                                first_pulse = TRUE;\r
                             }\r
-                            pulse_counter++;\r
-                        }\r
-                        else if (pause_counter < pause_len)\r
-                        {\r
-                            if (pause_counter == 0)\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\r
+                        else // if (irsnd_protocol == IRMP_RC5_PROTOCOL || irsnd_protocol == IRMP_SIEMENS_PROTOCOL)\r
+#endif\r
                         {\r
-                            current_bit++;\r
-                            pulse_counter = 0;\r
-                            pause_counter = 0;\r
-                        }\r
-                    }\r
-                    else                                                                        // send n'th bit\r
-                    {\r
-                        uint8_t first_pulse;\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
-                        first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;\r
+                            if (irsnd_protocol == IRMP_RC5_PROTOCOL)\r
+                            {\r
+                                first_pulse = first_pulse ? FALSE : TRUE;\r
+                            }\r
+                        }\r
 \r
                         if (first_pulse)\r
                         {\r
-                            if (pulse_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
+                            if (pulse_counter < pulse_len)\r
                             {\r
                                 if (pulse_counter == 0)\r
                                 {\r
@@ -1083,7 +1199,7 @@ irsnd_ISR (void)
                                 }\r
                                 pulse_counter++;\r
                             }\r
-                            else if (pause_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
+                            else // if (pause_counter < pause_len)\r
                             {\r
                                 if (pause_counter == 0)\r
                                 {\r
@@ -1091,14 +1207,10 @@ irsnd_ISR (void)
                                 }\r
                                 pause_counter++;\r
                             }\r
-                            else\r
-                            {\r
-                                next_bit = TRUE;\r
-                            }\r
                         }\r
                         else\r
                         {\r
-                            if (pause_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
+                            if (pause_counter < pause_len)\r
                             {\r
                                 if (pause_counter == 0)\r
                                 {\r
@@ -1106,7 +1218,7 @@ irsnd_ISR (void)
                                 }\r
                                 pause_counter++;\r
                             }\r
-                            else if (pulse_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
+                            else // if (pulse_counter < pulse_len)\r
                             {\r
                                 if (pulse_counter == 0)\r
                                 {\r
@@ -1114,38 +1226,11 @@ irsnd_ISR (void)
                                 }\r
                                 pulse_counter++;\r
                             }\r
-                            else\r
-                            {\r
-                                next_bit = TRUE;\r
-                            }\r
-                        }\r
-\r
-                        if (next_bit)\r
-                        {\r
-                            current_bit++;\r
-\r
-                            if (current_bit >= complete_data_len)\r
-                            {\r
-                                current_bit = 0xFF;\r
-                                frame_counter++;\r
-\r
-                                if (frame_counter == n_frames)\r
-                                {\r
-                                    irsnd_busy = FALSE;\r
-                                    frame_counter = 0;\r
-                                }\r
-\r
-                                new_frame = TRUE;\r
-                                irsnd_off ();\r
-                            }\r
-\r
-                            pulse_counter = 0;\r
-                            pause_counter = 0;\r
                         }\r
                     }\r
                     break;\r
                 }\r
-#endif // IRSND_SUPPORT_GRUNDIG_PROTOCOL || IRSND_SUPPORT_NOKIA_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
@@ -1154,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
@@ -1183,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
@@ -1204,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