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