Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
838 - 1
/*---------------------------------------------------------------------------------------------------------------------------------------------------
2
 * @file irsnd.c
3
 *
4
 * Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de
5
 *
6
 * $Id: irsnd.c,v 1.26 2010/11/09 21:14:31 fm Exp $
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *---------------------------------------------------------------------------------------------------------------------------------------------------
13
 */
14
 
15
#ifdef unix                                                                 // test/debug on linux/unix
16
#include <stdio.h>
17
#include <unistd.h>
18
#include <stdlib.h>
19
#include <string.h>
20
#include <inttypes.h>
21
 
22
#define DEBUG
23
#define F_CPU 8000000L
24
 
25
#else // not unix:
26
 
27
#ifdef WIN32                                                                 // test/debug on windows
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
 
32
#define F_CPU 8000000L
33
typedef unsigned char    uint8_t;
34
typedef unsigned short    uint16_t;
35
#define DEBUG
36
 
37
#else
38
 
39
#ifdef CODEVISION
40
  #define COM2A0 6
41
  #define WGM21  1
42
  #define CS20   0
43
#else
44
  #include <inttypes.h>
45
  #include <avr/io.h>
46
  #include <util/delay.h>
47
  #include <avr/pgmspace.h>
48
#endif // CODEVISION
49
 
50
#endif // WIN32
51
#endif // unix
52
 
53
#include "irmp.h"
54
#include "irsndconfig.h"
55
#include "irsnd.h"
56
 
57
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
58
typedef uint16_t    IRSND_PAUSE_LEN;
59
#else
60
typedef uint8_t     IRSND_PAUSE_LEN;
61
#endif
62
 
63
#define SIRCS_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME + 0.5)
64
#define SIRCS_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME + 0.5)
65
#define SIRCS_1_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME + 0.5)
66
#define SIRCS_0_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME + 0.5)
67
#define SIRCS_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME + 0.5)
68
#define SIRCS_AUTO_REPETITION_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * SIRCS_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!
69
#define SIRCS_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * SIRCS_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!
70
 
71
#define NEC_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)
72
#define NEC_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)
73
#define NEC_REPEAT_START_BIT_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME + 0.5)
74
#define NEC_PULSE_LEN                           (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)
75
#define NEC_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)
76
#define NEC_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)
77
#define NEC_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!
78
 
79
#define SAMSUNG_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)
80
#define SAMSUNG_START_BIT_PAUSE_LEN             (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)
81
#define SAMSUNG_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)
82
#define SAMSUNG_1_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)
83
#define SAMSUNG_0_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)
84
#define SAMSUNG_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * SAMSUNG_FRAME_REPEAT_PAUSE_TIME + 0.5)            // use uint16_t!
85
 
86
#define SAMSUNG32_AUTO_REPETITION_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * SAMSUNG32_AUTO_REPETITION_PAUSE_TIME + 0.5)       // use uint16_t!
87
#define SAMSUNG32_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * SAMSUNG32_FRAME_REPEAT_PAUSE_TIME + 0.5)          // use uint16_t!
88
 
89
#define MATSUSHITA_START_BIT_PULSE_LEN          (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)
90
#define MATSUSHITA_START_BIT_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)
91
#define MATSUSHITA_PULSE_LEN                    (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)
92
#define MATSUSHITA_1_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)
93
#define MATSUSHITA_0_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)
94
#define MATSUSHITA_FRAME_REPEAT_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * MATSUSHITA_FRAME_REPEAT_PAUSE_TIME + 0.5)         // use uint16_t!
95
 
96
#define KASEIKYO_START_BIT_PULSE_LEN            (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME + 0.5)
97
#define KASEIKYO_START_BIT_PAUSE_LEN            (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME + 0.5)
98
#define KASEIKYO_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME + 0.5)
99
#define KASEIKYO_1_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME + 0.5)
100
#define KASEIKYO_0_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME + 0.5)
101
#define KASEIKYO_AUTO_REPETITION_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * KASEIKYO_AUTO_REPETITION_PAUSE_TIME + 0.5)        // use uint16_t!
102
#define KASEIKYO_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * KASEIKYO_FRAME_REPEAT_PAUSE_TIME + 0.5)           // use uint16_t!
103
 
104
#define RECS80_START_BIT_PULSE_LEN              (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)
105
#define RECS80_START_BIT_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)
106
#define RECS80_PULSE_LEN                        (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)
107
#define RECS80_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)
108
#define RECS80_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)
109
#define RECS80_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * RECS80_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!
110
 
111
#define RC5_START_BIT_LEN                       (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
112
#define RC5_BIT_LEN                             (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
113
#define RC5_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * RC5_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!
114
 
115
#define RC6_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)
116
#define RC6_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)
117
#define RC6_TOGGLE_BIT_LEN                      (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME + 0.5)
118
#define RC6_BIT_LEN                             (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)
119
#define RC6_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * RC6_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!
120
 
121
#define DENON_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)
122
#define DENON_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)
123
#define DENON_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)
124
#define DENON_AUTO_REPETITION_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * DENON_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!
125
#define DENON_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * DENON_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!
126
 
127
#define RECS80EXT_START_BIT_PULSE_LEN           (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)
128
#define RECS80EXT_START_BIT_PAUSE_LEN           (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)
129
#define RECS80EXT_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)
130
#define RECS80EXT_1_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)
131
#define RECS80EXT_0_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)
132
#define RECS80EXT_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * RECS80EXT_FRAME_REPEAT_PAUSE_TIME + 0.5)          // use uint16_t!
133
 
134
#define NUBERT_START_BIT_PULSE_LEN              (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)
135
#define NUBERT_START_BIT_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)
136
#define NUBERT_1_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)
137
#define NUBERT_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)
138
#define NUBERT_0_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)
139
#define NUBERT_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)
140
#define NUBERT_AUTO_REPETITION_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * NUBERT_AUTO_REPETITION_PAUSE_TIME + 0.5)          // use uint16_t!
141
#define NUBERT_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!
142
 
143
#define BANG_OLUFSEN_START_BIT1_PULSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)
144
#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)
145
#define BANG_OLUFSEN_START_BIT2_PULSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)
146
#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)
147
#define BANG_OLUFSEN_START_BIT3_PULSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)
148
#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)
149
#define BANG_OLUFSEN_PULSE_LEN                  (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)
150
#define BANG_OLUFSEN_1_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)
151
#define BANG_OLUFSEN_0_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)
152
#define BANG_OLUFSEN_R_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)
153
#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN      (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)
154
#define BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * BANG_OLUFSEN_FRAME_REPEAT_PAUSE_TIME + 0.5)       // use uint16_t!
155
 
156
#define GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME + 0.5)
157
#define GRUNDIG_OR_NOKIA_BIT_LEN                (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME + 0.5)
158
#define GRUNDIG_AUTO_REPETITION_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * GRUNDIG_AUTO_REPETITION_PAUSE_TIME + 0.5)         // use uint16_t!
159
#define NOKIA_AUTO_REPETITION_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * NOKIA_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!
160
#define GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_TIME + 0.5)   // use uint16_t!
161
 
162
#define SIEMENS_START_BIT_LEN                   (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)
163
#define SIEMENS_BIT_LEN                         (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)
164
#define SIEMENS_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * SIEMENS_FRAME_REPEAT_PAUSE_TIME + 0.5)            // use uint16_t!
165
 
166
#define IRSND_FREQ_32_KHZ                       (uint8_t) ((F_CPU / 32000 / 2) - 1)
167
#define IRSND_FREQ_36_KHZ                       (uint8_t) ((F_CPU / 36000 / 2) - 1)
168
#define IRSND_FREQ_38_KHZ                       (uint8_t) ((F_CPU / 38000 / 2) - 1)
169
#define IRSND_FREQ_40_KHZ                       (uint8_t) ((F_CPU / 40000 / 2) - 1)
170
#define IRSND_FREQ_56_KHZ                       (uint8_t) ((F_CPU / 56000 / 2) - 1)
171
#define IRSND_FREQ_455_KHZ                      (uint8_t) ((F_CPU / 455000 / 2) - 1)
172
 
173
#define FDC_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME + 0.5)
174
#define FDC_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME + 0.5)
175
#define FDC_PULSE_LEN                           (uint8_t)(F_INTERRUPTS * FDC_PULSE_TIME + 0.5)
176
#define FDC_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME + 0.5)
177
#define FDC_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME + 0.5)
178
#define FDC_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * FDC_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!
179
 
180
#define RCCAR_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME + 0.5)
181
#define RCCAR_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME + 0.5)
182
#define RCCAR_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME + 0.5)
183
#define RCCAR_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME + 0.5)
184
#define RCCAR_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME + 0.5)
185
#define RCCAR_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * RCCAR_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!
186
 
187
#define JVC_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME + 0.5)
188
#define JVC_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PAUSE_TIME + 0.5)
189
#define JVC_REPEAT_START_BIT_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * JVC_REPEAT_START_BIT_PAUSE_TIME + 0.5)
190
#define JVC_PULSE_LEN                           (uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME + 0.5)
191
#define JVC_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME + 0.5)
192
#define JVC_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME + 0.5)
193
#define JVC_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!
194
 
195
#define NIKON_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME + 0.5)
196
#define NIKON_START_BIT_PAUSE_LEN               (uint16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME + 0.5)
197
#define NIKON_REPEAT_START_BIT_PAUSE_LEN        (uint8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME + 0.5)
198
#define NIKON_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * NIKON_PULSE_TIME + 0.5)
199
#define NIKON_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME + 0.5)
200
#define NIKON_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME + 0.5)
201
#define NIKON_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * NIKON_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!
202
 
203
static volatile uint8_t                         irsnd_busy;
204
static volatile uint8_t                         irsnd_protocol;
205
static volatile uint8_t                         irsnd_buffer[6];
206
static volatile uint8_t                         irsnd_repeat;
207
static volatile uint8_t                         irsnd_is_on = FALSE;
208
 
209
/*---------------------------------------------------------------------------------------------------------------------------------------------------
210
 *  Switch PWM on
211
 *  @details  Switches PWM on with a narrow spike on all 3 channels -> leds glowing
212
 *---------------------------------------------------------------------------------------------------------------------------------------------------
213
 */
214
static void
215
irsnd_on (void)
216
{
217
    if (! irsnd_is_on)
218
    {
219
#ifndef DEBUG
220
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
221
        TCCR2 |= (1<<COM20)|(1<<WGM21);                 // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
222
#else
223
        TCCR2A |= (1<<COM2A0)|(1<<WGM21);               // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
224
#endif  // __AVR...
225
#endif // DEBUG
226
        irsnd_is_on = TRUE;
227
    }
228
}
229
 
230
/*---------------------------------------------------------------------------------------------------------------------------------------------------
231
 *  Switch PWM off
232
 *  @details  Switches PWM off
233
 *---------------------------------------------------------------------------------------------------------------------------------------------------
234
 */
235
static void
236
irsnd_off (void)
237
{
238
    if (irsnd_is_on)
239
    {
240
#ifndef DEBUG
241
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
242
        TCCR2 &= ~(1<<COM20);                                                           // normal port operation, OC2A disconnected.
243
#else
244
        TCCR2A &= ~(1<<COM2A0);                                                         // normal port operation, OC2A disconnected.
245
#endif  // __AVR...
246
        IRSND_PORT  &= ~(1<<IRSND_BIT);                                                 // set IRSND_BIT to low
247
#endif // DEBUG
248
        irsnd_is_on = FALSE;
249
    }
250
}
251
 
252
/*---------------------------------------------------------------------------------------------------------------------------------------------------
253
 *  Set PWM frequency
254
 *  @details  sets pwm frequency
255
 *---------------------------------------------------------------------------------------------------------------------------------------------------
256
 */
257
static void
258
irsnd_set_freq (uint8_t freq)
259
{
260
#ifndef DEBUG
261
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
262
    OCR2 = freq;
263
#else
264
    OCR2A = freq;
265
#endif  // __AVR...
266
#endif // DEBUG
267
}
268
 
269
/*---------------------------------------------------------------------------------------------------------------------------------------------------
270
 *  Initialize the PWM
271
 *  @details  Configures 0CR0A, 0CR0B and 0CR2B as PWM channels
272
 *---------------------------------------------------------------------------------------------------------------------------------------------------
273
 */
274
void
275
irsnd_init (void)
276
{
277
#ifndef DEBUG
278
    IRSND_PORT &= ~(1<<IRSND_BIT);                                                  // set IRSND_BIT to low
279
    IRSND_DDR |= (1<<IRSND_BIT);                                                    // set IRSND_BIT to output
280
 
281
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
282
    TCCR2 = (1<<WGM21);                                                             // CTC mode
283
    TCCR2 |= (1<<CS20);                                                             // 0x01, start Timer 2, no prescaling
284
#else
285
    TCCR2A = (1<<WGM21);                                                            // CTC mode
286
    TCCR2B |= (1<<CS20);                                                            // 0x01, start Timer 2, no prescaling
287
#endif  // __AVR...    
288
 
289
    irsnd_set_freq (IRSND_FREQ_36_KHZ);                                             // default frequency
290
#endif // DEBUG
291
}
292
 
293
uint8_t
294
irsnd_is_busy (void)
295
{
296
    return irsnd_busy;
297
}
298
 
299
static uint16_t
300
bitsrevervse (uint16_t x, uint8_t len)
301
{
302
    uint16_t    xx = 0;
303
 
304
    while(len)
305
    {
306
        xx <<= 1;
307
        if (x & 1)
308
        {
309
            xx |= 1;
310
        }
311
        x >>= 1;
312
        len--;
313
    }
314
    return xx;
315
}
316
 
317
 
318
uint8_t
319
irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
320
{
321
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
322
    static uint8_t  toggle_bit_recs80;
323
#endif
324
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
325
    static uint8_t  toggle_bit_recs80ext;
326
#endif
327
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
328
    static uint8_t  toggle_bit_rc5;
329
#endif
330
    uint16_t        address;
331
    uint16_t        command;
332
 
333
    if (do_wait)
334
    {
335
        while (irsnd_busy)
336
        {
337
            // do nothing;
338
        }
339
    }
340
    else if (irsnd_busy)
341
    {
342
        return (FALSE);
343
    }
344
 
345
    irsnd_protocol  = irmp_data_p->protocol;
346
    irsnd_repeat    = irmp_data_p->flags;
347
 
348
    switch (irsnd_protocol)
349
    {
350
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
351
        case IRMP_SIRCS_PROTOCOL:
352
        {
353
            command = bitsrevervse (irmp_data_p->command, SIRCS_MINIMUM_DATA_LEN);
354
 
355
            irsnd_buffer[0] = (command & 0x0FF0) >> 4;                                                         // CCCCCCCC
356
            irsnd_buffer[1] = (command & 0x000F) << 4;                                                         // CCCC0000
357
            irsnd_busy      = TRUE;
358
            break;
359
        }
360
#endif
361
#if IRSND_SUPPORT_NEC_PROTOCOL == 1
362
        case IRMP_APPLE_PROTOCOL:
363
        {
364
            command = irmp_data_p->command | (irmp_data_p->address << 8);                               // store address as ID in upper byte of command
365
            address = 0x87EE;                                                                           // set fixed NEC-lookalike address (customer ID of apple)
366
 
367
            address = bitsrevervse (address, NEC_ADDRESS_LEN);
368
            command = bitsrevervse (command, NEC_COMMAND_LEN);
369
 
370
            irsnd_protocol = IRMP_NEC_PROTOCOL;                                                         // APPLE protocol is NEC with id instead of inverted command
371
 
372
            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                  // AAAAAAAA
373
            irsnd_buffer[1] = (address & 0x00FF);                                                       // AAAAAAAA
374
            irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                  // CCCCCCCC
375
            irsnd_buffer[3] = (command & 0x00FF);                                                       // CCCCCCCC
376
 
377
            irsnd_busy      = TRUE;
378
            break;
379
        }
380
        case IRMP_NEC_PROTOCOL:
381
        {
382
            address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);
383
            command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);
384
 
385
            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA
386
            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA
387
            irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC
388
 
389
            irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with fix bitmask instead of inverted command
390
            irsnd_buffer[3] = 0x8B;                                                                         // 10001011
391
            {
392
                irsnd_buffer[3] = ~((command & 0xFF00) >> 8);                                                   // cccccccc
393
            }
394
 
395
            irsnd_busy      = TRUE;
396
            break;
397
        }
398
#endif
399
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
400
        case IRMP_SAMSUNG_PROTOCOL:
401
        {
402
            address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
403
            command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN);
404
 
405
            irsnd_buffer[0] =  (address & 0xFF00) >> 8;                                                         // AAAAAAAA
406
            irsnd_buffer[1] =  (address & 0x00FF);                                                              // AAAAAAAA
407
            irsnd_buffer[2] =  (command & 0x00F0) | ((command & 0xF000) >> 12);                                 // IIIICCCC
408
            irsnd_buffer[3] = ((command & 0x0F00) >> 4) | ((~(command & 0xF000) >> 12) & 0x0F);                 // CCCCcccc
409
            irsnd_buffer[4] = (~(command & 0x0F00) >> 4) & 0xF0;                                                // cccc0000
410
            irsnd_busy      = TRUE;
411
            break;
412
        }
413
        case IRMP_SAMSUNG32_PROTOCOL:
414
        {
415
            address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
416
            command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN);
417
 
418
            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA
419
            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA
420
            irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC
421
            irsnd_buffer[3] = (command & 0x00FF);                                                               // CCCCCCCC
422
            irsnd_busy      = TRUE;
423
            break;
424
        }
425
#endif
426
#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
427
        case IRMP_MATSUSHITA_PROTOCOL:
428
        {
429
            address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN);
430
            command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN);
431
 
432
            irsnd_buffer[0] = (command & 0x0FF0) >> 4;                                                          // CCCCCCCC
433
            irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8);                            // CCCCAAAA
434
            irsnd_buffer[2] = (address & 0x00FF);                                                               // AAAAAAAA
435
            irsnd_busy      = TRUE;
436
            break;
437
        }
438
#endif
439
#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
440
        case IRMP_KASEIKYO_PROTOCOL:
441
        {
442
            uint8_t xor;
443
 
444
            address = bitsrevervse (irmp_data_p->address, KASEIKYO_ADDRESS_LEN);
445
            command = bitsrevervse (irmp_data_p->command, KASEIKYO_COMMAND_LEN + 4);
446
 
447
            xor = ((address & 0x000F) ^ ((address & 0x00F0) >> 4) ^ ((address & 0x0F00) >> 8) ^ ((address & 0xF000) >> 12)) & 0x0F;
448
 
449
            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA
450
            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA
451
            irsnd_buffer[2] = xor << 4 | (command & 0x000F);                                                    // XXXXCCCC
452
            irsnd_buffer[3] = 0 | (command & 0xF000) >> 12;                                                     // 0000CCCC
453
            irsnd_buffer[4] = (command & 0x0FF0) >> 4;                                                          // CCCCCCCC
454
 
455
            xor = irsnd_buffer[2] ^ irsnd_buffer[3] ^ irsnd_buffer[4];
456
 
457
            irsnd_buffer[5] = xor;
458
            irsnd_busy      = TRUE;
459
            break;
460
        }
461
#endif
462
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
463
        case IRMP_RECS80_PROTOCOL:
464
        {
465
            toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40;
466
 
467
            irsnd_buffer[0] = 0x80 | toggle_bit_recs80 | ((irmp_data_p->address & 0x0007) << 3) |
468
                              ((irmp_data_p->command & 0x0038) >> 3);                                           // STAAACCC
469
            irsnd_buffer[1] = (irmp_data_p->command & 0x07) << 5;                                               // CCC00000
470
            irsnd_busy      = TRUE;
471
            break;
472
        }
473
#endif
474
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
475
        case IRMP_RECS80EXT_PROTOCOL:
476
        {
477
            toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40;
478
 
479
            irsnd_buffer[0] = 0x80 | toggle_bit_recs80ext | ((irmp_data_p->address & 0x000F) << 2) |
480
                                ((irmp_data_p->command & 0x0030) >> 4);                                         // STAAAACC
481
            irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4;                                               // CCCC0000
482
            irsnd_busy      = TRUE;
483
            break;
484
        }
485
#endif
486
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
487
        case IRMP_RC5_PROTOCOL:
488
        {
489
            toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40;
490
 
491
            irsnd_buffer[0] = ((irmp_data_p->command & 0x40) ? 0x00 : 0x80) | toggle_bit_rc5 |
492
                                ((irmp_data_p->address & 0x001F) << 1) | ((irmp_data_p->command & 0x20) >> 5);  // CTAAAAAC
493
            irsnd_buffer[1] = (irmp_data_p->command & 0x1F) << 3;                                               // CCCCC000
494
            irsnd_busy      = TRUE;
495
            break;
496
        }
497
#endif
498
#if IRSND_SUPPORT_DENON_PROTOCOL == 1
499
        case IRMP_DENON_PROTOCOL:
500
        {
501
            irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7);    // AAAAACCC (1st frame)
502
            irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1;                                               // CCCCCCC
503
            irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC (2nd frame)
504
            irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1;                                            // CCCCCCC
505
            irsnd_busy      = TRUE;
506
            break;
507
        }
508
#endif
509
#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
510
        case IRMP_NUBERT_PROTOCOL:
511
        {
512
            irsnd_buffer[0] = irmp_data_p->command >> 2;                                                        // CCCCCCCC
513
            irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6;                                             // CC000000
514
            irsnd_busy      = TRUE;
515
            break;
516
        }
517
#endif
518
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
519
        case IRMP_BANG_OLUFSEN_PROTOCOL:
520
        {
521
            irsnd_buffer[0] = irmp_data_p->command >> 11;                                                       // SXSCCCCC
522
            irsnd_buffer[1] = irmp_data_p->command >> 3;                                                        // CCCCCCCC
523
            irsnd_buffer[2] = (irmp_data_p->command & 0x0007) << 5;                                             // CCC00000
524
            irsnd_busy      = TRUE;
525
            break;
526
        }
527
#endif
528
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
529
        case IRMP_GRUNDIG_PROTOCOL:
530
        {
531
            command = bitsrevervse (irmp_data_p->command, GRUNDIG_COMMAND_LEN);
532
 
533
            irsnd_buffer[0] = 0xFF;                                                                             // S1111111 (1st frame)
534
            irsnd_buffer[1] = 0xC0;                                                                             // 11
535
            irsnd_buffer[2] = 0x80 | (command >> 2);                                                            // SCCCCCCC (2nd frame)
536
            irsnd_buffer[3] = (command << 6) & 0xC0;                                                            // CC
537
 
538
            irsnd_busy      = TRUE;
539
            break;
540
        }
541
#endif
542
#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
543
        case IRMP_NOKIA_PROTOCOL:
544
        {
545
            address = bitsrevervse (irmp_data_p->address, NOKIA_ADDRESS_LEN);
546
            command = bitsrevervse (irmp_data_p->command, NOKIA_COMMAND_LEN);
547
 
548
            irsnd_buffer[0] = 0xBF;                                                                             // S0111111 (1st + 3rd frame)
549
            irsnd_buffer[1] = 0xFF;                                                                             // 11111111
550
            irsnd_buffer[2] = 0x80;                                                                             // 1
551
            irsnd_buffer[3] = 0x80 | command >> 1;                                                              // SCCCCCCC (2nd frame)
552
            irsnd_buffer[4] = (command << 7) | (address >> 1);                                                  // CAAAAAAA
553
            irsnd_buffer[5] = (address << 7);                                                                   // A
554
 
555
            irsnd_busy      = TRUE;
556
            break;
557
        }
558
#endif
559
#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
560
        case IRMP_SIEMENS_PROTOCOL:
561
        {
562
            irsnd_buffer[0] = ((irmp_data_p->address & 0x0FFF) >> 5);                                           // SAAAAAAA
563
            irsnd_buffer[1] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x7F) >> 5);      // AAAAA0CC
564
            irsnd_buffer[2] = (irmp_data_p->command << 3) | ((~irmp_data_p->command & 0x01) << 2);              // CCCCCc
565
 
566
            irsnd_busy      = TRUE;
567
            break;
568
        }
569
#endif
570
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
571
        case IRMP_FDC_PROTOCOL:
572
        {
573
            address = bitsrevervse (irmp_data_p->address, FDC_ADDRESS_LEN);
574
            command = bitsrevervse (irmp_data_p->command, FDC_COMMAND_LEN);
575
 
576
            irsnd_buffer[0] = (address & 0xFF);                                                                 // AAAAAAAA
577
            irsnd_buffer[1] = 0;                                                                                // 00000000
578
            irsnd_buffer[2] = 0;                                                                                // 0000RRRR
579
            irsnd_buffer[3] = (command & 0xFF);                                                                 // CCCCCCCC
580
            irsnd_buffer[4] = ~(command & 0xFF);                                                                // cccccccc
581
            irsnd_busy      = TRUE;
582
            break;
583
        }
584
#endif
585
#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
586
        case IRMP_RCCAR_PROTOCOL:
587
        {
588
            address = bitsrevervse (irmp_data_p->address, 2);                                                   //                            A0 A1
589
            command = bitsrevervse (irmp_data_p->command, RCCAR_COMMAND_LEN - 2);                               // D0 D1 D2 D3 D4 D5 D6 D7 C0 C1 V
590
 
591
            irsnd_buffer[0] = ((command & 0x06) << 5) | ((address & 0x0003) << 4) | ((command & 0x0780) >> 7);  //          C0 C1 A0 A1 D0 D1 D2 D3
592
            irsnd_buffer[1] = ((command & 0x78) << 1) | ((command & 0x0001) << 3);                              //          D4 D5 D6 D7 V  0  0  0
593
 
594
            irsnd_busy      = TRUE;
595
            break;
596
        }
597
#endif
598
#if IRSND_SUPPORT_JVC_PROTOCOL == 1
599
        case IRMP_JVC_PROTOCOL:
600
        {
601
            address = bitsrevervse (irmp_data_p->address, JVC_ADDRESS_LEN);
602
            command = bitsrevervse (irmp_data_p->command, JVC_COMMAND_LEN);
603
 
604
            irsnd_buffer[0] = ((address & 0x000F) << 4) | (command & 0x0F00) >> 8;                              // AAAACCCC
605
            irsnd_buffer[1] = (command & 0x00FF);                                                               // CCCCCCCC
606
 
607
            irsnd_busy      = TRUE;
608
            break;
609
        }
610
#endif
611
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
612
        case IRMP_NIKON_PROTOCOL:
613
        {
614
            irsnd_buffer[0] = (irmp_data_p->command & 0x0003) << 6;                                             // CC
615
            irsnd_busy      = TRUE;
616
            break;
617
        }
618
#endif
619
        default:
620
        {
621
            break;
622
        }
623
    }
624
 
625
    return irsnd_busy;
626
}
627
 
628
/*---------------------------------------------------------------------------------------------------------------------------------------------------
629
 *  ISR routine
630
 *  @details  ISR routine, called 10000 times per second
631
 *---------------------------------------------------------------------------------------------------------------------------------------------------
632
 */
633
uint8_t
634
irsnd_ISR (void)
635
{
636
    static uint8_t  current_bit = 0xFF;
637
    static uint8_t  pulse_counter;
638
    static IRSND_PAUSE_LEN  pause_counter;
639
    static uint8_t  startbit_pulse_len;
640
    static IRSND_PAUSE_LEN  startbit_pause_len;
641
    static uint8_t  pulse_1_len;
642
    static uint8_t  pause_1_len;
643
    static uint8_t  pulse_0_len;
644
    static uint8_t  pause_0_len;
645
    static uint8_t  has_stop_bit;
646
    static uint8_t  new_frame = TRUE;
647
    static uint8_t  complete_data_len;
648
    static uint8_t  n_auto_repetitions;                                             // number of auto_repetitions
649
    static uint8_t  auto_repetition_counter;                                        // auto_repetition counter
650
    static uint16_t auto_repetition_pause_len;                                      // pause before auto_repetition, uint16_t!
651
    static uint16_t auto_repetition_pause_counter;                                  // pause before auto_repetition, uint16_t!
652
    static uint8_t  n_repeat_frames;                                                // number of repeat frames
653
    static uint8_t  repeat_counter;                                                 // repeat counter
654
    static uint16_t repeat_frame_pause_len;                                         // pause before repeat, uint16_t!
655
    static uint16_t packet_repeat_pause_counter;                                    // pause before repeat, uint16_t!
656
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
657
    static uint8_t  last_bit_value;
658
#endif
659
    static uint8_t  pulse_len = 0xFF;
660
    static IRSND_PAUSE_LEN  pause_len = 0xFF;
661
 
662
    if (irsnd_busy)
663
    {
664
        if (current_bit == 0xFF && new_frame)                                       // start of transmission...
665
        {
666
            if (auto_repetition_counter > 0)
667
            {
668
                auto_repetition_pause_counter++;
669
 
670
                if (auto_repetition_pause_counter >= auto_repetition_pause_len)
671
                {
672
                    auto_repetition_pause_counter = 0;
673
 
674
                    if (irsnd_protocol == IRMP_DENON_PROTOCOL)
675
                    {
676
                        current_bit = 16;
677
                        complete_data_len   = 2 * DENON_COMPLETE_DATA_LEN + 1;
678
                    }
679
                    else if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL)                       // n'th grundig info frame
680
                    {
681
                        current_bit = 15;
682
                        complete_data_len   = 16 + GRUNDIG_COMPLETE_DATA_LEN;
683
                    }
684
                    else if (irsnd_protocol == IRMP_NOKIA_PROTOCOL)                         // n'th nokia info frame
685
                    {
686
                        if (auto_repetition_counter + 1 < n_auto_repetitions)
687
                        {
688
                            current_bit = 23;
689
                            complete_data_len   = 24 + NOKIA_COMPLETE_DATA_LEN;
690
                        }
691
                        else                                                                // nokia stop frame
692
                        {
693
                            current_bit = 0xFF;
694
                            complete_data_len   = NOKIA_COMPLETE_DATA_LEN;
695
                        }
696
                    }
697
                }
698
                else
699
                {
700
#ifdef DEBUG
701
                    if (irsnd_is_on)
702
                    {
703
                        putchar ('0');
704
                    }
705
                    else
706
                    {
707
                        putchar ('1');
708
                    }
709
#endif
710
                    return irsnd_busy;
711
                }
712
            }
713
            else if (repeat_counter > 0 && packet_repeat_pause_counter < repeat_frame_pause_len)
714
            {
715
                packet_repeat_pause_counter++;
716
 
717
#ifdef DEBUG
718
                if (irsnd_is_on)
719
                {
720
                    putchar ('0');
721
                }
722
                else
723
                {
724
                    putchar ('1');
725
                }
726
#endif
727
                return irsnd_busy;
728
            }
729
            else
730
            {
731
                n_repeat_frames             = irsnd_repeat;
732
                packet_repeat_pause_counter = 0;
733
                pulse_counter               = 0;
734
                pause_counter               = 0;
735
 
736
                switch (irsnd_protocol)
737
                {
738
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
739
                    case IRMP_SIRCS_PROTOCOL:
740
                    {
741
                        startbit_pulse_len          = SIRCS_START_BIT_PULSE_LEN;
742
                        startbit_pause_len          = SIRCS_START_BIT_PAUSE_LEN;
743
                        pulse_1_len                 = SIRCS_1_PULSE_LEN;
744
                        pause_1_len                 = SIRCS_PAUSE_LEN;
745
                        pulse_0_len                 = SIRCS_0_PULSE_LEN;
746
                        pause_0_len                 = SIRCS_PAUSE_LEN;
747
                        has_stop_bit                = SIRCS_STOP_BIT;
748
                        complete_data_len           = SIRCS_MINIMUM_DATA_LEN;
749
                        n_auto_repetitions          = (repeat_counter == 0) ? SIRCS_FRAMES : 1;     // 3 frames auto repetition if first frame
750
                        auto_repetition_pause_len   = SIRCS_AUTO_REPETITION_PAUSE_LEN;              // 25ms pause
751
                        repeat_frame_pause_len      = SIRCS_FRAME_REPEAT_PAUSE_LEN;
752
                        irsnd_set_freq (IRSND_FREQ_40_KHZ);
753
                        break;
754
                    }
755
#endif
756
#if IRSND_SUPPORT_NEC_PROTOCOL == 1
757
                    case IRMP_NEC_PROTOCOL:
758
                    {
759
                        startbit_pulse_len          = NEC_START_BIT_PULSE_LEN;
760
 
761
                        if (repeat_counter > 0)
762
                        {
763
                            startbit_pause_len      = NEC_REPEAT_START_BIT_PAUSE_LEN;
764
                            complete_data_len       = 0;
765
                        }
766
                        else
767
                        {
768
                            startbit_pause_len      = NEC_START_BIT_PAUSE_LEN;
769
                            complete_data_len       = NEC_COMPLETE_DATA_LEN;
770
                        }
771
 
772
                        pulse_1_len                 = NEC_PULSE_LEN;
773
                        pause_1_len                 = NEC_1_PAUSE_LEN;
774
                        pulse_0_len                 = NEC_PULSE_LEN;
775
                        pause_0_len                 = NEC_0_PAUSE_LEN;
776
                        has_stop_bit                = NEC_STOP_BIT;
777
                        n_auto_repetitions          = 1;                                            // 1 frame
778
                        auto_repetition_pause_len   = 0;
779
                        repeat_frame_pause_len      = NEC_FRAME_REPEAT_PAUSE_LEN;
780
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
781
                        break;
782
                    }
783
#endif
784
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
785
                    case IRMP_SAMSUNG_PROTOCOL:
786
                    {
787
                        startbit_pulse_len          = SAMSUNG_START_BIT_PULSE_LEN;
788
                        startbit_pause_len          = SAMSUNG_START_BIT_PAUSE_LEN;
789
                        pulse_1_len                 = SAMSUNG_PULSE_LEN;
790
                        pause_1_len                 = SAMSUNG_1_PAUSE_LEN;
791
                        pulse_0_len                 = SAMSUNG_PULSE_LEN;
792
                        pause_0_len                 = SAMSUNG_0_PAUSE_LEN;
793
                        has_stop_bit                = SAMSUNG_STOP_BIT;
794
                        complete_data_len           = SAMSUNG_COMPLETE_DATA_LEN;
795
                        n_auto_repetitions          = 1;                                            // 1 frame
796
                        auto_repetition_pause_len   = 0;
797
                        repeat_frame_pause_len      = SAMSUNG_FRAME_REPEAT_PAUSE_LEN;
798
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
799
                        break;
800
                    }
801
 
802
                    case IRMP_SAMSUNG32_PROTOCOL:
803
                    {
804
                        startbit_pulse_len          = SAMSUNG_START_BIT_PULSE_LEN;
805
                        startbit_pause_len          = SAMSUNG_START_BIT_PAUSE_LEN;
806
                        pulse_1_len                 = SAMSUNG_PULSE_LEN;
807
                        pause_1_len                 = SAMSUNG_1_PAUSE_LEN;
808
                        pulse_0_len                 = SAMSUNG_PULSE_LEN;
809
                        pause_0_len                 = SAMSUNG_0_PAUSE_LEN;
810
                        has_stop_bit                = SAMSUNG_STOP_BIT;
811
                        complete_data_len           = SAMSUNG32_COMPLETE_DATA_LEN;
812
                        n_auto_repetitions          = SAMSUNG32_FRAMES;                             // 2 frames
813
                        auto_repetition_pause_len   = SAMSUNG32_AUTO_REPETITION_PAUSE_LEN;          // 47 ms pause
814
                        repeat_frame_pause_len      = SAMSUNG32_FRAME_REPEAT_PAUSE_LEN;
815
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
816
                        break;
817
                    }
818
#endif
819
#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
820
                    case IRMP_MATSUSHITA_PROTOCOL:
821
                    {
822
                        startbit_pulse_len          = MATSUSHITA_START_BIT_PULSE_LEN;
823
                        startbit_pause_len          = MATSUSHITA_START_BIT_PAUSE_LEN;
824
                        pulse_1_len                 = MATSUSHITA_PULSE_LEN;
825
                        pause_1_len                 = MATSUSHITA_1_PAUSE_LEN;
826
                        pulse_0_len                 = MATSUSHITA_PULSE_LEN;
827
                        pause_0_len                 = MATSUSHITA_0_PAUSE_LEN;
828
                        has_stop_bit                = MATSUSHITA_STOP_BIT;
829
                        complete_data_len           = MATSUSHITA_COMPLETE_DATA_LEN;
830
                        n_auto_repetitions          = 1;                                            // 1 frame
831
                        auto_repetition_pause_len   = 0;
832
                        repeat_frame_pause_len      = MATSUSHITA_FRAME_REPEAT_PAUSE_LEN;
833
                        irsnd_set_freq (IRSND_FREQ_36_KHZ);
834
                        break;
835
                    }
836
#endif
837
#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
838
                    case IRMP_KASEIKYO_PROTOCOL:
839
                    {
840
                        startbit_pulse_len          = KASEIKYO_START_BIT_PULSE_LEN;
841
                        startbit_pause_len          = KASEIKYO_START_BIT_PAUSE_LEN;
842
                        pulse_1_len                 = KASEIKYO_PULSE_LEN;
843
                        pause_1_len                 = KASEIKYO_1_PAUSE_LEN;
844
                        pulse_0_len                 = KASEIKYO_PULSE_LEN;
845
                        pause_0_len                 = KASEIKYO_0_PAUSE_LEN;
846
                        has_stop_bit                = KASEIKYO_STOP_BIT;
847
                        complete_data_len           = KASEIKYO_COMPLETE_DATA_LEN;
848
                        n_auto_repetitions          = (repeat_counter == 0) ? KASEIKYO_FRAMES : 1;  // 2 frames auto repetition if first frame
849
                        auto_repetition_pause_len   = KASEIKYO_AUTO_REPETITION_PAUSE_LEN;           // 75 ms pause
850
                        repeat_frame_pause_len      = KASEIKYO_FRAME_REPEAT_PAUSE_LEN;
851
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
852
                        break;
853
                    }
854
#endif
855
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
856
                    case IRMP_RECS80_PROTOCOL:
857
                    {
858
                        startbit_pulse_len          = RECS80_START_BIT_PULSE_LEN;
859
                        startbit_pause_len          = RECS80_START_BIT_PAUSE_LEN;
860
                        pulse_1_len                 = RECS80_PULSE_LEN;
861
                        pause_1_len                 = RECS80_1_PAUSE_LEN;
862
                        pulse_0_len                 = RECS80_PULSE_LEN;
863
                        pause_0_len                 = RECS80_0_PAUSE_LEN;
864
                        has_stop_bit                = RECS80_STOP_BIT;
865
                        complete_data_len           = RECS80_COMPLETE_DATA_LEN;
866
                        n_auto_repetitions          = 1;                                            // 1 frame
867
                        auto_repetition_pause_len   = 0;
868
                        repeat_frame_pause_len      = RECS80_FRAME_REPEAT_PAUSE_LEN;
869
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
870
                        break;
871
                    }
872
#endif
873
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
874
                    case IRMP_RECS80EXT_PROTOCOL:
875
                    {
876
                        startbit_pulse_len          = RECS80EXT_START_BIT_PULSE_LEN;
877
                        startbit_pause_len          = RECS80EXT_START_BIT_PAUSE_LEN;
878
                        pulse_1_len                 = RECS80EXT_PULSE_LEN;
879
                        pause_1_len                 = RECS80EXT_1_PAUSE_LEN;
880
                        pulse_0_len                 = RECS80EXT_PULSE_LEN;
881
                        pause_0_len                 = RECS80EXT_0_PAUSE_LEN;
882
                        has_stop_bit                = RECS80EXT_STOP_BIT;
883
                        complete_data_len           = RECS80EXT_COMPLETE_DATA_LEN;
884
                        n_auto_repetitions          = 1;                                            // 1 frame
885
                        auto_repetition_pause_len   = 0;
886
                        repeat_frame_pause_len      = RECS80EXT_FRAME_REPEAT_PAUSE_LEN;
887
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
888
                        break;
889
                    }
890
#endif
891
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
892
                    case IRMP_RC5_PROTOCOL:
893
                    {
894
                        startbit_pulse_len          = RC5_BIT_LEN;
895
                        startbit_pause_len          = RC5_BIT_LEN;
896
                        pulse_len                   = RC5_BIT_LEN;
897
                        pause_len                   = RC5_BIT_LEN;
898
                        has_stop_bit                = RC5_STOP_BIT;
899
                        complete_data_len           = RC5_COMPLETE_DATA_LEN;
900
                        n_auto_repetitions          = 1;                                            // 1 frame
901
                        auto_repetition_pause_len   = 0;
902
                        repeat_frame_pause_len      = RC5_FRAME_REPEAT_PAUSE_LEN;
903
                        irsnd_set_freq (IRSND_FREQ_36_KHZ);
904
                        break;
905
                    }
906
#endif
907
#if IRSND_SUPPORT_DENON_PROTOCOL == 1
908
                    case IRMP_DENON_PROTOCOL:
909
                    {
910
                        startbit_pulse_len          = 0x00;
911
                        startbit_pause_len          = 0x00;
912
                        pulse_1_len                 = DENON_PULSE_LEN;
913
                        pause_1_len                 = DENON_1_PAUSE_LEN;
914
                        pulse_0_len                 = DENON_PULSE_LEN;
915
                        pause_0_len                 = DENON_0_PAUSE_LEN;
916
                        has_stop_bit                = DENON_STOP_BIT;
917
                        complete_data_len           = DENON_COMPLETE_DATA_LEN;
918
                        n_auto_repetitions          = DENON_FRAMES;                                 // 2 frames, 2nd with inverted command
919
                        auto_repetition_pause_len   = DENON_AUTO_REPETITION_PAUSE_LEN;              // 65 ms pause after 1st frame
920
                        repeat_frame_pause_len      = DENON_FRAME_REPEAT_PAUSE_LEN;
921
                        irsnd_set_freq (IRSND_FREQ_32_KHZ);
922
                        break;
923
                    }
924
#endif
925
#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
926
                    case IRMP_NUBERT_PROTOCOL:
927
                    {
928
                        startbit_pulse_len          = NUBERT_START_BIT_PULSE_LEN;
929
                        startbit_pause_len          = NUBERT_START_BIT_PAUSE_LEN;
930
                        pulse_1_len                 = NUBERT_1_PULSE_LEN;
931
                        pause_1_len                 = NUBERT_1_PAUSE_LEN;
932
                        pulse_0_len                 = NUBERT_0_PULSE_LEN;
933
                        pause_0_len                 = NUBERT_0_PAUSE_LEN;
934
                        has_stop_bit                = NUBERT_STOP_BIT;
935
                        complete_data_len           = NUBERT_COMPLETE_DATA_LEN;
936
                        n_auto_repetitions          = NUBERT_FRAMES;                                // 2 frames
937
                        auto_repetition_pause_len   = NUBERT_AUTO_REPETITION_PAUSE_LEN;             // 35 ms pause
938
                        repeat_frame_pause_len      = NUBERT_FRAME_REPEAT_PAUSE_LEN;
939
                        irsnd_set_freq (IRSND_FREQ_36_KHZ);
940
                        break;
941
                    }
942
#endif
943
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
944
                    case IRMP_BANG_OLUFSEN_PROTOCOL:
945
                    {
946
                        startbit_pulse_len          = BANG_OLUFSEN_START_BIT1_PULSE_LEN;
947
                        startbit_pause_len          = BANG_OLUFSEN_START_BIT1_PAUSE_LEN;
948
                        pulse_1_len                 = BANG_OLUFSEN_PULSE_LEN;
949
                        pause_1_len                 = BANG_OLUFSEN_1_PAUSE_LEN;
950
                        pulse_0_len                 = BANG_OLUFSEN_PULSE_LEN;
951
                        pause_0_len                 = BANG_OLUFSEN_0_PAUSE_LEN;
952
                        has_stop_bit                = BANG_OLUFSEN_STOP_BIT;
953
                        complete_data_len           = BANG_OLUFSEN_COMPLETE_DATA_LEN;
954
                        n_auto_repetitions          = 1;                                            // 1 frame
955
                        auto_repetition_pause_len   = 0;
956
                        repeat_frame_pause_len      = BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN;
957
                        last_bit_value              = 0;
958
                        irsnd_set_freq (IRSND_FREQ_455_KHZ);
959
                        break;
960
                    }
961
#endif
962
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
963
                    case IRMP_GRUNDIG_PROTOCOL:
964
                    {
965
                        startbit_pulse_len          = GRUNDIG_OR_NOKIA_BIT_LEN;
966
                        startbit_pause_len          = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;
967
                        pulse_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;
968
                        pause_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;
969
                        has_stop_bit                = GRUNDIG_OR_NOKIA_STOP_BIT;
970
                        complete_data_len           = GRUNDIG_COMPLETE_DATA_LEN;
971
                        n_auto_repetitions          = GRUNDIG_FRAMES;                               // 2 frames
972
                        auto_repetition_pause_len   = GRUNDIG_AUTO_REPETITION_PAUSE_LEN;            // 20m sec pause
973
                        repeat_frame_pause_len      = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;      // 117 msec pause
974
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
975
 
976
                        break;
977
                    }
978
#endif
979
#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
980
                    case IRMP_NOKIA_PROTOCOL:
981
                    {
982
                        startbit_pulse_len          = GRUNDIG_OR_NOKIA_BIT_LEN;
983
                        startbit_pause_len          = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;
984
                        pulse_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;
985
                        pause_len                   = GRUNDIG_OR_NOKIA_BIT_LEN;
986
                        has_stop_bit                = GRUNDIG_OR_NOKIA_STOP_BIT;
987
                        complete_data_len           = NOKIA_COMPLETE_DATA_LEN;
988
                        n_auto_repetitions          = NOKIA_FRAMES;                                 // 2 frames
989
                        auto_repetition_pause_len   = NOKIA_AUTO_REPETITION_PAUSE_LEN;              // 20 msec pause
990
                        repeat_frame_pause_len      = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;      // 117 msec pause
991
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
992
                        break;
993
                    }
994
#endif
995
#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
996
                    case IRMP_SIEMENS_PROTOCOL:
997
                    {
998
                        startbit_pulse_len          = SIEMENS_BIT_LEN;
999
                        startbit_pause_len          = SIEMENS_BIT_LEN;
1000
                        pulse_len                   = SIEMENS_BIT_LEN;
1001
                        pause_len                   = SIEMENS_BIT_LEN;
1002
                        has_stop_bit                = SIEMENS_STOP_BIT;
1003
                        complete_data_len           = SIEMENS_COMPLETE_DATA_LEN - 1;
1004
                        n_auto_repetitions          = 1;                                            // 1 frame
1005
                        auto_repetition_pause_len   = 0;
1006
                        repeat_frame_pause_len      = SIEMENS_FRAME_REPEAT_PAUSE_LEN;
1007
                        irsnd_set_freq (IRSND_FREQ_36_KHZ);
1008
                        break;
1009
                    }
1010
#endif
1011
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
1012
                    case IRMP_FDC_PROTOCOL:
1013
                    {
1014
                        startbit_pulse_len          = FDC_START_BIT_PULSE_LEN;
1015
                        startbit_pause_len          = FDC_START_BIT_PAUSE_LEN;
1016
                        complete_data_len           = FDC_COMPLETE_DATA_LEN;
1017
                        pulse_1_len                 = FDC_PULSE_LEN;
1018
                        pause_1_len                 = FDC_1_PAUSE_LEN;
1019
                        pulse_0_len                 = FDC_PULSE_LEN;
1020
                        pause_0_len                 = FDC_0_PAUSE_LEN;
1021
                        has_stop_bit                = FDC_STOP_BIT;
1022
                        n_auto_repetitions          = 1;                                            // 1 frame
1023
                        auto_repetition_pause_len   = 0;
1024
                        repeat_frame_pause_len      = FDC_FRAME_REPEAT_PAUSE_LEN;
1025
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
1026
                        break;
1027
                    }
1028
#endif
1029
#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
1030
                    case IRMP_RCCAR_PROTOCOL:
1031
                    {
1032
                        startbit_pulse_len          = RCCAR_START_BIT_PULSE_LEN;
1033
                        startbit_pause_len          = RCCAR_START_BIT_PAUSE_LEN;
1034
                        complete_data_len           = RCCAR_COMPLETE_DATA_LEN;
1035
                        pulse_1_len                 = RCCAR_PULSE_LEN;
1036
                        pause_1_len                 = RCCAR_1_PAUSE_LEN;
1037
                        pulse_0_len                 = RCCAR_PULSE_LEN;
1038
                        pause_0_len                 = RCCAR_0_PAUSE_LEN;
1039
                        has_stop_bit                = RCCAR_STOP_BIT;
1040
                        n_auto_repetitions          = 1;                                            // 1 frame
1041
                        auto_repetition_pause_len   = 0;
1042
                        repeat_frame_pause_len      = RCCAR_FRAME_REPEAT_PAUSE_LEN;
1043
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
1044
                        break;
1045
                    }
1046
#endif
1047
#if IRSND_SUPPORT_JVC_PROTOCOL == 1
1048
                    case IRMP_JVC_PROTOCOL:
1049
                    {
1050
                        if (repeat_counter != 0)                                                    // skip start bit if repetition frame
1051
                        {
1052
                            current_bit = 0;
1053
                        }
1054
 
1055
                        startbit_pulse_len          = JVC_START_BIT_PULSE_LEN;
1056
                        startbit_pause_len          = JVC_START_BIT_PAUSE_LEN;
1057
                        complete_data_len           = JVC_COMPLETE_DATA_LEN;
1058
                        pulse_1_len                 = JVC_PULSE_LEN;
1059
                        pause_1_len                 = JVC_1_PAUSE_LEN;
1060
                        pulse_0_len                 = JVC_PULSE_LEN;
1061
                        pause_0_len                 = JVC_0_PAUSE_LEN;
1062
                        has_stop_bit                = JVC_STOP_BIT;
1063
                        n_auto_repetitions          = 1;                                            // 1 frame
1064
                        auto_repetition_pause_len   = 0;
1065
                        repeat_frame_pause_len      = JVC_FRAME_REPEAT_PAUSE_LEN;
1066
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
1067
 
1068
                        break;
1069
                    }
1070
#endif
1071
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
1072
                    case IRMP_NIKON_PROTOCOL:
1073
                    {
1074
                        startbit_pulse_len          = NIKON_START_BIT_PULSE_LEN;
1075
                        startbit_pause_len          = 271; // NIKON_START_BIT_PAUSE_LEN;
1076
                        complete_data_len           = NIKON_COMPLETE_DATA_LEN;
1077
                        pulse_1_len                 = NIKON_PULSE_LEN;
1078
                        pause_1_len                 = NIKON_1_PAUSE_LEN;
1079
                        pulse_0_len                 = NIKON_PULSE_LEN;
1080
                        pause_0_len                 = NIKON_0_PAUSE_LEN;
1081
                        has_stop_bit                = NIKON_STOP_BIT;
1082
                        n_auto_repetitions          = 1;                                            // 1 frame
1083
                        auto_repetition_pause_len   = 0;
1084
                        repeat_frame_pause_len      = NIKON_FRAME_REPEAT_PAUSE_LEN;
1085
                        irsnd_set_freq (IRSND_FREQ_38_KHZ);
1086
 
1087
                        break;
1088
                    }
1089
#endif
1090
                    default:
1091
                    {
1092
                        irsnd_busy = FALSE;
1093
                        break;
1094
                    }
1095
                }
1096
            }
1097
        }
1098
 
1099
        if (irsnd_busy)
1100
        {
1101
            new_frame = FALSE;
1102
 
1103
            switch (irsnd_protocol)
1104
            {
1105
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
1106
                case IRMP_SIRCS_PROTOCOL:
1107
#endif
1108
#if IRSND_SUPPORT_NEC_PROTOCOL == 1
1109
                case IRMP_NEC_PROTOCOL:
1110
#endif
1111
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
1112
                case IRMP_SAMSUNG_PROTOCOL:
1113
                case IRMP_SAMSUNG32_PROTOCOL:
1114
#endif
1115
#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
1116
                case IRMP_MATSUSHITA_PROTOCOL:
1117
#endif
1118
#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
1119
                case IRMP_KASEIKYO_PROTOCOL:
1120
#endif
1121
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
1122
                case IRMP_RECS80_PROTOCOL:
1123
#endif
1124
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
1125
                case IRMP_RECS80EXT_PROTOCOL:
1126
#endif
1127
#if IRSND_SUPPORT_DENON_PROTOCOL == 1
1128
                case IRMP_DENON_PROTOCOL:
1129
#endif
1130
#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
1131
                case IRMP_NUBERT_PROTOCOL:
1132
#endif
1133
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
1134
                case IRMP_BANG_OLUFSEN_PROTOCOL:
1135
#endif
1136
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
1137
                case IRMP_FDC_PROTOCOL:
1138
#endif
1139
#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
1140
                case IRMP_RCCAR_PROTOCOL:
1141
#endif
1142
#if IRSND_SUPPORT_JVC_PROTOCOL == 1
1143
                case IRMP_JVC_PROTOCOL:
1144
#endif
1145
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
1146
                case IRMP_NIKON_PROTOCOL:
1147
#endif
1148
 
1149
 
1150
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1  || IRSND_SUPPORT_NEC_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 ||   \
1151
    IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1 || IRSND_SUPPORT_RECS80_PROTOCOL == 1 || IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 || IRSND_SUPPORT_DENON_PROTOCOL == 1 || \
1152
    IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 ||   \
1153
    IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1
1154
                {
1155
                    if (pulse_counter == 0)
1156
                    {
1157
                        if (current_bit == 0xFF)                                                    // send start bit
1158
                        {
1159
                            pulse_len = startbit_pulse_len;
1160
                            pause_len = startbit_pause_len;
1161
                        }
1162
                        else if (current_bit < complete_data_len)                                   // send n'th bit
1163
                        {
1164
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
1165
                            if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)
1166
                            {
1167
                                if (current_bit < SAMSUNG_ADDRESS_LEN)                              // send address bits
1168
                                {
1169
                                    pulse_len = SAMSUNG_PULSE_LEN;
1170
                                    pause_len = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ?
1171
                                                    SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;
1172
                                }
1173
                                else if (current_bit == SAMSUNG_ADDRESS_LEN)                        // send SYNC bit (16th bit)
1174
                                {
1175
                                    pulse_len = SAMSUNG_PULSE_LEN;
1176
                                    pause_len = SAMSUNG_START_BIT_PAUSE_LEN;
1177
                                }
1178
                                else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN)                   // send n'th bit
1179
                                {
1180
                                    uint8_t cur_bit = current_bit - 1;                              // sync skipped, offset = -1 !
1181
 
1182
                                    pulse_len = SAMSUNG_PULSE_LEN;
1183
                                    pause_len = (irsnd_buffer[cur_bit / 8] & (1<<(7-(cur_bit % 8)))) ?
1184
                                                    SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;
1185
                                }
1186
                            }
1187
                            else
1188
#endif
1189
 
1190
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
1191
                            if (irsnd_protocol == IRMP_BANG_OLUFSEN_PROTOCOL)
1192
                            {
1193
                                if (current_bit == 0)                                               // send 2nd start bit
1194
                                {
1195
                                    pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
1196
                                    pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;
1197
                                }
1198
                                else if (current_bit == 1)                                          // send 3rd start bit
1199
                                {
1200
                                    pulse_len = BANG_OLUFSEN_START_BIT3_PULSE_LEN;
1201
                                    pause_len = BANG_OLUFSEN_START_BIT3_PAUSE_LEN;
1202
                                }
1203
                                else if (current_bit == 2)                                          // send 4th start bit
1204
                                {
1205
                                    pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
1206
                                    pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;
1207
                                }
1208
                                else if (current_bit == 19)                                          // send trailer bit
1209
                                {
1210
                                    pulse_len = BANG_OLUFSEN_PULSE_LEN;
1211
                                    pause_len = BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN;
1212
                                }
1213
                                else if (current_bit < BANG_OLUFSEN_COMPLETE_DATA_LEN)              // send n'th bit
1214
                                {
1215
                                    uint8_t cur_bit_value = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0;
1216
                                    pulse_len = BANG_OLUFSEN_PULSE_LEN;
1217
 
1218
                                    if (cur_bit_value == last_bit_value)
1219
                                    {
1220
                                        pause_len = BANG_OLUFSEN_R_PAUSE_LEN;
1221
                                    }
1222
                                    else
1223
                                    {
1224
                                        pause_len = cur_bit_value ? BANG_OLUFSEN_1_PAUSE_LEN : BANG_OLUFSEN_0_PAUSE_LEN;
1225
                                        last_bit_value = cur_bit_value;
1226
                                    }
1227
                                }
1228
                            }
1229
                            else
1230
#endif
1231
                            if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))
1232
                            {
1233
                                pulse_len = pulse_1_len;
1234
                                pause_len = pause_1_len;
1235
                            }
1236
                            else
1237
                            {
1238
                                pulse_len = pulse_0_len;
1239
                                pause_len = pause_0_len;
1240
                            }
1241
                        }
1242
                        else if (has_stop_bit)                                                                      // send stop bit
1243
                        {
1244
                            pulse_len = pulse_0_len;
1245
 
1246
                            if (auto_repetition_counter < n_auto_repetitions)
1247
                            {
1248
                                pause_len = pause_0_len;
1249
                            }
1250
                            else
1251
                            {
1252
                                pause_len = 255;                                        // last frame: pause of 255
1253
                            }
1254
                        }
1255
                    }
1256
 
1257
                    if (pulse_counter < pulse_len)
1258
                    {
1259
                        if (pulse_counter == 0)
1260
                        {
1261
                            irsnd_on ();
1262
                        }
1263
                        pulse_counter++;
1264
                    }
1265
                    else if (pause_counter < pause_len)
1266
                    {
1267
                        if (pause_counter == 0)
1268
                        {
1269
                            irsnd_off ();
1270
                        }
1271
                        pause_counter++;
1272
                    }
1273
                    else
1274
                    {
1275
                        current_bit++;
1276
 
1277
                        if (current_bit >= complete_data_len + has_stop_bit)
1278
                        {
1279
                            current_bit = 0xFF;
1280
                            auto_repetition_counter++;
1281
 
1282
                            if (auto_repetition_counter == n_auto_repetitions)
1283
                            {
1284
                                irsnd_busy = FALSE;
1285
                                auto_repetition_counter = 0;
1286
                            }
1287
                            new_frame = TRUE;
1288
                        }
1289
 
1290
                        pulse_counter = 0;
1291
                        pause_counter = 0;
1292
                    }
1293
                    break;
1294
                }
1295
#endif
1296
 
1297
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
1298
                case IRMP_RC5_PROTOCOL:
1299
#endif
1300
#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
1301
                case IRMP_SIEMENS_PROTOCOL:
1302
#endif
1303
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
1304
                case IRMP_GRUNDIG_PROTOCOL:
1305
#endif
1306
#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1307
                case IRMP_NOKIA_PROTOCOL:
1308
#endif
1309
 
1310
#if IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 || IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1311
                {
1312
                    if (pulse_counter == pulse_len && pause_counter == pause_len)
1313
                    {
1314
                        current_bit++;
1315
 
1316
                        if (current_bit >= complete_data_len)
1317
                        {
1318
                            current_bit = 0xFF;
1319
 
1320
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1321
                            if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)
1322
                            {
1323
                                auto_repetition_counter++;
1324
 
1325
                                if (repeat_counter > 0)
1326
                                {                                       // set 117 msec pause time
1327
                                    auto_repetition_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;
1328
                                }
1329
 
1330
                                if (repeat_counter < n_repeat_frames)       // tricky: repeat n info frames per auto repetition before sending last stop frame
1331
                                {
1332
                                    n_auto_repetitions++;                   // increment number of auto repetitions
1333
                                    repeat_counter++;
1334
                                }
1335
                                else if (auto_repetition_counter == n_auto_repetitions)
1336
                                {
1337
                                    irsnd_busy = FALSE;
1338
                                    auto_repetition_counter = 0;
1339
                                }
1340
                            }
1341
                            else
1342
#endif
1343
                            {
1344
                                irsnd_busy  = FALSE;
1345
                            }
1346
 
1347
                            new_frame = TRUE;
1348
                            irsnd_off ();
1349
                        }
1350
 
1351
                        pulse_counter = 0;
1352
                        pause_counter = 0;
1353
                    }
1354
 
1355
                    if (! new_frame)
1356
                    {
1357
                        uint8_t first_pulse;
1358
 
1359
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1360
                        if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)
1361
                        {
1362
                            if (current_bit == 0xFF ||                                                                  // start bit of start-frame
1363
                                (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL && current_bit == 15) ||                       // start bit of info-frame (Grundig)
1364
                                (irsnd_protocol == IRMP_NOKIA_PROTOCOL && (current_bit == 23 || current_bit == 47)))    // start bit of info- or stop-frame (Nokia)
1365
                            {
1366
                                pulse_len = startbit_pulse_len;
1367
                                pause_len = startbit_pause_len;
1368
                                first_pulse = TRUE;
1369
                            }
1370
                            else                                                                        // send n'th bit
1371
                            {
1372
                                pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1373
                                pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1374
                                first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;
1375
                            }
1376
                        }
1377
                        else // if (irsnd_protocol == IRMP_RC5_PROTOCOL || irsnd_protocol == IRMP_SIEMENS_PROTOCOL)
1378
#endif
1379
                        {
1380
                            if (current_bit == 0xFF)                                                    // 1 start bit
1381
                            {
1382
                                first_pulse = TRUE;
1383
                            }
1384
                            else                                                                        // send n'th bit
1385
                            {
1386
                                first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;
1387
                            }
1388
 
1389
                            if (irsnd_protocol == IRMP_RC5_PROTOCOL)
1390
                            {
1391
                                first_pulse = first_pulse ? FALSE : TRUE;
1392
                            }
1393
                        }
1394
 
1395
                        if (first_pulse)
1396
                        {
1397
                            if (pulse_counter < pulse_len)
1398
                            {
1399
                                if (pulse_counter == 0)
1400
                                {
1401
                                    irsnd_on ();
1402
                                }
1403
                                pulse_counter++;
1404
                            }
1405
                            else // if (pause_counter < pause_len)
1406
                            {
1407
                                if (pause_counter == 0)
1408
                                {
1409
                                    irsnd_off ();
1410
                                }
1411
                                pause_counter++;
1412
                            }
1413
                        }
1414
                        else
1415
                        {
1416
                            if (pause_counter < pause_len)
1417
                            {
1418
                                if (pause_counter == 0)
1419
                                {
1420
                                    irsnd_off ();
1421
                                }
1422
                                pause_counter++;
1423
                            }
1424
                            else // if (pulse_counter < pulse_len)
1425
                            {
1426
                                if (pulse_counter == 0)
1427
                                {
1428
                                    irsnd_on ();
1429
                                }
1430
                                pulse_counter++;
1431
                            }
1432
                        }
1433
                    }
1434
                    break;
1435
                }
1436
#endif // IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 || IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1437
 
1438
                default:
1439
                {
1440
                    irsnd_busy = FALSE;
1441
                    break;
1442
                }
1443
            }
1444
        }
1445
 
1446
        if (! irsnd_busy)
1447
        {
1448
            if (repeat_counter < n_repeat_frames)
1449
            {
1450
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
1451
                if (irsnd_protocol == IRMP_FDC_PROTOCOL)
1452
                {
1453
                    irsnd_buffer[2] |= 0x0F;
1454
                }
1455
#endif
1456
                repeat_counter++;
1457
                irsnd_busy = TRUE;
1458
            }
1459
            else
1460
            {
1461
                n_repeat_frames = 0;
1462
                repeat_counter = 0;
1463
            }
1464
        }
1465
    }
1466
 
1467
#ifdef DEBUG
1468
    if (irsnd_is_on)
1469
    {
1470
        putchar ('0');
1471
    }
1472
    else
1473
    {
1474
        putchar ('1');
1475
    }
1476
#endif
1477
 
1478
    return irsnd_busy;
1479
}
1480
 
1481
#ifdef DEBUG
1482
 
1483
// main function - for unix/linux + windows only!
1484
// AVR: see main.c!
1485
// Compile it under linux with:
1486
// cc irsnd.c -o irsnd
1487
//
1488
// usage: ./irsnd protocol hex-address hex-command >filename
1489
 
1490
int
1491
main (int argc, char ** argv)
1492
{
1493
    int         idx;
1494
    int         protocol;
1495
    int         address;
1496
    int         command;
1497
    IRMP_DATA   irmp_data;
1498
 
1499
    if (argc != 4 && argc != 5)
1500
    {
1501
        fprintf (stderr, "usage: %s protocol hex-address hex-command [repeat] > filename\n", argv[0]);
1502
        return 1;
1503
    }
1504
 
1505
    if (sscanf (argv[1], "%d", &protocol) == 1 &&
1506
        sscanf (argv[2], "%x", &address) == 1 &&
1507
        sscanf (argv[3], "%x", &command) == 1)
1508
    {
1509
        irmp_data.protocol = protocol;
1510
        irmp_data.address = address;
1511
        irmp_data.command = command;
1512
 
1513
        if (argc == 5)
1514
        {
1515
            irmp_data.flags = atoi (argv[4]);
1516
        }
1517
        else
1518
        {
1519
            irmp_data.flags = 0;
1520
        }
1521
 
1522
        irsnd_init ();
1523
 
1524
        (void) irsnd_send_data (&irmp_data, TRUE);
1525
 
1526
        while (irsnd_busy)
1527
        {
1528
            irsnd_ISR ();
1529
        }
1530
        for (idx = 0; idx < 20; idx++)
1531
        {
1532
            irsnd_ISR ();
1533
        }
1534
 
1535
        putchar ('\n');
1536
    }
1537
    else
1538
    {
1539
        fprintf (stderr, "%s: wrong arguments\n", argv[0]);
1540
        return 1;
1541
    }
1542
    return 0;
1543
}
1544
 
1545
#endif // DEBUG